Merge "ARM: dts: msm: Add extcon handle for msm8937"
diff --git a/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt b/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt
index 35383adb..91a49af 100644
--- a/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt
+++ b/Documentation/devicetree/bindings/extcon/qcom,pm8941-misc.txt
@@ -8,7 +8,7 @@
- compatible:
Usage: required
Value type: <string>
- Definition: Should contain "qcom,pm8941-misc";
+ Definition: Should contain "qcom,pm8941-misc" or "qcom,pmd-vbus-det";
- reg:
Usage: required
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt
index 65c3cb8..8f8c87e 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-smb5.txt
@@ -164,6 +164,32 @@
to be get from these properties defined in battery profile:
qcom,step-chg-ranges, qcom,jeita-fcc-ranges, qcom,jeita-fv-ranges.
+- qcom,flash-derating-soc
+ Usage: optional
+ Value type: <u32>
+ Definition: SOC threshold in percentage below which hardware will start
+ derating flash. This is only applicable to certain PMICs like
+ PMI632 which has SCHGM_FLASH peripheral.
+
+- qcom,flash-disable-soc
+ Usage: optional
+ Value type: <u32>
+ Definition: SOC threshold in percentage below which hardware will disable
+ flash. This is only applicable to certain PMICs like PMI632
+ which has SCHGM_FLASH peripheral.
+
+- qcom,headroom-mode
+ Usage: optional
+ Value type: <u32>
+ Definition: Specifies flash hardware headroom management policy. The
+ possible values are:
+ <0>: Fixed mode, constant 5V at flash input.
+ <1>: Adaptive mode allows charger output voltage to be
+ dynamically controlled by the flash module based on the
+ required flash headroom.
+ This is only applicable to certain PMICs like PMI632 which
+ has SCHGM_FLASH peripheral.
+
=============================================
Second Level Nodes - SMB5 Charger Peripherals
=============================================
@@ -301,4 +327,25 @@
"temperature-change",
"switcher-power-ok";
};
+
+ qcom,schgm-flash@a600 {
+ reg = <0xa600 0x100>;
+ interrupts = <0x2 0xa6 0x0 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x1 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x2 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x3 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x4 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x5 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x6 IRQ_TYPE_NONE>,
+ <0x2 0xa6 0x7 IRQ_TYPE_NONE>;
+
+ interrupt-names = "flash-en",
+ "torch-req",
+ "flash-state-change",
+ "vout-up",
+ "vout-down",
+ "ilim1-s1",
+ "ilim2-s2",
+ "vreg-ok";
+ };
};
diff --git a/Documentation/devicetree/bindings/thermal/qcom-bcl-soc.txt b/Documentation/devicetree/bindings/thermal/qcom-bcl-soc.txt
new file mode 100644
index 0000000..00be6de
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/qcom-bcl-soc.txt
@@ -0,0 +1,13 @@
+===============================================================================
+PMIC state of charge driver:
+===============================================================================
+Battery state of charge driver can monitor for change in battery charge and
+notify thermal framework, when the value goes below a certain threshold.
+
+Required Parameters:
+- compatible: must be 'qcom,msm-bcl-soc' for battery state of charge driver.
+
+Example:
+ bcl-soc {
+ compatible = "qcom,msm-bcl-soc";
+ };
diff --git a/Documentation/devicetree/bindings/usb/msm-phy.txt b/Documentation/devicetree/bindings/usb/msm-phy.txt
index e94299f..c0a260f 100644
--- a/Documentation/devicetree/bindings/usb/msm-phy.txt
+++ b/Documentation/devicetree/bindings/usb/msm-phy.txt
@@ -186,6 +186,7 @@
state when attached in host mode and "suspend" state when detached.
- qcom,tune2-efuse-correction: The value to be adjusted from fused value for
improved rise/fall times.
+ - qcom,host-chirp-erratum: Indicates host chirp fix is required.
- nvmem-cells: specifies the handle to represent the SoC revision.
usually it is defined by qfprom device node.
- nvmem-cell-names: specifies the given nvmem cell name as defined in
diff --git a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
index f2f74c3..8f59515 100644
--- a/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
+++ b/arch/arm/boot/dts/qcom/sdxpoorwills.dtsi
@@ -912,6 +912,21 @@
qcom,pet-time = <10000>;
};
+ qcom_rng: qrng@793000{
+ compatible = "qcom,msm-rng";
+ reg = <0x793000 0x1000>;
+ qcom,msm-rng-iface-clk;
+ qcom,no-qrng-config;
+ qcom,msm-bus,name = "msm-rng-noc";
+ qcom,msm-bus,num-cases = <2>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <1 618 0 0>, /* No vote */
+ <1 618 0 800>; /* 100 KHz */
+ clocks = <&clock_gcc GCC_PRNG_AHB_CLK>;
+ clock-names = "iface_clk";
+ };
+
qcom_cedev: qcedev@1de0000 {
compatible = "qcom,qcedev";
reg = <0x1de0000 0x20000>,
diff --git a/arch/arm/configs/sdxpoorwills-perf_defconfig b/arch/arm/configs/sdxpoorwills-perf_defconfig
index 0c6fdf3..c39097c 100644
--- a/arch/arm/configs/sdxpoorwills-perf_defconfig
+++ b/arch/arm/configs/sdxpoorwills-perf_defconfig
@@ -213,6 +213,7 @@
CONFIG_SERIAL_MSM_HS=y
CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MSM_V2=y
@@ -230,6 +231,7 @@
CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_SUPPLY=y
+CONFIG_SMB1351_USB_CHARGER=y
CONFIG_SMB138X_CHARGER=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
@@ -390,4 +392,7 @@
CONFIG_CORESIGHT_CTI=y
CONFIG_CORESIGHT_EVENT=y
CONFIG_CORESIGHT_HWEVENT=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm/configs/sdxpoorwills_defconfig b/arch/arm/configs/sdxpoorwills_defconfig
index 05a7afb..b19a8ca 100644
--- a/arch/arm/configs/sdxpoorwills_defconfig
+++ b/arch/arm/configs/sdxpoorwills_defconfig
@@ -207,6 +207,7 @@
CONFIG_SERIAL_MSM_HS=y
CONFIG_DIAG_CHAR=y
CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_MSM_LEGACY=y
CONFIG_I2C=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_MSM_V2=y
@@ -223,6 +224,7 @@
CONFIG_POWER_RESET_QCOM=y
CONFIG_QCOM_DLOAD_MODE=y
CONFIG_POWER_SUPPLY=y
+CONFIG_SMB1351_USB_CHARGER=y
CONFIG_SMB138X_CHARGER=y
CONFIG_SENSORS_QPNP_ADC_VOLTAGE=y
CONFIG_THERMAL=y
@@ -408,8 +410,10 @@
CONFIG_CORESIGHT_TGU=y
CONFIG_CORESIGHT_HWEVENT=y
CONFIG_CORESIGHT_DUMMY=y
-CONFIG_CRYPTO_ECB=y
CONFIG_CRYPTO_CMAC=y
CONFIG_CRYPTO_SHA256=y
+CONFIG_CRYPTO_DEV_QCOM_MSM_QCE=y
+CONFIG_CRYPTO_DEV_QCRYPTO=y
+CONFIG_CRYPTO_DEV_QCEDEV=y
CONFIG_XZ_DEC=y
CONFIG_QMI_ENCDEC=y
diff --git a/arch/arm64/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi
index 1b38d06..ca28261 100644
--- a/arch/arm64/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi
+++ b/arch/arm64/boot/dts/qcom/dsi-panel-nt36850-truly-dualmipi-wqhd-cmd.dtsi
@@ -27,7 +27,6 @@
qcom,mdss-dsi-bllp-eof-power-mode;
qcom,mdss-dsi-bllp-power-mode;
qcom,mdss-dsi-tx-eot-append;
- qcom,cmd-sync-wait-broadcast;
qcom,mdss-dsi-lane-0-state;
qcom,mdss-dsi-lane-1-state;
qcom,mdss-dsi-lane-2-state;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-audio-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-audio-cdp.dtsi
new file mode 100644
index 0000000..493e002
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-audio-cdp.dtsi
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015-2016, 2018, 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.
+ */
+
+&int_codec {
+ status = "okay";
+ qcom,msm-hs-micbias-type = "external";
+};
+
+&msm_digital_codec {
+ status = "okay";
+};
+
+&pmic_analog_codec {
+ status = "okay";
+};
+
+&wsa881x_i2c_f {
+ status = "okay";
+};
+
+&wsa881x_i2c_45 {
+ status = "okay";
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi b/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi
new file mode 100644
index 0000000..c19f267
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2015-2016, 2018, 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 "msm-audio-lpass.dtsi"
+#include "msm8953-wsa881x.dtsi"
+
+&msm_audio_ion {
+ iommus = <&apps_iommu 0x2401 0x0>;
+ qcom,smmu-sid-mask = /bits/ 64 <0xf>;
+};
+
+&soc {
+ qcom,msm-audio-apr {
+ compatible = "qcom,msm-audio-apr";
+ msm_audio_apr_dummy {
+ compatible = "qcom,msm-audio-apr-dummy";
+ };
+ };
+
+ qcom,avtimer@c0a300c {
+ compatible = "qcom,avtimer";
+ reg = <0x0c0a300c 0x4>,
+ <0x0c0a3010 0x4>;
+ reg-names = "avtimer_lsb_addr", "avtimer_msb_addr";
+ qcom,clk-div = <27>;
+ };
+
+ int_codec: sound {
+ status = "okay";
+ compatible = "qcom,msm8952-audio-codec";
+ qcom,model = "msm8953-snd-card-mtp";
+ reg = <0xc051000 0x4>,
+ <0xc051004 0x4>,
+ <0xc055000 0x4>,
+ <0xc052000 0x4>;
+ reg-names = "csr_gp_io_mux_mic_ctl",
+ "csr_gp_io_mux_spkr_ctl",
+ "csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel",
+ "csr_gp_io_mux_quin_ctl";
+
+ qcom,msm-ext-pa = "primary";
+ qcom,msm-mclk-freq = <9600000>;
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-hs-micbias-type = "internal";
+ qcom,msm-micbias1-ext-cap;
+
+ qcom,audio-routing =
+ "RX_BIAS", "MCLK",
+ "SPK_RX_BIAS", "MCLK",
+ "INT_LDO_H", "MCLK",
+ "RX_I2S_CLK", "MCLK",
+ "TX_I2S_CLK", "MCLK",
+ "MIC BIAS External", "Handset Mic",
+ "MIC BIAS External2", "Headset Mic",
+ "MIC BIAS External", "Secondary Mic",
+ "AMIC1", "MIC BIAS External",
+ "AMIC2", "MIC BIAS External2",
+ "AMIC3", "MIC BIAS External",
+ "ADC1_IN", "ADC1_OUT",
+ "ADC2_IN", "ADC2_OUT",
+ "ADC3_IN", "ADC3_OUT",
+ "PDM_IN_RX1", "PDM_OUT_RX1",
+ "PDM_IN_RX2", "PDM_OUT_RX2",
+ "PDM_IN_RX3", "PDM_OUT_RX3",
+ "WSA_SPK OUT", "VDD_WSA_SWITCH",
+ "SpkrMono WSA_IN", "WSA_SPK OUT";
+
+ qcom,cdc-us-euro-gpios = <&tlmm 63 0>;
+ qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>;
+ qcom,cdc-comp-gpios = <&cdc_comp_gpios>;
+ qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>;
+ qcom,quin-mi2s-gpios = <&cdc_quin_mi2s_gpios>;
+
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>, <&pcm_noirq>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2", "msm-voip-dsp",
+ "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-lsm-client",
+ "msm-pcm-routing", "msm-pcm-dsp-noirq";
+ asoc-cpu = <&dai_pri_auxpcm>,
+ <&dai_mi2s0>, <&dai_mi2s1>,
+ <&dai_mi2s2>, <&dai_mi2s3>,
+ <&dai_mi2s4>, <&dai_mi2s5>,
+ <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
+ <&sb_3_rx>, <&sb_3_tx>, <&sb_4_rx>, <&sb_4_tx>,
+ <&bt_sco_rx>, <&bt_sco_tx>,
+ <&int_fm_rx>, <&int_fm_tx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>,
+ <&afe_proxy_rx>, <&afe_proxy_tx>,
+ <&incall_record_rx>, <&incall_record_tx>,
+ <&incall_music_rx>, <&incall_music_2_rx>;
+
+ asoc-cpu-names = "msm-dai-q6-auxpcm.1",
+ "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-mi2s.4", "msm-dai-q6-mi2s.6",
+ "msm-dai-q6-dev.16384", "msmdai-q6-dev.16385",
+ "msm-dai-q6-dev.16386", "msm-dai-q6-dev.16387",
+ "msm-dai-q6-dev.16390", "msm-dai-q6-dev.16391",
+ "msm-dai-q6-dev.16392", "msm-dai-q6-dev.16393",
+ "msm-dai-q6-dev.12288", "msm-dai-q6-dev.12289",
+ "msm-dai-q6-dev.12292", "msm-dai-q6-dev.12293",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770";
+
+ asoc-codec = <&stub_codec>, <&msm_digital_codec>,
+ <&pmic_analog_codec>;
+ asoc-codec-names = "msm-stub-codec.1", "msm-dig-codec",
+ "analog-codec";
+ asoc-wsa-codec-names = "wsa881x-i2c-codec.2-000f";
+ asoc-wsa-codec-prefixes = "SpkrMono";
+ msm-vdd-wsa-switch-supply = <&pm8953_l5>;
+ qcom,msm-vdd-wsa-switch-voltage = <1800000>;
+ qcom,msm-vdd-wsa-switch-current = <10000>;
+ };
+
+ cdc_us_euro_sw: msm_cdc_pinctrl_us_euro_sw {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cross_conn_det_act>;
+ pinctrl-1 = <&cross_conn_det_sus>;
+ };
+
+ cdc_comp_gpios: cdc_comp_pinctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_pdm_comp_lines_act>;
+ pinctrl-1 = <&cdc_pdm_comp_lines_sus>;
+ };
+
+ cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&cdc_pdm_lines_act &cdc_pdm_lines_2_act>;
+ pinctrl-1 = <&cdc_pdm_lines_sus &cdc_pdm_lines_2_sus>;
+ };
+
+ cdc_quin_mi2s_gpios: msm_cdc_pinctrl_quin {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&pri_tlmm_lines_act &pri_tlmm_ws_act>;
+ pinctrl-1 = <&pri_tlmm_lines_sus &pri_tlmm_ws_sus>;
+ };
+
+
+ i2c@78b6000 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ wsa881x_i2c_f: wsa881x-i2c-codec@f {
+ status = "okay";
+ compatible = "qcom,wsa881x-i2c-codec";
+ reg = <0x0f>;
+ qcom,wsa-analog-vi-gpio = <&wsa881x_analog_vi_gpio>;
+ qcom,wsa-analog-clk-gpio = <&wsa881x_analog_clk_gpio>;
+ qcom,wsa-analog-reset-gpio =
+ <&wsa881x_analog_reset_gpio>;
+ };
+ wsa881x_i2c_45: wsa881x-i2c-codec@45 {
+ status = "okay";
+ compatible = "qcom,wsa881x-i2c-codec";
+ reg = <0x45>;
+ };
+ };
+
+ wsa881x_analog_vi_gpio: wsa881x_analog_vi_pctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&wsa_vi_on>;
+ pinctrl-1 = <&wsa_vi_off>;
+ };
+ wsa881x_analog_clk_gpio: wsa881x_analog_clk_pctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&wsa_clk_on>;
+ pinctrl-1 = <&wsa_clk_off>;
+ };
+ wsa881x_analog_reset_gpio: wsa881x_analog_reset_pctrl {
+ compatible = "qcom,msm-cdc-pinctrl";
+ pinctrl-names = "aud_active", "aud_sleep";
+ pinctrl-0 = <&wsa_reset_on>;
+ pinctrl-1 = <&wsa_reset_off>;
+ };
+
+ ext_codec: sound-9335 {
+ status = "disabled";
+ compatible = "qcom,msm8952-audio-slim-codec";
+ qcom,model = "msm8953-tasha-snd-card";
+
+ reg = <0xc051000 0x4>,
+ <0xc051004 0x4>,
+ <0xc055000 0x4>,
+ <0xc052000 0x4>;
+ reg-names = "csr_gp_io_mux_mic_ctl",
+ "csr_gp_io_mux_spkr_ctl",
+ "csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel",
+ "csr_gp_io_mux_quin_ctl";
+
+ qcom,audio-routing =
+ "AIF4 VI", "MCLK",
+ "AIF4 VI", "MICBIAS_REGULATOR",
+ "RX_BIAS", "MCLK",
+ "MADINPUT", "MCLK",
+ "AIF4 MAD", "MICBIAS_REGULATOR",
+ "AMIC2", "MIC BIAS2",
+ "MIC BIAS2", "Headset Mic",
+ "AMIC3", "MIC BIAS2",
+ "MIC BIAS2", "ANCRight Headset Mic",
+ "AMIC4", "MIC BIAS2",
+ "MIC BIAS2", "ANCLeft Headset Mic",
+ "AMIC5", "MIC BIAS3",
+ "MIC BIAS3", "Handset Mic",
+ "AMIC6", "MIC BIAS4",
+ "MIC BIAS4", "Analog Mic6",
+ "DMIC0", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic0",
+ "DMIC1", "MIC BIAS1",
+ "MIC BIAS1", "Digital Mic1",
+ "DMIC2", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic2",
+ "DMIC3", "MIC BIAS3",
+ "MIC BIAS3", "Digital Mic3",
+ "DMIC4", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic4",
+ "DMIC5", "MIC BIAS4",
+ "MIC BIAS4", "Digital Mic5",
+ "MIC BIAS1", "MICBIAS_REGULATOR",
+ "MIC BIAS2", "MICBIAS_REGULATOR",
+ "MIC BIAS3", "MICBIAS_REGULATOR",
+ "MIC BIAS4", "MICBIAS_REGULATOR",
+ "SpkrLeft IN", "SPK1 OUT",
+ "SpkrRight IN", "SPK2 OUT";
+
+ qcom,tasha-mclk-clk-freq = <9600000>;
+
+ asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
+ <&loopback>, <&compress>, <&hostless>,
+ <&afe>, <&lsm>, <&routing>;
+ asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
+ "msm-pcm-dsp.2", "msm-voip-dsp",
+ "msm-pcm-voice", "msm-pcm-loopback",
+ "msm-compress-dsp", "msm-pcm-hostless",
+ "msm-pcm-afe", "msm-lsm-client",
+ "msm-pcm-routing";
+
+ asoc-cpu = <&dai_pri_auxpcm>,
+ <&dai_mi2s2>, <&dai_mi2s3>, <&dai_mi2s5>,
+ <&sb_0_rx>, <&sb_0_tx>, <&sb_1_rx>, <&sb_1_tx>,
+ <&sb_2_rx>, <&sb_2_tx>, <&sb_3_rx>, <&sb_3_tx>,
+ <&sb_4_rx>, <&sb_4_tx>, <&sb_5_tx>,
+ <&afe_pcm_rx>, <&afe_pcm_tx>,
+ <&afe_proxy_rx>, <&afe_proxy_tx>,
+ <&incall_record_rx>, <&incall_record_tx>,
+ <&incall_music_rx>, <&incall_music_2_rx>,
+ <&sb_5_rx>, <&bt_sco_rx>, <&bt_sco_tx>,
+ <&int_fm_rx>, <&int_fm_tx>, <&sb_6_rx>;
+
+ asoc-cpu-names = "msm-dai-q6-auxpcm.1",
+ "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3",
+ "msm-dai-q6-mi2s.5", "msm-dai-q6-dev.16384",
+ "msm-dai-q6-dev.16385", "msm-dai-q6-dev.16386",
+ "msm-dai-q6-dev.16387", "msm-dai-q6-dev.16388",
+ "msm-dai-q6-dev.16389", "msm-dai-q6-dev.16390",
+ "msm-dai-q6-dev.16391", "msm-dai-q6-dev.16392",
+ "msm-dai-q6-dev.16393", "msm-dai-q6-dev.16395",
+ "msm-dai-q6-dev.224", "msm-dai-q6-dev.225",
+ "msm-dai-q6-dev.241", "msm-dai-q6-dev.240",
+ "msm-dai-q6-dev.32771", "msm-dai-q6-dev.32772",
+ "msm-dai-q6-dev.32773", "msm-dai-q6-dev.32770",
+ "msm-dai-q6-dev.16394", "msm-dai-q6-dev.12288",
+ "msm-dai-q6-dev.12289", "msm-dai-q6-dev.12292",
+ "msm-dai-q6-dev.12293", "msm-dai-q6-dev.16396";
+
+ asoc-codec = <&stub_codec>, <&hdmi_dba>;
+ asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-dba-codec-rx";
+ qcom,cdc-us-euro-gpios = <&tlmm 63 0>;
+ qcom,msm-mbhc-hphl-swh = <0>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+
+ qcom,wsa-max-devs = <2>;
+ qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>,
+ <&wsa881x_213>, <&wsa881x_214>;
+ qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight",
+ "SpkrLeft", "SpkrRight";
+ };
+
+ wcd9xxx_intc: wcd9xxx-irq {
+ status = "disabled";
+ interrupt-parent = <&tlmm>;
+ interrupts = <73 0>;
+ qcom,gpio-connect = <&tlmm 73 0>;
+ };
+
+ clock_audio: audio_ext_clk {
+ status = "disabled";
+ compatible = "qcom,audio-ref-clk";
+ clock-names = "osr_clk";
+ qcom,node_has_rpm_clock;
+ #clock-cells = <1>;
+ qcom,audio-ref-clk-gpio = <&pm8953_gpios 1 0>;
+ qcom,lpass-mclk-id = "pri_mclk";
+ clocks = <&clock_gcc clk_div_clk2>;
+ pinctrl-0 = <&cdc_mclk2_sleep>;
+ pinctrl-1 = <&cdc_mclk2_active>;
+ };
+
+ wcd_rst_gpio: wcd_gpio_ctrl {
+ status = "disabled";
+ qcom,cdc-rst-n-gpio = <&tlmm 67 0>;
+ };
+};
+
+&slim_msm {
+ status = "disabled";
+ wcd9335: tasha_codec {
+ status = "disabled";
+ compatible = "qcom,tasha-slim-pgd";
+ clock-names = "wcd_clk", "wcd_native_clk";
+ clocks = <&clock_audio clk_audio_pmi_clk>,
+ <&clock_audio clk_audio_ap_clk2>;
+
+ qcom,cdc-reset-gpio = <&tlmm 67 0>;
+
+ cdc-vdd-buck-supply = <&eldo2_8953>;
+ qcom,cdc-vdd-buck-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-buck-current = <650000>;
+
+ cdc-buck-sido-supply = <&eldo2_8953>;
+ qcom,cdc-buck-sido-voltage = <1800000 1800000>;
+ qcom,cdc-buck-sido-current = <150000>;
+
+ cdc-vdd-tx-h-supply = <&eldo2_8953>;
+ qcom,cdc-vdd-tx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-tx-h-current = <25000>;
+
+ cdc-vdd-rx-h-supply = <&eldo2_8953>;
+ qcom,cdc-vdd-rx-h-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-rx-h-current = <25000>;
+
+ cdc-vdd-px-supply = <&eldo2_8953>;
+ qcom,cdc-vdd-px-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-px-current = <10000>;
+
+ cdc-vdd-mic-bias-supply = <&pm8953_l13>;
+ qcom,cdc-vdd-mic-bias-voltage = <3125000 3125000>;
+ qcom,cdc-vdd-mic-bias-current = <15000>;
+ };
+};
+&pm8953_gpios {
+ gpio@c000 {
+ status = "ok";
+ qcom,mode = <1>;
+ qcom,pull = <5>;
+ qcom,vin-sel = <0>;
+ qcom,src-sel = <2>;
+ qcom,master-en = <1>;
+ qcom,out-strength = <2>;
+ };
+};
+
+&pm8953_1 {
+ pmic_analog_codec: analog-codec@f000 {
+ status = "okay";
+ compatible = "qcom,pmic-analog-codec";
+ reg = <0xf000 0x200>;
+ #address-cells = <2>;
+ #size-cells = <0>;
+ interrupt-parent = <&spmi_bus>;
+ interrupts = <0x1 0xf0 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x5 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x6 IRQ_TYPE_NONE>,
+ <0x1 0xf0 0x7 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x0 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x1 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x2 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x3 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x4 IRQ_TYPE_NONE>,
+ <0x1 0xf1 0x5 IRQ_TYPE_NONE>;
+ interrupt-names = "spk_cnp_int",
+ "spk_clip_int",
+ "spk_ocp_int",
+ "ins_rem_det1",
+ "but_rel_det",
+ "but_press_det",
+ "ins_rem_det",
+ "mbhc_int",
+ "ear_ocp_int",
+ "hphr_ocp_int",
+ "hphl_ocp_det",
+ "ear_cnp_int",
+ "hphr_cnp_int",
+ "hphl_cnp_int";
+
+ cdc-vdda-cp-supply = <&pm8953_s4>;
+ qcom,cdc-vdda-cp-voltage = <1900000 2050000>;
+ qcom,cdc-vdda-cp-current = <500000>;
+
+ cdc-vdd-io-supply = <&pm8953_l5>;
+ qcom,cdc-vdd-io-voltage = <1800000 1800000>;
+ qcom,cdc-vdd-io-current = <5000>;
+
+ cdc-vdd-pa-supply = <&pm8953_s4>;
+ qcom,cdc-vdd-pa-voltage = <1900000 2050000>;
+ qcom,cdc-vdd-pa-current = <260000>;
+
+ cdc-vdd-mic-bias-supply = <&pm8953_l13>;
+ qcom,cdc-vdd-mic-bias-voltage = <3125000 3125000>;
+ qcom,cdc-vdd-mic-bias-current = <5000>;
+
+ qcom,cdc-mclk-clk-rate = <9600000>;
+
+ qcom,cdc-static-supplies = "cdc-vdd-io",
+ "cdc-vdd-pa",
+ "cdc-vdda-cp";
+
+ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias";
+
+ msm_digital_codec: msm-dig-codec {
+ compatible = "qcom,msm-digital-codec";
+ reg = <0xc0f0000 0x0>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..a46bce3
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-cdp.dtsi
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2015-2018, 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@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l2>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <1>;
+ reg = <0x2>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 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,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l2>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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,eeprom-src = <&eeprom2>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..a7688f0
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2015-2018, 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@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l2>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <1>;
+ reg = <0x2>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 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,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l2>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vana-supply = <&pm8953_l22>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf",
+ "cam_vana";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000 80000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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,eeprom-src = <&eeprom2>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi
new file mode 100644
index 0000000..8098efb
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-qrd.dtsi
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 2015-2018, 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@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ reg = <0x2>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-mode = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 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,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vana-supply = <&pm8953_l22>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf",
+ "cam_vana";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000 80000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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 = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "disabled";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ qcom,camera@2 {
+ cell-index = <2>;
+ compatible = "qcom,camera";
+ reg = <0x02>;
+ qcom,csiphy-sd-index = <2>;
+ qcom,csid-sd-index = <2>;
+ qcom,mount-angle = <270>;
+ qcom,eeprom-src = <&eeprom2>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera.dtsi
index 39d67ab..2685f5a 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-camera.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-camera.dtsi
@@ -332,32 +332,31 @@
compatible = "qcom,vfe";
num_child = <2>;
};
-/*
- * qcom,cam_smmu {
- * status = "ok";
- * compatible = "qcom,msm-cam-smmu";
- * msm_cam_smmu_cb1: msm_cam_smmu_cb1 {
- * compatible = "qcom,qsmmu-cam-cb";
- * iommus = <&apps_iommu 0x400>,
- * <&apps_iommu 0x2800>;
- * label = "vfe";
- * qcom,scratch-buf-support;
- * };
- *
- *
- * msm_cam_smmu_cb3: msm_cam_smmu_cb3 {
- * compatible = "qcom,qsmmu-cam-cb";
- * iommus = <&apps_iommu 0x1c00>;
- * label = "cpp";
- * };
- *
- * msm_cam_smmu_cb4: msm_cam_smmu_cb4 {
- * compatible = "qcom,qsmmu-cam-cb";
- * iommus = <&apps_iommu 0x1800>;
- * label = "jpeg_enc0";
- * };
- * };
- */
+
+ qcom,cam_smmu {
+ status = "ok";
+ compatible = "qcom,msm-cam-smmu";
+ msm_cam_smmu_cb1: msm_cam_smmu_cb1 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_iommu 0x400 0x00>,
+ <&apps_iommu 0x2800 0x00>;
+ label = "vfe";
+ qcom,scratch-buf-support;
+ };
+
+ msm_cam_smmu_cb3: msm_cam_smmu_cb3 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_iommu 0x1c00 0x00>;
+ label = "cpp";
+ };
+
+ msm_cam_smmu_cb4: msm_cam_smmu_cb4 {
+ compatible = "qcom,msm-cam-smmu-cb";
+ iommus = <&apps_iommu 0x1800 0x00>;
+ label = "jpeg_enc0";
+ };
+ };
+
qcom,jpeg@1b1c000 {
status = "ok";
cell-index = <0>;
@@ -422,6 +421,8 @@
qcom,clock-rates = <0 180000000 0 0 180000000 0 0>;
qcom,min-clock-rate = <100000000>;
qcom,bus-master = <1>;
+ resets = <&clock_gcc GCC_CAMSS_MICRO_BCR>;
+ reset-names = "micro_iface_reset";
qcom,msm-bus,name = "msm_camera_cpp";
qcom,msm-bus,num-cases = <2>;
qcom,msm-bus,num-paths = <1>;
@@ -429,6 +430,7 @@
<106 512 0 0>,
<106 512 0 0>;
qcom,msm-bus-vector-dyn-vote;
+ qcom,micro-reset;
qcom,cpp-fw-payload-info {
qcom,stripe-base = <156>;
qcom,plane-base = <141>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-cdp.dts b/arch/arm64/boot/dts/qcom/msm8953-cdp.dts
index 34c5f8f..6105b52 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-cdp.dts
@@ -17,6 +17,7 @@
#include "pmi8950.dtsi"
#include "msm8953-cdp.dtsi"
#include "msm8953-pmi8950.dtsi"
+#include "msm8953-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM8953 + PMI8950 CDP";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi
index 46ff0b7..9aa5260 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-cdp.dtsi
@@ -11,6 +11,8 @@
* GNU General Public License for more details.
*/
+#include "msm8953-audio-cdp.dtsi"
+
&blsp1_uart0 {
status = "ok";
pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp.dts b/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp.dts
index b80583e..59a3136 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-ext-codec-mtp.dts
@@ -17,6 +17,7 @@
#include "pmi8950.dtsi"
#include "msm8953-mtp.dtsi"
#include "msm8953-pmi8950.dtsi"
+#include "msm8953-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM8953 + PMI8950 Ext Codec MTP";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
index 97c6db3..82f6315 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dts
@@ -17,6 +17,7 @@
#include "pmi8950.dtsi"
#include "msm8953-mtp.dtsi"
#include "msm8953-pmi8950.dtsi"
+#include "msm8953-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. MSM8953 + PMI8950 MTP";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pmi632-cdp-s2.dts b/arch/arm64/boot/dts/qcom/msm8953-pmi632-cdp-s2.dts
index 78ff97f..4639f02 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-pmi632-cdp-s2.dts
+++ b/arch/arm64/boot/dts/qcom/msm8953-pmi632-cdp-s2.dts
@@ -16,6 +16,7 @@
#include "msm8953.dtsi"
#include "sdm450-pmi632-cdp-s2.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "sdm632-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. msm8953 + PMI632 CDP S2";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
index d81a0a5..e8bdb7a 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-pmi8950.dtsi
@@ -11,17 +11,6 @@
* GNU General Public License for more details.
*/
-&soc {
- led_flash0: qcom,camera-flash {
- cell-index = <0>;
- compatible = "qcom,camera-flash";
- qcom,flash-type = <1>;
- qcom,flash-source = <&pmi8950_flash0 &pmi8950_flash1>;
- qcom,torch-source = <&pmi8950_torch0 &pmi8950_torch1>;
- qcom,switch-source = <&pmi8950_switch>;
- };
-};
-
&labibb {
status = "ok";
qpnp,qpnp-labibb-mode = "lcd";
diff --git a/arch/arm64/boot/dts/qcom/msm8953-qrd.dtsi b/arch/arm64/boot/dts/qcom/msm8953-qrd.dtsi
index 6f15c42..4e1c030 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-qrd.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-qrd.dtsi
@@ -11,7 +11,6 @@
* GNU General Public License for more details.
*/
-
&soc {
i2c@78b7000 { /* BLSP1 QUP3 */
/delete-node/ synaptics@4b;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi b/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
index d5a6f52..d6d4427 100644
--- a/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953-thermal.dtsi
@@ -1087,4 +1087,19 @@
};
};
};
+
+ pa-therm0 {
+ polling-delay-passive = <0>;
+ polling-delay = <0>;
+ thermal-sensors = <&pm8953_adc_tm 0x36>;
+ thermal-governor = "user_space";
+
+ trips {
+ active-config0 {
+ temperature = <65000>;
+ hysteresis = <5000>;
+ type = "passive";
+ };
+ };
+ };
};
diff --git a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi
new file mode 100644
index 0000000..671b736
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015-2016, 2018, 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.
+ */
+
+&slim_msm {
+ tasha_codec {
+ swr_master {
+ compatible = "qcom,swr-wcd";
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ wsa881x_211: wsa881x@20170211 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x20170211>;
+ qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
+ };
+
+ wsa881x_212: wsa881x@20170212 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x20170212>;
+ qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
+ };
+
+ wsa881x_213: wsa881x@21170213 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x21170213>;
+ qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
+ };
+
+ wsa881x_214: wsa881x@21170214 {
+ compatible = "qcom,wsa881x";
+ reg = <0x00 0x21170214>;
+ qcom,spkr-sd-n-gpio = <&tlmm 96 0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi
index aa96539..b4111b9 100644
--- a/arch/arm64/boot/dts/qcom/msm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi
@@ -1921,6 +1921,7 @@
#include "msm-gdsc-8916.dtsi"
#include "msm8953-thermal.dtsi"
#include "msm8953-camera.dtsi"
+#include "msm8953-audio.dtsi"
&gdsc_venus {
clock-names = "bus_clk", "core_clk";
diff --git a/arch/arm64/boot/dts/qcom/pm8953.dtsi b/arch/arm64/boot/dts/qcom/pm8953.dtsi
index 6cce3b7..21fdfd3 100644
--- a/arch/arm64/boot/dts/qcom/pm8953.dtsi
+++ b/arch/arm64/boot/dts/qcom/pm8953.dtsi
@@ -248,6 +248,7 @@
qcom,adc-bit-resolution = <15>;
qcom,adc-vdd-reference = <1800>;
qcom,adc_tm-vadc = <&pm8953_vadc>;
+ #thermal-sensor-cells = <1>;
};
pm8953_rtc: qcom,pm8953_rtc {
diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi
index 4f27e1f..e263058 100644
--- a/arch/arm64/boot/dts/qcom/pmi632.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi
@@ -355,6 +355,20 @@
"temp-change-smb";
};
+ qcom,schgm-flash@a600 {
+ reg = <0xa600 0x100>;
+ interrupts =
+ <0x2 0xa6 0x2 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0xa6 0x5 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0xa6 0x6 IRQ_TYPE_EDGE_RISING>,
+ <0x2 0xa6 0x7 IRQ_TYPE_EDGE_BOTH>;
+
+ interrupt-names = "flash-state-change",
+ "ilim1-s1",
+ "ilim2-s2",
+ "vreg-ok";
+ };
+
smb5_vbus: qcom,smb5-vbus {
regulator-name = "smb5-vbus";
};
@@ -547,3 +561,13 @@
};
};
+&soc {
+ led_flash0: qcom,camera-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pmi632_flash0 &pmi632_flash1>;
+ qcom,torch-source = <&pmi632_torch0 &pmi632_torch1>;
+ qcom,switch-source = <&pmi632_switch0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/pmi8950.dtsi b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
index ce3637a..6f1f899 100644
--- a/arch/arm64/boot/dts/qcom/pmi8950.dtsi
+++ b/arch/arm64/boot/dts/qcom/pmi8950.dtsi
@@ -627,3 +627,14 @@
};
};
};
+
+&soc {
+ led_flash0: qcom,camera-flash {
+ cell-index = <0>;
+ compatible = "qcom,camera-flash";
+ qcom,flash-type = <1>;
+ qcom,flash-source = <&pmi8950_flash0 &pmi8950_flash1>;
+ qcom,torch-source = <&pmi8950_torch0 &pmi8950_torch1>;
+ qcom,switch-source = <&pmi8950_switch>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
index 02b6821..f592c0e 100644
--- a/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605-lc-mtp.dtsi
@@ -41,3 +41,46 @@
status = "ok";
};
+
+&tlmm {
+ sdc2_cd_on: cd_on {
+ mux {
+ pins = "gpio116";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio116";
+ drive-strength = <2>;
+ bias-pull-up;
+ };
+ };
+
+ sdc2_cd_off: cd_off {
+ mux {
+ pins = "gpio116";
+ function = "gpio";
+ };
+
+ config {
+ pins = "gpio116";
+ drive-strength = <2>;
+ bias-disable;
+ };
+ };
+};
+
+&sdhc_2 {
+ /* VDD external regulator is enabled/disabled by pm660_l18 regulator */
+ vdd-io-supply = <&pm660_l18>;
+ qcom,vdd-io-voltage-level = <1800000 2960000>;
+ qcom,vdd-io-current-level = <0 22000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+ pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+
+ cd-gpios = <&tlmm 116 0x1>;
+
+ status = "ok";
+};
diff --git a/arch/arm64/boot/dts/qcom/qcs605.dtsi b/arch/arm64/boot/dts/qcom/qcs605.dtsi
index 23da195..5adbbb8 100644
--- a/arch/arm64/boot/dts/qcom/qcs605.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcs605.dtsi
@@ -83,3 +83,7 @@
};
};
};
+
+&msm_gpu {
+ /delete-node/qcom,gpu-mempools;
+};
diff --git a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
index fa82be2..51dbe74 100644
--- a/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
+++ b/arch/arm64/boot/dts/qcom/sda845-svr.dtsi
@@ -324,6 +324,10 @@
};
};
+&adsp_mem {
+ size = <0 0xc800000>;
+};
+
&qupv3_se9_2uart {
status = "ok";
};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-cdp.dts b/arch/arm64/boot/dts/qcom/sdm450-cdp.dts
index c55622a..0458650 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-cdp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-cdp.dts
@@ -17,6 +17,7 @@
#include "pmi8950.dtsi"
#include "msm8953-cdp.dtsi"
#include "msm8953-pmi8950.dtsi"
+#include "msm8953-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM450 + PMI8950 CDP";
diff --git a/arch/arm64/boot/dts/qcom/sdm450-mtp.dts b/arch/arm64/boot/dts/qcom/sdm450-mtp.dts
index 5744390..f097895 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-mtp.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-mtp.dts
@@ -17,6 +17,7 @@
#include "pmi8950.dtsi"
#include "msm8953-mtp.dtsi"
#include "msm8953-pmi8950.dtsi"
+#include "msm8953-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM450 + PMI8950 MTP";
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dts b/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dts
index 68f02a8..004186b6be 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632-cdp-s2.dts
@@ -16,6 +16,7 @@
#include "sdm450.dtsi"
#include "sdm450-pmi632-cdp-s2.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "sdm632-camera-sensor-cdp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM450 + PMI632 CDP S2";
diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dts b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dts
index b9aadc1..1a2309f 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dts
@@ -16,6 +16,7 @@
#include "sdm450.dtsi"
#include "sdm450-pmi632-mtp-s3.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "sdm632-camera-sensor-mtp.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM450 + PMI632 MTP S3";
diff --git a/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dts b/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dts
index 977a978..1dc8874 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dts
+++ b/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dts
@@ -16,6 +16,7 @@
#include "sdm450.dtsi"
#include "sdm450-qrd-sku4.dtsi"
#include "sdm450-pmi632.dtsi"
+#include "msm8953-camera-sensor-qrd.dtsi"
/ {
model = "Qualcomm Technologies, Inc. SDM450 + PMI632 QRD SKU4";
@@ -24,3 +25,8 @@
qcom,pmic-id = <0x010016 0x25 0x0 0x0>;
};
+&pmi632_vadc {
+ chan@4a {
+ qcom,scale-function = <22>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi b/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi
index cb78869..d33c42c 100644
--- a/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm450-qrd-sku4.dtsi
@@ -32,6 +32,23 @@
status = "disabled";
};
+&int_codec {
+ status = "okay";
+ qcom,model = "msm8953-sku4-snd-card";
+ qcom,msm-micbias1-ext-cap;
+ qcom,msm-mbhc-hphl-swh = <1>;
+ qcom,msm-mbhc-gnd-swh = <0>;
+ qcom,msm-hs-micbias-type = "internal";
+};
+
+&wsa881x_i2c_f {
+ status = "okay";
+};
+
+&wsa881x_i2c_45 {
+ status = "okay";
+};
+
&tlmm {
pmx_mdss {
mdss_dsi_active: mdss_dsi_active {
diff --git a/arch/arm64/boot/dts/qcom/sdm632-camera-sensor-cdp.dtsi b/arch/arm64/boot/dts/qcom/sdm632-camera-sensor-cdp.dtsi
new file mode 100644
index 0000000..e9295ad
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm632-camera-sensor-cdp.dtsi
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2015-2018, 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@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <1>;
+ reg = <0x2>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 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,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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,eeprom-src = <&eeprom2>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/sdm632-camera-sensor-mtp.dtsi
new file mode 100644
index 0000000..07b3811
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sdm632-camera-sensor-mtp.dtsi
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2015-2018, 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@0 {
+ cell-index = <0>;
+ reg = <0x0>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <0>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ actuator1: qcom,actuator@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ compatible = "qcom,actuator";
+ qcom,cci-master = <1>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vaf";
+ qcom,cam-vreg-min-voltage = <2850000>;
+ qcom,cam-vreg-max-voltage = <2850000>;
+ qcom,cam-vreg-op-mode = <80000>;
+ };
+
+ eeprom0: qcom,eeprom@0 {
+ cell-index = <0>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <0>;
+ reg = <0x0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom1: qcom,eeprom@1 {
+ cell-index = <1>;
+ reg = <0x1>;
+ qcom,eeprom-name = "sunny_8865";
+ compatible = "qcom,eeprom";
+ qcom,slave-addr = <0x6c>;
+ qcom,cci-master = <0>;
+ qcom,num-blocks = <8>;
+
+ qcom,page0 = <1 0x0100 2 0x01 1 1>;
+ qcom,poll0 = <0 0x0 2 0x0 1 0>;
+ qcom,mem0 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page1 = <1 0x5002 2 0x00 1 0>;
+ qcom,poll1 = <0 0x0 2 0x0 1 0>;
+ qcom,mem1 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page2 = <1 0x3d84 2 0xc0 1 0>;
+ qcom,poll2 = <0 0x0 2 0x0 1 0>;
+ qcom,mem2 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page3 = <1 0x3d88 2 0x70 1 0>;
+ qcom,poll3 = <0 0x0 2 0x0 1 0>;
+ qcom,mem3 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page4 = <1 0x3d89 2 0x10 1 0>;
+ qcom,poll4 = <0 0x0 2 0x0 1 0>;
+ qcom,mem4 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page5 = <1 0x3d8a 2 0x70 1 0>;
+ qcom,poll5 = <0 0x0 2 0x0 1 0>;
+ qcom,mem5 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page6 = <1 0x3d8b 2 0xf4 1 0>;
+ qcom,poll6 = <0 0x0 2 0x0 1 0>;
+ qcom,mem6 = <0 0x0 2 0x0 1 0>;
+
+ qcom,page7 = <1 0x3d81 2 0x01 1 10>;
+ qcom,poll7 = <0 0x0 2 0x0 1 1>;
+ qcom,mem7 = <1536 0x7010 2 0 1 0>;
+
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,cam-power-seq-type = "sensor_vreg", "sensor_vreg",
+ "sensor_vreg",
+ "sensor_gpio", "sensor_gpio" , "sensor_clk";
+ qcom,cam-power-seq-val = "cam_vdig", "cam_vana", "cam_vio",
+ "sensor_gpio_reset", "sensor_gpio_standby",
+ "sensor_cam_mclk";
+ qcom,cam-power-seq-cfg-val = <1 1 1 1 1 24000000>;
+ qcom,cam-power-seq-delay = <1 1 1 30 30 5>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 0>;
+ };
+
+ eeprom2: qcom,eeprom@2 {
+ cell-index = <2>;
+ compatible = "qcom,eeprom";
+ qcom,cci-master = <1>;
+ reg = <0x2>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <19200000 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,led-flash-src = <&led_flash0>;
+ qcom,eeprom-src = <&eeprom0>;
+ qcom,actuator-src = <&actuator0>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vaf-supply = <&pm8953_l17>;
+ cam_vana-supply = <&pm8953_l22>;
+ qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf",
+ "cam_vana";
+ qcom,cam-vreg-min-voltage = <0 1100000 2850000 2800000>;
+ qcom,cam-vreg-max-voltage = <0 1100000 2850000 2800000>;
+ qcom,cam-vreg-op-mode = <0 105000 100000 80000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk0_default
+ &cam_sensor_rear_default
+ &cam_sensor_rear_vana>;
+ pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep
+ &cam_sensor_rear_vana_sleep>;
+ gpios = <&tlmm 26 0>,
+ <&tlmm 40 0>,
+ <&tlmm 39 0>,
+ <&tlmm 134 0>;
+ qcom,gpio-reset = <1>;
+ qcom,gpio-standby = <2>;
+ qcom,gpio-vana = <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_MCLK0",
+ "CAM_RESET0",
+ "CAM_STANDBY0",
+ "CAM_VANA";
+ qcom,sensor-position = <0>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <0>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk0_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk0_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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,eeprom-src = <&eeprom2>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <200000 0 80000 100000>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk2_default
+ &cam_sensor_front_default>;
+ pinctrl-1 = <&cam_sensor_mclk2_sleep
+ &cam_sensor_front_sleep>;
+ gpios = <&tlmm 28 0>,
+ <&tlmm 131 0>,
+ <&tlmm 132 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_MCLK1",
+ "CAM_RESET1",
+ "CAM_STANDBY1";
+ qcom,sensor-position = <0x100>;
+ qcom,sensor-mode = <1>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk2_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk2_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+
+ 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>;
+ qcom,eeprom-src = <&eeprom1>;
+ qcom,actuator-src = <&actuator1>;
+ cam_vdig-supply = <&pm8953_l23>;
+ cam_vio-supply = <&pm8953_l6>;
+ cam_vana-supply = <&pm8953_l22>;
+ cam_vaf-supply = <&pm8953_l17>;
+ qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana",
+ "cam_vaf";
+ qcom,cam-vreg-min-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-max-voltage = <1175000 0 2800000 2850000>;
+ qcom,cam-vreg-op-mode = <105000 0 80000 100000>;
+ qcom,gpio-no-mux = <0>;
+ pinctrl-names = "cam_default", "cam_suspend";
+ pinctrl-0 = <&cam_sensor_mclk1_default
+ &cam_sensor_front1_default>;
+ pinctrl-1 = <&cam_sensor_mclk1_sleep
+ &cam_sensor_front1_sleep>;
+ gpios = <&tlmm 27 0>,
+ <&tlmm 129 0>,
+ <&tlmm 130 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_MCLK2",
+ "CAM_RESET2",
+ "CAM_STANDBY2";
+ qcom,sensor-position = <1>;
+ qcom,sensor-mode = <0>;
+ qcom,cci-master = <1>;
+ status = "ok";
+ clocks = <&clock_gcc clk_mclk1_clk_src>,
+ <&clock_gcc clk_gcc_camss_mclk1_clk>;
+ clock-names = "cam_src_clk", "cam_clk";
+ qcom,clock-rates = <24000000 0>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts b/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts
index 9f33721..6b90e1d 100644
--- a/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts
+++ b/arch/arm64/boot/dts/qcom/sdm632-qrd-sku4.dts
@@ -24,3 +24,8 @@
qcom,pmic-id = <0x010016 0x25 0xC 0x0>;
};
+&pmi632_vadc {
+ chan@4a {
+ qcom,scale-function = <22>;
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi b/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
index 3df6d09..8b1f3d1 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-usb.dtsi
@@ -35,6 +35,27 @@
vdd-supply = <&pm660l_l1>;
vdda18-supply = <&pm660_l10>;
vdda33-supply = <&pm660l_l7>;
+ qcom,host-chirp-erratum;
+ qcom,qusb-phy-host-init-seq =
+ /* <value reg_offset> */
+ <0x23 0x210 /* PWR_CTRL1 */
+ 0x03 0x04 /* PLL_ANALOG_CONTROLS_TWO */
+ 0x7c 0x18c /* PLL_CLOCK_INVERTERS */
+ 0x80 0x2c /* PLL_CMODE */
+ 0x0a 0x184 /* PLL_LOCK_DELAY */
+ 0x19 0xb4 /* PLL_DIGITAL_TIMERS_TWO */
+ 0x40 0x194 /* PLL_BIAS_CONTROL_1 */
+ 0x20 0x198 /* PLL_BIAS_CONTROL_2 */
+ 0x21 0x214 /* PWR_CTRL2 */
+ 0x08 0x220 /* IMP_CTRL1 */
+ 0x58 0x224 /* IMP_CTRL2 */
+ 0x45 0x240 /* TUNE1 */
+ 0x29 0x244 /* TUNE2 */
+ 0xca 0x248 /* TUNE3 */
+ 0x04 0x24c /* TUNE4 */
+ 0x03 0x250 /* TUNE5 */
+ 0x00 0x23c /* CHG_CTRL2 */
+ 0x22 0x210>; /* PWR_CTRL1 */
qcom,qusb-phy-init-seq =
/* <value reg_offset> */
<0x23 0x210 /* PWR_CTRL1 */
diff --git a/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi b/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi
index 01d4057..a0b4a22 100644
--- a/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670-vidc.dtsi
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, 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,7 +42,7 @@
"bus_clk", "core0_clk", "core0_bus_clk",
"core1_clk", "core1_bus_clk";
qcom,clock-configs = <0x1 0x0 0x0 0x1 0x0 0x1 0x0>;
- qcom,allowed-clock-rates = <100000000 200000000 320000000
+ qcom,allowed-clock-rates = <100000000 200000000 330000000
380000000 444000000 533000000>;
/* Buses */
@@ -138,7 +138,7 @@
qcom,proxy-clock-names = "core_clk", "iface_clk",
"bus_clk", "core0_clk", "core0_bus_clk";
qcom,clock-configs = <0x1 0x0 0x0 0x1 0x0>;
- qcom,allowed-clock-rates = <100000000 200000000 320000000
+ qcom,allowed-clock-rates = <100000000 200000000 330000000
364700000>;
/* Buses */
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi
index 06113c6..e576baf 100644
--- a/arch/arm64/boot/dts/qcom/sdm670.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -809,6 +809,10 @@
<&apps_smmu 0x716 0x1>;
};
+ qcom_msmhdcp: qcom,msm_hdcp {
+ compatible = "qcom,msm-hdcp";
+ };
+
qcom_crypto: qcrypto@1de0000 {
compatible = "qcom,qcrypto";
reg = <0x1de0000 0x20000>,
diff --git a/arch/arm64/configs/sdm670-perf_defconfig b/arch/arm64/configs/sdm670-perf_defconfig
index 83b0d66..560c510 100644
--- a/arch/arm64/configs/sdm670-perf_defconfig
+++ b/arch/arm64/configs/sdm670-perf_defconfig
@@ -378,6 +378,7 @@
CONFIG_DRM=y
CONFIG_DRM_SDE_EVTLOG_DEBUG=y
CONFIG_DRM_SDE_RSC=y
+CONFIG_DRM_LT_LT9611=y
CONFIG_FB_VIRTUAL=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
diff --git a/drivers/extcon/extcon-qcom-spmi-misc.c b/drivers/extcon/extcon-qcom-spmi-misc.c
index b8cde09..41245d8 100644
--- a/drivers/extcon/extcon-qcom-spmi-misc.c
+++ b/drivers/extcon/extcon-qcom-spmi-misc.c
@@ -1,6 +1,6 @@
/**
* extcon-qcom-spmi-misc.c - Qualcomm USB extcon driver to support USB ID
- * detection based on extcon-usb-gpio.c.
+ * and VBUS detection based on extcon-usb-gpio.c.
*
* Copyright (C) 2016 Linaro, Ltd.
* Stephen Boyd <stephen.boyd@linaro.org>
@@ -28,30 +28,56 @@
struct qcom_usb_extcon_info {
struct extcon_dev *edev;
- int irq;
+ int id_irq;
+ int vbus_irq;
struct delayed_work wq_detcable;
unsigned long debounce_jiffies;
};
static const unsigned int qcom_usb_extcon_cable[] = {
+ EXTCON_USB,
EXTCON_USB_HOST,
EXTCON_NONE,
};
static void qcom_usb_extcon_detect_cable(struct work_struct *work)
{
- bool id;
+ bool state = 0;
int ret;
+ union extcon_property_value val;
struct qcom_usb_extcon_info *info = container_of(to_delayed_work(work),
struct qcom_usb_extcon_info,
wq_detcable);
- /* check ID and update cable state */
- ret = irq_get_irqchip_state(info->irq, IRQCHIP_STATE_LINE_LEVEL, &id);
- if (ret)
- return;
+ if (info->id_irq > 0) {
+ /* check ID and update cable state */
+ ret = irq_get_irqchip_state(info->id_irq,
+ IRQCHIP_STATE_LINE_LEVEL, &state);
+ if (ret)
+ return;
- extcon_set_state_sync(info->edev, EXTCON_USB_HOST, !id);
+ if (!state) {
+ val.intval = true;
+ extcon_set_property(info->edev, EXTCON_USB_HOST,
+ EXTCON_PROP_USB_SS, val);
+ }
+ extcon_set_state_sync(info->edev, EXTCON_USB_HOST, !state);
+ }
+
+ if (info->vbus_irq > 0) {
+ /* check VBUS and update cable state */
+ ret = irq_get_irqchip_state(info->vbus_irq,
+ IRQCHIP_STATE_LINE_LEVEL, &state);
+ if (ret)
+ return;
+
+ if (state) {
+ val.intval = true;
+ extcon_set_property(info->edev, EXTCON_USB,
+ EXTCON_PROP_USB_SS, val);
+ }
+ extcon_set_cable_state_(info->edev, EXTCON_USB, state);
+ }
}
static irqreturn_t qcom_usb_irq_handler(int irq, void *dev_id)
@@ -86,21 +112,48 @@
return ret;
}
+ ret = extcon_set_property_capability(info->edev,
+ EXTCON_USB, EXTCON_PROP_USB_SS);
+ ret |= extcon_set_property_capability(info->edev,
+ EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
+ if (ret) {
+ dev_err(dev, "failed to register extcon props rc=%d\n",
+ ret);
+ return ret;
+ }
+
info->debounce_jiffies = msecs_to_jiffies(USB_ID_DEBOUNCE_MS);
INIT_DELAYED_WORK(&info->wq_detcable, qcom_usb_extcon_detect_cable);
- info->irq = platform_get_irq_byname(pdev, "usb_id");
- if (info->irq < 0)
- return info->irq;
-
- ret = devm_request_threaded_irq(dev, info->irq, NULL,
+ info->id_irq = platform_get_irq_byname(pdev, "usb_id");
+ if (info->id_irq > 0) {
+ ret = devm_request_threaded_irq(dev, info->id_irq, NULL,
qcom_usb_irq_handler,
IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
pdev->name, info);
- if (ret < 0) {
- dev_err(dev, "failed to request handler for ID IRQ\n");
- return ret;
+ if (ret < 0) {
+ dev_err(dev, "failed to request handler for ID IRQ\n");
+ return ret;
+ }
+ }
+
+ info->vbus_irq = platform_get_irq_byname(pdev, "usb_vbus");
+ if (info->vbus_irq > 0) {
+ ret = devm_request_threaded_irq(dev, info->vbus_irq, NULL,
+ qcom_usb_irq_handler,
+ IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ pdev->name, info);
+ if (ret < 0) {
+ dev_err(dev, "failed to request handler for VBUS IRQ\n");
+ return ret;
+ }
+ }
+
+ if (info->id_irq < 0 && info->vbus_irq < 0) {
+ dev_err(dev, "ID and VBUS IRQ not found\n");
+ return -EINVAL;
}
platform_set_drvdata(pdev, info);
@@ -127,8 +180,12 @@
struct qcom_usb_extcon_info *info = dev_get_drvdata(dev);
int ret = 0;
- if (device_may_wakeup(dev))
- ret = enable_irq_wake(info->irq);
+ if (device_may_wakeup(dev)) {
+ if (info->id_irq > 0)
+ ret = enable_irq_wake(info->id_irq);
+ if (info->vbus_irq > 0)
+ ret = enable_irq_wake(info->vbus_irq);
+ }
return ret;
}
@@ -138,8 +195,12 @@
struct qcom_usb_extcon_info *info = dev_get_drvdata(dev);
int ret = 0;
- if (device_may_wakeup(dev))
- ret = disable_irq_wake(info->irq);
+ if (device_may_wakeup(dev)) {
+ if (info->id_irq > 0)
+ ret = disable_irq_wake(info->id_irq);
+ if (info->vbus_irq > 0)
+ ret = disable_irq_wake(info->vbus_irq);
+ }
return ret;
}
@@ -150,6 +211,7 @@
static const struct of_device_id qcom_usb_extcon_dt_match[] = {
{ .compatible = "qcom,pm8941-misc", },
+ { .compatible = "qcom,pmd-vbus-det", },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_usb_extcon_dt_match);
diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c
index b1d03d6..731a554 100644
--- a/drivers/gpu/drm/msm/dp/dp_display.c
+++ b/drivers/gpu/drm/msm/dp/dp_display.c
@@ -48,11 +48,6 @@
void *hdcp1;
void *hdcp2;
- int enc_lvl;
-
- bool auth_state;
- bool hdcp1_present;
- bool hdcp2_present;
bool feature_enabled;
};
@@ -65,6 +60,8 @@
bool power_on;
bool audio_supported;
+ atomic_t aborted;
+
struct platform_device *pdev;
struct dentry *root;
struct completion notification_comp;
@@ -93,7 +90,6 @@
struct work_struct attention_work;
struct mutex hdcp_mutex;
struct mutex session_lock;
- int hdcp_status;
unsigned long audio_status;
};
@@ -109,9 +105,8 @@
static inline bool dp_display_is_hdcp_enabled(struct dp_display_private *dp)
{
- return dp->hdcp.feature_enabled &&
- (dp->hdcp.hdcp1_present || dp->hdcp.hdcp2_present) &&
- dp->hdcp.ops;
+ return dp->hdcp.feature_enabled && dp->link->hdcp_status.hdcp_version
+ && dp->hdcp.ops;
}
static irqreturn_t dp_display_irq(int irq, void *dev_id)
@@ -156,32 +151,25 @@
ops = dp->hdcp.ops;
- switch (dp->hdcp_status) {
- case HDCP_STATE_AUTHENTICATING:
- pr_debug("start authenticaton\n");
+ pr_debug("%s: %s\n",
+ sde_hdcp_version(dp->link->hdcp_status.hdcp_version),
+ sde_hdcp_state_name(dp->link->hdcp_status.hdcp_state));
+ switch (dp->link->hdcp_status.hdcp_state) {
+ case HDCP_STATE_AUTHENTICATING:
if (dp->hdcp.ops && dp->hdcp.ops->authenticate)
rc = dp->hdcp.ops->authenticate(dp->hdcp.data);
-
- break;
- case HDCP_STATE_AUTHENTICATED:
- pr_debug("hdcp authenticated\n");
- dp->hdcp.auth_state = true;
break;
case HDCP_STATE_AUTH_FAIL:
- dp->hdcp.auth_state = false;
-
if (dp->power_on) {
- pr_debug("Reauthenticating\n");
if (ops && ops->reauthenticate) {
rc = ops->reauthenticate(dp->hdcp.data);
if (rc)
- pr_err("reauth failed rc=%d\n", rc);
+ pr_err("failed rc=%d\n", rc);
}
} else {
pr_debug("not reauthenticating, cable disconnected\n");
}
-
break;
default:
break;
@@ -189,7 +177,7 @@
}
static void dp_display_notify_hdcp_status_cb(void *ptr,
- enum sde_hdcp_states status)
+ enum sde_hdcp_state state)
{
struct dp_display_private *dp = ptr;
@@ -198,7 +186,7 @@
return;
}
- dp->hdcp_status = status;
+ dp->link->hdcp_status.hdcp_state = state;
if (dp->dp_display.is_connected)
queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ/4);
@@ -214,12 +202,16 @@
{
void *fd = NULL;
struct sde_hdcp_ops *ops = NULL;
+ bool hdcp2_present = false, hdcp1_present = false;
if (!dp) {
pr_err("invalid input\n");
return;
}
+ dp->link->hdcp_status.hdcp_state = HDCP_STATE_INACTIVE;
+ dp->link->hdcp_status.hdcp_version = HDCP_VERSION_NONE;
+
if (!dp->hdcp.feature_enabled) {
pr_debug("feature not enabled\n");
return;
@@ -230,26 +222,29 @@
ops = sde_dp_hdcp2p2_start(fd);
if (ops && ops->feature_supported)
- dp->hdcp.hdcp2_present = ops->feature_supported(fd);
+ hdcp2_present = ops->feature_supported(fd);
else
- dp->hdcp.hdcp2_present = false;
+ hdcp2_present = false;
pr_debug("hdcp2p2: %s\n",
- dp->hdcp.hdcp2_present ? "supported" : "not supported");
+ hdcp2_present ? "supported" : "not supported");
- if (!dp->hdcp.hdcp2_present) {
- dp->hdcp.hdcp1_present = hdcp1_check_if_supported_load_app();
+ if (!hdcp2_present) {
+ hdcp1_present = hdcp1_check_if_supported_load_app();
- if (dp->hdcp.hdcp1_present) {
+ if (hdcp1_present) {
fd = dp->hdcp.hdcp1;
ops = sde_hdcp_1x_start(fd);
+ dp->link->hdcp_status.hdcp_version = HDCP_VERSION_1X;
}
+ } else {
+ dp->link->hdcp_status.hdcp_version = HDCP_VERSION_2P2;
}
pr_debug("hdcp1x: %s\n",
- dp->hdcp.hdcp1_present ? "supported" : "not supported");
+ hdcp1_present ? "supported" : "not supported");
- if (dp->hdcp.hdcp2_present || dp->hdcp.hdcp1_present) {
+ if (hdcp2_present || hdcp1_present) {
dp->hdcp.data = fd;
dp->hdcp.ops = ops;
} else {
@@ -290,7 +285,6 @@
hdcp_init_data.drm_aux = dp->aux->drm_aux;
hdcp_init_data.cb_data = (void *)dp;
hdcp_init_data.workq = dp->wq;
- hdcp_init_data.mutex = &dp->hdcp_mutex;
hdcp_init_data.sec_access = true;
hdcp_init_data.notify_status = dp_display_notify_hdcp_status_cb;
hdcp_init_data.dp_ahb = &parser->get_io(parser, "dp_ahb")->io;
@@ -302,6 +296,7 @@
hdcp_init_data.hdcp_io = &parser->get_io(parser,
"hdcp_physical")->io;
hdcp_init_data.revision = &dp->panel->link_info.revision;
+ hdcp_init_data.msm_hdcp_dev = dp->parser->msm_hdcp_dev;
dp->hdcp.hdcp1 = sde_hdcp_1x_init(&hdcp_init_data);
if (IS_ERR_OR_NULL(dp->hdcp.hdcp1)) {
@@ -627,7 +622,7 @@
static void dp_display_clean(struct dp_display_private *dp)
{
if (dp_display_is_hdcp_enabled(dp)) {
- dp->hdcp_status = HDCP_STATE_INACTIVE;
+ dp->link->hdcp_status.hdcp_state = HDCP_STATE_INACTIVE;
cancel_delayed_work_sync(&dp->hdcp_cb_work);
if (dp->hdcp.ops->off)
@@ -646,6 +641,11 @@
int rc;
rc = dp_display_process_hpd_low(dp);
+ if (rc) {
+ /* cancel any pending request */
+ dp->ctrl->abort(dp->ctrl);
+ dp->aux->abort(dp->aux);
+ }
mutex_lock(&dp->session_lock);
if (rc && dp->power_on)
@@ -688,6 +688,7 @@
dp->link->psm_config(dp->link, &dp->panel->link_info, true);
/* cancel any pending request */
+ atomic_set(&dp->aborted, 1);
dp->ctrl->abort(dp->ctrl);
dp->aux->abort(dp->aux);
@@ -696,6 +697,7 @@
flush_workqueue(dp->wq);
dp_display_handle_disconnect(dp);
+ atomic_set(&dp->aborted, 0);
end:
return rc;
}
@@ -779,6 +781,12 @@
return -ENODEV;
}
+ /* check if framework is ready */
+ if (!dp_display_framework_ready(dp)) {
+ pr_err("framework not ready\n");
+ return -ENODEV;
+ }
+
if (dp->usbpd->hpd_irq && dp->usbpd->hpd_high &&
dp->power_on) {
dp->link->process_request(dp->link);
@@ -787,6 +795,7 @@
queue_delayed_work(dp->wq, &dp->connect_work, 0);
} else {
/* cancel any pending request */
+ atomic_set(&dp->aborted, 1);
dp->ctrl->abort(dp->ctrl);
dp->aux->abort(dp->aux);
@@ -795,6 +804,7 @@
flush_workqueue(dp->wq);
dp_display_handle_disconnect(dp);
+ atomic_set(&dp->aborted, 0);
}
return 0;
@@ -811,6 +821,11 @@
return;
}
+ if (atomic_read(&dp->aborted)) {
+ pr_err("aborted\n");
+ return;
+ }
+
dp_display_process_hpd_high(dp);
}
@@ -1063,6 +1078,11 @@
goto end;
}
+ if (atomic_read(&dp->aborted)) {
+ pr_err("aborted\n");
+ goto end;
+ }
+
dp->aux->init(dp->aux, dp->parser->aux_cfg);
rc = dp->ctrl->on(dp->ctrl);
@@ -1095,6 +1115,11 @@
goto end;
}
+ if (atomic_read(&dp->aborted)) {
+ pr_err("aborted\n");
+ goto end;
+ }
+
dp->panel->spd_config(dp->panel);
if (dp->audio_supported) {
@@ -1108,7 +1133,7 @@
if (dp_display_is_hdcp_enabled(dp)) {
cancel_delayed_work_sync(&dp->hdcp_cb_work);
- dp->hdcp_status = HDCP_STATE_AUTHENTICATING;
+ dp->link->hdcp_status.hdcp_state = HDCP_STATE_AUTHENTICATING;
queue_delayed_work(dp->wq, &dp->hdcp_cb_work, HZ / 2);
}
@@ -1142,7 +1167,7 @@
}
if (dp_display_is_hdcp_enabled(dp)) {
- dp->hdcp_status = HDCP_STATE_INACTIVE;
+ dp->link->hdcp_status.hdcp_state = HDCP_STATE_INACTIVE;
cancel_delayed_work_sync(&dp->hdcp_cb_work);
if (dp->hdcp.ops->off)
@@ -1370,6 +1395,7 @@
dp->pdev = pdev;
dp->name = "drm_dp";
dp->audio_status = -ENODEV;
+ atomic_set(&dp->aborted, 0);
rc = dp_display_create_workqueue(dp);
if (rc) {
diff --git a/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c b/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c
index 0e1490f..2b7b217 100644
--- a/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c
+++ b/drivers/gpu/drm/msm/dp/dp_hdcp2p2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, 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,6 +19,7 @@
#include <linux/types.h>
#include <linux/kthread.h>
#include <linux/hdcp_qseecom.h>
+#include <linux/msm_hdcp.h>
#include <drm/drm_dp_helper.h>
#include "sde_hdcp.h"
@@ -320,35 +321,16 @@
struct dp_hdcp2p2_ctrl *ctrl = (struct dp_hdcp2p2_ctrl *)client_ctx;
struct hdcp_lib_wakeup_data cdata = {
HDCP_LIB_WKUP_CMD_QUERY_STREAM_TYPE};
- bool enc_notify = true;
- int enc_lvl;
if (!ctrl) {
pr_err("invalid input\n");
return;
}
- switch (min_enc_level) {
- case 0:
- enc_lvl = HDCP_STATE_AUTH_ENC_NONE;
- break;
- case 1:
- enc_lvl = HDCP_STATE_AUTH_ENC_1X;
- break;
- case 2:
- enc_lvl = HDCP_STATE_AUTH_ENC_2P2;
- break;
- default:
- enc_notify = false;
- }
-
pr_debug("enc level changed %d\n", min_enc_level);
cdata.context = ctrl->lib_ctx;
dp_hdcp2p2_wakeup_lib(ctrl, &cdata);
-
- if (enc_notify && ctrl->init_data.notify_status)
- ctrl->init_data.notify_status(ctrl->init_data.cb_data, enc_lvl);
}
static void dp_hdcp2p2_auth_failed(struct dp_hdcp2p2_ctrl *ctrl)
@@ -812,7 +794,6 @@
static struct hdcp_client_ops client_ops = {
.wakeup = dp_hdcp2p2_wakeup,
- .notify_lvl_change = dp_hdcp2p2_min_level_change,
};
static struct dp_hdcp2p2_int_set int_set1[] = {
{BIT(17), "authentication successful", NULL},
@@ -867,6 +848,9 @@
goto error;
}
+ msm_hdcp_register_cb(init_data->msm_hdcp_dev, ctrl,
+ dp_hdcp2p2_min_level_change);
+
kthread_init_worker(&ctrl->worker);
kthread_init_work(&ctrl->auth, dp_hdcp2p2_auth_work);
diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
index 46d30a7..d14b881 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.h
+++ b/drivers/gpu/drm/msm/dp/dp_link.h
@@ -72,6 +72,11 @@
u32 test_audio_period_ch_8;
};
+struct dp_link_hdcp_status {
+ int hdcp_state;
+ int hdcp_version;
+};
+
struct dp_link_phy_params {
u32 phy_test_pattern_sel;
u8 v_level;
@@ -110,6 +115,7 @@
struct dp_link_test_audio test_audio;
struct dp_link_phy_params phy_params;
struct dp_link_params link_params;
+ struct dp_link_hdcp_status hdcp_status;
u32 (*get_test_bits_depth)(struct dp_link *dp_link, u32 bpp);
int (*process_request)(struct dp_link *dp_link);
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.c b/drivers/gpu/drm/msm/dp/dp_parser.c
index adcc762..0174ea10 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.c
+++ b/drivers/gpu/drm/msm/dp/dp_parser.c
@@ -15,6 +15,7 @@
#define pr_fmt(fmt) "[drm-dp] %s: " fmt, __func__
#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
#include "dp_parser.h"
@@ -159,6 +160,30 @@
return 0;
}
+static int dp_parser_msm_hdcp_dev(struct dp_parser *parser)
+{
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_find_compatible_node(NULL, NULL, "qcom,msm-hdcp");
+ if (!node) {
+ // This is a non-fatal error, module initialization can proceed
+ pr_warn("couldn't find msm-hdcp node\n");
+ return 0;
+ }
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ // This is a non-fatal error, module initialization can proceed
+ pr_warn("couldn't find msm-hdcp pdev\n");
+ return 0;
+ }
+
+ parser->msm_hdcp_dev = &pdev->dev;
+
+ return 0;
+}
+
static int dp_parser_pinctrl(struct dp_parser *parser)
{
int rc = 0;
@@ -587,6 +612,10 @@
goto err;
rc = dp_parser_pinctrl(parser);
+ if (rc)
+ goto err;
+
+ rc = dp_parser_msm_hdcp_dev(parser);
err:
return rc;
}
diff --git a/drivers/gpu/drm/msm/dp/dp_parser.h b/drivers/gpu/drm/msm/dp/dp_parser.h
index 6e78db2..a768ca3 100644
--- a/drivers/gpu/drm/msm/dp/dp_parser.h
+++ b/drivers/gpu/drm/msm/dp/dp_parser.h
@@ -156,6 +156,7 @@
* struct dp_parser - DP parser's data exposed to clients
*
* @pdev: platform data of the client
+ * @msm_hdcp_dev: device pointer for the HDCP driver
* @mp: gpio, regulator and clock related data
* @pinctrl: pin-control related data
* @ctrl_resouce: controller's register address realated data
@@ -167,6 +168,7 @@
*/
struct dp_parser {
struct platform_device *pdev;
+ struct device *msm_hdcp_dev;
struct dss_module_power mp[DP_MAX_PM];
struct dp_pinctrl pinctrl;
struct dp_io io;
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
index 0113c83..5b8c910 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.c
@@ -1416,8 +1416,7 @@
u32 lanes = 0;
u32 ulps_lanes;
- if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE)
- lanes = dsi_ctrl->host_config.common_config.data_lanes;
+ lanes = dsi_ctrl->host_config.common_config.data_lanes;
rc = dsi_ctrl->hw.ops.wait_for_lane_idle(&dsi_ctrl->hw, lanes);
if (rc) {
@@ -1458,9 +1457,7 @@
return 0;
}
- if (dsi_ctrl->host_config.panel_mode == DSI_OP_CMD_MODE)
- lanes = dsi_ctrl->host_config.common_config.data_lanes;
-
+ lanes = dsi_ctrl->host_config.common_config.data_lanes;
lanes |= DSI_CLOCK_LANE;
ulps_lanes = dsi_ctrl->hw.ops.ulps_ops.get_lanes_in_ulps(&dsi_ctrl->hw);
@@ -2439,6 +2436,31 @@
}
/**
+ * dsi_ctrl_update_host_init_state() - Update the host initialization state.
+ * @dsi_ctrl: DSI controller handle.
+ * @enable: boolean signifying host state.
+ *
+ * Update the host initialization status only while exiting from ulps during
+ * suspend state.
+ *
+ * Return: error code.
+ */
+int dsi_ctrl_update_host_init_state(struct dsi_ctrl *dsi_ctrl, bool enable)
+{
+ int rc = 0;
+ u32 state = enable ? 0x1 : 0x0;
+
+ rc = dsi_ctrl_check_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, state);
+ if (rc) {
+ pr_err("[DSI_%d] Controller state check failed, rc=%d\n",
+ dsi_ctrl->cell_index, rc);
+ return rc;
+ }
+ dsi_ctrl_update_state(dsi_ctrl, DSI_CTRL_OP_HOST_INIT, state);
+ return rc;
+}
+
+/**
* dsi_ctrl_host_init() - Initialize DSI host hardware.
* @dsi_ctrl: DSI controller handle.
* @is_splash_enabled: boolean signifying splash status.
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
index 9636dbe..ed3d0eb 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_ctrl.h
@@ -743,4 +743,9 @@
int dsi_ctrl_get_host_engine_init_state(struct dsi_ctrl *dsi_ctrl,
bool *state);
+/**
+ * dsi_ctrl_update_host_init_state() - Set the host initialization state
+ */
+int dsi_ctrl_update_host_init_state(struct dsi_ctrl *dsi_ctrl, bool en);
+
#endif /* _DSI_CTRL_H_ */
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
index fd18905..c5f8092 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.c
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/of.h>
#include <linux/of_graph.h>
+#include <linux/of_gpio.h>
#include <linux/err.h>
#include "msm_drv.h"
@@ -309,6 +310,90 @@
dsi_panel_release_panel_lock(display->panel);
}
+static irqreturn_t dsi_display_panel_te_irq_handler(int irq, void *data)
+{
+ struct dsi_display *display = (struct dsi_display *)data;
+
+ /*
+ * This irq handler is used for sole purpose of identifying
+ * ESD attacks on panel and we can safely assume IRQ_HANDLED
+ * in case of display not being initalized yet
+ */
+ if (!display)
+ return IRQ_HANDLED;
+
+ atomic_set(&display->te_irq_triggered, 1);
+
+ return IRQ_HANDLED;
+}
+
+static void dsi_display_change_te_irq_status(struct dsi_display *display,
+ bool enable)
+{
+ if (!display) {
+ pr_err("Invalid params\n");
+ return;
+ }
+
+ /* Handle unbalanced irq enable/disbale calls */
+ if (enable && !display->is_te_irq_enabled) {
+ atomic_set(&display->te_irq_triggered, 1);
+ enable_irq(gpio_to_irq(display->disp_te_gpio));
+ display->is_te_irq_enabled = true;
+ } else if (!enable && display->is_te_irq_enabled) {
+ disable_irq(gpio_to_irq(display->disp_te_gpio));
+ atomic_set(&display->te_irq_triggered, 0);
+ display->is_te_irq_enabled = false;
+ }
+}
+
+static void dsi_display_register_te_irq(struct dsi_display *display)
+{
+ int rc;
+ struct platform_device *pdev;
+ struct device *dev;
+
+ pdev = display->pdev;
+ if (!pdev) {
+ pr_err("invalid platform device\n");
+ return;
+ }
+
+ dev = &pdev->dev;
+ if (!dev) {
+ pr_err("invalid device\n");
+ return;
+ }
+
+ rc = devm_request_irq(dev, gpio_to_irq(display->disp_te_gpio),
+ dsi_display_panel_te_irq_handler, IRQF_TRIGGER_FALLING,
+ "TE_GPIO", display);
+ if (rc) {
+ pr_err("TE request_irq failed for ESD rc:%d\n", rc);
+ return;
+ }
+
+ disable_irq(gpio_to_irq(display->disp_te_gpio));
+ display->is_te_irq_enabled = false;
+}
+
+static bool dsi_display_is_te_based_esd(struct dsi_display *display)
+{
+ u32 status_mode = 0;
+
+ if (!display->panel) {
+ pr_err("Invalid panel data\n");
+ return false;
+ }
+
+ status_mode = display->panel->esd_config.status_mode;
+
+ if (status_mode == ESD_MODE_PANEL_TE &&
+ gpio_is_valid(display->disp_te_gpio))
+ return true;
+ return false;
+}
+
/* Allocate memory for cmd dma tx buffer */
static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display)
{
@@ -421,6 +506,27 @@
return false;
}
+static void dsi_display_parse_te_gpio(struct dsi_display *display)
+{
+ struct platform_device *pdev;
+ struct device *dev;
+
+ pdev = display->pdev;
+ if (!pdev) {
+ pr_err("Inavlid platform device\n");
+ return;
+ }
+
+ dev = &pdev->dev;
+ if (!dev) {
+ pr_err("Inavlid platform device\n");
+ return;
+ }
+
+ display->disp_te_gpio = of_get_named_gpio(dev->of_node,
+ "qcom,platform-te-gpio", 0);
+}
+
static int dsi_display_read_status(struct dsi_display_ctrl *ctrl,
struct dsi_panel *panel)
{
@@ -566,12 +672,16 @@
static int dsi_display_status_check_te(struct dsi_display *display)
{
- int rc = 0;
+ int const esd_check_success = 1;
- pr_debug(" ++\n");
- /* TODO: wait for TE interrupt from panel */
+ if (atomic_read(&display->te_irq_triggered)) {
+ atomic_set(&display->te_irq_triggered, 0);
+ } else {
+ pr_err("ESD check failed\n");
+ return -EINVAL;
+ }
- return rc;
+ return esd_check_success;
}
int dsi_display_check_status(void *display)
@@ -1933,18 +2043,34 @@
int i;
struct dsi_display_ctrl *ctrl;
- for (i = 0 ; i < display->ctrl_count; i++) {
- ctrl = &display->ctrl[i];
- rc = dsi_ctrl_host_init(ctrl->ctrl,
- display->is_cont_splash_enabled);
- if (rc) {
- pr_err("[%s] failed to init host_%d, rc=%d\n",
- display->name, i, rc);
- goto error_host_deinit;
+ /* when ULPS suspend feature is enabled, we will keep the lanes in
+ * ULPS during suspend state and clamp DSI phy. Hence while resuming
+ * we will programe DSI controller as part of core clock enable.
+ * After that we should not re-configure DSI controller again here for
+ * usecases where we are resuming from ulps suspend as it might put
+ * the HW in bad state.
+ */
+ if (!display->panel->ulps_suspend_enabled || !display->ulps_enabled) {
+ for (i = 0 ; i < display->ctrl_count; i++) {
+ ctrl = &display->ctrl[i];
+ rc = dsi_ctrl_host_init(ctrl->ctrl,
+ display->is_cont_splash_enabled);
+ if (rc) {
+ pr_err("[%s] failed to init host_%d, rc=%d\n",
+ display->name, i, rc);
+ goto error_host_deinit;
+ }
+ }
+ } else {
+ for (i = 0 ; i < display->ctrl_count; i++) {
+ ctrl = &display->ctrl[i];
+ rc = dsi_ctrl_update_host_init_state(ctrl->ctrl, true);
+ if (rc)
+ pr_debug("host init update failed rc=%d\n", rc);
}
}
- return 0;
+ return rc;
error_host_deinit:
for (i = i - 1; i >= 0; i--) {
ctrl = &display->ctrl[i];
@@ -3078,6 +3204,9 @@
display->type = DSI_DISPLAY_SINGLE;
}
+ /* Parse TE gpio */
+ dsi_display_parse_te_gpio(display);
+
error:
return rc;
}
@@ -3934,6 +4063,9 @@
}
}
+ /* register te irq handler */
+ dsi_display_register_te_irq(display);
+
/* Initialize resources for continuous splash */
rc = dsi_display_splash_res_init(display);
if (rc)
@@ -5174,6 +5306,9 @@
mode = display->panel->cur_mode;
+ if (dsi_display_is_te_based_esd(display))
+ dsi_display_change_te_irq_status(display, true);
+
if (mode->dsi_mode_flags & DSI_MODE_FLAG_DMS) {
if (display->is_cont_splash_enabled) {
pr_err("DMS is not supposed to be set on first frame\n");
@@ -5701,6 +5836,10 @@
pr_err("[%s] display wake up failed, rc=%d\n",
display->name, rc);
+ /* Disable panel TE irq */
+ if (dsi_display_is_te_based_esd(display))
+ dsi_display_change_te_irq_status(display, false);
+
rc = dsi_panel_unprepare(display->panel);
if (rc)
pr_err("[%s] panel unprepare failed, rc=%d\n",
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
index 53004e4..e243a92 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_display.h
@@ -132,6 +132,9 @@
* @is_active: Is display active.
* @is_cont_splash_enabled: Is continuous splash enabled
* @display_lock: Mutex for dsi_display interface.
+ * @disp_te_gpio: GPIO for panel TE interrupt.
+ * @is_te_irq_enabled:bool to specify whether TE interrupt is enabled.
+ * @te_irq_triggered: atomic state notifying panel TE interrupt.
* @ctrl_count: Number of DSI interfaces required by panel.
* @ctrl: Controller information for DSI display.
* @panel: Handle to DSI panel.
@@ -173,6 +176,9 @@
bool is_active;
bool is_cont_splash_enabled;
struct mutex display_lock;
+ int disp_te_gpio;
+ bool is_te_irq_enabled;
+ atomic_t te_irq_triggered;
u32 ctrl_count;
struct dsi_display_ctrl ctrl[MAX_DSI_CTRLS_PER_DISPLAY];
diff --git a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
index 07b2305..cc74de2 100644
--- a/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
+++ b/drivers/gpu/drm/msm/dsi-staging/dsi_phy.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, 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
@@ -694,8 +694,7 @@
u32 lanes = 0;
u32 ulps_lanes;
- if (config->panel_mode == DSI_OP_CMD_MODE)
- lanes = config->common_config.data_lanes;
+ lanes = config->common_config.data_lanes;
lanes |= DSI_CLOCK_LANE;
/*
@@ -730,8 +729,7 @@
{
u32 ulps_lanes, lanes = 0;
- if (config->panel_mode == DSI_OP_CMD_MODE)
- lanes = config->common_config.data_lanes;
+ lanes = config->common_config.data_lanes;
lanes |= DSI_CLOCK_LANE;
ulps_lanes = phy->hw.ops.ulps_ops.get_lanes_in_ulps(&phy->hw);
diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c
index 21b67d9..2adae3d 100644
--- a/drivers/gpu/drm/msm/sde/sde_connector.c
+++ b/drivers/gpu/drm/msm/sde/sde_connector.c
@@ -1736,6 +1736,7 @@
event.length = sizeof(bool);
msm_mode_object_event_notify(&conn->base.base,
conn->base.dev, &event, (u8 *)&panel_dead);
+ sde_encoder_display_failure_notification(conn->encoder);
}
static const struct drm_connector_helper_funcs sde_connector_helper_ops = {
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.c b/drivers/gpu/drm/msm/sde/sde_encoder.c
index e0023d0..e35a46b 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.c
@@ -1513,6 +1513,29 @@
return ret;
}
+static int _sde_encoder_switch_to_watchdog_vsync(struct drm_encoder *drm_enc)
+{
+ struct sde_encoder_virt *sde_enc;
+ struct msm_display_info disp_info;
+
+ if (!drm_enc) {
+ pr_err("invalid drm encoder\n");
+ return -EINVAL;
+ }
+
+ sde_enc = to_sde_encoder_virt(drm_enc);
+
+ sde_encoder_control_te(drm_enc, false);
+
+ memcpy(&disp_info, &sde_enc->disp_info, sizeof(disp_info));
+ disp_info.is_te_using_watchdog_timer = true;
+ _sde_encoder_update_vsync_source(sde_enc, &disp_info, false);
+
+ sde_encoder_control_te(drm_enc, true);
+
+ return 0;
+}
+
static int _sde_encoder_update_rsc_client(
struct drm_encoder *drm_enc,
struct sde_encoder_rsc_config *config, bool enable)
@@ -1652,7 +1675,12 @@
if (ret) {
SDE_ERROR_ENC(sde_enc,
"wait for vblank failed ret:%d\n", ret);
- break;
+ /**
+ * rsc hardware may hang without vsync. avoid rsc hang
+ * by generating the vsync from watchdog timer.
+ */
+ if (crtc->base.id == wait_vblank_crtc_id)
+ _sde_encoder_switch_to_watchdog_vsync(drm_enc);
}
}
@@ -2546,6 +2574,9 @@
return;
}
+ if (drm_enc->crtc && !sde_enc->crtc)
+ sde_enc->crtc = drm_enc->crtc;
+
comp_info = &mode_info.comp_info;
cur_mode = &sde_enc->base.crtc->state->adjusted_mode;
@@ -4755,3 +4786,17 @@
return ret;
}
+
+int sde_encoder_display_failure_notification(struct drm_encoder *enc)
+{
+ /**
+ * panel may stop generating te signal (vsync) during esd failure. rsc
+ * hardware may hang without vsync. Avoid rsc hang by generating the
+ * vsync from watchdog timer instead of panel.
+ */
+ _sde_encoder_switch_to_watchdog_vsync(enc);
+
+ sde_encoder_wait_for_event(enc, MSM_ENC_TX_COMPLETE);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder.h b/drivers/gpu/drm/msm/sde/sde_encoder.h
index 2c84e20..4696736 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder.h
+++ b/drivers/gpu/drm/msm/sde/sde_encoder.h
@@ -237,4 +237,14 @@
*/
int sde_encoder_update_caps_for_cont_splash(struct drm_encoder *encoder);
+/**
+ * sde_encoder_display_failure_notification - update sde encoder state for
+ * esd timeout or other display failure notification. This event flows from
+ * dsi, sde_connector to sde_encoder.
+ * TODO: manage the event at sde_kms level for forward processing.
+ * @drm_enc: Pointer to drm encoder structure
+ * @Return: true if successful in updating the encoder structure
+ */
+int sde_encoder_display_failure_notification(struct drm_encoder *enc);
+
#endif /* __SDE_ENCODER_H__ */
diff --git a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
index 53c8dfb..792654d 100644
--- a/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/sde/sde_encoder_phys_cmd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018 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
@@ -450,6 +450,17 @@
cmd_enc->pp_timeout_report_cnt++;
+ if (sde_encoder_phys_cmd_is_master(phys_enc)) {
+ /* trigger the retire fence if it was missed */
+ if (atomic_add_unless(&phys_enc->pending_retire_fence_cnt,
+ -1, 0))
+ phys_enc->parent_ops.handle_frame_done(
+ phys_enc->parent,
+ phys_enc,
+ SDE_ENCODER_FRAME_EVENT_SIGNAL_RETIRE_FENCE);
+ atomic_add_unless(&phys_enc->pending_ctlstart_cnt, -1, 0);
+ }
+
SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
cmd_enc->pp_timeout_report_cnt,
atomic_read(&phys_enc->pending_kickoff_cnt),
diff --git a/drivers/gpu/drm/msm/sde_hdcp.h b/drivers/gpu/drm/msm/sde_hdcp.h
index 6c44260..c8e84d3cc 100644
--- a/drivers/gpu/drm/msm/sde_hdcp.h
+++ b/drivers/gpu/drm/msm/sde_hdcp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, 2014-2018, 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,17 +30,21 @@
HDCP_CLIENT_DP,
};
-enum sde_hdcp_states {
+enum sde_hdcp_state {
HDCP_STATE_INACTIVE,
HDCP_STATE_AUTHENTICATING,
HDCP_STATE_AUTHENTICATED,
HDCP_STATE_AUTH_FAIL,
- HDCP_STATE_AUTH_ENC_NONE,
- HDCP_STATE_AUTH_ENC_1X,
- HDCP_STATE_AUTH_ENC_2P2
+};
+
+enum sde_hdcp_version {
+ HDCP_VERSION_NONE,
+ HDCP_VERSION_1X,
+ HDCP_VERSION_2P2
};
struct sde_hdcp_init_data {
+ struct device *msm_hdcp_dev;
struct dss_io_data *core_io;
struct dss_io_data *dp_ahb;
struct dss_io_data *dp_aux;
@@ -52,7 +56,7 @@
struct mutex *mutex;
struct workqueue_struct *workq;
void *cb_data;
- void (*notify_status)(void *cb_data, enum sde_hdcp_states status);
+ void (*notify_status)(void *cb_data, enum sde_hdcp_state state);
u8 sink_rx_status;
unsigned char *revision;
u32 phy_addr;
@@ -69,11 +73,32 @@
void (*off)(void *hdcp_ctrl);
};
+static inline const char *sde_hdcp_state_name(enum sde_hdcp_state hdcp_state)
+{
+ switch (hdcp_state) {
+ case HDCP_STATE_INACTIVE: return "HDCP_STATE_INACTIVE";
+ case HDCP_STATE_AUTHENTICATING: return "HDCP_STATE_AUTHENTICATING";
+ case HDCP_STATE_AUTHENTICATED: return "HDCP_STATE_AUTHENTICATED";
+ case HDCP_STATE_AUTH_FAIL: return "HDCP_STATE_AUTH_FAIL";
+ default: return "???";
+ }
+}
+
+static inline const char *sde_hdcp_version(enum sde_hdcp_version hdcp_version)
+{
+ switch (hdcp_version) {
+ case HDCP_VERSION_NONE: return "HDCP_VERSION_NONE";
+ case HDCP_VERSION_1X: return "HDCP_VERSION_1X";
+ case HDCP_VERSION_2P2: return "HDCP_VERSION_2P2";
+ default: return "???";
+ }
+}
+
void *sde_hdcp_1x_init(struct sde_hdcp_init_data *init_data);
void sde_hdcp_1x_deinit(void *input);
struct sde_hdcp_ops *sde_hdcp_1x_start(void *input);
void *sde_dp_hdcp2p2_init(struct sde_hdcp_init_data *init_data);
void sde_dp_hdcp2p2_deinit(void *input);
-const char *sde_hdcp_state_name(enum sde_hdcp_states hdcp_state);
+const char *sde_hdcp_state_name(enum sde_hdcp_state hdcp_state);
struct sde_hdcp_ops *sde_dp_hdcp2p2_start(void *input);
#endif /* __SDE_HDCP_H__ */
diff --git a/drivers/gpu/drm/msm/sde_hdcp_1x.c b/drivers/gpu/drm/msm/sde_hdcp_1x.c
index 2f900ece..2c7f52c 100644
--- a/drivers/gpu/drm/msm/sde_hdcp_1x.c
+++ b/drivers/gpu/drm/msm/sde_hdcp_1x.c
@@ -18,6 +18,7 @@
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/iopoll.h>
+#include <linux/msm_hdcp.h>
#include <linux/hdcp_qseecom.h>
#include <drm/drm_dp_helper.h>
#include "sde_hdcp.h"
@@ -213,8 +214,7 @@
bool sink_r0_ready;
bool reauth;
bool ksv_ready;
- enum sde_hdcp_states hdcp_state;
- struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
+ enum sde_hdcp_state hdcp_state;
struct HDCP_V2V1_MSG_TOPOLOGY current_tp;
struct delayed_work hdcp_auth_work;
struct completion r0_checked;
@@ -227,17 +227,6 @@
struct workqueue_struct *workq;
};
-const char *sde_hdcp_state_name(enum sde_hdcp_states hdcp_state)
-{
- switch (hdcp_state) {
- case HDCP_STATE_INACTIVE: return "HDCP_STATE_INACTIVE";
- case HDCP_STATE_AUTHENTICATING: return "HDCP_STATE_AUTHENTICATING";
- case HDCP_STATE_AUTHENTICATED: return "HDCP_STATE_AUTHENTICATED";
- case HDCP_STATE_AUTH_FAIL: return "HDCP_STATE_AUTH_FAIL";
- default: return "???";
- }
-}
-
static int sde_hdcp_1x_count_one(u8 *array, u8 len)
{
int i, j, count = 0;
@@ -1062,30 +1051,12 @@
return rc;
}
-static void sde_hdcp_1x_cache_topology(struct sde_hdcp_1x *hdcp)
-{
- if (!hdcp || !hdcp->init_data.dp_ahb || !hdcp->init_data.dp_aux ||
- !hdcp->init_data.dp_link || !hdcp->init_data.dp_p0) {
- pr_err("invalid input\n");
- return;
- }
-
- memcpy((void *)&hdcp->cached_tp,
- (void *) &hdcp->current_tp,
- sizeof(hdcp->cached_tp));
- hdcp1_cache_repeater_topology((void *)&hdcp->cached_tp);
-}
-
-static void sde_hdcp_1x_notify_topology(void)
-{
- hdcp1_notify_topology();
-}
-
static void sde_hdcp_1x_update_auth_status(struct sde_hdcp_1x *hdcp)
{
if (sde_hdcp_1x_state(HDCP_STATE_AUTHENTICATED)) {
- sde_hdcp_1x_cache_topology(hdcp);
- sde_hdcp_1x_notify_topology();
+ msm_hdcp_cache_repeater_topology(hdcp->init_data.msm_hdcp_dev,
+ &hdcp->current_tp);
+ msm_hdcp_notify_topology(hdcp->init_data.msm_hdcp_dev);
}
if (hdcp->init_data.notify_status &&
@@ -1262,11 +1233,9 @@
* Also, need to set the state to inactive here so that any ongoing
* reauth works will know that the HDCP session has been turned off.
*/
- mutex_lock(hdcp->init_data.mutex);
DSS_REG_W(io, isr->int_reg,
DSS_REG_R(io, isr->int_reg) & ~HDCP_INT_EN);
hdcp->hdcp_state = HDCP_STATE_INACTIVE;
- mutex_unlock(hdcp->init_data.mutex);
/* complete any wait pending */
complete_all(&hdcp->sink_r0_available);
@@ -1510,7 +1479,7 @@
.off = sde_hdcp_1x_off
};
- if (!init_data || !init_data->mutex || !init_data->notify_status ||
+ if (!init_data || !init_data->notify_status ||
!init_data->workq || !init_data->cb_data) {
pr_err("invalid input\n");
goto error;
diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c
index a615dca..4775c3e 100644
--- a/drivers/gpu/msm/adreno_a5xx.c
+++ b/drivers/gpu/msm/adreno_a5xx.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, 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
@@ -1353,31 +1353,27 @@
/* todo double check the reg writes */
while ((cur - opcode) < length) {
- switch (cur[0]) {
- /* Write a 32 bit value to a 64 bit reg */
- case 1:
+ if (cur[0] == 1 && ((cur + 4) - opcode) <= length) {
+ /* Write a 32 bit value to a 64 bit reg */
reg = cur[2];
reg = (reg << 32) | cur[1];
kgsl_regwrite(KGSL_DEVICE(adreno_dev), reg, cur[3]);
cur += 4;
- break;
- /* Write a 64 bit value to a 64 bit reg */
- case 2:
+ } else if (cur[0] == 2 && ((cur + 5) - opcode) <= length) {
+ /* Write a 64 bit value to a 64 bit reg */
reg = cur[2];
reg = (reg << 32) | cur[1];
val = cur[4];
val = (val << 32) | cur[3];
kgsl_regwrite(KGSL_DEVICE(adreno_dev), reg, val);
cur += 5;
- break;
- /* Delay for X usec */
- case 3:
+ } else if (cur[0] == 3 && ((cur + 2) - opcode) <= length) {
+ /* Delay for X usec */
udelay(cur[1]);
cur += 2;
- break;
- default:
+ } else
return -EINVAL;
- } }
+ }
return 0;
}
diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c
index 1250437..06bf506 100644
--- a/drivers/gpu/msm/adreno_a6xx.c
+++ b/drivers/gpu/msm/adreno_a6xx.c
@@ -1258,7 +1258,7 @@
_regwrite(gmu->pdc_reg_virt,
PDC_GPU_TCS3_CMD0_ADDR + PDC_CMD_OFFSET, 0x30000);
_regwrite(gmu->pdc_reg_virt,
- PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET, 0x3);
+ PDC_GPU_TCS3_CMD0_DATA + PDC_CMD_OFFSET, 0x6);
_regwrite(gmu->pdc_reg_virt,
PDC_GPU_TCS3_CMD0_MSGID + PDC_CMD_OFFSET * 2, 0x10108);
_regwrite(gmu->pdc_reg_virt,
diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c
index f3e16b3..b35605d 100644
--- a/drivers/hwmon/qpnp-adc-common.c
+++ b/drivers/hwmon/qpnp-adc-common.c
@@ -677,6 +677,80 @@
{124, 980}
};
+/* Voltage to temperature */
+static const struct qpnp_vadc_map_pt adcmap_batt_therm_qrd[] = {
+ {1840, -400},
+ {1835, -380},
+ {1828, -360},
+ {1821, -340},
+ {1813, -320},
+ {1803, -300},
+ {1793, -280},
+ {1781, -260},
+ {1768, -240},
+ {1753, -220},
+ {1737, -200},
+ {1719, -180},
+ {1700, -160},
+ {1679, -140},
+ {1655, -120},
+ {1630, -100},
+ {1603, -80},
+ {1574, -60},
+ {1543, -40},
+ {1510, -20},
+ {1475, 00},
+ {1438, 20},
+ {1400, 40},
+ {1360, 60},
+ {1318, 80},
+ {1276, 100},
+ {1232, 120},
+ {1187, 140},
+ {1142, 160},
+ {1097, 180},
+ {1051, 200},
+ {1005, 220},
+ {960, 240},
+ {915, 260},
+ {871, 280},
+ {828, 300},
+ {786, 320},
+ {745, 340},
+ {705, 360},
+ {666, 380},
+ {629, 400},
+ {594, 420},
+ {560, 440},
+ {527, 460},
+ {497, 480},
+ {467, 500},
+ {439, 520},
+ {413, 540},
+ {388, 560},
+ {365, 580},
+ {343, 600},
+ {322, 620},
+ {302, 640},
+ {284, 660},
+ {267, 680},
+ {251, 700},
+ {235, 720},
+ {221, 740},
+ {208, 760},
+ {195, 780},
+ {184, 800},
+ {173, 820},
+ {163, 840},
+ {153, 860},
+ {144, 880},
+ {136, 900},
+ {128, 920},
+ {120, 940},
+ {114, 960},
+ {107, 980}
+};
+
/*
* Voltage to temperature table for 100k pull up for NTCG104EF104 with
* 1.875V reference.
@@ -1016,6 +1090,36 @@
}
EXPORT_SYMBOL(qpnp_adc_batt_therm);
+int32_t qpnp_adc_batt_therm_qrd(struct qpnp_vadc_chip *chip,
+ int32_t adc_code,
+ const struct qpnp_adc_properties *adc_properties,
+ const struct qpnp_vadc_chan_properties *chan_properties,
+ struct qpnp_vadc_result *adc_chan_result)
+{
+ int64_t batt_thm_voltage = 0;
+
+ if (!chan_properties || !chan_properties->offset_gain_numerator ||
+ !chan_properties->offset_gain_denominator || !adc_properties
+ || !adc_chan_result)
+ return -EINVAL;
+
+ if (adc_properties->adc_hc) {
+ /* (code * vref_vadc (1.875V) * 1000) / (scale_code * 1000) */
+ if (adc_code > QPNP_VADC_HC_MAX_CODE)
+ adc_code = 0;
+ batt_thm_voltage = (int64_t) adc_code;
+ batt_thm_voltage *= (adc_properties->adc_vdd_reference
+ * 1000);
+ batt_thm_voltage = div64_s64(batt_thm_voltage,
+ adc_properties->full_scale_code * 1000);
+ qpnp_adc_map_voltage_temp(adcmap_batt_therm_qrd,
+ ARRAY_SIZE(adcmap_batt_therm_qrd),
+ batt_thm_voltage, &adc_chan_result->physical);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(qpnp_adc_batt_therm_qrd);
+
int32_t qpnp_adc_scale_batt_therm(struct qpnp_vadc_chip *chip,
int32_t adc_code,
const struct qpnp_adc_properties *adc_properties,
diff --git a/drivers/hwmon/qpnp-adc-voltage.c b/drivers/hwmon/qpnp-adc-voltage.c
index ea022f0..f5f914fc6 100644
--- a/drivers/hwmon/qpnp-adc-voltage.c
+++ b/drivers/hwmon/qpnp-adc-voltage.c
@@ -224,6 +224,7 @@
[SCALE_DIE_TEMP] = {qpnp_adc_scale_die_temp},
[SCALE_I_DEFAULT] = {qpnp_iadc_scale_default},
[SCALE_USBIN_I] = {qpnp_adc_scale_usbin_curr},
+ [SCALE_BATT_THERM_TEMP_QRD] = {qpnp_adc_batt_therm_qrd},
};
static struct qpnp_vadc_rscale_fn adc_vadc_rscale_fn[] = {
diff --git a/drivers/hwtracing/coresight/coresight-dbgui.c b/drivers/hwtracing/coresight/coresight-dbgui.c
index e4feea2..eb01fca 100644
--- a/drivers/hwtracing/coresight/coresight-dbgui.c
+++ b/drivers/hwtracing/coresight/coresight-dbgui.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, 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
@@ -375,10 +375,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -403,10 +403,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -434,10 +434,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -463,10 +463,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -492,10 +492,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (!val)
@@ -528,10 +528,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val > drvdata->size)
@@ -569,10 +569,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val > drvdata->size)
@@ -615,10 +615,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -643,10 +643,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val >= drvdata->size)
@@ -674,10 +674,10 @@
const char *buf,
size_t size)
{
- uint32_t val;
+ unsigned long val;
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
mutex_lock(&drvdata->mutex);
@@ -755,9 +755,10 @@
size_t size)
{
struct dbgui_drvdata *drvdata = dev_get_drvdata(dev->parent);
- uint32_t val, ret;
+ uint32_t ret;
+ unsigned long val;
- if (kstrtoul(buf, 16, (unsigned long *)&val))
+ if (kstrtoul(buf, 16, &val))
return -EINVAL;
if (val)
diff --git a/drivers/i2c/busses/i2c-msm-v2.c b/drivers/i2c/busses/i2c-msm-v2.c
index 4daed7f..ad77697 100644
--- a/drivers/i2c/busses/i2c-msm-v2.c
+++ b/drivers/i2c/busses/i2c-msm-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, 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
@@ -1274,10 +1274,10 @@
tx->dir,
(SPS_IOVEC_FLAG_EOT |
SPS_IOVEC_FLAG_NWD));
- if (dma_desc_tx < 0) {
+ if (IS_ERR_OR_NULL(dma_desc_tx)) {
dev_err(ctrl->dev, "error dmaengine_prep_slave_sg tx:%ld\n",
PTR_ERR(dma_desc_tx));
- ret = PTR_ERR(dma_desc_tx);
+ ret = dma_desc_tx ? PTR_ERR(dma_desc_tx) : -ENOMEM;
goto dma_xfer_end;
}
@@ -1292,11 +1292,11 @@
sg_rx_itr - sg_rx, rx->dir,
(SPS_IOVEC_FLAG_EOT |
SPS_IOVEC_FLAG_NWD));
- if (dma_desc_rx < 0) {
+ if (IS_ERR_OR_NULL(dma_desc_rx)) {
dev_err(ctrl->dev,
"error dmaengine_prep_slave_sg rx:%ld\n",
PTR_ERR(dma_desc_rx));
- ret = PTR_ERR(dma_desc_rx);
+ ret = dma_desc_rx ? PTR_ERR(dma_desc_rx) : -ENOMEM;
goto dma_xfer_end;
}
diff --git a/drivers/media/platform/msm/camera_v2/Makefile b/drivers/media/platform/msm/camera_v2/Makefile
index cdb0468..4348d44 100644
--- a/drivers/media/platform/msm/camera_v2/Makefile
+++ b/drivers/media/platform/msm/camera_v2/Makefile
@@ -1,7 +1,7 @@
ccflags-y += -Idrivers/media/platform/msm/camera_v2
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor
ccflags-y += -Idrivers/media/platform/msm/camera_v2/codecs
-ccflags-y += -Idrivers/media/platform/msm/camera_v2/isps
+ccflags-y += -Idrivers/media/platform/msm/camera_v2/isp
ccflags-y += -Idrivers/media/platform/msm/camera_v2/pproc
ccflags-y += -Idrivers/media/platform/msm/camera_v2/msm_vb2
ccflags-y += -Idrivers/media/platform/msm/camera_v2/camera
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index 0efbd1b..01ee5d4 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -917,9 +917,7 @@
rc = media_entity_pads_init(&pvdev->vdev->entity, 0, NULL);
if (WARN_ON(rc < 0))
goto entity_fail;
- pvdev->vdev->entity.function = MEDIA_ENT_F_IO_V4L;
- //TODO: Use entity.name in from userspcae to find device.
- //pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
+ pvdev->vdev->entity.function = QCAMERA_VNODE_GROUP_ID;
#endif
v4l2_dev->notify = NULL;
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
index 36e3752..08c8575 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_smmu_api.c
@@ -1390,7 +1390,7 @@
virt_len, &iova);
if (rc < 0) {
- pr_err("Could not find valid iova for scratch buffer");
+ pr_err("Could not find valid iova for scratch buffer\n");
goto err_iommu_map;
}
@@ -2118,7 +2118,7 @@
/* set the name of the context bank */
property = of_get_property(dev->of_node, "iommus", &cnt);
cnt /= 4;
- for (i = 0, j = 0; i < cnt; i = i + 2, j++) {
+ for (i = 0, j = 0; i < cnt; i = i + 3, j++) {
rc = of_property_read_u32_index(dev->of_node,
"iommus", i + 1, &cb->sids[j]);
if (rc < 0)
diff --git a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
index 3c38f12..2eb00eb 100644
--- a/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
+++ b/drivers/media/platform/msm/camera_v2/common/cam_soc_api.c
@@ -710,7 +710,7 @@
CDBG("name : %s, enable : %d\n", tmp->name, mode);
if (mode) {
rc = regulator_set_mode(tmp->vdd,
- REGULATOR_MODE_FAST);
+ REGULATOR_MODE_NORMAL);
if (rc < 0) {
pr_err("regulator enable failed %d\n",
i);
diff --git a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
index 009b4cd..9a212825 100644
--- a/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/common/msm_camera_io_util.c
@@ -408,14 +408,14 @@
return -EINVAL;
}
- if (cam_vreg == NULL) {
- pr_err("%s:%d cam_vreg sequence invalid\n", __func__, __LINE__);
- return -EINVAL;
- }
-
if (!num_vreg_seq)
num_vreg_seq = num_vreg;
+ if ((cam_vreg == NULL) && num_vreg_seq) {
+ pr_err("%s:%d cam_vreg NULL\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
if (config) {
for (i = 0; i < num_vreg_seq; i++) {
if (vreg_seq) {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
index 7af9a3e..cfe8054 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp.c
@@ -693,7 +693,7 @@
spin_lock_init(&req_history_lock);
spin_lock_init(&vfe_dev->completion_lock);
media_entity_pads_init(&vfe_dev->subdev.sd.entity, 0, NULL);
- vfe_dev->subdev.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ vfe_dev->subdev.sd.entity.function = MSM_CAMERA_SUBDEV_VFE;
//vfe_dev->subdev.sd.entity.group_id = MSM_CAMERA_SUBDEV_VFE;
vfe_dev->subdev.sd.entity.name = pdev->name;
vfe_dev->subdev.close_seq = MSM_SD_CLOSE_1ST_CATEGORY | 0x2;
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
index 0b7bb8d..fab2623f 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
@@ -935,8 +935,12 @@
}
if (frame_src == VFE_PIX_0) {
- vfe_dev->isp_page->kernel_sofid =
- vfe_dev->axi_data.src_info[frame_src].frame_id;
+ if (vfe_dev->isp_page == NULL)
+ pr_err("Invalid ISP PAGE");
+ else
+ vfe_dev->isp_page->kernel_sofid =
+ vfe_dev->axi_data.src_info[frame_src].frame_id;
+
if (!src_info->frame_id &&
!src_info->reg_update_frame_id &&
((src_info->frame_id -
diff --git a/drivers/media/platform/msm/camera_v2/msm.c b/drivers/media/platform/msm/camera_v2/msm.c
index 121e42a5..d52d8bc 100644
--- a/drivers/media/platform/msm/camera_v2/msm.c
+++ b/drivers/media/platform/msm/camera_v2/msm.c
@@ -350,8 +350,11 @@
return -EINVAL;
rc = v4l2_device_register_subdev(msm_v4l2_dev, sd);
- if (rc < 0)
+ if (rc < 0) {
+ pr_err("v4l2_device_register_subdev: failed for %s", sd->name);
+ WARN_ON(1);
return rc;
+ }
/* Register a device node for every subdev marked with the
* V4L2_SUBDEV_FL_HAS_DEVNODE flag.
@@ -1303,7 +1306,7 @@
uint64_t seq_num = 0;
int ret;
- if (copy_from_user(lbuf, buf, sizeof(lbuf)))
+ if (copy_from_user(lbuf, buf, sizeof(lbuf) - 1))
return -EFAULT;
ret = kstrtoull(lbuf, 0, &seq_num);
@@ -1366,8 +1369,7 @@
0, NULL)) < 0))
goto entity_fail;
- pvdev->vdev->entity.function = MEDIA_ENT_F_IO_V4L;
- //pvdev->vdev->entity.group_id = QCAMERA_VNODE_GROUP_ID;
+ pvdev->vdev->entity.function = QCAMERA_VNODE_GROUP_ID;
#endif
msm_v4l2_dev->notify = msm_sd_notify;
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 8a91c3e..e350096 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
@@ -857,9 +857,8 @@
v4l2_set_subdevdata(&msm_buf_mngr_dev->subdev.sd, msm_buf_mngr_dev);
media_entity_pads_init(&msm_buf_mngr_dev->subdev.sd.entity, 0, NULL);
- msm_buf_mngr_dev->subdev.sd.entity.function = MEDIA_ENT_F_IO_V4L;
- //msm_buf_mngr_dev->subdev.sd.entity.group_id =
- // MSM_CAMERA_SUBDEV_BUF_MNGR;
+ msm_buf_mngr_dev->subdev.sd.entity.function =
+ MSM_CAMERA_SUBDEV_BUF_MNGR;
msm_buf_mngr_dev->subdev.sd.internal_ops =
&msm_generic_buf_mngr_subdev_internal_ops;
msm_buf_mngr_dev->subdev.close_seq = MSM_SD_CLOSE_4TH_CATEGORY;
diff --git a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index 1322707..5c13de5 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
@@ -399,7 +399,7 @@
static int msm_vb2_buf_done(struct vb2_v4l2_buffer *vb, int session_id,
unsigned int stream_id, uint32_t sequence,
- struct timeval *ts, uint32_t reserved)
+ struct timeval *ts, uint32_t buf_type)
{
unsigned long flags, rl_flags;
struct msm_vb2_buffer *msm_vb2;
@@ -441,7 +441,9 @@
/* put buf before buf done */
if (msm_vb2->in_freeq) {
vb2_v4l2_buf->sequence = sequence;
- //vb2_v4l2_buf->timestamp = *ts;
+ vb2_v4l2_buf->timecode.type = buf_type;
+ vb2_v4l2_buf->vb2_buf.timestamp =
+ (ts->tv_sec * 1000000 + ts->tv_usec) * 1000;
vb2_buffer_done(&vb2_v4l2_buf->vb2_buf,
VB2_BUF_STATE_DONE);
msm_vb2->in_freeq = 0;
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 6fd9c4d..70bb3f2 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -4579,15 +4579,6 @@
}
}
- if (of_find_property(pdev->dev.of_node, "qcom,cpp-cx-ipeak", NULL)) {
- cpp_dev->cpp_cx_ipeak = cx_ipeak_register(
- pdev->dev.of_node, "qcom,cpp-cx-ipeak");
- if (cpp_dev->cpp_cx_ipeak)
- CPP_DBG("Cx ipeak Registration Successful ");
- else
- pr_err("Cx ipeak Registration Unsuccessful");
- }
-
rc = msm_camera_get_reset_info(pdev,
&cpp_dev->micro_iface_reset);
if (rc < 0) {
@@ -4596,7 +4587,6 @@
__func__);
goto get_reg_err;
}
-
rc = msm_camera_get_regulator_info(pdev, &cpp_dev->cpp_vdd,
&cpp_dev->num_reg);
if (rc < 0) {
@@ -4625,7 +4615,7 @@
goto bus_de_init;
media_entity_pads_init(&cpp_dev->msm_sd.sd.entity, 0, NULL);
- cpp_dev->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ cpp_dev->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_CPP;
cpp_dev->msm_sd.sd.entity.name = pdev->name;
cpp_dev->msm_sd.close_seq = MSM_SD_CLOSE_3RD_CATEGORY;
msm_sd_register(&cpp_dev->msm_sd);
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
index d733d2a..64f3104 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
@@ -83,67 +83,37 @@
return -EINVAL;
}
-static int cpp_get_clk_freq_tbl_dt(struct cpp_device *cpp_dev)
+static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info,
+ uint32_t min_clk_rate)
{
- uint32_t i, count, min_clk_rate;
+ uint32_t i;
uint32_t idx = 0;
- struct device_node *of_node;
- uint32_t *rates;
- int32_t rc = 0;
- struct cpp_hw_info *hw_info;
+ signed long freq_tbl_entry = 0;
- if (cpp_dev == NULL) {
+ if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
+ (clk->ops->list_rate == NULL)) {
pr_err("Bad parameter\n");
- rc = -EINVAL;
- goto err;
+ return -EINVAL;
}
- of_node = cpp_dev->pdev->dev.of_node;
- min_clk_rate = cpp_dev->min_clk_rate;
- hw_info = &cpp_dev->hw_info;
-
- if ((hw_info == NULL) || (of_node == NULL)) {
- pr_err("Invalid hw_info %pK or ofnode %pK\n", hw_info, of_node);
- rc = -EINVAL;
- goto err;
-
- }
- count = of_property_count_u32_elems(of_node, "qcom,src-clock-rates");
- if ((count == 0) || (count > MAX_FREQ_TBL)) {
- pr_err("Clock count is invalid\n");
- rc = -EINVAL;
- goto err;
- }
-
- rates = devm_kcalloc(&cpp_dev->pdev->dev, count, sizeof(uint32_t),
- GFP_KERNEL);
- if (!rates) {
- rc = -ENOMEM;
- goto err;
- }
-
- rc = of_property_read_u32_array(of_node, "qcom,src-clock-rates",
- rates, count);
- if (rc) {
- rc = -EINVAL;
- goto mem_free;
- }
-
- for (i = 0; i < count; i++) {
- pr_debug("entry=%d\n", rates[i]);
- if (rates[i] >= min_clk_rate) {
- hw_info->freq_tbl[idx++] = rates[i];
- pr_debug("tbl[%d]=%d\n", idx-1, rates[i]);
+ for (i = 0; i < MAX_FREQ_TBL; i++) {
+ freq_tbl_entry = clk->ops->list_rate(clk, i);
+ pr_debug("entry=%ld\n", freq_tbl_entry);
+ if (freq_tbl_entry >= 0) {
+ if (freq_tbl_entry >= min_clk_rate) {
+ hw_info->freq_tbl[idx++] = freq_tbl_entry;
+ pr_debug("tbl[%d]=%ld\n", idx-1,
+ freq_tbl_entry);
+ }
+ } else {
+ pr_debug("freq table returned invalid entry/end %ld\n",
+ freq_tbl_entry);
+ break;
}
}
-
- pr_debug("%s: idx %d\n", __func__, idx);
+ pr_debug("%s: idx %d", __func__, idx);
hw_info->freq_tbl_count = idx;
-
-mem_free:
- devm_kfree(&cpp_dev->pdev->dev, rates);
-err:
- return rc;
+ return 0;
}
int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev)
@@ -192,7 +162,8 @@
rc = msm_cpp_core_clk_idx;
return rc;
}
- rc = cpp_get_clk_freq_tbl_dt(cpp_dev);
+ rc = cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
+ &cpp_dev->hw_info, cpp_dev->min_clk_rate);
if (rc < 0) {
pr_err("%s: fail to get frequency table\n", __func__);
return rc;
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 295e203..769a9a5 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
@@ -1895,7 +1895,7 @@
act_ctrl_t->msm_sd.sd.internal_ops = &msm_actuator_internal_ops;
act_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
media_entity_pads_init(&act_ctrl_t->msm_sd.sd.entity, 0, NULL);
- act_ctrl_t->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ act_ctrl_t->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_ACTUATOR;
act_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
msm_sd_register(&act_ctrl_t->msm_sd);
msm_cam_copy_v4l2_subdev_fops(&msm_actuator_v4l2_subdev_fops);
@@ -2007,7 +2007,7 @@
snprintf(msm_actuator_t->msm_sd.sd.name,
ARRAY_SIZE(msm_actuator_t->msm_sd.sd.name), "msm_actuator");
media_entity_pads_init(&msm_actuator_t->msm_sd.sd.entity, 0, NULL);
- msm_actuator_t->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ msm_actuator_t->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_ACTUATOR;
msm_actuator_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
msm_sd_register(&msm_actuator_t->msm_sd);
msm_actuator_t->actuator_state = ACT_DISABLE_STATE;
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 0f4bd88..b67af9c 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -2095,11 +2095,11 @@
return -ENOMEM;
}
v4l2_subdev_init(&new_cci_dev->msm_sd.sd, &msm_cci_subdev_ops);
- new_cci_dev->msm_sd.sd.internal_ops = &msm_cci_internal_ops;
snprintf(new_cci_dev->msm_sd.sd.name,
ARRAY_SIZE(new_cci_dev->msm_sd.sd.name), "msm_cci");
v4l2_set_subdevdata(&new_cci_dev->msm_sd.sd, new_cci_dev);
platform_set_drvdata(pdev, &new_cci_dev->msm_sd.sd);
+
CDBG("%s sd %pK\n", __func__, &new_cci_dev->msm_sd.sd);
if (pdev->dev.of_node)
of_property_read_u32((&pdev->dev)->of_node,
@@ -2141,6 +2141,13 @@
}
msm_camera_enable_irq(new_cci_dev->irq, false);
+
+ new_cci_dev->pdev = pdev;
+ new_cci_dev->msm_sd.sd.internal_ops = &msm_cci_internal_ops;
+ new_cci_dev->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+ media_entity_pads_init(&new_cci_dev->msm_sd.sd.entity, 0, NULL);
+ new_cci_dev->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_CCI;
+ new_cci_dev->msm_sd.sd.entity.name = new_cci_dev->msm_sd.sd.name;
new_cci_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x6;
msm_sd_register(&new_cci_dev->msm_sd);
new_cci_dev->pdev = pdev;
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 057472a..ba32526 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
@@ -1008,6 +1008,8 @@
if (!new_csid_dev)
return -ENOMEM;
+ CDBG("%s: csid_probe entry\n", __func__);
+
new_csid_dev->csid_3p_enabled = 0;
new_csid_dev->ctrl_reg = NULL;
new_csid_dev->ctrl_reg = kzalloc(sizeof(struct csid_ctrl_t),
@@ -1088,7 +1090,7 @@
snprintf(new_csid_dev->msm_sd.sd.name,
ARRAY_SIZE(new_csid_dev->msm_sd.sd.name), "msm_csid");
media_entity_pads_init(&new_csid_dev->msm_sd.sd.entity, 0, NULL);
- new_csid_dev->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ new_csid_dev->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_CSID;
new_csid_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x5;
msm_sd_register(&new_csid_dev->msm_sd);
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 04f7732..edf022e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
@@ -1743,7 +1743,7 @@
snprintf(new_csiphy_dev->msm_sd.sd.name,
ARRAY_SIZE(new_csiphy_dev->msm_sd.sd.name), "msm_csiphy");
media_entity_pads_init(&new_csiphy_dev->msm_sd.sd.entity, 0, NULL);
- new_csiphy_dev->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ new_csiphy_dev->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_CSIPHY;
new_csiphy_dev->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x4;
msm_sd_register(&new_csiphy_dev->msm_sd);
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 30a3113..cd16236 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
@@ -847,7 +847,7 @@
e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
media_entity_pads_init(&e_ctrl->msm_sd.sd.entity, 0, NULL);
- e_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ e_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_EEPROM;
msm_sd_register(&e_ctrl->msm_sd);
CDBG("%s success result=%d X\n", __func__, rc);
return rc;
@@ -1215,7 +1215,7 @@
e_ctrl->msm_sd.sd.internal_ops = &msm_eeprom_internal_ops;
e_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
media_entity_pads_init(&e_ctrl->msm_sd.sd.entity, 0, NULL);
- e_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ e_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_EEPROM;
msm_sd_register(&e_ctrl->msm_sd);
e_ctrl->is_supported = (e_ctrl->is_supported << 1) | 1;
CDBG("%s success result=%d supported=%x X\n", __func__, rc,
@@ -1755,7 +1755,7 @@
snprintf(e_ctrl->msm_sd.sd.name,
ARRAY_SIZE(e_ctrl->msm_sd.sd.name), "msm_eeprom");
media_entity_pads_init(&e_ctrl->msm_sd.sd.entity, 0, NULL);
- e_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ e_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_EEPROM;
msm_sd_register(&e_ctrl->msm_sd);
#ifdef CONFIG_COMPAT
diff --git a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
index b26fee4..656b1ca 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/flash/msm_flash.c
@@ -1314,7 +1314,7 @@
ARRAY_SIZE(flash_ctrl->msm_sd.sd.name),
"msm_camera_flash");
media_entity_pads_init(&flash_ctrl->msm_sd.sd.entity, 0, NULL);
- flash_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ flash_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_FLASH;
flash_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
msm_sd_register(&flash_ctrl->msm_sd);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c b/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c
index 165f0c3..002a9b9 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ir_cut/msm_ir_cut.c
@@ -601,7 +601,7 @@
ARRAY_SIZE(ir_cut_ctrl->msm_sd.sd.name),
"msm_camera_ir_cut");
media_entity_pads_init(&ir_cut_ctrl->msm_sd.sd.entity, 0, NULL);
- ir_cut_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ ir_cut_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_IR_CUT;
ir_cut_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
msm_sd_register(&ir_cut_ctrl->msm_sd);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c b/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c
index 00ce821..2beca58 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ir_led/msm_ir_led.c
@@ -398,7 +398,7 @@
ARRAY_SIZE(ir_led_ctrl->msm_sd.sd.name),
"msm_camera_ir_led");
media_entity_pads_init(&ir_led_ctrl->msm_sd.sd.entity, 0, NULL);
- ir_led_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ ir_led_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_IR_LED;
ir_led_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
msm_sd_register(&ir_led_ctrl->msm_sd);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c b/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c
index d30fc95..ee695d8 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/laser_led/msm_laser_led.c
@@ -515,11 +515,7 @@
ARRAY_SIZE(laser_led_ctrl->msm_sd.sd.name),
"msm_camera_laser_led");
media_entity_pads_init(&laser_led_ctrl->msm_sd.sd.entity, 0, NULL);
- laser_led_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
- /*
- * laser_led_ctrl->msm_sd.sd.entity.group_id
- * = MSM_CAMERA_SUBDEV_LASER_LED;
- */
+ laser_led_ctrl->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_LASER_LED;
laser_led_ctrl->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x1;
msm_sd_register(&laser_led_ctrl->msm_sd);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
index 80149a9..0b0f98a 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c
@@ -104,7 +104,7 @@
v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, client);
s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
media_entity_pads_init(&s_ctrl->msm_sd.sd.entity, 0, NULL);
- s_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ s_ctrl->msm_sd.sd.entity.function = 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;
@@ -148,7 +148,7 @@
v4l2_set_subdevdata(&s_ctrl->msm_sd.sd, s_ctrl->pdev);
s_ctrl->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
media_entity_pads_init(&s_ctrl->msm_sd.sd.entity, 0, NULL);
- s_ctrl->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ s_ctrl->msm_sd.sd.entity.function = 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;
rc = msm_sd_register(&s_ctrl->msm_sd);
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
index b9fafc8..acab45e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_init.c
@@ -187,7 +187,7 @@
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_pads_init(&s_init->msm_sd.sd.entity, 0, NULL);
- s_init->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ s_init->msm_sd.sd.entity.function = 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;
ret = msm_sd_register(&s_init->msm_sd);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
index 2253eee..0e17b7d 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/ois/msm_ois.c
@@ -830,7 +830,7 @@
ois_ctrl_t->msm_sd.sd.internal_ops = &msm_ois_internal_ops;
ois_ctrl_t->msm_sd.sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
media_entity_pads_init(&ois_ctrl_t->msm_sd.sd.entity, 0, NULL);
- ois_ctrl_t->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ ois_ctrl_t->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_OIS;
ois_ctrl_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
msm_sd_register(&ois_ctrl_t->msm_sd);
ois_ctrl_t->ois_state = OIS_DISABLE_STATE;
@@ -1032,7 +1032,7 @@
snprintf(msm_ois_t->msm_sd.sd.name,
ARRAY_SIZE(msm_ois_t->msm_sd.sd.name), "msm_ois");
media_entity_pads_init(&msm_ois_t->msm_sd.sd.entity, 0, NULL);
- msm_ois_t->msm_sd.sd.entity.function = MEDIA_ENT_F_IO_V4L;
+ msm_ois_t->msm_sd.sd.entity.function = MSM_CAMERA_SUBDEV_OIS;
msm_ois_t->msm_sd.close_seq = MSM_SD_CLOSE_2ND_CATEGORY | 0x2;
msm_sd_register(&msm_ois_t->msm_sd);
msm_ois_t->ois_state = OIS_DISABLE_STATE;
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 744001a..fb07ce4 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -49,7 +49,8 @@
obj-$(CONFIG_SRAM) += sram.o
obj-y += mic/
obj-$(CONFIG_GENWQE) += genwqe/
-obj-$(CONFIG_HDCP_QSEECOM) += hdcp.o
+obj-$(CONFIG_HDCP_QSEECOM) += hdcp_qseecom.o
+obj-$(CONFIG_HDCP_QSEECOM) += msm_hdcp.o
obj-$(CONFIG_QSEECOM) += qseecom.o
obj-$(CONFIG_ECHO) += echo/
obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
diff --git a/drivers/misc/hdcp.c b/drivers/misc/hdcp_qseecom.c
similarity index 87%
rename from drivers/misc/hdcp.c
rename to drivers/misc/hdcp_qseecom.c
index a86d9f1..6ce3776 100644
--- a/drivers/misc/hdcp.c
+++ b/drivers/misc/hdcp_qseecom.c
@@ -38,8 +38,6 @@
#include "qseecom_kernel.h"
-#define CLASS_NAME "hdcp"
-#define DRIVER_NAME "msm_hdcp"
#define TZAPP_NAME "hdcp2p2"
#define HDCP1_APP_NAME "hdcp1"
#define QSEECOM_SBUFF_SIZE 0x1000
@@ -509,21 +507,6 @@
const char *msg_name;
};
-struct msm_hdcp_mgr {
- struct platform_device *pdev;
- dev_t dev_num;
- struct cdev cdev;
- struct class *class;
- struct device *device;
- struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
- u32 tp_msgid;
- void *client_ctx;
- struct hdcp_lib_handle *handle;
-};
-
-static struct msm_hdcp_mgr *hdcp_drv_mgr;
-static struct hdcp_lib_handle *drv_client_handle;
-
static void hdcp_lib_clean(struct hdcp_lib_handle *handle);
static void hdcp_lib_init(struct hdcp_lib_handle *handle);
static void hdcp_lib_msg_sent(struct hdcp_lib_handle *handle);
@@ -751,7 +734,7 @@
QSEECOM_ALIGN(sizeof
(struct hdcp_set_hw_key_rsp)));
- if ((rc < 0) || (rsp_buf->status < 0)) {
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS)) {
pr_err("qseecom cmd failed with err = %d status = %d\n",
rc, rsp_buf->status);
rc = -EINVAL;
@@ -1125,7 +1108,7 @@
(struct
hdcp_lib_session_deinit_rsp)));
- if ((rc < 0) || (rsp_buf->status < 0) ||
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
(rsp_buf->commandid != HDCP_SESSION_DEINIT)) {
pr_err("qseecom cmd failed with err = %d status = %d\n",
rc, rsp_buf->status);
@@ -1231,7 +1214,7 @@
QSEECOM_ALIGN(sizeof
(struct hdcp_deinit_rsp)));
- if ((rc < 0) || (rsp_buf->status < 0) ||
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
(rsp_buf->commandid != HDCP_TXMTR_DEINIT)) {
pr_err("qseecom cmd failed with err = %d status = %d\n",
rc, rsp_buf->status);
@@ -1285,7 +1268,7 @@
if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
(rsp_buf->commandid != HDCP_TXMTR_START_AUTHENTICATE) ||
- (rsp_buf->msglen <= 0) || (rsp_buf->message == NULL)) {
+ (rsp_buf->msglen == 0) || (rsp_buf->message == NULL)) {
pr_err("qseecom cmd failed with err = %d, status = %d\n",
rc, rsp_buf->status);
rc = -EINVAL;
@@ -1352,9 +1335,10 @@
(struct
hdcp_query_stream_type_rsp)));
- if ((rc < 0) || (rsp_buf->status < 0) || (rsp_buf->msglen <= 0) ||
- (rsp_buf->commandid != HDCP_TXMTR_QUERY_STREAM_TYPE) ||
- (rsp_buf->msg == NULL)) {
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
+ (rsp_buf->msglen == 0) ||
+ (rsp_buf->commandid != HDCP_TXMTR_QUERY_STREAM_TYPE) ||
+ (rsp_buf->msg == NULL)) {
pr_err("qseecom cmd failed with err=%d status=%d\n",
rc, rsp_buf->status);
rc = -EINVAL;
@@ -1851,7 +1835,7 @@
mutex_lock(&handle->msg_lock);
msglen = handle->last_msg_recvd_len;
- if (msglen <= 0) {
+ if (msglen == 0) {
pr_err("invalid msg len\n");
mutex_unlock(&handle->msg_lock);
rc = -EINVAL;
@@ -1937,9 +1921,10 @@
goto exit;
}
- if ((rc < 0) || (rsp_buf->status != 0) || (rsp_buf->msglen <= 0) ||
- (rsp_buf->commandid != HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) ||
- (rsp_buf->msg == NULL)) {
+ if ((rc < 0) || (rsp_buf->status != HDCP_SUCCESS) ||
+ (rsp_buf->msglen == 0) ||
+ (rsp_buf->commandid != HDCP_TXMTR_PROCESS_RECEIVED_MESSAGE) ||
+ (rsp_buf->msg == NULL)) {
pr_err("qseecom cmd failed with err=%d status=%d\n",
rc, rsp_buf->status);
rc = -EINVAL;
@@ -2089,14 +2074,10 @@
}
/* copy bytes into msb and lsb */
- *aksv_msb = key_set_rsp->ksv[0] << 24;
- *aksv_msb |= key_set_rsp->ksv[1] << 16;
- *aksv_msb |= key_set_rsp->ksv[2] << 8;
- *aksv_msb |= key_set_rsp->ksv[3];
- *aksv_lsb = key_set_rsp->ksv[4] << 24;
- *aksv_lsb |= key_set_rsp->ksv[5] << 16;
- *aksv_lsb |= key_set_rsp->ksv[6] << 8;
- *aksv_lsb |= key_set_rsp->ksv[7];
+ *aksv_msb = key_set_rsp->ksv[0] << 24 | key_set_rsp->ksv[1] << 16 |
+ key_set_rsp->ksv[2] << 8 | key_set_rsp->ksv[3];
+ *aksv_lsb = key_set_rsp->ksv[4] << 24 | key_set_rsp->ksv[5] << 16 |
+ key_set_rsp->ksv[6] << 8 | key_set_rsp->ksv[7];
return 0;
}
@@ -2217,23 +2198,6 @@
*data->hdcp_ctx = handle;
- /* Cache the client ctx to be used later if
- * Misc HDCP driver probe happens later than
- * SDE driver probe hence caching it to
- * be used later.
- */
- drv_client_handle = handle;
-
- /* if misc HDCP driver probe happens earlier
- * than SDE driver probe store the client
- * handle to be used to sysfs notifications.
- */
-
- if (hdcp_drv_mgr && !hdcp_drv_mgr->handle) {
- if (drv_client_handle)
- hdcp_drv_mgr->handle = drv_client_handle;
- }
-
handle->thread = kthread_run(kthread_worker_fn,
&handle->worker, "hdcp_tz_lib");
@@ -2274,287 +2238,3 @@
}
EXPORT_SYMBOL(hdcp_library_deregister);
-void hdcp1_notify_topology(void)
-{
- char *envp[4];
- char *a;
- char *b;
-
- if (!hdcp_drv_mgr) {
- pr_err("invalid input\n");
- return;
- }
-
- a = kzalloc(SZ_16, GFP_KERNEL);
-
- if (!a)
- return;
-
- b = kzalloc(SZ_16, GFP_KERNEL);
-
- if (!b) {
- kfree(a);
- return;
- }
-
- envp[0] = "HDCP_MGR_EVENT=MSG_READY";
- envp[1] = a;
- envp[2] = b;
- envp[3] = NULL;
-
- snprintf(envp[1], 16, "%d", (int)DOWN_CHECK_TOPOLOGY);
- snprintf(envp[2], 16, "%d", (int)HDCP_V1_TX);
-
- kobject_uevent_env(&hdcp_drv_mgr->device->kobj, KOBJ_CHANGE, envp);
- kfree(a);
- kfree(b);
-}
-
-static ssize_t msm_hdcp_1x_sysfs_rda_tp(struct device *dev,
-struct device_attribute *attr, char *buf)
-{
- ssize_t ret = 0;
-
- if (!hdcp_drv_mgr) {
- pr_err("invalid input\n");
- return -EINVAL;
- }
-
- switch (hdcp_drv_mgr->tp_msgid) {
- case DOWN_CHECK_TOPOLOGY:
- case DOWN_REQUEST_TOPOLOGY:
- buf[MSG_ID_IDX] = hdcp_drv_mgr->tp_msgid;
- buf[RET_CODE_IDX] = HDCP_AUTHED;
- ret = HEADER_LEN;
-
- memcpy(buf + HEADER_LEN, &hdcp_drv_mgr->cached_tp,
- sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));
-
- ret += sizeof(struct HDCP_V2V1_MSG_TOPOLOGY);
-
- /* clear the flag once data is read back to user space*/
- hdcp_drv_mgr->tp_msgid = -1;
- break;
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static ssize_t msm_hdcp_1x_sysfs_wta_tp(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int msgid = 0;
- ssize_t ret = count;
-
- if (!hdcp_drv_mgr || !buf) {
- pr_err("invalid input\n");
- return -EINVAL;
- }
-
- msgid = buf[0];
-
- switch (msgid) {
- case DOWN_CHECK_TOPOLOGY:
- case DOWN_REQUEST_TOPOLOGY:
- hdcp_drv_mgr->tp_msgid = msgid;
- break;
- /* more cases added here */
- default:
- ret = -EINVAL;
- }
-
- return ret;
-}
-
-static ssize_t hdcp2p2_sysfs_wta_min_level_change(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- int rc;
- int min_enc_lvl;
- struct hdcp_lib_handle *handle;
- ssize_t ret = count;
-
- if (!hdcp_drv_mgr) {
- pr_err("invalid input\n");
- return -EINVAL;
- }
-
- handle = hdcp_drv_mgr->handle;
-
- rc = kstrtoint(buf, 10, &min_enc_lvl);
- if (rc) {
- pr_err("%s: kstrtoint failed. rc=%d\n", __func__, rc);
- return -EINVAL;
- }
-
- if (handle && handle->client_ops->notify_lvl_change) {
- handle->client_ops->notify_lvl_change(handle->client_ctx,
- min_enc_lvl);
- }
-
- return ret;
-}
-
-static DEVICE_ATTR(tp, 0644, msm_hdcp_1x_sysfs_rda_tp,
- msm_hdcp_1x_sysfs_wta_tp);
-
-static DEVICE_ATTR(min_level_change, 0200, NULL,
- hdcp2p2_sysfs_wta_min_level_change);
-
-void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp)
-{
- if (!hdcp_drv_mgr) {
- pr_err("invalid input\n");
- return;
- }
-
- memcpy((void *)&hdcp_drv_mgr->cached_tp,
- hdcp1_cached_tp,
- sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));
-}
-
-static struct attribute *msm_hdcp_fs_attrs[] = {
- &dev_attr_tp.attr,
- &dev_attr_min_level_change.attr,
- NULL
-};
-
-static struct attribute_group msm_hdcp_fs_attr_group = {
- .attrs = msm_hdcp_fs_attrs
-};
-
-static int msm_hdcp_open(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static int msm_hdcp_close(struct inode *inode, struct file *file)
-{
- return 0;
-}
-
-static const struct file_operations msm_hdcp_fops = {
- .owner = THIS_MODULE,
- .open = msm_hdcp_open,
- .release = msm_hdcp_close,
-};
-
-static const struct of_device_id msm_hdcp_dt_match[] = {
- { .compatible = "qcom,msm-hdcp",},
- {}
-};
-
-MODULE_DEVICE_TABLE(of, msm_hdcp_dt_match);
-
-static int msm_hdcp_probe(struct platform_device *pdev)
-{
- int ret;
-
- hdcp_drv_mgr = devm_kzalloc(&pdev->dev, sizeof(struct msm_hdcp_mgr),
- GFP_KERNEL);
- if (!hdcp_drv_mgr)
- return -ENOMEM;
-
- hdcp_drv_mgr->pdev = pdev;
-
- platform_set_drvdata(pdev, hdcp_drv_mgr);
-
- ret = alloc_chrdev_region(&hdcp_drv_mgr->dev_num, 0, 1, DRIVER_NAME);
- if (ret < 0) {
- pr_err("alloc_chrdev_region failed ret = %d\n", ret);
- goto error_get_dev_num;
- }
-
- hdcp_drv_mgr->class = class_create(THIS_MODULE, CLASS_NAME);
- if (IS_ERR(hdcp_drv_mgr->class)) {
- ret = PTR_ERR(hdcp_drv_mgr->class);
- pr_err("couldn't create class rc = %d\n", ret);
- goto error_class_create;
- }
-
- hdcp_drv_mgr->device = device_create(hdcp_drv_mgr->class, NULL,
- hdcp_drv_mgr->dev_num, NULL, DRIVER_NAME);
- if (IS_ERR(hdcp_drv_mgr->device)) {
- ret = PTR_ERR(hdcp_drv_mgr->device);
- pr_err("device_create failed %d\n", ret);
- goto error_class_device_create;
- }
-
- cdev_init(&hdcp_drv_mgr->cdev, &msm_hdcp_fops);
- ret = cdev_add(&hdcp_drv_mgr->cdev,
- MKDEV(MAJOR(hdcp_drv_mgr->dev_num), 0), 1);
- if (ret < 0) {
- pr_err("cdev_add failed %d\n", ret);
- goto error_cdev_add;
- }
-
- ret = sysfs_create_group(&hdcp_drv_mgr->device->kobj,
- &msm_hdcp_fs_attr_group);
- if (ret)
- pr_err("unable to register rotator sysfs nodes\n");
-
- /* Store the handle in the hdcp drv mgr
- * to be used for the sysfs notifications
- */
- hdcp_drv_mgr->handle = drv_client_handle;
-
- return 0;
-error_cdev_add:
- device_destroy(hdcp_drv_mgr->class, hdcp_drv_mgr->dev_num);
-error_class_device_create:
- class_destroy(hdcp_drv_mgr->class);
-error_class_create:
- unregister_chrdev_region(hdcp_drv_mgr->dev_num, 1);
-error_get_dev_num:
- devm_kfree(&pdev->dev, hdcp_drv_mgr);
- hdcp_drv_mgr = NULL;
- return ret;
-}
-
-static int msm_hdcp_remove(struct platform_device *pdev)
-{
- struct msm_hdcp_mgr *mgr;
-
- mgr = (struct msm_hdcp_mgr *)platform_get_drvdata(pdev);
- if (!mgr)
- return -ENODEV;
-
- sysfs_remove_group(&hdcp_drv_mgr->device->kobj,
- &msm_hdcp_fs_attr_group);
- cdev_del(&hdcp_drv_mgr->cdev);
- device_destroy(hdcp_drv_mgr->class, hdcp_drv_mgr->dev_num);
- class_destroy(hdcp_drv_mgr->class);
- unregister_chrdev_region(hdcp_drv_mgr->dev_num, 1);
-
- devm_kfree(&pdev->dev, hdcp_drv_mgr);
- hdcp_drv_mgr = NULL;
- return 0;
-}
-
-static struct platform_driver msm_hdcp_driver = {
- .probe = msm_hdcp_probe,
- .remove = msm_hdcp_remove,
- .driver = {
- .name = "msm_hdcp",
- .of_match_table = msm_hdcp_dt_match,
- .pm = NULL,
- }
-};
-
-static int __init msm_hdcp_init(void)
-{
- return platform_driver_register(&msm_hdcp_driver);
-}
-
-static void __exit msm_hdcp_exit(void)
-{
- return platform_driver_unregister(&msm_hdcp_driver);
-}
-
-module_init(msm_hdcp_init);
-module_exit(msm_hdcp_exit);
-
-MODULE_DESCRIPTION("MSM HDCP driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/misc/msm_hdcp.c b/drivers/misc/msm_hdcp.c
new file mode 100644
index 0000000..ea8e84d
--- /dev/null
+++ b/drivers/misc/msm_hdcp.c
@@ -0,0 +1,356 @@
+/* Copyright (c) 2018, 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-hdcp] %s: " fmt, __func__
+
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/uaccess.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/msm_hdcp.h>
+#include <linux/of.h>
+
+#define CLASS_NAME "hdcp"
+#define DRIVER_NAME "msm_hdcp"
+
+struct msm_hdcp {
+ struct platform_device *pdev;
+ dev_t dev_num;
+ struct cdev cdev;
+ struct class *class;
+ struct device *device;
+ struct HDCP_V2V1_MSG_TOPOLOGY cached_tp;
+ u32 tp_msgid;
+ void *client_ctx;
+ void (*cb)(void *ctx, int data);
+};
+
+void msm_hdcp_register_cb(struct device *dev, void *ctx,
+ void (*cb)(void *ctx, int data))
+{
+ struct msm_hdcp *hdcp = NULL;
+
+ if (!dev) {
+ pr_err("invalid device pointer\n");
+ return;
+ }
+
+ hdcp = dev_get_drvdata(dev);
+ if (!hdcp) {
+ pr_err("invalid driver pointer\n");
+ return;
+ }
+
+ hdcp->cb = cb;
+ hdcp->client_ctx = ctx;
+}
+
+void msm_hdcp_notify_topology(struct device *dev)
+{
+ char *envp[4];
+ char tp[SZ_16];
+ char ver[SZ_16];
+ struct msm_hdcp *hdcp = NULL;
+
+ if (!dev) {
+ pr_err("invalid device pointer\n");
+ return;
+ }
+
+ hdcp = dev_get_drvdata(dev);
+ if (!hdcp) {
+ pr_err("invalid driver pointer\n");
+ return;
+ }
+
+ snprintf(tp, SZ_16, "%d", DOWN_CHECK_TOPOLOGY);
+ snprintf(ver, SZ_16, "%d", HDCP_V1_TX);
+
+ envp[0] = "HDCP_MGR_EVENT=MSG_READY";
+ envp[1] = tp;
+ envp[2] = ver;
+ envp[3] = NULL;
+
+ kobject_uevent_env(&hdcp->device->kobj, KOBJ_CHANGE, envp);
+}
+
+void msm_hdcp_cache_repeater_topology(struct device *dev,
+ struct HDCP_V2V1_MSG_TOPOLOGY *tp)
+{
+ struct msm_hdcp *hdcp = NULL;
+
+ if (!dev || !tp) {
+ pr_err("invalid input\n");
+ return;
+ }
+
+ hdcp = dev_get_drvdata(dev);
+ if (!hdcp) {
+ pr_err("invalid driver pointer\n");
+ return;
+ }
+
+ memcpy(&hdcp->cached_tp, tp,
+ sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));
+}
+
+static ssize_t msm_hdcp_1x_sysfs_rda_tp(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = 0;
+ struct msm_hdcp *hdcp = NULL;
+
+ if (!dev) {
+ pr_err("invalid device pointer\n");
+ return -ENODEV;
+ }
+
+ hdcp = dev_get_drvdata(dev);
+ if (!hdcp) {
+ pr_err("invalid driver pointer\n");
+ return -ENODEV;
+ }
+
+ switch (hdcp->tp_msgid) {
+ case DOWN_CHECK_TOPOLOGY:
+ case DOWN_REQUEST_TOPOLOGY:
+ buf[MSG_ID_IDX] = hdcp->tp_msgid;
+ buf[RET_CODE_IDX] = HDCP_AUTHED;
+ ret = HEADER_LEN;
+
+ memcpy(buf + HEADER_LEN, &hdcp->cached_tp,
+ sizeof(struct HDCP_V2V1_MSG_TOPOLOGY));
+
+ ret += sizeof(struct HDCP_V2V1_MSG_TOPOLOGY);
+
+ /* clear the flag once data is read back to user space*/
+ hdcp->tp_msgid = -1;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static ssize_t msm_hdcp_1x_sysfs_wta_tp(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int msgid = 0;
+ ssize_t ret = count;
+ struct msm_hdcp *hdcp = NULL;
+
+ if (!dev) {
+ pr_err("invalid device pointer\n");
+ return -ENODEV;
+ }
+
+ hdcp = dev_get_drvdata(dev);
+ if (!hdcp) {
+ pr_err("invalid driver pointer\n");
+ return -ENODEV;
+ }
+
+ msgid = buf[0];
+
+ switch (msgid) {
+ case DOWN_CHECK_TOPOLOGY:
+ case DOWN_REQUEST_TOPOLOGY:
+ hdcp->tp_msgid = msgid;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static ssize_t msm_hdcp_2x_sysfs_wta_min_level_change(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int rc;
+ int min_enc_lvl;
+ ssize_t ret = count;
+ struct msm_hdcp *hdcp = NULL;
+
+ if (!dev) {
+ pr_err("invalid device pointer\n");
+ return -ENODEV;
+ }
+
+ hdcp = dev_get_drvdata(dev);
+ if (!hdcp) {
+ pr_err("invalid driver pointer\n");
+ return -ENODEV;
+ }
+
+ rc = kstrtoint(buf, 10, &min_enc_lvl);
+ if (rc) {
+ pr_err("kstrtoint failed. rc=%d\n", rc);
+ return -EINVAL;
+ }
+
+ if (hdcp->cb && hdcp->client_ctx)
+ hdcp->cb(hdcp->client_ctx, min_enc_lvl);
+
+ return ret;
+}
+
+static DEVICE_ATTR(tp, 0644, msm_hdcp_1x_sysfs_rda_tp,
+ msm_hdcp_1x_sysfs_wta_tp);
+
+static DEVICE_ATTR(min_level_change, 0200, NULL,
+ msm_hdcp_2x_sysfs_wta_min_level_change);
+
+static struct attribute *msm_hdcp_fs_attrs[] = {
+ &dev_attr_tp.attr,
+ &dev_attr_min_level_change.attr,
+ NULL
+};
+
+static struct attribute_group msm_hdcp_fs_attr_group = {
+ .attrs = msm_hdcp_fs_attrs
+};
+
+static int msm_hdcp_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int msm_hdcp_close(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static const struct file_operations msm_hdcp_fops = {
+ .owner = THIS_MODULE,
+ .open = msm_hdcp_open,
+ .release = msm_hdcp_close,
+};
+
+static const struct of_device_id msm_hdcp_dt_match[] = {
+ { .compatible = "qcom,msm-hdcp",},
+ {}
+};
+
+MODULE_DEVICE_TABLE(of, msm_hdcp_dt_match);
+
+static int msm_hdcp_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct msm_hdcp *hdcp;
+
+ hdcp = devm_kzalloc(&pdev->dev, sizeof(struct msm_hdcp), GFP_KERNEL);
+ if (!hdcp)
+ return -ENOMEM;
+
+ hdcp->pdev = pdev;
+
+ platform_set_drvdata(pdev, hdcp);
+
+ ret = alloc_chrdev_region(&hdcp->dev_num, 0, 1, DRIVER_NAME);
+ if (ret < 0) {
+ pr_err("alloc_chrdev_region failed ret = %d\n", ret);
+ goto error_get_dev_num;
+ }
+
+ hdcp->class = class_create(THIS_MODULE, CLASS_NAME);
+ if (IS_ERR(hdcp->class)) {
+ ret = PTR_ERR(hdcp->class);
+ pr_err("couldn't create class rc = %d\n", ret);
+ goto error_class_create;
+ }
+
+ hdcp->device = device_create(hdcp->class, NULL,
+ hdcp->dev_num, NULL, DRIVER_NAME);
+ if (IS_ERR(hdcp->device)) {
+ ret = PTR_ERR(hdcp->device);
+ pr_err("device_create failed %d\n", ret);
+ goto error_class_device_create;
+ }
+
+ cdev_init(&hdcp->cdev, &msm_hdcp_fops);
+ ret = cdev_add(&hdcp->cdev, MKDEV(MAJOR(hdcp->dev_num), 0), 1);
+ if (ret < 0) {
+ pr_err("cdev_add failed %d\n", ret);
+ goto error_cdev_add;
+ }
+
+ ret = sysfs_create_group(&hdcp->device->kobj, &msm_hdcp_fs_attr_group);
+ if (ret)
+ pr_err("unable to register msm_hdcp sysfs nodes\n");
+
+ return 0;
+error_cdev_add:
+ device_destroy(hdcp->class, hdcp->dev_num);
+error_class_device_create:
+ class_destroy(hdcp->class);
+error_class_create:
+ unregister_chrdev_region(hdcp->dev_num, 1);
+error_get_dev_num:
+ devm_kfree(&pdev->dev, hdcp);
+ hdcp = NULL;
+ return ret;
+}
+
+static int msm_hdcp_remove(struct platform_device *pdev)
+{
+ struct msm_hdcp *hdcp;
+
+ hdcp = platform_get_drvdata(pdev);
+ if (!hdcp)
+ return -ENODEV;
+
+ sysfs_remove_group(&hdcp->device->kobj,
+ &msm_hdcp_fs_attr_group);
+ cdev_del(&hdcp->cdev);
+ device_destroy(hdcp->class, hdcp->dev_num);
+ class_destroy(hdcp->class);
+ unregister_chrdev_region(hdcp->dev_num, 1);
+
+ devm_kfree(&pdev->dev, hdcp);
+ hdcp = NULL;
+ return 0;
+}
+
+static struct platform_driver msm_hdcp_driver = {
+ .probe = msm_hdcp_probe,
+ .remove = msm_hdcp_remove,
+ .driver = {
+ .name = "msm_hdcp",
+ .of_match_table = msm_hdcp_dt_match,
+ .pm = NULL,
+ }
+};
+
+static int __init msm_hdcp_init(void)
+{
+ return platform_driver_register(&msm_hdcp_driver);
+}
+
+static void __exit msm_hdcp_exit(void)
+{
+ return platform_driver_unregister(&msm_hdcp_driver);
+}
+
+module_init(msm_hdcp_init);
+module_exit(msm_hdcp_exit);
+
+MODULE_DESCRIPTION("MSM HDCP driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/platform/msm/usb_bam.c b/drivers/platform/msm/usb_bam.c
index dec698f..6314270 100644
--- a/drivers/platform/msm/usb_bam.c
+++ b/drivers/platform/msm/usb_bam.c
@@ -3313,7 +3313,7 @@
return ret;
}
-bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx)
+bool usb_bam_get_prod_granted(enum usb_ctrl bam_type)
{
return (info[bam_type].cur_prod_state == IPA_RM_RESOURCE_GRANTED);
}
diff --git a/drivers/power/supply/qcom/Makefile b/drivers/power/supply/qcom/Makefile
index 6c7fc78..662f18d 100644
--- a/drivers/power/supply/qcom/Makefile
+++ b/drivers/power/supply/qcom/Makefile
@@ -9,4 +9,4 @@
obj-$(CONFIG_QPNP_QG) += qpnp-qg.o pmic-voter.o qg-util.o qg-soc.o qg-sdam.o qg-battery-profile.o qg-profile-lib.o
obj-$(CONFIG_QPNP_QNOVO) += qpnp-qnovo.o battery.o
obj-$(CONFIG_QPNP_TYPEC) += qpnp-typec.o
-obj-$(CONFIG_QPNP_SMB5) += step-chg-jeita.o battery.o qpnp-smb5.o smb5-lib.o pmic-voter.o storm-watch.o
+obj-$(CONFIG_QPNP_SMB5) += step-chg-jeita.o battery.o qpnp-smb5.o smb5-lib.o pmic-voter.o storm-watch.o schgm-flash.o
diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c
index b07efdf..b3f66d5 100644
--- a/drivers/power/supply/qcom/qpnp-smb5.c
+++ b/drivers/power/supply/qcom/qpnp-smb5.c
@@ -27,6 +27,7 @@
#include <linux/pmic-voter.h>
#include "smb5-reg.h"
#include "smb5-lib.h"
+#include "schgm-flash.h"
static struct smb_params smb5_pmi632_params = {
.fcc = {
@@ -371,6 +372,7 @@
POWER_SUPPLY_PROP_SDP_CURRENT_MAX,
POWER_SUPPLY_PROP_CONNECTOR_TYPE,
POWER_SUPPLY_PROP_VOLTAGE_MAX,
+ POWER_SUPPLY_PROP_SCOPE,
};
static int smb5_usb_get_prop(struct power_supply *psy,
@@ -379,6 +381,7 @@
{
struct smb5 *chip = power_supply_get_drvdata(psy);
struct smb_charger *chg = &chip->chg;
+ union power_supply_propval pval;
int rc = 0;
switch (psp) {
@@ -476,6 +479,15 @@
case POWER_SUPPLY_PROP_CONNECTOR_TYPE:
val->intval = chg->connector_type;
break;
+ case POWER_SUPPLY_PROP_SCOPE:
+ val->intval = POWER_SUPPLY_SCOPE_UNKNOWN;
+ rc = smblib_get_prop_usb_present(chg, &pval);
+ if (rc < 0)
+ break;
+ val->intval = pval.intval ? POWER_SUPPLY_SCOPE_DEVICE
+ : chg->otg_present ? POWER_SUPPLY_SCOPE_SYSTEM
+ : POWER_SUPPLY_SCOPE_UNKNOWN;
+ break;
default:
pr_err("get prop %d is not supported in usb\n", psp);
rc = -EINVAL;
@@ -701,6 +713,8 @@
POWER_SUPPLY_PROP_INPUT_VOLTAGE_SETTLED,
POWER_SUPPLY_PROP_FCC_DELTA,
POWER_SUPPLY_PROP_CURRENT_MAX,
+ POWER_SUPPLY_PROP_FLASH_ACTIVE,
+ POWER_SUPPLY_PROP_FLASH_TRIGGER,
};
static int smb5_usb_main_get_prop(struct power_supply *psy,
@@ -734,6 +748,12 @@
case POWER_SUPPLY_PROP_CURRENT_MAX:
rc = smblib_get_icl_current(chg, &val->intval);
break;
+ case POWER_SUPPLY_PROP_FLASH_ACTIVE:
+ val->intval = chg->flash_active;
+ break;
+ case POWER_SUPPLY_PROP_FLASH_TRIGGER:
+ rc = schgm_flash_get_vreg_ok(chg, &val->intval);
+ break;
default:
pr_debug("get prop %d is not supported in usb-main\n", psp);
rc = -EINVAL;
@@ -765,6 +785,9 @@
case POWER_SUPPLY_PROP_CURRENT_MAX:
rc = smblib_set_icl_current(chg, val->intval);
break;
+ case POWER_SUPPLY_PROP_FLASH_ACTIVE:
+ chg->flash_active = val->intval;
+ break;
default:
pr_err("set prop %d is not supported\n", psp);
rc = -EINVAL;
@@ -1367,6 +1390,13 @@
: POWER_SUPPLY_CONNECTOR_TYPEC;
pr_debug("Connector type=%s\n", type ? "Micro USB" : "TypeC");
+ /*
+ * PMI632 based hw init:
+ * - Initialize flash module for PMI632
+ */
+ if (chg->smb_version == PMI632_SUBTYPE)
+ schgm_flash_init(chg);
+
smblib_rerun_apsd_if_required(chg);
/* vote 0mA on usb_icl for non battery platforms */
@@ -1829,6 +1859,39 @@
.name = "temp-change-smb",
.handler = default_irq_handler,
},
+ /* FLASH */
+ [VREG_OK_IRQ] = {
+ .name = "vreg-ok",
+ .handler = schgm_flash_default_irq_handler,
+ },
+ [ILIM_S2_IRQ] = {
+ .name = "ilim2-s2",
+ .handler = schgm_flash_ilim2_irq_handler,
+ },
+ [ILIM_S1_IRQ] = {
+ .name = "ilim1-s1",
+ .handler = schgm_flash_default_irq_handler,
+ },
+ [VOUT_DOWN_IRQ] = {
+ .name = "vout-down",
+ .handler = schgm_flash_default_irq_handler,
+ },
+ [VOUT_UP_IRQ] = {
+ .name = "vout-up",
+ .handler = schgm_flash_default_irq_handler,
+ },
+ [FLASH_STATE_CHANGE_IRQ] = {
+ .name = "flash-state-change",
+ .handler = schgm_flash_state_change_irq_handler,
+ },
+ [TORCH_REQ_IRQ] = {
+ .name = "torch-req",
+ .handler = schgm_flash_default_irq_handler,
+ },
+ [FLASH_EN_IRQ] = {
+ .name = "flash-en",
+ .handler = schgm_flash_default_irq_handler,
+ },
};
static int smb5_get_irq_index_byname(const char *irq_name)
diff --git a/drivers/power/supply/qcom/schgm-flash.c b/drivers/power/supply/qcom/schgm-flash.c
new file mode 100644
index 0000000..eed70d3
--- /dev/null
+++ b/drivers/power/supply/qcom/schgm-flash.c
@@ -0,0 +1,216 @@
+/* Copyright (c) 2018 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) "SCHG-FLASH: %s: " fmt, __func__
+
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/regmap.h>
+#include <linux/power_supply.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/printk.h>
+#include <linux/pmic-voter.h>
+#include "smb5-lib.h"
+#include "schgm-flash.h"
+
+#define IS_BETWEEN(left, right, value) \
+ (((left) >= (right) && (left) >= (value) \
+ && (value) >= (right)) \
+ || ((left) <= (right) && (left) <= (value) \
+ && (value) <= (right)))
+
+irqreturn_t schgm_flash_default_irq_handler(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+
+ pr_debug("IRQ: %s\n", irq_data->name);
+
+ return IRQ_HANDLED;
+}
+
+irqreturn_t schgm_flash_ilim2_irq_handler(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb_charger *chg = irq_data->parent_data;
+ int rc;
+
+ rc = smblib_write(chg, SCHGM_FLASH_S2_LATCH_RESET_CMD_REG,
+ FLASH_S2_LATCH_RESET_BIT);
+ if (rc < 0)
+ pr_err("Couldn't reset S2_LATCH reset rc=%d\n", rc);
+
+ return IRQ_HANDLED;
+}
+
+irqreturn_t schgm_flash_state_change_irq_handler(int irq, void *data)
+{
+ struct smb_irq_data *irq_data = data;
+ struct smb_charger *chg = irq_data->parent_data;
+ int rc;
+ u8 reg;
+
+ rc = smblib_read(chg, SCHGM_FLASH_STATUS_3_REG, ®);
+ if (rc < 0)
+ pr_err("Couldn't read flash status_3 rc=%d\n", rc);
+ else
+ pr_debug("Flash status changed state=[%x]\n",
+ (reg && FLASH_STATE_MASK));
+
+ return IRQ_HANDLED;
+}
+
+#define FIXED_MODE 0
+#define ADAPTIVE_MODE 1
+static void schgm_flash_parse_dt(struct smb_charger *chg)
+{
+ struct device_node *node = chg->dev->of_node;
+ u32 val;
+ int rc;
+
+ chg->flash_derating_soc = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,flash-derating-soc", &val);
+ if (!rc) {
+ if (IS_BETWEEN(0, 100, val))
+ chg->flash_derating_soc = (val * 255) / 100;
+ }
+
+ chg->flash_disable_soc = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,flash-disable-soc", &val);
+ if (!rc) {
+ if (IS_BETWEEN(0, 100, val))
+ chg->flash_disable_soc = (val * 255) / 100;
+ }
+
+ chg->headroom_mode = -EINVAL;
+ rc = of_property_read_u32(node, "qcom,headroom-mode", &val);
+ if (!rc) {
+ if (IS_BETWEEN(FIXED_MODE, ADAPTIVE_MODE, val))
+ chg->headroom_mode = val;
+ }
+}
+
+int schgm_flash_get_vreg_ok(struct smb_charger *chg, int *val)
+{
+ int rc, vreg_state;
+ u8 stat = 0;
+
+ if (!chg->flash_init_done)
+ return -EPERM;
+
+ rc = smblib_read(chg, SCHGM_FLASH_STATUS_2_REG, &stat);
+ if (rc < 0) {
+ pr_err("Couldn't read FLASH STATUS_2 rc=%d\n", rc);
+ return rc;
+ }
+ vreg_state = !!(stat & VREG_OK_BIT);
+
+ /* If VREG_OK is not set check for flash error */
+ if (!vreg_state) {
+ rc = smblib_read(chg, SCHGM_FLASH_STATUS_3_REG, &stat);
+ if (rc < 0) {
+ pr_err("Couldn't read FLASH_STATUS_3 rc=%d\n", rc);
+ return rc;
+ }
+ if ((stat & FLASH_STATE_MASK) == FLASH_ERROR_VAL) {
+ vreg_state = -EFAULT;
+ rc = smblib_read(chg, SCHGM_FLASH_STATUS_5_REG,
+ &stat);
+ if (rc < 0) {
+ pr_err("Couldn't read FLASH_STATUS_5 rc=%d\n",
+ rc);
+ return rc;
+ }
+ pr_debug("Flash error: status=%x\n", stat);
+ }
+ }
+
+ /*
+ * val can be one of the following:
+ * 1 - VREG_OK is set.
+ * 0 - VREG_OK is 0 but no Flash error.
+ * -EFAULT - Flash Error is set.
+ */
+ *val = vreg_state;
+
+ return 0;
+}
+
+int schgm_flash_init(struct smb_charger *chg)
+{
+ int rc;
+ u8 reg;
+
+ schgm_flash_parse_dt(chg);
+
+ if (chg->flash_derating_soc != -EINVAL) {
+ rc = smblib_write(chg, SCHGM_SOC_BASED_FLASH_DERATE_TH_CFG_REG,
+ chg->flash_derating_soc);
+ if (rc < 0) {
+ pr_err("Couldn't configure SOC for flash derating rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if (chg->flash_disable_soc != -EINVAL) {
+ rc = smblib_write(chg, SCHGM_SOC_BASED_FLASH_DISABLE_TH_CFG_REG,
+ chg->flash_disable_soc);
+ if (rc < 0) {
+ pr_err("Couldn't configure SOC for flash disable rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if (chg->headroom_mode != -EINVAL) {
+ /*
+ * configure headroom management policy for
+ * flash and torch mode.
+ */
+ reg = (chg->headroom_mode == FIXED_MODE)
+ ? FORCE_FLASH_BOOST_5V_BIT : 0;
+ rc = smblib_write(chg, SCHGM_FORCE_BOOST_CONTROL, reg);
+ if (rc < 0) {
+ pr_err("Couldn't write force boost control reg rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ reg = (chg->headroom_mode == FIXED_MODE)
+ ? TORCH_PRIORITY_CONTROL_BIT : 0;
+ rc = smblib_write(chg, SCHGM_TORCH_PRIORITY_CONTROL, reg);
+ if (rc < 0) {
+ pr_err("Couldn't force 5V boost in torch mode rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+ if ((chg->flash_derating_soc != -EINVAL)
+ || (chg->flash_disable_soc != -EINVAL)) {
+ /* Check if SOC based derating/disable is enabled */
+ rc = smblib_read(chg, SCHGM_FLASH_CONTROL_REG, ®);
+ if (rc < 0) {
+ pr_err("Couldn't read flash control reg rc=%d\n", rc);
+ return rc;
+ }
+ if (!(reg & SOC_LOW_FOR_FLASH_EN_BIT))
+ pr_warn("Soc based flash derating not enabled\n");
+ }
+
+ chg->flash_init_done = true;
+
+ return 0;
+}
diff --git a/drivers/power/supply/qcom/schgm-flash.h b/drivers/power/supply/qcom/schgm-flash.h
new file mode 100644
index 0000000..b6fff6c
--- /dev/null
+++ b/drivers/power/supply/qcom/schgm-flash.h
@@ -0,0 +1,54 @@
+/* Copyright (c) 2018 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 __SCHGM_FLASH_H__
+#define __SCHGM_FLASH_H__
+
+#include <linux/bitops.h>
+
+#define SCHGM_FLASH_BASE 0xA600
+
+#define SCHGM_FLASH_STATUS_2_REG (SCHGM_FLASH_BASE + 0x07)
+#define VREG_OK_BIT BIT(4)
+
+#define SCHGM_FLASH_STATUS_3_REG (SCHGM_FLASH_BASE + 0x08)
+#define FLASH_STATE_MASK GENMASK(2, 0)
+#define FLASH_ERROR_VAL 0x7
+
+#define SCHGM_FLASH_INT_RT_STS_REG (SCHGM_FLASH_BASE + 0x10)
+
+#define SCHGM_FLASH_STATUS_5_REG (SCHGM_FLASH_BASE + 0x0B)
+
+#define SCHGM_FORCE_BOOST_CONTROL (SCHGM_FLASH_BASE + 0x41)
+#define FORCE_FLASH_BOOST_5V_BIT BIT(0)
+
+#define SCHGM_FLASH_S2_LATCH_RESET_CMD_REG (SCHGM_FLASH_BASE + 0x44)
+#define FLASH_S2_LATCH_RESET_BIT BIT(0)
+
+#define SCHGM_FLASH_CONTROL_REG (SCHGM_FLASH_BASE + 0x60)
+#define SOC_LOW_FOR_FLASH_EN_BIT BIT(7)
+
+#define SCHGM_TORCH_PRIORITY_CONTROL (SCHGM_FLASH_BASE + 0x63)
+#define TORCH_PRIORITY_CONTROL_BIT BIT(0)
+
+#define SCHGM_SOC_BASED_FLASH_DERATE_TH_CFG_REG (SCHGM_FLASH_BASE + 0x67)
+
+#define SCHGM_SOC_BASED_FLASH_DISABLE_TH_CFG_REG \
+ (SCHGM_FLASH_BASE + 0x68)
+
+int schgm_flash_get_vreg_ok(struct smb_charger *chg, int *val);
+int schgm_flash_init(struct smb_charger *chg);
+
+irqreturn_t schgm_flash_default_irq_handler(int irq, void *data);
+irqreturn_t schgm_flash_ilim2_irq_handler(int irq, void *data);
+irqreturn_t schgm_flash_state_change_irq_handler(int irq, void *data);
+#endif /* __SCHGM_FLASH_H__ */
diff --git a/drivers/power/supply/qcom/smb1351-charger.c b/drivers/power/supply/qcom/smb1351-charger.c
index dfedece..63d57fe 100644
--- a/drivers/power/supply/qcom/smb1351-charger.c
+++ b/drivers/power/supply/qcom/smb1351-charger.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018 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,6 +15,7 @@
#include <linux/i2c.h>
#include <linux/debugfs.h>
#include <linux/errno.h>
+#include <linux/extcon.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
@@ -376,6 +377,7 @@
#define USB2_MAX_CURRENT_MA 500
#define USB3_MIN_CURRENT_MA 150
#define USB3_MAX_CURRENT_MA 900
+#define DCP_MAX_CURRENT_MA 1500
#define SMB1351_IRQ_REG_COUNT 8
#define SMB1351_CHG_PRE_MIN_MA 100
#define SMB1351_CHG_FAST_MIN_MA 1000
@@ -424,6 +426,12 @@
[SMB1351] = "SMB1351",
};
+static const unsigned int smb1351_extcon_cable[] = {
+ EXTCON_USB,
+ EXTCON_USB_HOST,
+ EXTCON_NONE,
+};
+
struct smb1351_charger {
struct i2c_client *client;
struct device *dev;
@@ -472,6 +480,7 @@
enum chip_version version;
/* psy */
+ struct power_supply_desc usb_psy_d;
struct power_supply *usb_psy;
int usb_psy_ma;
struct power_supply *bms_psy;
@@ -505,6 +514,12 @@
/* pinctrl parameters */
const char *pinctrl_state_name;
struct pinctrl *smb_pinctrl;
+
+ /* standalone */
+ bool charger_present;
+ struct extcon_dev *extcon;
+ struct regulator *dpdm_reg;
+ enum power_supply_type charger_type;
};
struct smb_irq_info {
@@ -633,6 +648,65 @@
return rc;
}
+static int smb1351_get_closest_usb_setpoint(int val)
+{
+ int i;
+
+ for (i = ARRAY_SIZE(usb_chg_current) - 1; i >= 0; i--) {
+ if (usb_chg_current[i] <= val)
+ break;
+ }
+ if (i < 0)
+ i = 0;
+
+ if (i >= ARRAY_SIZE(usb_chg_current) - 1)
+ return ARRAY_SIZE(usb_chg_current) - 1;
+
+ /* check what is closer, i or i + 1 */
+ if (abs(usb_chg_current[i] - val) < abs(usb_chg_current[i + 1] - val))
+ return i;
+ else
+ return i + 1;
+}
+
+static int smb1351_request_dpdm(struct smb1351_charger *chip, bool enable)
+{
+ int rc = 0;
+
+ /* fetch the DPDM regulator */
+ if (!chip->dpdm_reg && of_get_property(chip->dev->of_node,
+ "dpdm-supply", NULL)) {
+ chip->dpdm_reg = devm_regulator_get(chip->dev, "dpdm");
+ if (IS_ERR(chip->dpdm_reg)) {
+ rc = PTR_ERR(chip->dpdm_reg);
+ pr_err("Couldn't get dpdm regulator rc=%d\n",
+ rc);
+ chip->dpdm_reg = NULL;
+ return rc;
+ }
+ }
+
+ if (enable) {
+ if (chip->dpdm_reg && !regulator_is_enabled(chip->dpdm_reg)) {
+ pr_err("enabling DPDM regulator\n");
+ rc = regulator_enable(chip->dpdm_reg);
+ if (rc < 0)
+ pr_err("Couldn't enable dpdm regulator rc=%d\n",
+ rc);
+ }
+ } else {
+ if (chip->dpdm_reg && regulator_is_enabled(chip->dpdm_reg)) {
+ pr_err("disabling DPDM regulator\n");
+ rc = regulator_disable(chip->dpdm_reg);
+ if (rc < 0)
+ pr_err("Couldn't disable dpdm regulator rc=%d\n",
+ rc);
+ }
+ }
+
+ return rc;
+}
+
static int smb1351_usb_suspend(struct smb1351_charger *chip, int reason,
bool suspend)
{
@@ -1290,6 +1364,75 @@
return rc;
}
+static char *smb1351_usb_supplicants[] = {
+ "bms",
+};
+
+static enum power_supply_property smb1351_usb_properties[] = {
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_CURRENT_MAX,
+ POWER_SUPPLY_PROP_TYPE,
+};
+
+static int smb1351_usb_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct smb1351_charger *chip = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ val->intval = chip->usb_psy_ma * 1000;
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = chip->chg_present;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = chip->chg_present && !chip->usb_suspended_status;
+ break;
+ case POWER_SUPPLY_PROP_TYPE:
+ val->intval = chip->charger_type;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int smb1351_usb_set_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct smb1351_charger *chip = power_supply_get_drvdata(psy);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ chip->usb_psy_ma = val->intval / 1000;
+ smb1351_enable_volatile_writes(chip);
+ smb1351_set_usb_chg_current(chip, chip->usb_psy_ma);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ power_supply_changed(psy);
+ return 0;
+}
+
+static int smb1351_usb_is_writeable(struct power_supply *psy,
+ enum power_supply_property psp)
+{
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CURRENT_MAX:
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static int smb1351_batt_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
{
@@ -1535,27 +1678,6 @@
return 0;
}
-static int smb1351_get_closest_usb_setpoint(int val)
-{
- int i;
-
- for (i = ARRAY_SIZE(usb_chg_current) - 1; i >= 0; i--) {
- if (usb_chg_current[i] <= val)
- break;
- }
- if (i < 0)
- i = 0;
-
- if (i >= ARRAY_SIZE(usb_chg_current) - 1)
- return ARRAY_SIZE(usb_chg_current) - 1;
-
- /* check what is closer, i or i + 1 */
- if (abs(usb_chg_current[i] - val) < abs(usb_chg_current[i + 1] - val))
- return i;
- else
- return i + 1;
-}
-
static bool smb1351_is_input_current_limited(struct smb1351_charger *chip)
{
int rc;
@@ -2001,10 +2123,10 @@
static int smb1351_apsd_complete_handler(struct smb1351_charger *chip,
u8 status)
{
- int rc;
+ int rc, usb_psy_ma = 0;
u8 reg = 0;
- union power_supply_propval prop = {0, };
enum power_supply_type type = POWER_SUPPLY_TYPE_UNKNOWN;
+ union extcon_property_value val;
/*
* If apsd is disabled, charger detection is done by
@@ -2055,18 +2177,12 @@
type, chip->chg_present);
if (!chip->battery_missing && !chip->apsd_rerun) {
if (type == POWER_SUPPLY_TYPE_USB) {
- pr_debug("Setting usb psy dp=f dm=f SDP and rerun\n");
- prop.intval = POWER_SUPPLY_DP_DM_DPF_DMF;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_DP_DM, &prop);
+ smb1351_request_dpdm(chip, false);
+ smb1351_request_dpdm(chip, true);
chip->apsd_rerun = true;
rerun_apsd(chip);
return 0;
}
- pr_debug("Set usb psy dp=f dm=f DCP and no rerun\n");
- prop.intval = POWER_SUPPLY_DP_DM_DPF_DMF;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_DP_DM, &prop);
}
/*
* If defined force hvdcp 2p0 property,
@@ -2087,35 +2203,33 @@
msecs_to_jiffies(HVDCP_NOTIFY_MS));
}
- prop.intval = type;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_TYPE, &prop);
- /*
- * SMB is now done sampling the D+/D- lines,
- * indicate USB driver
- */
- pr_debug("updating usb_psy present=%d\n", chip->chg_present);
- prop.intval = chip->chg_present;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_PRESENT,
- &prop);
+ chip->charger_type = type;
+ if (type == POWER_SUPPLY_TYPE_USB
+ || type == POWER_SUPPLY_TYPE_USB_CDP) {
+ val.intval = true;
+ extcon_set_property(chip->extcon, EXTCON_USB,
+ EXTCON_PROP_USB_SS, val);
+ extcon_set_cable_state_(chip->extcon, EXTCON_USB, true);
+ }
chip->apsd_rerun = false;
+
+ /* set the charge current as required */
+ if (type == POWER_SUPPLY_TYPE_USB)
+ usb_psy_ma = USB2_MIN_CURRENT_MA;
+ else /* DCP */
+ usb_psy_ma = DCP_MAX_CURRENT_MA;
+
+ chip->usb_psy_ma = usb_psy_ma;
+ smb1351_enable_volatile_writes(chip);
+ rc = smb1351_set_usb_chg_current(chip, chip->usb_psy_ma);
+ if (rc < 0)
+ pr_err("Failed to set USB current rc=%d\n", rc);
+
} else if (!chip->apsd_rerun) {
/* Handle Charger removal */
- prop.intval = POWER_SUPPLY_TYPE_UNKNOWN;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_TYPE, &prop);
-
- chip->chg_present = false;
- prop.intval = chip->chg_present;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_PRESENT,
- &prop);
-
- pr_debug("Set usb psy dm=r df=r\n");
- prop.intval = POWER_SUPPLY_DP_DM_DPR_DMR;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_DP_DM, &prop);
+ chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
+ extcon_set_cable_state_(chip->extcon, EXTCON_USB, false);
+ smb1351_request_dpdm(chip, false);
}
return 0;
@@ -2163,42 +2277,7 @@
static int smb1351_usbin_uv_handler(struct smb1351_charger *chip, u8 status)
{
- union power_supply_propval pval = {0, };
-
- /* use this to detect USB insertion only if !apsd */
- if (chip->disable_apsd) {
- /*
- * If APSD is disabled, src det interrupt won't trigger.
- * Hence use usbin_uv for removal and insertion notification
- */
- if (status == 0) {
- chip->chg_present = true;
- pr_debug("updating usb_psy present=%d\n",
- chip->chg_present);
- pval.intval = POWER_SUPPLY_TYPE_USB;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_TYPE, &pval);
-
- pval.intval = chip->chg_present;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_PRESENT,
- &pval);
- } else {
- chip->chg_present = false;
-
- pval.intval = POWER_SUPPLY_TYPE_UNKNOWN;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_TYPE, &pval);
-
- pr_debug("updating usb_psy present=%d\n",
- chip->chg_present);
- pval.intval = chip->chg_present;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_PRESENT,
- &pval);
- }
- return 0;
- }
+ smb1351_request_dpdm(chip, !!status);
if (status) {
cancel_delayed_work_sync(&chip->hvdcp_det_work);
@@ -2218,24 +2297,19 @@
{
int rc;
u8 reg = 0;
- union power_supply_propval pval = {0, };
rc = smb1351_read_reg(chip, IRQ_E_REG, ®);
if (rc)
pr_err("Couldn't read IRQ_E rc = %d\n", rc);
if (status != 0) {
- chip->chg_present = false;
chip->usbin_ov = true;
+ chip->charger_type = POWER_SUPPLY_TYPE_UNKNOWN;
+ if (chip->chg_present)
+ extcon_set_cable_state_(chip->extcon, EXTCON_USB,
+ false);
+ chip->chg_present = false;
- pval.intval = POWER_SUPPLY_TYPE_UNKNOWN;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_TYPE, &pval);
-
- pval.intval = chip->chg_present;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_PRESENT,
- &pval);
} else {
chip->usbin_ov = false;
if (reg & IRQ_USBIN_UV_BIT)
@@ -2244,13 +2318,6 @@
smb1351_apsd_complete_handler(chip, 1);
}
- if (chip->usb_psy) {
- pval.intval = status ? POWER_SUPPLY_HEALTH_OVERVOLTAGE
- : POWER_SUPPLY_HEALTH_GOOD;
- power_supply_set_property(chip->usb_psy,
- POWER_SUPPLY_PROP_HEALTH, &pval);
- pr_debug("chip ov status is %d\n", pval.intval);
- }
pr_debug("chip->chg_present = %d\n", chip->chg_present);
return 0;
@@ -2319,6 +2386,21 @@
return 0;
}
+static int smb1351_rid_handler(struct smb1351_charger *chip,
+ u8 status)
+{
+ union extcon_property_value val;
+
+ if (!!status) {
+ val.intval = true;
+ extcon_set_property(chip->extcon, EXTCON_USB_HOST,
+ EXTCON_PROP_USB_SS, val);
+ }
+ extcon_set_cable_state_(chip->extcon, EXTCON_USB_HOST, !!status);
+
+ return 0;
+}
+
static struct irq_handler_info handlers[] = {
[0] = {
.stat_reg = IRQ_A_REG,
@@ -2413,6 +2495,7 @@
{ .name = "otg_oc_retry",
},
{ .name = "rid",
+ .smb_irq = smb1351_rid_handler,
},
{ .name = "otg_fail",
},
@@ -2524,30 +2607,21 @@
{
struct smb1351_charger *chip = power_supply_get_drvdata(psy);
union power_supply_propval prop = {0,};
- int rc, current_limit = 0, online = 0;
+ int rc, current_limit = 0;
if (chip->bms_psy_name)
chip->bms_psy =
power_supply_get_by_name((char *)chip->bms_psy_name);
rc = power_supply_get_property(chip->usb_psy,
- POWER_SUPPLY_PROP_ONLINE, &prop);
- if (rc)
- pr_err("Couldn't read USB online property, rc=%d\n", rc);
- else
- online = prop.intval;
-
- rc = power_supply_get_property(chip->usb_psy,
POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
if (rc)
pr_err("Couldn't read USB current_max property, rc=%d\n", rc);
else
current_limit = prop.intval / 1000;
- pr_debug("online = %d, current_limit = %d\n", online, current_limit);
+ pr_debug("current_limit = %d\n", current_limit);
- smb1351_enable_volatile_writes(chip);
- smb1351_set_usb_chg_current(chip, current_limit);
pr_debug("updating batt psy\n");
}
@@ -3002,28 +3076,65 @@
{
int rc;
struct smb1351_charger *chip;
- struct power_supply *usb_psy;
struct power_supply_config batt_psy_cfg = {};
+ struct power_supply_config usb_psy_cfg = {};
u8 reg = 0;
- usb_psy = power_supply_get_by_name("usb");
- if (!usb_psy) {
- pr_debug("USB psy not found; deferring probe\n");
- return -EPROBE_DEFER;
- }
-
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
chip->client = client;
chip->dev = &client->dev;
- chip->usb_psy = usb_psy;
chip->fake_battery_soc = -EINVAL;
+
+ chip->extcon = devm_extcon_dev_allocate(chip->dev,
+ smb1351_extcon_cable);
+ if (IS_ERR(chip->extcon)) {
+ pr_err("failed to allocate extcon device\n");
+ rc = PTR_ERR(chip->extcon);
+ return rc;
+ }
+
+ rc = devm_extcon_dev_register(chip->dev, chip->extcon);
+ if (rc) {
+ pr_err("failed to register extcon device\n");
+ return rc;
+ }
+
+ rc = extcon_set_property_capability(chip->extcon,
+ EXTCON_USB, EXTCON_PROP_USB_SS);
+ rc |= extcon_set_property_capability(chip->extcon,
+ EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
+ if (rc < 0) {
+ pr_err("Failed to register extcon capability rc=%d\n", rc);
+ return rc;
+ }
+
+ chip->usb_psy_d.name = "usb";
+ chip->usb_psy_d.type = POWER_SUPPLY_TYPE_USB;
+ chip->usb_psy_d.get_property = smb1351_usb_get_property;
+ chip->usb_psy_d.set_property = smb1351_usb_set_property;
+ chip->usb_psy_d.properties = smb1351_usb_properties;
+ chip->usb_psy_d.num_properties = ARRAY_SIZE(smb1351_usb_properties);
+ chip->usb_psy_d.property_is_writeable = smb1351_usb_is_writeable;
+
+ usb_psy_cfg.drv_data = chip;
+ usb_psy_cfg.supplied_to = smb1351_usb_supplicants;
+ usb_psy_cfg.num_supplicants = ARRAY_SIZE(smb1351_usb_supplicants);
+
+ chip->usb_psy = devm_power_supply_register(chip->dev,
+ &chip->usb_psy_d, &usb_psy_cfg);
+ if (IS_ERR(chip->usb_psy)) {
+ pr_err("Unable to register usb_psy rc = %ld\n",
+ PTR_ERR(chip->usb_psy));
+ rc = PTR_ERR(chip->usb_psy);
+ return rc;
+ }
+
INIT_DELAYED_WORK(&chip->chg_remove_work, smb1351_chg_remove_work);
INIT_DELAYED_WORK(&chip->hvdcp_det_work, smb1351_hvdcp_det_work);
device_init_wakeup(chip->dev, true);
-
/* probe the device to check if its actually connected */
rc = smb1351_read_reg(chip, CHG_REVISION_REG, ®);
if (rc) {
diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h
index fa7381c..d7b9a17 100644
--- a/drivers/power/supply/qcom/smb5-lib.h
+++ b/drivers/power/supply/qcom/smb5-lib.h
@@ -143,6 +143,15 @@
IMP_TRIGGER_IRQ,
TEMP_CHANGE_IRQ,
TEMP_CHANGE_SMB_IRQ,
+ /* FLASH */
+ VREG_OK_IRQ,
+ ILIM_S2_IRQ,
+ ILIM_S1_IRQ,
+ VOUT_DOWN_IRQ,
+ VOUT_UP_IRQ,
+ FLASH_STATE_CHANGE_IRQ,
+ TORCH_REQ_IRQ,
+ FLASH_EN_IRQ,
/* END */
SMB_IRQ_MAX,
};
@@ -351,6 +360,13 @@
int pulse_cnt;
int die_health;
+
+ /* flash */
+ u32 flash_derating_soc;
+ u32 flash_disable_soc;
+ u32 headroom_mode;
+ bool flash_init_done;
+ bool flash_active;
};
int smblib_read(struct smb_charger *chg, u16 addr, u8 *val);
diff --git a/drivers/slimbus/slim-msm.c b/drivers/slimbus/slim-msm.c
index 01779f9..24a3ccf 100644
--- a/drivers/slimbus/slim-msm.c
+++ b/drivers/slimbus/slim-msm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, 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
@@ -490,32 +490,26 @@
return SLIM_P_INPROGRESS;
}
-static int msm_slim_iommu_map(struct msm_slim_ctrl *dev, phys_addr_t iobuf,
+static dma_addr_t msm_slim_iommu_map(struct msm_slim_ctrl *dev, void *buf_addr,
u32 len)
{
- int ret;
+ dma_addr_t ret;
+ struct device *devp = dev->iommu_desc.cb_dev ? dev->iommu_desc.cb_dev :
+ dev->dev;
+ ret = dma_map_single(devp, buf_addr, len, DMA_BIDIRECTIONAL);
- if (!dev->iommu_desc.cb_dev)
- return 0;
+ if (dma_mapping_error(devp, ret))
+ return DMA_ERROR_CODE;
- ret = iommu_map(dev->iommu_desc.iommu_map->domain,
- rounddown(iobuf, PAGE_SIZE),
- rounddown(iobuf, PAGE_SIZE),
- roundup((len + (iobuf - rounddown(iobuf, PAGE_SIZE))),
- PAGE_SIZE), IOMMU_READ | IOMMU_WRITE);
return ret;
}
-static void msm_slim_iommu_unmap(struct msm_slim_ctrl *dev, phys_addr_t iobuf,
+static void msm_slim_iommu_unmap(struct msm_slim_ctrl *dev, dma_addr_t buf_addr,
u32 len)
{
- if (!dev->iommu_desc.cb_dev)
- return;
-
- iommu_unmap(dev->iommu_desc.iommu_map->domain,
- rounddown(iobuf, PAGE_SIZE),
- roundup((len + (iobuf - rounddown(iobuf, PAGE_SIZE))),
- PAGE_SIZE));
+ struct device *devp = dev->iommu_desc.cb_dev ? dev->iommu_desc.cb_dev :
+ dev->dev;
+ dma_unmap_single(devp, buf_addr, len, DMA_BIDIRECTIONAL);
}
static void msm_slim_port_cb(struct sps_event_notify *ev)
@@ -539,11 +533,12 @@
complete(comp);
}
-int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, phys_addr_t iobuf,
+int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, void *buf,
u32 len, struct completion *comp)
{
struct sps_register_event sreg;
int ret;
+ dma_addr_t dma_buf;
struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
if (pn >= dev->port_nums)
@@ -552,9 +547,11 @@
if (!dev->pipes[pn].connected)
return -ENOTCONN;
- ret = msm_slim_iommu_map(dev, iobuf, len);
- if (ret)
- return ret;
+ dma_buf = msm_slim_iommu_map(dev, buf, len);
+ if (dma_buf == DMA_ERROR_CODE) {
+ dev_err(dev->dev, "error DMA mapping buffers\n");
+ return -ENOMEM;
+ }
sreg.options = (SPS_EVENT_DESC_DONE|SPS_EVENT_ERROR);
sreg.mode = SPS_TRIGGER_WAIT;
@@ -564,10 +561,10 @@
ret = sps_register_event(dev->pipes[pn].sps, &sreg);
if (ret) {
dev_dbg(dev->dev, "sps register event error:%x\n", ret);
- msm_slim_iommu_unmap(dev, iobuf, len);
+ msm_slim_iommu_unmap(dev, dma_buf, len);
return ret;
}
- ret = sps_transfer_one(dev->pipes[pn].sps, iobuf, len, comp,
+ ret = sps_transfer_one(dev->pipes[pn].sps, dma_buf, len, comp,
SPS_IOVEC_FLAG_INT);
dev_dbg(dev->dev, "sps submit xfer error code:%x\n", ret);
if (!ret) {
@@ -581,7 +578,7 @@
/* Make sure that port registers are updated before returning */
mb();
} else {
- msm_slim_iommu_unmap(dev, iobuf, len);
+ msm_slim_iommu_unmap(dev, dma_buf, len);
}
return ret;
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 5859c5f..edebfd9 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, 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
@@ -423,7 +423,7 @@
int msm_slim_connect_pipe_port(struct msm_slim_ctrl *dev, u8 pn);
enum slim_port_err msm_slim_port_xfer_status(struct slim_controller *ctr,
u8 pn, phys_addr_t *done_buf, u32 *done_len);
-int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, phys_addr_t iobuf,
+int msm_slim_port_xfer(struct slim_controller *ctrl, u8 pn, void *buf,
u32 len, struct completion *comp);
int msm_send_msg_buf(struct msm_slim_ctrl *dev, u32 *buf, u8 len, u32 tx_reg);
u32 *msm_get_msg_buf(struct msm_slim_ctrl *dev, int len,
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index f34467b..1140b33 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, 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
@@ -1600,14 +1600,14 @@
* Client will call slim_port_get_xfer_status to get error and/or number of
* bytes transferred if used asynchronously.
*/
-int slim_port_xfer(struct slim_device *sb, u32 ph, phys_addr_t iobuf, u32 len,
+int slim_port_xfer(struct slim_device *sb, u32 ph, void *buf, u32 len,
struct completion *comp)
{
struct slim_controller *ctrl = sb->ctrl;
u8 pn = SLIM_HDL_TO_PORT(ph);
dev_dbg(&ctrl->dev, "port xfer: num:%d", pn);
- return ctrl->port_xfer(ctrl, pn, iobuf, len, comp);
+ return ctrl->port_xfer(ctrl, pn, buf, len, comp);
}
EXPORT_SYMBOL(slim_port_xfer);
diff --git a/drivers/soc/qcom/dcc.c b/drivers/soc/qcom/dcc.c
index 43dddb4..a687286 100644
--- a/drivers/soc/qcom/dcc.c
+++ b/drivers/soc/qcom/dcc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 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
@@ -554,7 +554,8 @@
if (strlen(buf) >= 10)
return -EINVAL;
- strlcpy(str, buf, sizeof(str));
+ if (sscanf(buf, "%9s", str) != 1)
+ return -EINVAL;
mutex_lock(&drvdata->mutex);
if (drvdata->enable) {
@@ -599,7 +600,8 @@
if (strlen(buf) >= 10)
return -EINVAL;
- strlcpy(str, buf, sizeof(str));
+ if (sscanf(buf, "%9s", str) != 1)
+ return -EINVAL;
mutex_lock(&drvdata->mutex);
if (drvdata->enable) {
diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c
index bb5f706..c662cd7 100644
--- a/drivers/thermal/of-thermal.c
+++ b/drivers/thermal/of-thermal.c
@@ -430,7 +430,16 @@
if (trip >= data->ntrips || trip < 0)
return -EDOM;
- *temp = data->trips[trip].temperature;
+ if (data->senps && data->senps->ops->get_trip_temp) {
+ int ret;
+
+ ret = data->senps->ops->get_trip_temp(data->senps->sensor_data,
+ trip, temp);
+ if (ret)
+ return ret;
+ } else {
+ *temp = data->trips[trip].temperature;
+ }
return 0;
}
diff --git a/drivers/thermal/qcom/Kconfig b/drivers/thermal/qcom/Kconfig
index e7d6241..f334a1d 100644
--- a/drivers/thermal/qcom/Kconfig
+++ b/drivers/thermal/qcom/Kconfig
@@ -71,3 +71,13 @@
voltage.
If you want this support, you should say Y here.
+
+config QTI_BCL_SOC_DRIVER
+ bool "QTI Battery state of charge sensor driver"
+ depends on THERMAL_OF
+ help
+ This driver registers battery state of charge as a sensor with
+ thermal zone. This sensor can monitor for state of charge
+ threshold and notify the thermal framework.
+
+ If you want this support, you should say Y here.
diff --git a/drivers/thermal/qcom/Makefile b/drivers/thermal/qcom/Makefile
index 257b714..784ef21 100644
--- a/drivers/thermal/qcom/Makefile
+++ b/drivers/thermal/qcom/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_QTI_AOP_REG_COOLING_DEVICE) += regulator_aop_cdev.o
obj-$(CONFIG_REGULATOR_COOLING_DEVICE) += regulator_cdev.o
obj-$(CONFIG_QTI_QMI_COOLING_DEVICE) += thermal_mitigation_device_service_v01.o qmi_cooling.o
+obj-$(CONFIG_QTI_BCL_SOC_DRIVER) += bcl_soc.o
diff --git a/drivers/thermal/qcom/bcl_soc.c b/drivers/thermal/qcom/bcl_soc.c
new file mode 100644
index 0000000..e4d5157
--- /dev/null
+++ b/drivers/thermal/qcom/bcl_soc.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2018, 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) "%s:%s " fmt, KBUILD_MODNAME, __func__
+
+#include <linux/module.h>
+#include <linux/workqueue.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/power_supply.h>
+#include <linux/thermal.h>
+
+#include "../thermal_core.h"
+
+#define BCL_DRIVER_NAME "bcl_soc_peripheral"
+
+struct bcl_device {
+ struct notifier_block psy_nb;
+ struct work_struct soc_eval_work;
+ long int trip_temp;
+ int trip_val;
+ struct mutex state_trans_lock;
+ bool irq_enabled;
+ struct thermal_zone_device *tz_dev;
+ struct thermal_zone_of_device_ops ops;
+};
+
+static struct bcl_device *bcl_perph;
+
+static int bcl_set_soc(void *data, int low, int high)
+{
+ if (low == bcl_perph->trip_temp)
+ return 0;
+
+ mutex_lock(&bcl_perph->state_trans_lock);
+ pr_debug("low soc threshold:%d\n", low);
+ bcl_perph->trip_temp = low;
+ if (low == INT_MIN) {
+ bcl_perph->irq_enabled = false;
+ goto unlock_and_exit;
+ }
+ bcl_perph->irq_enabled = true;
+ schedule_work(&bcl_perph->soc_eval_work);
+
+unlock_and_exit:
+ mutex_unlock(&bcl_perph->state_trans_lock);
+ return 0;
+}
+
+static int bcl_read_soc(void *data, int *val)
+{
+ static struct power_supply *batt_psy;
+ union power_supply_propval ret = {0,};
+ int err = 0;
+
+ *val = 100;
+ if (!batt_psy)
+ batt_psy = power_supply_get_by_name("battery");
+ if (batt_psy) {
+ err = power_supply_get_property(batt_psy,
+ POWER_SUPPLY_PROP_CAPACITY, &ret);
+ if (err) {
+ pr_err("battery percentage read error:%d\n",
+ err);
+ return err;
+ }
+ *val = ret.intval;
+ }
+ pr_debug("soc:%d\n", *val);
+
+ return err;
+}
+
+static void bcl_evaluate_soc(struct work_struct *work)
+{
+ int battery_percentage;
+
+ if (bcl_read_soc(NULL, &battery_percentage))
+ return;
+
+ mutex_lock(&bcl_perph->state_trans_lock);
+ if (!bcl_perph->irq_enabled)
+ goto eval_exit;
+ if (battery_percentage > bcl_perph->trip_temp)
+ goto eval_exit;
+
+ bcl_perph->trip_val = battery_percentage;
+ mutex_unlock(&bcl_perph->state_trans_lock);
+ of_thermal_handle_trip(bcl_perph->tz_dev);
+
+ return;
+eval_exit:
+ mutex_unlock(&bcl_perph->state_trans_lock);
+}
+
+static int battery_supply_callback(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct power_supply *psy = data;
+
+ if (strcmp(psy->desc->name, "battery"))
+ return NOTIFY_OK;
+ schedule_work(&bcl_perph->soc_eval_work);
+
+ return NOTIFY_OK;
+}
+
+static int bcl_soc_remove(struct platform_device *pdev)
+{
+ power_supply_unreg_notifier(&bcl_perph->psy_nb);
+ flush_work(&bcl_perph->soc_eval_work);
+ if (bcl_perph->tz_dev)
+ thermal_zone_of_sensor_unregister(&pdev->dev,
+ bcl_perph->tz_dev);
+
+ return 0;
+}
+
+static int bcl_soc_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+
+ bcl_perph = devm_kzalloc(&pdev->dev, sizeof(*bcl_perph), GFP_KERNEL);
+ if (!bcl_perph)
+ return -ENOMEM;
+
+ mutex_init(&bcl_perph->state_trans_lock);
+ bcl_perph->ops.get_temp = bcl_read_soc;
+ bcl_perph->ops.set_trips = bcl_set_soc;
+ INIT_WORK(&bcl_perph->soc_eval_work, bcl_evaluate_soc);
+ bcl_perph->psy_nb.notifier_call = battery_supply_callback;
+
+ ret = power_supply_reg_notifier(&bcl_perph->psy_nb);
+ if (ret < 0) {
+ pr_err("soc notifier registration error. defer. err:%d\n",
+ ret);
+ ret = -EPROBE_DEFER;
+ goto bcl_soc_probe_exit;
+ }
+ bcl_perph->tz_dev = thermal_zone_of_sensor_register(&pdev->dev,
+ 0, bcl_perph, &bcl_perph->ops);
+ if (IS_ERR(bcl_perph->tz_dev)) {
+ pr_err("soc TZ register failed. err:%ld\n",
+ PTR_ERR(bcl_perph->tz_dev));
+ ret = PTR_ERR(bcl_perph->tz_dev);
+ bcl_perph->tz_dev = NULL;
+ goto bcl_soc_probe_exit;
+ }
+ thermal_zone_device_update(bcl_perph->tz_dev, THERMAL_DEVICE_UP);
+ schedule_work(&bcl_perph->soc_eval_work);
+
+ dev_set_drvdata(&pdev->dev, bcl_perph);
+
+ return 0;
+
+bcl_soc_probe_exit:
+ bcl_soc_remove(pdev);
+ return ret;
+}
+
+static const struct of_device_id bcl_match[] = {
+ {
+ .compatible = "qcom,msm-bcl-soc",
+ },
+ {},
+};
+
+static struct platform_driver bcl_driver = {
+ .probe = bcl_soc_probe,
+ .remove = bcl_soc_remove,
+ .driver = {
+ .name = BCL_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = bcl_match,
+ },
+};
+
+builtin_platform_driver(bcl_driver);
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
index bec3dea..f8fdc13 100644
--- a/drivers/thermal/qpnp-adc-tm.c
+++ b/drivers/thermal/qpnp-adc-tm.c
@@ -42,15 +42,128 @@
#define QPNP_PERPH_TYPE2 0x2
#define QPNP_REVISION_EIGHT_CHANNEL_SUPPORT 2
#define QPNP_PERPH_SUBTYPE_TWO_CHANNEL_SUPPORT 0x22
+#define QPNP_STATUS1 0x8
+#define QPNP_STATUS1_OP_MODE 4
+#define QPNP_STATUS1_MEAS_INTERVAL_EN_STS BIT(2)
+#define QPNP_STATUS1_REQ_STS BIT(1)
+#define QPNP_STATUS1_EOC BIT(0)
+#define QPNP_STATUS2 0x9
+#define QPNP_STATUS2_CONV_SEQ_STATE 6
+#define QPNP_STATUS2_FIFO_NOT_EMPTY_FLAG BIT(1)
+#define QPNP_STATUS2_CONV_SEQ_TIMEOUT_STS BIT(0)
+#define QPNP_CONV_TIMEOUT_ERR 2
+
+#define QPNP_MODE_CTL 0x40
+#define QPNP_OP_MODE_SHIFT 3
+#define QPNP_VREF_XO_THM_FORCE BIT(2)
+#define QPNP_AMUX_TRIM_EN BIT(1)
+#define QPNP_ADC_TRIM_EN BIT(0)
#define QPNP_EN_CTL1 0x46
#define QPNP_ADC_TM_EN BIT(7)
#define QPNP_BTM_CONV_REQ 0x47
#define QPNP_ADC_CONV_REQ_EN BIT(7)
+#define QPNP_ADC_DIG_PARAM 0x50
+#define QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT 3
+#define QPNP_HW_SETTLE_DELAY 0x51
+#define QPNP_CONV_SEQ_CTL 0x54
+#define QPNP_CONV_SEQ_HOLDOFF_SHIFT 4
+#define QPNP_CONV_SEQ_TRIG_CTL 0x55
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL 0x57
+#define QPNP_ADC_TM_MEAS_INTERVAL_TIME_SHIFT 0x3
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2 0x58
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2_SHIFT 0x4
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL2_MASK 0xf0
+#define QPNP_ADC_TM_MEAS_INTERVAL_CTL3_MASK 0xf
+
+#define QPNP_ADC_MEAS_INTERVAL_OP_CTL 0x59
+#define QPNP_ADC_MEAS_INTERVAL_OP BIT(7)
+
#define QPNP_OP_MODE_SHIFT 3
#define QPNP_CONV_REQ 0x52
#define QPNP_CONV_REQ_SET BIT(7)
+#define QPNP_FAST_AVG_CTL 0x5a
+#define QPNP_FAST_AVG_EN 0x5b
+#define QPNP_FAST_AVG_ENABLED BIT(7)
+
+#define QPNP_M0_LOW_THR_LSB 0x5c
+#define QPNP_M0_LOW_THR_MSB 0x5d
+#define QPNP_M0_HIGH_THR_LSB 0x5e
+#define QPNP_M0_HIGH_THR_MSB 0x5f
+#define QPNP_M1_ADC_CH_SEL_CTL 0x68
+#define QPNP_M1_LOW_THR_LSB 0x69
+#define QPNP_M1_LOW_THR_MSB 0x6a
+#define QPNP_M1_HIGH_THR_LSB 0x6b
+#define QPNP_M1_HIGH_THR_MSB 0x6c
+#define QPNP_M2_ADC_CH_SEL_CTL 0x70
+#define QPNP_M2_LOW_THR_LSB 0x71
+#define QPNP_M2_LOW_THR_MSB 0x72
+#define QPNP_M2_HIGH_THR_LSB 0x73
+#define QPNP_M2_HIGH_THR_MSB 0x74
+#define QPNP_M3_ADC_CH_SEL_CTL 0x78
+#define QPNP_M3_LOW_THR_LSB 0x79
+#define QPNP_M3_LOW_THR_MSB 0x7a
+#define QPNP_M3_HIGH_THR_LSB 0x7b
+#define QPNP_M3_HIGH_THR_MSB 0x7c
+#define QPNP_M4_ADC_CH_SEL_CTL 0x80
+#define QPNP_M4_LOW_THR_LSB 0x81
+#define QPNP_M4_LOW_THR_MSB 0x82
+#define QPNP_M4_HIGH_THR_LSB 0x83
+#define QPNP_M4_HIGH_THR_MSB 0x84
+#define QPNP_M5_ADC_CH_SEL_CTL 0x88
+#define QPNP_M5_LOW_THR_LSB 0x89
+#define QPNP_M5_LOW_THR_MSB 0x8a
+#define QPNP_M5_HIGH_THR_LSB 0x8b
+#define QPNP_M5_HIGH_THR_MSB 0x8c
+#define QPNP_M6_ADC_CH_SEL_CTL 0x90
+#define QPNP_M6_LOW_THR_LSB 0x91
+#define QPNP_M6_LOW_THR_MSB 0x92
+#define QPNP_M6_HIGH_THR_LSB 0x93
+#define QPNP_M6_HIGH_THR_MSB 0x94
+#define QPNP_M7_ADC_CH_SEL_CTL 0x98
+#define QPNP_M7_LOW_THR_LSB 0x99
+#define QPNP_M7_LOW_THR_MSB 0x9a
+#define QPNP_M7_HIGH_THR_LSB 0x9b
+#define QPNP_M7_HIGH_THR_MSB 0x9c
+
+#define QPNP_ADC_TM_MULTI_MEAS_EN 0x41
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M0 BIT(0)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M1 BIT(1)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M2 BIT(2)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M3 BIT(3)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M4 BIT(4)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M5 BIT(5)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M6 BIT(6)
+#define QPNP_ADC_TM_MULTI_MEAS_EN_M7 BIT(7)
+#define QPNP_ADC_TM_LOW_THR_INT_EN 0x42
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M0 BIT(0)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M1 BIT(1)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M2 BIT(2)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M3 BIT(3)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M4 BIT(4)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M5 BIT(5)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M6 BIT(6)
+#define QPNP_ADC_TM_LOW_THR_INT_EN_M7 BIT(7)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN 0x43
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M0 BIT(0)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M1 BIT(1)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M2 BIT(2)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M3 BIT(3)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M4 BIT(4)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M5 BIT(5)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M6 BIT(6)
+#define QPNP_ADC_TM_HIGH_THR_INT_EN_M7 BIT(7)
+
+#define QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL 0x59
+#define QPNP_ADC_TM_M1_MEAS_INTERVAL_CTL 0x6d
+#define QPNP_ADC_TM_M2_MEAS_INTERVAL_CTL 0x75
+#define QPNP_ADC_TM_M3_MEAS_INTERVAL_CTL 0x7d
+#define QPNP_ADC_TM_M4_MEAS_INTERVAL_CTL 0x85
+#define QPNP_ADC_TM_M5_MEAS_INTERVAL_CTL 0x8d
+#define QPNP_ADC_TM_M6_MEAS_INTERVAL_CTL 0x95
+#define QPNP_ADC_TM_M7_MEAS_INTERVAL_CTL 0x9d
+
#define QPNP_ADC_TM_STATUS1 0x8
#define QPNP_ADC_TM_STATUS_LOW 0xa
#define QPNP_ADC_TM_STATUS_HIGH 0xb
@@ -62,6 +175,10 @@
#define QPNP_ADC_TM_THR_LSB_MASK(val) (val & 0xff)
#define QPNP_ADC_TM_THR_MSB_MASK(val) ((val & 0xff00) >> 8)
+#define QPNP_MIN_TIME 2000
+#define QPNP_MAX_TIME 2100
+#define QPNP_RETRY 1000
+
/* QPNP ADC TM HC start */
#define QPNP_BTM_HC_STATUS1 0x08
#define QPNP_BTM_HC_STATUS_LOW 0x0a
@@ -110,6 +227,8 @@
u8 adc_tm_high_enable;
u8 adc_tm_low_thr_set;
u8 adc_tm_high_thr_set;
+ spinlock_t adc_tm_low_lock;
+ spinlock_t adc_tm_high_lock;
};
struct qpnp_adc_thr_client_info {
@@ -168,6 +287,69 @@
LIST_HEAD(qpnp_adc_tm_device_list);
+struct qpnp_adc_tm_trip_reg_type {
+ enum qpnp_adc_tm_channel_select btm_amux_chan;
+ uint16_t low_thr_lsb_addr;
+ uint16_t low_thr_msb_addr;
+ uint16_t high_thr_lsb_addr;
+ uint16_t high_thr_msb_addr;
+ u8 multi_meas_en;
+ u8 low_thr_int_chan_en;
+ u8 high_thr_int_chan_en;
+ u8 meas_interval_ctl;
+};
+
+static struct qpnp_adc_tm_trip_reg_type adc_tm_data[] = {
+ [QPNP_ADC_TM_CHAN0] = {QPNP_ADC_TM_M0_ADC_CH_SEL_CTL,
+ QPNP_M0_LOW_THR_LSB,
+ QPNP_M0_LOW_THR_MSB, QPNP_M0_HIGH_THR_LSB,
+ QPNP_M0_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M0,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M0, QPNP_ADC_TM_HIGH_THR_INT_EN_M0,
+ QPNP_ADC_TM_M0_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN1] = {QPNP_ADC_TM_M1_ADC_CH_SEL_CTL,
+ QPNP_M1_LOW_THR_LSB,
+ QPNP_M1_LOW_THR_MSB, QPNP_M1_HIGH_THR_LSB,
+ QPNP_M1_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M1,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M1, QPNP_ADC_TM_HIGH_THR_INT_EN_M1,
+ QPNP_ADC_TM_M1_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN2] = {QPNP_ADC_TM_M2_ADC_CH_SEL_CTL,
+ QPNP_M2_LOW_THR_LSB,
+ QPNP_M2_LOW_THR_MSB, QPNP_M2_HIGH_THR_LSB,
+ QPNP_M2_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M2,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M2, QPNP_ADC_TM_HIGH_THR_INT_EN_M2,
+ QPNP_ADC_TM_M2_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN3] = {QPNP_ADC_TM_M3_ADC_CH_SEL_CTL,
+ QPNP_M3_LOW_THR_LSB,
+ QPNP_M3_LOW_THR_MSB, QPNP_M3_HIGH_THR_LSB,
+ QPNP_M3_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M3,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M3, QPNP_ADC_TM_HIGH_THR_INT_EN_M3,
+ QPNP_ADC_TM_M3_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN4] = {QPNP_ADC_TM_M4_ADC_CH_SEL_CTL,
+ QPNP_M4_LOW_THR_LSB,
+ QPNP_M4_LOW_THR_MSB, QPNP_M4_HIGH_THR_LSB,
+ QPNP_M4_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M4,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M4, QPNP_ADC_TM_HIGH_THR_INT_EN_M4,
+ QPNP_ADC_TM_M4_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN5] = {QPNP_ADC_TM_M5_ADC_CH_SEL_CTL,
+ QPNP_M5_LOW_THR_LSB,
+ QPNP_M5_LOW_THR_MSB, QPNP_M5_HIGH_THR_LSB,
+ QPNP_M5_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M5,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M5, QPNP_ADC_TM_HIGH_THR_INT_EN_M5,
+ QPNP_ADC_TM_M5_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN6] = {QPNP_ADC_TM_M6_ADC_CH_SEL_CTL,
+ QPNP_M6_LOW_THR_LSB,
+ QPNP_M6_LOW_THR_MSB, QPNP_M6_HIGH_THR_LSB,
+ QPNP_M6_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M6,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M6, QPNP_ADC_TM_HIGH_THR_INT_EN_M6,
+ QPNP_ADC_TM_M6_MEAS_INTERVAL_CTL},
+ [QPNP_ADC_TM_CHAN7] = {QPNP_ADC_TM_M7_ADC_CH_SEL_CTL,
+ QPNP_M7_LOW_THR_LSB,
+ QPNP_M7_LOW_THR_MSB, QPNP_M7_HIGH_THR_LSB,
+ QPNP_M7_HIGH_THR_MSB, QPNP_ADC_TM_MULTI_MEAS_EN_M7,
+ QPNP_ADC_TM_LOW_THR_INT_EN_M7, QPNP_ADC_TM_HIGH_THR_INT_EN_M7,
+ QPNP_ADC_TM_M7_MEAS_INTERVAL_CTL},
+};
+
static struct qpnp_adc_tm_reverse_scale_fn adc_tm_rscale_fn[] = {
[SCALE_R_VBATT] = {qpnp_adc_vbatt_rscaler},
[SCALE_RBATT_THERM] = {qpnp_adc_btm_scaler},
@@ -208,6 +390,33 @@
return rc;
}
+static int32_t qpnp_adc_tm_fast_avg_en(struct qpnp_adc_tm_chip *chip,
+ uint32_t *fast_avg_sample)
+{
+ int rc = 0, version = 0;
+ u8 fast_avg_en = 0;
+
+ version = qpnp_adc_get_revid_version(chip->dev);
+ if (!((version == QPNP_REV_ID_8916_1_0) ||
+ (version == QPNP_REV_ID_8916_1_1) ||
+ (version == QPNP_REV_ID_8916_2_0))) {
+ pr_debug("fast-avg-en not required for this version\n");
+ return rc;
+ }
+
+ fast_avg_en = QPNP_FAST_AVG_ENABLED;
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_FAST_AVG_EN, fast_avg_en, 1);
+ if (rc < 0) {
+ pr_err("adc-tm fast-avg enable err\n");
+ return rc;
+ }
+
+ if (*fast_avg_sample >= 3)
+ *fast_avg_sample = 2;
+
+ return rc;
+}
+
static int qpnp_adc_tm_check_vreg_vote(struct qpnp_adc_tm_chip *chip)
{
int rc = 0;
@@ -244,19 +453,37 @@
return rc;
}
- data = QPNP_ADC_CONV_REQ_EN;
- rc = qpnp_adc_tm_write_reg(chip, QPNP_BTM_CONV_REQ, data, 1);
- if (rc < 0) {
- pr_err("adc-tm enable failed\n");
- return rc;
+ if (chip->adc_tm_hc) {
+ data = QPNP_ADC_CONV_REQ_EN;
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_BTM_CONV_REQ, data, 1);
+ if (rc < 0) {
+ pr_err("adc-tm enable failed\n");
+ return rc;
+ }
}
-
return rc;
}
static int32_t qpnp_adc_tm_disable(struct qpnp_adc_tm_chip *chip)
{
- return 0;
+ u8 data = 0;
+ int rc = 0;
+
+ if (chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_BTM_CONV_REQ, data, 1);
+ if (rc < 0) {
+ pr_err("adc-tm enable failed\n");
+ return rc;
+ }
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_EN_CTL1, data, 1);
+ if (rc < 0) {
+ pr_err("adc-tm disable failed\n");
+ return rc;
+ }
+
+ return rc;
}
static int qpnp_adc_tm_is_valid(struct qpnp_adc_tm_chip *chip)
@@ -320,11 +547,129 @@
static int32_t qpnp_adc_tm_enable_if_channel_meas(
struct qpnp_adc_tm_chip *chip)
{
+ u8 adc_tm_meas_en = 0, status_low = 0, status_high = 0;
int rc = 0;
- rc = qpnp_adc_tm_rc_check_channel_en(chip);
+ if (chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_rc_check_channel_en(chip);
+ if (rc) {
+ pr_err("adc_tm channel check failed\n");
+ return rc;
+ }
+ } else {
+ /* Check if a measurement request is still required */
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ &adc_tm_meas_en, 1);
+ if (rc) {
+ pr_err("read status high failed with %d\n", rc);
+ return rc;
+ }
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+ &status_low, 1);
+ if (rc) {
+ pr_err("read status low failed with %d\n", rc);
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
+ &status_high, 1);
+ if (rc) {
+ pr_err("read status high failed with %d\n", rc);
+ return rc;
+ }
+
+ /* Enable only if there are pending measurement requests */
+ if ((adc_tm_meas_en && status_high) ||
+ (adc_tm_meas_en && status_low)) {
+ qpnp_adc_tm_enable(chip);
+ /* Request conversion */
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_CONV_REQ,
+ QPNP_CONV_REQ_SET, 1);
+ if (rc < 0) {
+ pr_err("adc-tm request conversion failed\n");
+ return rc;
+ }
+ } else {
+ /* disable the vote if applicable */
+ if (chip->adc_vote_enable && chip->adc->hkadc_ldo &&
+ chip->adc->hkadc_ldo_ok) {
+ qpnp_adc_disable_voltage(chip->adc);
+ chip->adc_vote_enable = false;
+ }
+ }
+ }
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_mode_select(struct qpnp_adc_tm_chip *chip,
+ u8 mode_ctl)
+{
+ int rc;
+
+ mode_ctl |= (QPNP_ADC_TRIM_EN | QPNP_AMUX_TRIM_EN);
+
+ /* VADC_BTM current sets mode to recurring measurements */
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_MODE_CTL, mode_ctl, 1);
+ if (rc < 0)
+ pr_err("adc-tm write mode selection err\n");
+
+ return rc;
+}
+
+static int32_t qpnp_adc_tm_req_sts_check(struct qpnp_adc_tm_chip *chip)
+{
+ u8 status1 = 0, mode_ctl = 0;
+ int rc, count = 0;
+
+ /* Re-enable the peripheral */
+ rc = qpnp_adc_tm_enable(chip);
if (rc) {
- pr_err("adc_tm channel check failed\n");
+ pr_err("adc-tm re-enable peripheral failed\n");
+ return rc;
+ }
+
+ /* The VADC_TM bank needs to be disabled for new conversion request */
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS1, &status1, 1);
+ if (rc) {
+ pr_err("adc-tm read status1 failed\n");
+ return rc;
+ }
+
+ /* Disable the bank if a conversion is occurring */
+ while (status1 & QPNP_STATUS1_REQ_STS) {
+ if (count > QPNP_RETRY) {
+ pr_err("retry error=%d with 0x%x\n", count, status1);
+ break;
+ }
+ /*
+ * Wait time is based on the optimum sampling rate
+ * and adding enough time buffer to account for ADC conversions
+ * occurring on different peripheral banks
+ */
+ usleep_range(QPNP_MIN_TIME, QPNP_MAX_TIME);
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS1,
+ &status1, 1);
+ if (rc < 0) {
+ pr_err("adc-tm disable failed\n");
+ return rc;
+ }
+ count++;
+ }
+
+ if (!chip->adc_tm_hc) {
+ /* Change the mode back to recurring measurement mode */
+ mode_ctl = ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
+ rc = qpnp_adc_tm_mode_select(chip, mode_ctl);
+ if (rc < 0) {
+ pr_err("adc-tm mode change to recurring failed\n");
+ return rc;
+ }
+ }
+
+ /* Disable the peripheral */
+ rc = qpnp_adc_tm_disable(chip);
+ if (rc < 0) {
+ pr_err("adc-tm peripheral disable failed\n");
return rc;
}
@@ -337,17 +682,25 @@
int rc = 0, i;
bool chan_found = false;
- for (i = 0; i < chip->max_channels_available; i++) {
- if (chip->sensor[i].btm_channel_num == btm_chan) {
- *btm_chan_idx = i;
- chan_found = true;
- break;
+ if (!chip->adc_tm_hc) {
+ for (i = 0; i < QPNP_ADC_TM_CHAN_NONE; i++) {
+ if (adc_tm_data[i].btm_amux_chan == btm_chan) {
+ *btm_chan_idx = i;
+ chan_found = true;
+ }
+ }
+ } else {
+ for (i = 0; i < chip->max_channels_available; i++) {
+ if (chip->sensor[i].btm_channel_num == btm_chan) {
+ *btm_chan_idx = i;
+ chan_found = true;
+ break;
+ }
}
}
if (!chan_found)
return -EINVAL;
-
return rc;
}
@@ -412,19 +765,29 @@
switch (chip->sensor[chan_idx].timer_select) {
case ADC_MEAS_TIMER_SELECT1:
- rc = qpnp_adc_tm_write_reg(chip,
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL,
+ chip->sensor[chan_idx].meas_interval, 1);
+ else
+ rc = qpnp_adc_tm_write_reg(chip,
QPNP_BTM_MEAS_INTERVAL_CTL,
chip->sensor[chan_idx].meas_interval, 1);
if (rc < 0) {
pr_err("timer1 configure failed\n");
return rc;
}
- break;
+ break;
case ADC_MEAS_TIMER_SELECT2:
/* Thermal channels uses timer2, default to 1 second */
- rc = qpnp_adc_tm_read_reg(chip,
- QPNP_BTM_MEAS_INTERVAL_CTL2,
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_read_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
&meas_interval_timer2, 1);
+ else
+ rc = qpnp_adc_tm_read_reg(chip,
+ QPNP_BTM_MEAS_INTERVAL_CTL2,
+ &meas_interval_timer2, 1);
if (rc < 0) {
pr_err("timer2 configure read failed\n");
return rc;
@@ -433,7 +796,12 @@
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,
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ meas_interval_timer2, 1);
+ else
+ rc = qpnp_adc_tm_write_reg(chip,
QPNP_BTM_MEAS_INTERVAL_CTL2,
meas_interval_timer2, 1);
if (rc < 0) {
@@ -442,7 +810,12 @@
}
break;
case ADC_MEAS_TIMER_SELECT3:
- rc = qpnp_adc_tm_read_reg(chip,
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_read_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ &meas_interval_timer2, 1);
+ else
+ rc = qpnp_adc_tm_read_reg(chip,
QPNP_BTM_MEAS_INTERVAL_CTL2,
&meas_interval_timer2, 1);
if (rc < 0) {
@@ -452,6 +825,11 @@
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;
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_ADC_TM_MEAS_INTERVAL_CTL2,
+ meas_interval_timer2, 1);
+ else
rc = qpnp_adc_tm_write_reg(chip,
QPNP_BTM_MEAS_INTERVAL_CTL2,
meas_interval_timer2, 1);
@@ -471,7 +849,12 @@
pr_err("Invalid btm channel idx\n");
return rc;
}
- rc = qpnp_adc_tm_write_reg(chip,
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_write_reg(chip,
+ adc_tm_data[btm_chan_idx].meas_interval_ctl,
+ chip->sensor[chan_idx].timer_select, 1);
+ else
+ rc = qpnp_adc_tm_write_reg(chip,
QPNP_BTM_Mn_MEAS_INTERVAL_CTL(btm_chan_idx),
chip->sensor[chan_idx].timer_select, 1);
if (rc < 0) {
@@ -556,6 +939,69 @@
return rc;
}
+static int32_t qpnp_adc_tm_read_thr_value(struct qpnp_adc_tm_chip *chip,
+ uint32_t btm_chan)
+{
+ int rc = 0;
+ u8 data_lsb = 0, data_msb = 0;
+ uint32_t btm_chan_idx = 0;
+ int32_t low_thr = 0, high_thr = 0;
+
+ if (!chip->adc_tm_hc) {
+ pr_err("Not applicable for VADC HC peripheral\n");
+ return -EINVAL;
+ }
+
+ rc = qpnp_adc_tm_get_btm_idx(chip, btm_chan, &btm_chan_idx);
+ if (rc < 0) {
+ pr_err("Invalid btm channel idx\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip,
+ adc_tm_data[btm_chan_idx].low_thr_lsb_addr,
+ &data_lsb, 1);
+ if (rc < 0) {
+ pr_err("low threshold lsb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip,
+ adc_tm_data[btm_chan_idx].low_thr_msb_addr,
+ &data_msb, 1);
+ if (rc < 0) {
+ pr_err("low threshold msb setting failed\n");
+ return rc;
+ }
+
+ low_thr = (data_msb << 8) | data_lsb;
+
+ rc = qpnp_adc_tm_read_reg(chip,
+ adc_tm_data[btm_chan_idx].high_thr_lsb_addr,
+ &data_lsb, 1);
+ if (rc < 0) {
+ pr_err("high threshold lsb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip,
+ adc_tm_data[btm_chan_idx].high_thr_msb_addr,
+ &data_msb, 1);
+ if (rc < 0) {
+ pr_err("high threshold msb setting failed\n");
+ return rc;
+ }
+
+ high_thr = (data_msb << 8) | data_lsb;
+
+ pr_debug("configured thresholds high:0x%x and low:0x%x\n",
+ high_thr, low_thr);
+
+ return rc;
+}
+
+
+
static int32_t qpnp_adc_tm_thr_update(struct qpnp_adc_tm_chip *chip,
uint32_t btm_chan, int32_t high_thr, int32_t low_thr)
{
@@ -568,38 +1014,71 @@
return rc;
}
- rc = qpnp_adc_tm_write_reg(chip,
- QPNP_BTM_Mn_LOW_THR0(btm_chan_idx),
- QPNP_ADC_TM_THR_LSB_MASK(low_thr), 1);
- if (rc < 0) {
- pr_err("low threshold lsb setting failed\n");
- return rc;
- }
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_write_reg(chip,
+ adc_tm_data[btm_chan_idx].low_thr_lsb_addr,
+ QPNP_ADC_TM_THR_LSB_MASK(low_thr), 1);
+ if (rc < 0) {
+ pr_err("low threshold lsb setting failed\n");
+ return rc;
+ }
- rc = qpnp_adc_tm_write_reg(chip,
- QPNP_BTM_Mn_LOW_THR1(btm_chan_idx),
- QPNP_ADC_TM_THR_MSB_MASK(low_thr), 1);
- if (rc < 0) {
- pr_err("low threshold msb setting failed\n");
- return rc;
- }
+ rc = qpnp_adc_tm_write_reg(chip,
+ adc_tm_data[btm_chan_idx].low_thr_msb_addr,
+ QPNP_ADC_TM_THR_MSB_MASK(low_thr), 1);
+ if (rc < 0) {
+ pr_err("low threshold msb setting failed\n");
+ return rc;
+ }
- rc = qpnp_adc_tm_write_reg(chip,
- QPNP_BTM_Mn_HIGH_THR0(btm_chan_idx),
- QPNP_ADC_TM_THR_LSB_MASK(high_thr), 1);
- if (rc < 0) {
- pr_err("high threshold lsb setting failed\n");
- return rc;
- }
+ rc = qpnp_adc_tm_write_reg(chip,
+ adc_tm_data[btm_chan_idx].high_thr_lsb_addr,
+ QPNP_ADC_TM_THR_LSB_MASK(high_thr), 1);
+ if (rc < 0) {
+ pr_err("high threshold lsb setting failed\n");
+ return rc;
+ }
- rc = qpnp_adc_tm_write_reg(chip,
- QPNP_BTM_Mn_HIGH_THR1(btm_chan_idx),
- QPNP_ADC_TM_THR_MSB_MASK(high_thr), 1);
- if (rc < 0)
- pr_err("high threshold msb setting failed\n");
+ rc = qpnp_adc_tm_write_reg(chip,
+ adc_tm_data[btm_chan_idx].high_thr_msb_addr,
+ QPNP_ADC_TM_THR_MSB_MASK(high_thr), 1);
+ if (rc < 0)
+ pr_err("high threshold msb setting failed\n");
+ } else {
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_BTM_Mn_LOW_THR0(btm_chan_idx),
+ QPNP_ADC_TM_THR_LSB_MASK(low_thr), 1);
+ if (rc < 0) {
+ pr_err("low threshold lsb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_BTM_Mn_LOW_THR1(btm_chan_idx),
+ QPNP_ADC_TM_THR_MSB_MASK(low_thr), 1);
+ if (rc < 0) {
+ pr_err("low threshold msb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_BTM_Mn_HIGH_THR0(btm_chan_idx),
+ QPNP_ADC_TM_THR_LSB_MASK(high_thr), 1);
+ if (rc < 0) {
+ pr_err("high threshold lsb setting failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip,
+ QPNP_BTM_Mn_HIGH_THR1(btm_chan_idx),
+ QPNP_ADC_TM_THR_MSB_MASK(high_thr), 1);
+ if (rc < 0)
+ pr_err("high threshold msb setting failed\n");
+
+ }
pr_debug("client requested high:%d and low:%d\n",
- high_thr, low_thr);
+ high_thr, low_thr);
return rc;
}
@@ -734,9 +1213,14 @@
pr_debug("low sensor mask:%x with state:%d\n",
sensor_mask, chan_prop->state_request);
/* Enable low threshold's interrupt */
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_LOW_THR_INT_EN, true);
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, true);
+ else
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_LOW_THR_INT_EN, true);
if (rc < 0) {
pr_err("low thr enable err:%d\n", btm_chan);
return rc;
@@ -746,9 +1230,14 @@
if (high_thr_set) {
/* Enable high threshold's interrupt */
pr_debug("high sensor mask:%x\n", sensor_mask);
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_HIGH_THR_INT_EN, true);
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_HIGH_THR_INT_EN,
+ sensor_mask, true);
+ else
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_HIGH_THR_INT_EN, true);
if (rc < 0) {
pr_err("high thr enable err:%d\n", btm_chan);
return rc;
@@ -757,13 +1246,16 @@
}
/* Enable corresponding BTM channel measurement */
- rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_idx),
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_MULTI_MEAS_EN, sensor_mask, true);
+ else
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_idx),
QPNP_BTM_Mn_MEAS_EN, true);
if (rc < 0) {
pr_err("multi measurement en failed\n");
return rc;
}
-
return rc;
}
@@ -872,12 +1364,120 @@
return 0;
}
+static int32_t qpnp_adc_tm_configure(struct qpnp_adc_tm_chip *chip,
+ struct qpnp_adc_amux_properties *chan_prop)
+{
+ u8 decimation = 0, op_cntrl = 0, mode_ctl = 0;
+ int rc = 0;
+ uint32_t btm_chan = 0;
+
+ /* Set measurement in single measurement mode */
+ mode_ctl = ADC_OP_NORMAL_MODE << QPNP_OP_MODE_SHIFT;
+ rc = qpnp_adc_tm_mode_select(chip, mode_ctl);
+ if (rc < 0) {
+ pr_err("adc-tm single mode select failed\n");
+ return rc;
+ }
+
+ /* Disable bank */
+ rc = qpnp_adc_tm_disable(chip);
+ if (rc)
+ return rc;
+
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_req_sts_check(chip);
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ return rc;
+ }
+
+ /* Configure AMUX channel select for the corresponding BTM channel*/
+ btm_chan = chan_prop->chan_prop->tm_channel_select;
+ rc = qpnp_adc_tm_write_reg(chip, btm_chan, chan_prop->amux_channel, 1);
+ if (rc < 0) {
+ pr_err("adc-tm channel selection err\n");
+ return rc;
+ }
+
+ /* Digital parameter setup */
+ decimation |= chan_prop->decimation <<
+ QPNP_ADC_DIG_DEC_RATIO_SEL_SHIFT;
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_DIG_PARAM, decimation, 1);
+ if (rc < 0) {
+ pr_err("adc-tm digital parameter setup err\n");
+ return rc;
+ }
+
+ /* Hardware setting time */
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_HW_SETTLE_DELAY,
+ chan_prop->hw_settle_time, 1);
+ if (rc < 0) {
+ pr_err("adc-tm hw settling time setup err\n");
+ return rc;
+ }
+
+ /* Fast averaging setup/enable */
+ rc = qpnp_adc_tm_fast_avg_en(chip, &chan_prop->fast_avg_setup);
+ if (rc < 0) {
+ pr_err("adc-tm fast-avg enable err\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_FAST_AVG_CTL,
+ chan_prop->fast_avg_setup, 1);
+ if (rc < 0) {
+ pr_err("adc-tm fast-avg setup err\n");
+ return rc;
+ }
+
+ /* Measurement interval setup */
+ rc = qpnp_adc_tm_timer_interval_select(chip, btm_chan,
+ chan_prop->chan_prop);
+ if (rc < 0) {
+ pr_err("adc-tm timer select failed\n");
+ return rc;
+ }
+
+ /* Channel configuration setup */
+ rc = qpnp_adc_tm_channel_configure(chip, btm_chan,
+ chan_prop->chan_prop, chan_prop->amux_channel);
+ if (rc < 0) {
+ pr_err("adc-tm channel configure failed\n");
+ return rc;
+ }
+
+ /* Recurring interval measurement enable */
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_MEAS_INTERVAL_OP_CTL,
+ &op_cntrl, 1);
+ op_cntrl |= QPNP_ADC_MEAS_INTERVAL_OP;
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_MEAS_INTERVAL_OP_CTL,
+ op_cntrl, true);
+ if (rc < 0) {
+ pr_err("adc-tm meas interval op configure failed\n");
+ return rc;
+ }
+
+ /* Enable bank */
+ rc = qpnp_adc_tm_enable(chip);
+ if (rc)
+ return rc;
+
+ /* Request conversion */
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_CONV_REQ, QPNP_CONV_REQ_SET, 1);
+ if (rc < 0) {
+ pr_err("adc-tm request conversion failed\n");
+ return rc;
+ }
+
+ return 0;
+}
+
static int qpnp_adc_tm_set_mode(struct qpnp_adc_tm_sensor *adc_tm,
enum thermal_device_mode mode)
{
struct qpnp_adc_tm_chip *chip = adc_tm->chip;
int rc = 0, channel;
- u8 sensor_mask = 0;
+ u8 sensor_mask = 0, mode_ctl = 0;
uint32_t btm_chan_idx = 0, btm_chan = 0;
if (qpnp_adc_tm_is_valid(chip)) {
@@ -916,13 +1516,30 @@
chip->adc->amux_prop->calib_type =
chip->adc->adc_channels[channel].calib_type;
- rc = qpnp_adc_tm_hc_configure(chip, chip->adc->amux_prop);
- if (rc) {
- pr_err("hc configure failed with %d\n", rc);
- goto fail;
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm configure failed with %d\n", rc);
+ goto fail;
+ }
+ } else {
+ rc = qpnp_adc_tm_hc_configure(chip,
+ chip->adc->amux_prop);
+ if (rc) {
+ pr_err("hc configure failed with %d\n", rc);
+ goto fail;
+ }
}
} else if (mode == THERMAL_DEVICE_DISABLED) {
sensor_mask = 1 << adc_tm->sensor_num;
+ if (!chip->adc_tm_hc) {
+ mode_ctl = ADC_OP_NORMAL_MODE << QPNP_OP_MODE_SHIFT;
+ rc = qpnp_adc_tm_mode_select(chip, mode_ctl);
+ if (rc < 0) {
+ pr_err("adc-tm single mode select failed\n");
+ goto fail;
+ }
+ }
/* Disable bank */
rc = qpnp_adc_tm_disable(chip);
@@ -931,12 +1548,28 @@
goto fail;
}
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_MEAS_EN, false);
- if (rc < 0) {
- pr_err("multi measurement disable failed\n");
- goto fail;
+ if (!chip->adc_tm_hc) {
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_req_sts_check(chip);
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ goto fail;
+ }
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi measurement update failed\n");
+ goto fail;
+ }
+ } else {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_MEAS_EN, false);
+ if (rc < 0) {
+ pr_err("multi measurement disable failed\n");
+ goto fail;
+ }
}
rc = qpnp_adc_tm_enable_if_channel_meas(chip);
@@ -959,6 +1592,7 @@
{
struct qpnp_adc_tm_chip *chip = adc_tm->chip;
int rc = 0, sensor_mask = 0;
+ u8 thr_int_en = 0;
bool state = false;
uint32_t btm_chan_idx = 0, btm_chan = 0;
@@ -986,17 +1620,29 @@
switch (trip) {
case ADC_TM_TRIP_HIGH_WARM:
/* low_thr (lower voltage) for higher temp */
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_LOW_THR_INT_EN, state);
+ thr_int_en = adc_tm_data[btm_chan_idx].low_thr_int_chan_en;
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, state);
+ else
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_LOW_THR_INT_EN, state);
if (rc)
pr_err("channel:%x failed\n", btm_chan);
break;
case ADC_TM_TRIP_LOW_COOL:
/* high_thr (higher voltage) for cooler temp */
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_HIGH_THR_INT_EN, state);
+ thr_int_en = adc_tm_data[btm_chan_idx].high_thr_int_chan_en;
+ if (!chip->adc_tm_hc)
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_HIGH_THR_INT_EN,
+ sensor_mask, state);
+ else
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_HIGH_THR_INT_EN, state);
if (rc)
pr_err("channel:%x failed\n", btm_chan);
break;
@@ -1060,10 +1706,17 @@
return rc;
}
- reg_low_thr_lsb = QPNP_BTM_Mn_LOW_THR0(btm_chan_idx);
- reg_low_thr_msb = QPNP_BTM_Mn_LOW_THR1(btm_chan_idx);
- reg_high_thr_lsb = QPNP_BTM_Mn_HIGH_THR0(btm_chan_idx);
- reg_high_thr_msb = QPNP_BTM_Mn_HIGH_THR1(btm_chan_idx);
+ if (!chip->adc_tm_hc) {
+ reg_low_thr_lsb = adc_tm_data[btm_chan_idx].low_thr_lsb_addr;
+ reg_low_thr_msb = adc_tm_data[btm_chan_idx].low_thr_msb_addr;
+ reg_high_thr_lsb = adc_tm_data[btm_chan_idx].high_thr_lsb_addr;
+ reg_high_thr_msb = adc_tm_data[btm_chan_idx].high_thr_msb_addr;
+ } else {
+ reg_low_thr_lsb = QPNP_BTM_Mn_LOW_THR0(btm_chan_idx);
+ reg_low_thr_msb = QPNP_BTM_Mn_LOW_THR1(btm_chan_idx);
+ reg_high_thr_lsb = QPNP_BTM_Mn_HIGH_THR0(btm_chan_idx);
+ reg_high_thr_msb = QPNP_BTM_Mn_HIGH_THR1(btm_chan_idx);
+ }
if (high_temp != INT_MAX) {
rc = qpnp_adc_tm_write_reg(chip, reg_low_thr_lsb,
@@ -1222,6 +1875,144 @@
atomic_dec(&chip->wq_cnt);
}
+static int qpnp_adc_tm_recalib_request_check(struct qpnp_adc_tm_chip *chip,
+ int sensor_num, u8 status_high, u8 *notify_check)
+{
+ int rc = 0;
+ u8 sensor_mask = 0, mode_ctl = 0;
+ int32_t old_thr = 0, new_thr = 0;
+ uint32_t channel, btm_chan_num, scale_type;
+ struct qpnp_vadc_result result;
+ struct qpnp_adc_thr_client_info *client_info = NULL;
+ struct list_head *thr_list;
+ bool status = false;
+
+ if (!chip->adc_tm_recalib_check) {
+ *notify_check = 1;
+ return rc;
+ }
+
+ list_for_each(thr_list, &chip->sensor[sensor_num].thr_list) {
+ client_info = list_entry(thr_list,
+ struct qpnp_adc_thr_client_info, list);
+ channel = client_info->btm_param->channel;
+ btm_chan_num = chip->sensor[sensor_num].btm_channel_num;
+ sensor_mask = 1 << sensor_num;
+
+ rc = qpnp_vadc_read(chip->vadc_dev, channel, &result);
+ if (rc < 0) {
+ pr_err("failure to read vadc channel=%d\n",
+ client_info->btm_param->channel);
+ goto fail;
+ }
+ new_thr = result.physical;
+
+ if (status_high)
+ old_thr = client_info->btm_param->high_thr;
+ else
+ old_thr = client_info->btm_param->low_thr;
+
+ if (new_thr > old_thr)
+ status = (status_high) ? true : false;
+ else
+ status = (status_high) ? false : true;
+
+ pr_debug(
+ "recalib:sen=%d, new_thr=%d, new_thr_adc_code=0x%x, old_thr=%d status=%d valid_status=%d\n",
+ sensor_num, new_thr, result.adc_code,
+ old_thr, status_high, status);
+
+ rc = qpnp_adc_tm_read_thr_value(chip, btm_chan_num);
+ if (rc < 0) {
+ pr_err("adc-tm thresholds read failed\n");
+ goto fail;
+ }
+
+ if (status) {
+ *notify_check = 1;
+ pr_debug("Client can be notify\n");
+ return rc;
+ }
+
+ pr_debug("Client can not be notify, restart measurement\n");
+ /* Set measurement in single measurement mode */
+ mode_ctl = ADC_OP_NORMAL_MODE << QPNP_OP_MODE_SHIFT;
+ rc = qpnp_adc_tm_mode_select(chip, mode_ctl);
+ if (rc < 0) {
+ pr_err("adc-tm single mode select failed\n");
+ goto fail;
+ }
+
+ /* Disable bank */
+ rc = qpnp_adc_tm_disable(chip);
+ if (rc < 0) {
+ pr_err("adc-tm disable failed\n");
+ goto fail;
+ }
+
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_req_sts_check(chip);
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("low threshold int write failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("high threshold int enable failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi measurement en failed\n");
+ goto fail;
+ }
+
+ /* restart measurement */
+ scale_type = chip->sensor[sensor_num].scale_type;
+ chip->adc->amux_prop->amux_channel = channel;
+ chip->adc->amux_prop->decimation =
+ chip->adc->adc_channels[sensor_num].adc_decimation;
+ chip->adc->amux_prop->hw_settle_time =
+ chip->adc->adc_channels[sensor_num].hw_settle_time;
+ chip->adc->amux_prop->fast_avg_setup =
+ chip->adc->adc_channels[sensor_num].fast_avg_setup;
+ chip->adc->amux_prop->mode_sel =
+ ADC_OP_MEASUREMENT_INTERVAL << QPNP_OP_MODE_SHIFT;
+ adc_tm_rscale_fn[scale_type].chan(chip->vadc_dev,
+ client_info->btm_param,
+ &chip->adc->amux_prop->chan_prop->low_thr,
+ &chip->adc->amux_prop->chan_prop->high_thr);
+ qpnp_adc_tm_add_to_list(chip, sensor_num,
+ client_info->btm_param,
+ chip->adc->amux_prop->chan_prop);
+ chip->adc->amux_prop->chan_prop->tm_channel_select =
+ chip->sensor[sensor_num].btm_channel_num;
+ chip->adc->amux_prop->chan_prop->state_request =
+ client_info->btm_param->state_request;
+
+ rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm configure failed with %d\n", rc);
+ goto fail;
+ }
+ *notify_check = 0;
+ pr_debug("BTM channel reconfigured for measuremnt\n");
+ }
+fail:
+ return rc;
+}
+
static int qpnp_adc_tm_disable_rearm_high_thresholds(
struct qpnp_adc_tm_chip *chip, int sensor_num)
{
@@ -1229,7 +2020,7 @@
struct qpnp_adc_thr_client_info *client_info = NULL;
struct list_head *thr_list;
uint32_t btm_chan_num = 0, btm_chan_idx = 0;
- u8 sensor_mask = 0;
+ u8 sensor_mask = 0, notify_check = 0;
int rc = 0;
btm_chan_num = chip->sensor[sensor_num].btm_channel_num;
@@ -1250,14 +2041,24 @@
*/
sensor_mask = 1 << sensor_num;
pr_debug("non thermal node - mask:%x\n", sensor_mask);
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_HIGH_THR_INT_EN, false);
- if (rc < 0) {
- pr_err("high threshold int update failed\n");
- return rc;
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_recalib_request_check(chip,
+ sensor_num, true, ¬ify_check);
+ if (rc < 0 || !notify_check) {
+ pr_debug("Calib recheck re-armed rc=%d\n", rc);
+ chip->th_info.adc_tm_high_enable = 0;
+ return rc;
+ }
+ } else {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_HIGH_THR_INT_EN, false);
+ if (rc < 0) {
+ pr_err("high threshold int update failed\n");
+ return rc;
+ }
}
- } else {
+ } else {
/*
* Uses the thermal sysfs registered device to disable
* the corresponding high voltage threshold which
@@ -1291,12 +2092,22 @@
}
qpnp_adc_tm_manage_thresholds(chip, sensor_num, btm_chan_num);
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(sensor_num),
- QPNP_BTM_Mn_MEAS_EN, false);
- if (rc < 0) {
- pr_err("multi meas disable failed\n");
- return rc;
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi meas disable failed\n");
+ return rc;
+ }
+ } else {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(sensor_num),
+ QPNP_BTM_Mn_MEAS_EN, false);
+ if (rc < 0) {
+ pr_err("multi meas disable failed\n");
+ return rc;
+ }
}
rc = qpnp_adc_tm_enable_if_channel_meas(chip);
@@ -1320,7 +2131,7 @@
struct qpnp_adc_thr_client_info *client_info = NULL;
struct list_head *thr_list;
uint32_t btm_chan_num = 0, btm_chan_idx = 0;
- u8 sensor_mask = 0;
+ u8 sensor_mask = 0, notify_check = 0;
int rc = 0;
btm_chan_num = chip->sensor[sensor_num].btm_channel_num;
@@ -1341,12 +2152,22 @@
*/
sensor_mask = 1 << sensor_num;
pr_debug("non thermal node - mask:%x\n", sensor_mask);
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(btm_chan_idx),
- QPNP_BTM_Mn_LOW_THR_INT_EN, false);
- if (rc < 0) {
- pr_err("low threshold int update failed\n");
- return rc;
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_recalib_request_check(chip,
+ sensor_num, false, ¬ify_check);
+ if (rc < 0 || !notify_check) {
+ pr_debug("Calib recheck re-armed rc=%d\n", rc);
+ chip->th_info.adc_tm_low_enable = 0;
+ return rc;
+ }
+ } else {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(btm_chan_idx),
+ QPNP_BTM_Mn_LOW_THR_INT_EN, false);
+ if (rc < 0) {
+ pr_err("low threshold int update failed\n");
+ return rc;
+ }
}
} else {
/*
@@ -1382,12 +2203,22 @@
}
qpnp_adc_tm_manage_thresholds(chip, sensor_num, btm_chan_num);
- rc = qpnp_adc_tm_reg_update(chip,
- QPNP_BTM_Mn_EN(sensor_num),
- QPNP_BTM_Mn_MEAS_EN, false);
- if (rc < 0) {
- pr_err("multi meas disable failed\n");
- return rc;
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi meas disable failed\n");
+ return rc;
+ }
+ } else {
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_BTM_Mn_EN(sensor_num),
+ QPNP_BTM_Mn_MEAS_EN, false);
+ if (rc < 0) {
+ pr_err("multi meas disable failed\n");
+ return rc;
+ }
}
rc = qpnp_adc_tm_enable_if_channel_meas(chip);
@@ -1416,6 +2247,13 @@
mutex_lock(&chip->adc->adc_lock);
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_req_sts_check(chip);
+ if (rc) {
+ pr_err("adc-tm-tm req sts check failed with %d\n", rc);
+ goto fail;
+ }
+ }
while (sensor_num < chip->max_channels_available) {
if (chip->sensor[sensor_num].high_thr_triggered) {
rc = qpnp_adc_tm_disable_rearm_high_thresholds(
@@ -1473,6 +2311,92 @@
pr_err("adc-tm high thr work failed\n");
}
+static irqreturn_t qpnp_adc_tm_high_thr_isr(int irq, void *data)
+{
+ struct qpnp_adc_tm_chip *chip = data;
+ u8 mode_ctl = 0, status1 = 0, sensor_mask = 0;
+ int rc = 0, sensor_notify_num = 0, i = 0, sensor_num = 0;
+
+ mode_ctl = ADC_OP_NORMAL_MODE << QPNP_OP_MODE_SHIFT;
+ /* Set measurement in single measurement mode */
+ qpnp_adc_tm_mode_select(chip, mode_ctl);
+
+ qpnp_adc_tm_disable(chip);
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS1, &status1, 1);
+ if (rc) {
+ pr_err("adc-tm read status1 failed\n");
+ return IRQ_HANDLED;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS_HIGH,
+ &chip->th_info.status_high, 1);
+ if (rc) {
+ pr_err("adc-tm-tm read status high failed with %d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
+ &chip->th_info.adc_tm_high_thr_set, 1);
+ if (rc) {
+ pr_err("adc-tm-tm read high thr failed with %d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ /* Check which interrupt threshold is lower and measure against the
+ * enabled channel
+ */
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ &chip->th_info.qpnp_adc_tm_meas_en, 1);
+ if (rc) {
+ pr_err("adc-tm-tm read status high failed with %d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ chip->th_info.adc_tm_high_enable = chip->th_info.qpnp_adc_tm_meas_en &
+ chip->th_info.status_high;
+ chip->th_info.adc_tm_high_enable &= chip->th_info.adc_tm_high_thr_set;
+
+ sensor_notify_num = chip->th_info.adc_tm_high_enable;
+ while (i < chip->max_channels_available) {
+ if ((sensor_notify_num & 0x1) == 1)
+ sensor_num = i;
+ sensor_notify_num >>= 1;
+ i++;
+ }
+
+ if (!chip->sensor[sensor_num].thermal_node) {
+ sensor_mask = 1 << sensor_num;
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_HIGH_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("high threshold int read failed\n");
+ return IRQ_HANDLED;
+ }
+ } else {
+ /*
+ * Uses the thermal sysfs registered device to disable
+ * the corresponding high voltage threshold which
+ * is triggered by low temp
+ */
+ pr_debug("thermal node with mask:%x\n", sensor_mask);
+ rc = qpnp_adc_tm_activate_trip_type(
+ &chip->sensor[sensor_num],
+ ADC_TM_TRIP_LOW_COOL,
+ THERMAL_TRIP_ACTIVATION_DISABLED);
+ if (rc < 0) {
+ pr_err("notify error:%d\n", sensor_num);
+ return IRQ_HANDLED;
+ }
+ }
+
+ atomic_inc(&chip->wq_cnt);
+ queue_work(chip->high_thr_wq, &chip->trigger_high_thr_work);
+
+ return IRQ_HANDLED;
+}
+
static void qpnp_adc_tm_low_thr_work(struct work_struct *work)
{
struct qpnp_adc_tm_chip *chip = container_of(work,
@@ -1493,6 +2417,89 @@
pr_err("adc-tm low thr work failed\n");
}
+static irqreturn_t qpnp_adc_tm_low_thr_isr(int irq, void *data)
+{
+ struct qpnp_adc_tm_chip *chip = data;
+ u8 mode_ctl = 0, status1 = 0, sensor_mask = 0;
+ int rc = 0, sensor_notify_num = 0, i = 0, sensor_num = 0;
+
+ mode_ctl = ADC_OP_NORMAL_MODE << QPNP_OP_MODE_SHIFT;
+ /* Set measurement in single measurement mode */
+ qpnp_adc_tm_mode_select(chip, mode_ctl);
+
+ qpnp_adc_tm_disable(chip);
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS1, &status1, 1);
+ if (rc) {
+ pr_err("adc-tm read status1 failed\n");
+ return IRQ_HANDLED;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_STATUS_LOW,
+ &chip->th_info.status_low, 1);
+ if (rc) {
+ pr_err("adc-tm-tm read status low failed with %d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+ &chip->th_info.adc_tm_low_thr_set, 1);
+ if (rc) {
+ pr_err("adc-tm-tm read low thr failed with %d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ rc = qpnp_adc_tm_read_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ &chip->th_info.qpnp_adc_tm_meas_en, 1);
+ if (rc) {
+ pr_err("adc-tm-tm read status high failed with %d\n", rc);
+ return IRQ_HANDLED;
+ }
+
+ chip->th_info.adc_tm_low_enable = chip->th_info.qpnp_adc_tm_meas_en &
+ chip->th_info.status_low;
+ chip->th_info.adc_tm_low_enable &= chip->th_info.adc_tm_low_thr_set;
+
+ sensor_notify_num = chip->th_info.adc_tm_low_enable;
+ while (i < chip->max_channels_available) {
+ if ((sensor_notify_num & 0x1) == 1)
+ sensor_num = i;
+ sensor_notify_num >>= 1;
+ i++;
+ }
+
+ if (!chip->sensor[sensor_num].thermal_node) {
+ sensor_mask = 1 << sensor_num;
+ rc = qpnp_adc_tm_reg_update(chip,
+ QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("low threshold int read failed\n");
+ return IRQ_HANDLED;
+ }
+ } else {
+ /*
+ * Uses the thermal sysfs registered device to disable
+ * the corresponding low voltage threshold which
+ * is triggered by high temp
+ */
+ pr_debug("thermal node with mask:%x\n", sensor_mask);
+ rc = qpnp_adc_tm_activate_trip_type(
+ &chip->sensor[sensor_num],
+ ADC_TM_TRIP_HIGH_WARM,
+ THERMAL_TRIP_ACTIVATION_DISABLED);
+ if (rc < 0) {
+ pr_err("notify error:%d\n", sensor_num);
+ return IRQ_HANDLED;
+ }
+ }
+
+ atomic_inc(&chip->wq_cnt);
+ queue_work(chip->low_thr_wq, &chip->trigger_low_thr_work);
+
+ return IRQ_HANDLED;
+}
+
static int qpnp_adc_tm_rc_check_sensor_trip(struct qpnp_adc_tm_chip *chip,
u8 status_low, u8 status_high, int i,
int *sensor_low_notify_num, int *sensor_high_notify_num)
@@ -1743,11 +2750,18 @@
param->state_request;
chip->adc->amux_prop->calib_type =
chip->adc->adc_channels[dt_index].calib_type;
-
- rc = qpnp_adc_tm_hc_configure(chip, chip->adc->amux_prop);
- if (rc) {
- pr_err("adc-tm hc configure failed with %d\n", rc);
- goto fail_unlock;
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_configure(chip, chip->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm configure failed with %d\n", rc);
+ goto fail_unlock;
+ }
+ } else {
+ rc = qpnp_adc_tm_hc_configure(chip, chip->adc->amux_prop);
+ if (rc) {
+ pr_err("adc-tm hc configure failed with %d\n", rc);
+ goto fail_unlock;
+ }
}
chip->sensor[dt_index].scale_type = scale_type;
@@ -1763,6 +2777,7 @@
struct qpnp_adc_tm_btm_param *param)
{
uint32_t channel, dt_index = 0, btm_chan_num;
+ u8 sensor_mask = 0, mode_ctl = 0;
int rc = 0;
if (qpnp_adc_tm_is_valid(chip))
@@ -1770,6 +2785,16 @@
mutex_lock(&chip->adc->adc_lock);
+ if (!chip->adc_tm_hc) {
+ /* Set measurement in single measurement mode */
+ mode_ctl = ADC_OP_NORMAL_MODE << QPNP_OP_MODE_SHIFT;
+ rc = qpnp_adc_tm_mode_select(chip, mode_ctl);
+ if (rc < 0) {
+ pr_err("adc-tm single mode select failed\n");
+ goto fail;
+ }
+ }
+
/* Disable bank */
rc = qpnp_adc_tm_disable(chip);
if (rc < 0) {
@@ -1777,6 +2802,15 @@
goto fail;
}
+ if (!chip->adc_tm_hc) {
+ /* Check if a conversion is in progress */
+ rc = qpnp_adc_tm_req_sts_check(chip);
+ if (rc < 0) {
+ pr_err("adc-tm req_sts check failed\n");
+ goto fail;
+ }
+ }
+
channel = param->channel;
while ((chip->adc->adc_channels[dt_index].channel_num
!= channel) && (dt_index < chip->max_channels_available))
@@ -1790,25 +2824,43 @@
btm_chan_num = chip->sensor[dt_index].btm_channel_num;
- rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_num),
- QPNP_BTM_Mn_HIGH_THR_INT_EN, false);
- if (rc < 0) {
- pr_err("high thr disable err:%d\n", btm_chan_num);
- return rc;
- }
+ if (!chip->adc_tm_hc) {
+ sensor_mask = 1 << chip->sensor[dt_index].sensor_num;
- rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_num),
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("high threshold int enable failed\n");
+ goto fail;
+ }
+
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ sensor_mask, false);
+ if (rc < 0) {
+ pr_err("multi measurement en failed\n");
+ goto fail;
+ }
+ } else {
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_num),
+ QPNP_BTM_Mn_HIGH_THR_INT_EN, false);
+ if (rc < 0) {
+ pr_err("high thr disable err:%d\n", btm_chan_num);
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_num),
QPNP_BTM_Mn_LOW_THR_INT_EN, false);
- if (rc < 0) {
- pr_err("low thr disable err:%d\n", btm_chan_num);
- return rc;
- }
+ if (rc < 0) {
+ pr_err("low thr disable err:%d\n", btm_chan_num);
+ return rc;
+ }
- rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_num),
+ rc = qpnp_adc_tm_reg_update(chip, QPNP_BTM_Mn_EN(btm_chan_num),
QPNP_BTM_Mn_MEAS_EN, false);
- if (rc < 0) {
- pr_err("multi measurement disable failed\n");
- return rc;
+ if (rc < 0) {
+ pr_err("multi measurement disable failed\n");
+ return rc;
+ }
}
rc = qpnp_adc_tm_enable_if_channel_meas(chip);
@@ -1842,6 +2894,35 @@
}
EXPORT_SYMBOL(qpnp_get_adc_tm);
+static int qpnp_adc_tm_initial_setup(struct qpnp_adc_tm_chip *chip)
+{
+ u8 thr_init = 0;
+ int rc = 0;
+
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_TM_HIGH_THR_INT_EN,
+ thr_init, 1);
+ if (rc < 0) {
+ pr_err("high thr init failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_TM_LOW_THR_INT_EN,
+ thr_init, 1);
+ if (rc < 0) {
+ pr_err("low thr init failed\n");
+ return rc;
+ }
+
+ rc = qpnp_adc_tm_write_reg(chip, QPNP_ADC_TM_MULTI_MEAS_EN,
+ thr_init, 1);
+ if (rc < 0) {
+ pr_err("multi meas en failed\n");
+ return rc;
+ }
+
+ return rc;
+}
+
static const struct of_device_id qpnp_adc_tm_match_table[] = {
{ .compatible = "qcom,qpnp-adc-tm" },
{ .compatible = "qcom,qpnp-adc-tm-hc" },
@@ -1894,8 +2975,10 @@
goto fail;
}
- chip->adc_tm_hc = true;
- chip->adc->adc_hc = true;
+ if (of_device_is_compatible(node, "qcom,qpnp-adc-tm-hc")) {
+ chip->adc_tm_hc = true;
+ chip->adc->adc_hc = true;
+ }
rc = qpnp_adc_get_devicetree_data(pdev, chip->adc);
if (rc) {
@@ -1904,6 +2987,24 @@
}
mutex_init(&chip->adc->adc_lock);
+ /* Register the ADC peripheral interrupt */
+ if (!chip->adc_tm_hc) {
+ chip->adc->adc_high_thr_irq = platform_get_irq_byname(pdev,
+ "high-thr-en-set");
+ if (chip->adc->adc_high_thr_irq < 0) {
+ pr_err("Invalid irq\n");
+ rc = -ENXIO;
+ goto fail;
+ }
+
+ chip->adc->adc_low_thr_irq = platform_get_irq_byname(pdev,
+ "low-thr-en-set");
+ if (chip->adc->adc_low_thr_irq < 0) {
+ pr_err("Invalid irq\n");
+ rc = -ENXIO;
+ goto fail;
+ }
+ }
chip->vadc_dev = qpnp_get_vadc(&pdev->dev, "adc_tm");
if (IS_ERR(chip->vadc_dev)) {
rc = PTR_ERR(chip->vadc_dev);
@@ -2016,17 +3117,45 @@
INIT_WORK(&chip->trigger_low_thr_work, qpnp_adc_tm_low_thr_work);
atomic_set(&chip->wq_cnt, 0);
- rc = devm_request_irq(&pdev->dev, chip->adc->adc_irq_eoc,
- qpnp_adc_tm_rc_thr_isr,
- IRQF_TRIGGER_HIGH, "qpnp_adc_tm_interrupt", chip);
- if (rc)
- dev_err(&pdev->dev, "failed to request adc irq\n");
- else
- enable_irq_wake(chip->adc->adc_irq_eoc);
+ if (!chip->adc_tm_hc) {
+ rc = qpnp_adc_tm_initial_setup(chip);
+ if (rc)
+ goto fail;
+ rc = devm_request_irq(&pdev->dev, chip->adc->adc_high_thr_irq,
+ qpnp_adc_tm_high_thr_isr,
+ IRQF_TRIGGER_RISING, "qpnp_adc_tm_high_interrupt", chip);
+ if (rc) {
+ dev_err(&pdev->dev, "failed to request adc irq\n");
+ goto fail;
+ } else {
+ enable_irq_wake(chip->adc->adc_high_thr_irq);
+ }
+
+ rc = devm_request_irq(&pdev->dev, chip->adc->adc_low_thr_irq,
+ qpnp_adc_tm_low_thr_isr,
+ IRQF_TRIGGER_RISING,
+ "qpnp_adc_tm_low_interrupt", chip);
+ if (rc) {
+ dev_err(&pdev->dev, "failed to request adc irq\n");
+ goto fail;
+ } else {
+ enable_irq_wake(chip->adc->adc_low_thr_irq);
+ }
+ } else {
+ rc = devm_request_irq(&pdev->dev, chip->adc->adc_irq_eoc,
+ qpnp_adc_tm_rc_thr_isr,
+ IRQF_TRIGGER_HIGH, "qpnp_adc_tm_interrupt", chip);
+ if (rc)
+ dev_err(&pdev->dev, "failed to request adc irq\n");
+ else
+ enable_irq_wake(chip->adc->adc_irq_eoc);
+ }
chip->adc_vote_enable = false;
dev_set_drvdata(&pdev->dev, chip);
list_add(&chip->list, &qpnp_adc_tm_device_list);
+ spin_lock_init(&chip->th_info.adc_tm_low_lock);
+ spin_lock_init(&chip->th_info.adc_tm_high_lock);
pr_debug("OK\n");
return 0;
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile
index 857c734..a9344a5 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -66,5 +66,5 @@
obj-$(CONFIG_USB_F_QDSS) += usb_f_qdss.o
usb_f_qcrndis-y := f_qc_rndis.o u_data_ipa.o
obj-$(CONFIG_USB_F_QCRNDIS) += usb_f_qcrndis.o
-usb_f_rmnet_bam-y := f_rmnet.o u_ctrl_qti.o
+usb_f_rmnet_bam-y := f_rmnet.o u_ctrl_qti.o u_bam_dmux.o
obj-$(CONFIG_USB_F_RMNET_BAM) += usb_f_rmnet_bam.o
diff --git a/drivers/usb/gadget/function/f_qc_rndis.c b/drivers/usb/gadget/function/f_qc_rndis.c
index a8e7092..908805a 100644
--- a/drivers/usb/gadget/function/f_qc_rndis.c
+++ b/drivers/usb/gadget/function/f_qc_rndis.c
@@ -102,7 +102,7 @@
struct usb_ep *notify;
struct usb_request *notify_req;
atomic_t notify_count;
- struct gadget_ipa_port bam_port;
+ struct data_port bam_port;
struct cdev cdev;
struct device *dev;
u8 port_num;
diff --git a/drivers/usb/gadget/function/f_rmnet.c b/drivers/usb/gadget/function/f_rmnet.c
index d6d7e73..47b87b0a 100644
--- a/drivers/usb/gadget/function/f_rmnet.c
+++ b/drivers/usb/gadget/function/f_rmnet.c
@@ -19,7 +19,6 @@
#include <linux/usb_bam.h>
#include <linux/module.h>
-#include "u_rmnet.h"
#include "u_data_ipa.h"
#include "configfs.h"
@@ -31,13 +30,15 @@
struct f_rmnet {
struct usb_function func;
enum qti_port_type qti_port_type;
- enum ipa_func_type func_type;
+ enum bam_dmux_func_type bam_dmux_func_type;
+ enum data_xport_type xport_type;
+ enum ipa_func_type ipa_func_type;
struct grmnet port;
int ifc_id;
atomic_t online;
atomic_t ctrl_online;
struct usb_composite_dev *cdev;
- struct gadget_ipa_port ipa_port;
+ struct data_port bam_port;
spinlock_t lock;
/* usb eps*/
@@ -308,11 +309,22 @@
if (!strncasecmp("rmnet", name, MAX_INST_NAME_LEN)) {
dev->qti_port_type = QTI_PORT_RMNET;
- dev->func_type = USB_IPA_FUNC_RMNET;
+ dev->xport_type = BAM2BAM_IPA;
+ dev->ipa_func_type = USB_IPA_FUNC_RMNET;
} else if (!strncasecmp("dpl", name, MAX_INST_NAME_LEN)) {
dev->qti_port_type = QTI_PORT_DPL;
- dev->func_type = USB_IPA_FUNC_DPL;
+ dev->xport_type = BAM2BAM_IPA;
+ dev->ipa_func_type = USB_IPA_FUNC_DPL;
+ } else if (!strncasecmp("rmnet_bam_dmux", name, MAX_INST_NAME_LEN)) {
+ dev->qti_port_type = QTI_PORT_RMNET;
+ dev->xport_type = BAM_DMUX;
+ dev->bam_dmux_func_type = BAM_DMUX_FUNC_RMNET;
+ } else if (!strncasecmp("dpl_bam_dmux", name, MAX_INST_NAME_LEN)) {
+ dev->qti_port_type = QTI_PORT_DPL;
+ dev->xport_type = BAM_DMUX;
+ dev->bam_dmux_func_type = BAM_DMUX_FUNC_DPL;
}
+
return 0;
error:
@@ -380,7 +392,8 @@
enum usb_ctrl usb_bam_type;
int bam_pipe_num = (dev->qti_port_type == QTI_PORT_DPL) ? 1 : 0;
- ret = gqti_ctrl_connect(&dev->port, dev->qti_port_type, dev->ifc_id);
+ ret = gqti_ctrl_connect(&dev->port, dev->qti_port_type, dev->ifc_id,
+ dev->xport_type);
if (ret) {
pr_err("%s: gqti_ctrl_connect failed: err:%d\n",
__func__, ret);
@@ -388,31 +401,42 @@
}
if (dev->qti_port_type == QTI_PORT_DPL)
dev->port.send_encap_cmd(QTI_PORT_DPL, NULL, 0);
- dev->ipa_port.cdev = dev->cdev;
- ipa_data_port_select(dev->func_type);
- usb_bam_type = usb_bam_get_bam_type(gadget->name);
+ dev->bam_port.cdev = dev->cdev;
+ if (dev->xport_type == BAM_DMUX) {
+ ret = gbam_connect(&dev->bam_port, dev->bam_dmux_func_type);
+ if (ret)
+ pr_err("%s: gbam_connect failed: err:%d\n",
+ __func__, ret);
+ } else {
+ ipa_data_port_select(dev->ipa_func_type);
+ usb_bam_type = usb_bam_get_bam_type(gadget->name);
- if (dev->ipa_port.in) {
- dst_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
- IPA_P_BAM, PEER_PERIPHERAL_TO_USB,
- USB_BAM_DEVICE, bam_pipe_num);
+ if (dev->bam_port.in) {
+ dst_connection_idx = usb_bam_get_connection_idx(
+ usb_bam_type, IPA_P_BAM,
+ PEER_PERIPHERAL_TO_USB,
+ USB_BAM_DEVICE, bam_pipe_num);
+ }
+ if (dev->bam_port.out) {
+ src_connection_idx = usb_bam_get_connection_idx(
+ usb_bam_type, IPA_P_BAM,
+ USB_TO_PEER_PERIPHERAL,
+ USB_BAM_DEVICE, bam_pipe_num);
+ }
+ if (dst_connection_idx < 0 || src_connection_idx < 0) {
+ pr_err("%s: usb_bam_get_connection_idx failed\n",
+ __func__);
+ gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
+ return -EINVAL;
+ }
+ ret = ipa_data_connect(&dev->bam_port, dev->ipa_func_type,
+ src_connection_idx, dst_connection_idx);
+ if (ret)
+ pr_err("%s: ipa_data_connect failed: err:%d\n",
+ __func__, ret);
}
- if (dev->ipa_port.out) {
- src_connection_idx = usb_bam_get_connection_idx(usb_bam_type,
- IPA_P_BAM, USB_TO_PEER_PERIPHERAL,
- USB_BAM_DEVICE, bam_pipe_num);
- }
- if (dst_connection_idx < 0 || src_connection_idx < 0) {
- pr_err("%s: usb_bam_get_connection_idx failed\n",
- __func__);
- gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
- return -EINVAL;
- }
- ret = ipa_data_connect(&dev->ipa_port, dev->func_type,
- src_connection_idx, dst_connection_idx);
+
if (ret) {
- pr_err("%s: ipa_data_connect failed: err:%d\n",
- __func__, ret);
gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
return ret;
}
@@ -422,7 +446,11 @@
static int gport_rmnet_disconnect(struct f_rmnet *dev)
{
gqti_ctrl_disconnect(&dev->port, dev->qti_port_type);
- ipa_data_disconnect(&dev->ipa_port, dev->func_type);
+ if (dev->xport_type == BAM_DMUX)
+ gbam_disconnect(&dev->bam_port, dev->bam_dmux_func_type);
+ else
+ ipa_data_disconnect(&dev->bam_port, dev->ipa_func_type);
+
return 0;
}
@@ -488,7 +516,10 @@
usb_ep_fifo_flush(dev->notify);
frmnet_purge_responses(dev);
}
- ipa_data_suspend(&dev->ipa_port, dev->func_type, remote_wakeup_allowed);
+
+ if (dev->xport_type == BAM2BAM_IPA)
+ ipa_data_suspend(&dev->bam_port, dev->ipa_func_type,
+ remote_wakeup_allowed);
}
static void frmnet_resume(struct usb_function *f)
@@ -503,8 +534,9 @@
pr_debug("%s: dev: %pK remote_wakeup: %d\n", __func__, dev,
remote_wakeup_allowed);
-
- ipa_data_resume(&dev->ipa_port, dev->func_type, remote_wakeup_allowed);
+ if (dev->xport_type == BAM2BAM_IPA)
+ ipa_data_resume(&dev->bam_port, dev->ipa_func_type,
+ remote_wakeup_allowed);
}
static void frmnet_disable(struct usb_function *f)
@@ -557,20 +589,20 @@
dev->notify->driver_data = dev;
}
- if (dev->ipa_port.in && !dev->ipa_port.in->desc
- && config_ep_by_speed(cdev->gadget, f, dev->ipa_port.in)) {
+ if (dev->bam_port.in && !dev->bam_port.in->desc
+ && config_ep_by_speed(cdev->gadget, f, dev->bam_port.in)) {
pr_err("%s(): config_ep_by_speed failed.\n",
__func__);
- dev->ipa_port.in->desc = NULL;
+ dev->bam_port.in->desc = NULL;
ret = -EINVAL;
goto err_disable_ep;
}
- if (dev->ipa_port.out && !dev->ipa_port.out->desc
- && config_ep_by_speed(cdev->gadget, f, dev->ipa_port.out)) {
+ if (dev->bam_port.out && !dev->bam_port.out->desc
+ && config_ep_by_speed(cdev->gadget, f, dev->bam_port.out)) {
pr_err("%s(): config_ep_by_speed failed.\n",
__func__);
- dev->ipa_port.out->desc = NULL;
+ dev->bam_port.out->desc = NULL;
ret = -EINVAL;
goto err_disable_ep;
}
@@ -954,7 +986,7 @@
__func__);
return -ENODEV;
}
- dev->ipa_port.in = ep;
+ dev->bam_port.in = ep;
ep->driver_data = cdev;
}
@@ -966,7 +998,7 @@
status = -ENODEV;
goto ep_auto_out_fail;
}
- dev->ipa_port.out = ep;
+ dev->bam_port.out = ep;
ep->driver_data = cdev;
}
@@ -1058,11 +1090,11 @@
dev->notify->driver_data = NULL;
dev->notify = NULL;
ep_auto_notify_fail:
- dev->ipa_port.out->driver_data = NULL;
- dev->ipa_port.out = NULL;
+ dev->bam_port.out->driver_data = NULL;
+ dev->bam_port.out = NULL;
ep_auto_out_fail:
- dev->ipa_port.in->driver_data = NULL;
- dev->ipa_port.in = NULL;
+ dev->bam_port.in->driver_data = NULL;
+ dev->bam_port.in = NULL;
return status;
}
@@ -1163,7 +1195,11 @@
{
struct f_rmnet_opts *opts = container_of(f, struct f_rmnet_opts,
func_inst);
- ipa_data_free(opts->dev->func_type);
+ if (opts->dev->xport_type == BAM_DMUX)
+ gbam_cleanup(opts->dev->bam_dmux_func_type);
+ else
+ ipa_data_free(opts->dev->ipa_func_type);
+
kfree(opts->dev);
kfree(opts);
}
@@ -1194,14 +1230,20 @@
}
if (dev->qti_port_type >= QTI_NUM_PORTS ||
- dev->func_type >= USB_IPA_NUM_FUNCS) {
+ dev->xport_type >= NR_XPORT_TYPES ||
+ dev->ipa_func_type >= USB_IPA_NUM_FUNCS ||
+ dev->bam_dmux_func_type >= BAM_DMUX_NUM_FUNCS) {
pr_err("%s: invalid prot\n", __func__);
ret = -EINVAL;
goto fail;
}
INIT_LIST_HEAD(&dev->cpkt_resp_q);
- ret = ipa_data_setup(dev->func_type);
+ if (dev->xport_type == BAM_DMUX)
+ ret = gbam_setup(dev->bam_dmux_func_type);
+ else
+ ret = ipa_data_setup(dev->ipa_func_type);
+
if (ret)
goto fail;
diff --git a/drivers/usb/gadget/function/u_bam_dmux.c b/drivers/usb/gadget/function/u_bam_dmux.c
index 2ad184a..78dfe7b 100644
--- a/drivers/usb/gadget/function/u_bam_dmux.c
+++ b/drivers/usb/gadget/function/u_bam_dmux.c
@@ -21,6 +21,7 @@
#include <linux/debugfs.h>
#include <linux/bitops.h>
#include <linux/termios.h>
+#include <linux/platform_device.h>
#include <soc/qcom/bam_dmux.h>
@@ -28,32 +29,18 @@
#include <linux/usb/usb_ctrl_qti.h>
#include <linux/usb_bam.h>
-#include "usb_gadget_xport.h"
#include "u_rmnet.h"
-#define BAM_N_PORTS 2
-#define BAM2BAM_N_PORTS 4
-
static struct workqueue_struct *gbam_wq;
-static int n_bam_ports;
-static int n_bam2bam_ports;
static unsigned int n_tx_req_queued;
-static unsigned int bam_ch_ids[BAM_N_PORTS] = {
+static unsigned int bam_ch_ids[BAM_DMUX_NUM_FUNCS] = {
+ BAM_DMUX_USB_RMNET_0,
BAM_DMUX_USB_RMNET_0,
BAM_DMUX_USB_DPL
};
-static char bam_ch_names[BAM_N_PORTS][BAM_DMUX_CH_NAME_MAX_LEN];
-
-static const enum ipa_client_type usb_prod[BAM2BAM_N_PORTS] = {
- IPA_CLIENT_USB_PROD, IPA_CLIENT_USB2_PROD,
- IPA_CLIENT_USB3_PROD, IPA_CLIENT_USB4_PROD
-};
-static const enum ipa_client_type usb_cons[BAM2BAM_N_PORTS] = {
- IPA_CLIENT_USB_CONS, IPA_CLIENT_USB2_CONS,
- IPA_CLIENT_USB3_CONS, IPA_CLIENT_USB4_CONS
-};
+static char bam_ch_names[BAM_DMUX_NUM_FUNCS][BAM_DMUX_CH_NAME_MAX_LEN];
#define BAM_PENDING_PKTS_LIMIT 220
#define BAM_MUX_TX_PKT_DROP_THRESHOLD 1000
@@ -119,11 +106,6 @@
U_BAM_RESUME_E
};
-struct sys2ipa_sw {
- void *teth_priv;
- ipa_notify_cb teth_cb;
-};
-
struct bam_ch_info {
unsigned long flags;
unsigned int id;
@@ -141,22 +123,6 @@
struct usb_request *rx_req;
struct usb_request *tx_req;
- bool tx_req_dequeued;
- bool rx_req_dequeued;
-
- u32 src_pipe_idx;
- u32 dst_pipe_idx;
- u8 src_connection_idx;
- u8 dst_connection_idx;
- enum usb_ctrl usb_bam_type;
-
- enum transport_type trans;
- struct usb_bam_connect_ipa_params ipa_params;
-
- /* added to support sys to ipa sw UL path */
- struct sys2ipa_sw ul_params;
- enum usb_bam_pipe_type src_pipe_type;
- enum usb_bam_pipe_type dst_pipe_type;
/* stats */
unsigned int pending_pkts_with_bam;
@@ -184,21 +150,19 @@
spinlock_t port_lock_dl;
spinlock_t port_lock;
- struct grmnet *port_usb;
+ struct data_port *port_usb;
struct usb_gadget *gadget;
struct bam_ch_info data_ch;
struct work_struct connect_w;
struct work_struct disconnect_w;
- struct work_struct suspend_w;
- struct work_struct resume_w;
};
static struct bam_portmaster {
struct gbam_port *port;
struct platform_driver pdrv;
-} bam_ports[BAM_N_PORTS];
+} bam_ports[BAM_DMUX_NUM_FUNCS];
struct u_bam_data_connect_info {
u32 usb_bam_pipe_idx;
@@ -206,10 +170,7 @@
unsigned long usb_bam_handle;
};
-struct gbam_port *bam2bam_ports[BAM2BAM_N_PORTS];
static void gbam_start_rx(struct gbam_port *port);
-static void gbam_start_endless_rx(struct gbam_port *port);
-static void gbam_start_endless_tx(struct gbam_port *port);
static void gbam_notify(void *p, int event, unsigned long data);
static void gbam_data_write_tobam(struct work_struct *w);
@@ -260,7 +221,6 @@
struct bam_ch_info *d;
struct sk_buff *skb;
dma_addr_t skb_buf_dma_addr;
- struct usb_gadget *gadget;
if (!port)
return NULL;
@@ -283,24 +243,7 @@
goto alloc_exit;
skb_reserve(skb, BAM_MUX_HDR);
-
- if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-
- gadget = port->port_usb->gadget;
-
- skb_buf_dma_addr =
- dma_map_single(&gadget->dev, skb->data,
- bam_mux_rx_req_size, DMA_BIDIRECTIONAL);
-
- if (dma_mapping_error(&gadget->dev, skb_buf_dma_addr)) {
- pr_err("%s: Could not DMA map SKB buffer\n",
- __func__);
- skb_buf_dma_addr = DMA_ERROR_CODE;
- }
- } else {
- skb_buf_dma_addr = DMA_ERROR_CODE;
- }
-
+ skb_buf_dma_addr = DMA_ERROR_CODE;
memcpy(skb->cb, &skb_buf_dma_addr,
sizeof(skb_buf_dma_addr));
@@ -308,6 +251,9 @@
} else {
pr_debug("%s: pull skb from pool\n", __func__);
skb = __skb_dequeue(&d->rx_skb_idle);
+ if (!skb)
+ goto alloc_exit;
+
if (skb_headroom(skb) < BAM_MUX_HDR)
skb_reserve(skb, BAM_MUX_HDR);
}
@@ -341,10 +287,13 @@
return;
d = &port->data_ch;
- gadget = port->port_usb->gadget;
+ gadget = port->port_usb->cdev->gadget;
while (d->rx_skb_idle.qlen > 0) {
skb = __skb_dequeue(&d->rx_skb_idle);
+ if (!skb)
+ break;
+
dma_addr = gbam_get_dma_from_skb(skb);
if (gadget && dma_addr != DMA_ERROR_CODE) {
@@ -359,36 +308,6 @@
}
}
-/*----- sys2bam towards the IPA --------------- */
-static void gbam_ipa_sys2bam_notify_cb(void *priv, enum ipa_dp_evt_type event,
- unsigned long data)
-{
- struct sys2ipa_sw *ul = (struct sys2ipa_sw *)priv;
- struct gbam_port *port;
- struct bam_ch_info *d;
-
- switch (event) {
- case IPA_WRITE_DONE:
- d = container_of(ul, struct bam_ch_info, ul_params);
- port = container_of(d, struct gbam_port, data_ch);
- /* call into bam_demux functionality that'll recycle the data */
- gbam_notify(port, BAM_DMUX_WRITE_DONE, data);
- break;
- case IPA_RECEIVE:
- /* call the callback given by tethering driver init function
- * (and was given to ipa_connect)
- */
- if (ul->teth_cb)
- ul->teth_cb(ul->teth_priv, event, data);
- break;
- default:
- /* unexpected event */
- pr_err("%s: unexpected event %d\n", __func__, event);
- break;
- }
-}
-
-
/*--------------------------------------------- */
/*------------data_path----------------------------*/
@@ -485,7 +404,7 @@
gbam_write_data_tohost(port);
}
-void gbam_data_recv_cb(void *p, struct sk_buff *skb)
+static void gbam_data_recv_cb(void *p, struct sk_buff *skb)
{
struct gbam_port *port = p;
struct bam_ch_info *d = &port->data_ch;
@@ -506,8 +425,7 @@
if (d->tx_skb_q.qlen > bam_mux_tx_pkt_drop_thld) {
d->tohost_drp_cnt++;
- if (printk_ratelimited())
- pr_err("%s: tx pkt dropped: tx_drop_cnt:%u\n",
+ printk_ratelimited(KERN_ERR "%s: tx pkt dropped: tx_drop_cnt:%u\n",
__func__, d->tohost_drp_cnt);
spin_unlock_irqrestore(&port->port_lock_dl, flags);
dev_kfree_skb_any(skb);
@@ -520,7 +438,7 @@
gbam_write_data_tohost(port);
}
-void gbam_data_write_done(void *p, struct sk_buff *skb)
+static void gbam_data_write_done(void *p, struct sk_buff *skb)
{
struct gbam_port *port = p;
struct bam_ch_info *d = &port->data_ch;
@@ -599,10 +517,7 @@
set_bit(BAM_CH_WRITE_INPROGRESS, &d->flags);
- while (!gbam_ul_bam_limit_reached(d) &&
- (d->trans != USB_GADGET_XPORT_BAM2BAM_IPA ||
- usb_bam_get_prod_granted(d->usb_bam_type,
- d->dst_connection_idx))) {
+ while (!gbam_ul_bam_limit_reached(d)) {
skb = __skb_dequeue(&d->rx_skb_q);
if (!skb)
break;
@@ -617,23 +532,7 @@
d->pending_bytes_with_bam, port->port_num);
spin_unlock_irqrestore(&port->port_lock_ul, flags);
- if (d->src_pipe_type == USB_BAM_PIPE_SYS2BAM) {
- dma_addr_t skb_dma_addr;
- struct ipa_tx_meta ipa_meta = {0x0};
-
- skb_dma_addr = gbam_get_dma_from_skb(skb);
- if (skb_dma_addr != DMA_ERROR_CODE) {
- ipa_meta.dma_address = skb_dma_addr;
- ipa_meta.dma_address_valid = true;
- }
-
- ret = ipa_tx_dp(usb_prod[port->port_num],
- skb,
- &ipa_meta);
- } else {
- ret = msm_bam_dmux_write(d->id, skb);
- }
-
+ ret = msm_bam_dmux_write(d->id, skb);
spin_lock_irqsave(&port->port_lock_ul, flags);
if (ret) {
pr_debug("%s: write error:%d\n", __func__, ret);
@@ -723,14 +622,12 @@
spin_lock(&port->port_lock_ul);
gbam_free_skb_to_pool(port, skb);
spin_unlock(&port->port_lock_ul);
- req->buf = 0;
+ req->buf = NULL;
usb_ep_free_request(ep, req);
return;
default:
- if (printk_ratelimited())
- pr_err("%s: %s response error %d, %d/%d\n",
- __func__, ep->name, status,
- req->actual, req->length);
+ printk_ratelimited(KERN_ERR "%s: %s response error %d, %d/%d\n",
+ __func__, ep->name, status, req->actual, req->length);
spin_lock(&port->port_lock_ul);
gbam_free_skb_to_pool(port, skb);
spin_unlock(&port->port_lock_ul);
@@ -741,14 +638,6 @@
if (queue) {
__skb_queue_tail(&d->rx_skb_q, skb);
- if ((d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) &&
- !usb_bam_get_prod_granted(d->usb_bam_type,
- d->dst_connection_idx)) {
- list_add_tail(&req->list, &d->rx_idle);
- spin_unlock(&port->port_lock_ul);
- return;
- }
-
queue_work(gbam_wq, &d->write_tobam_w);
}
@@ -778,11 +667,6 @@
req->dma = gbam_get_dma_from_skb(skb);
req->length = bam_mux_rx_req_size;
- if (req->dma != DMA_ERROR_CODE)
- req->dma_pre_mapped = true;
- else
- req->dma_pre_mapped = false;
-
req->context = skb;
status = usb_ep_queue(ep, req, GFP_ATOMIC);
@@ -791,8 +675,7 @@
gbam_free_skb_to_pool(port, skb);
spin_unlock(&port->port_lock_ul);
- if (printk_ratelimited())
- pr_err("%s: data rx enqueue err %d\n",
+ printk_ratelimited(KERN_ERR "%s: data rx enqueue err %d\n",
__func__, status);
spin_lock(&port->port_lock_ul);
@@ -801,20 +684,6 @@
}
}
-static void gbam_endless_rx_complete(struct usb_ep *ep, struct usb_request *req)
-{
- int status = req->status;
-
- pr_debug("%s status: %d\n", __func__, status);
-}
-
-static void gbam_endless_tx_complete(struct usb_ep *ep, struct usb_request *req)
-{
- int status = req->status;
-
- pr_debug("%s status: %d\n", __func__, status);
-}
-
static void gbam_start_rx(struct gbam_port *port)
{
struct usb_request *req;
@@ -850,11 +719,6 @@
req->dma = gbam_get_dma_from_skb(skb);
req->length = bam_mux_rx_req_size;
- if (req->dma != DMA_ERROR_CODE)
- req->dma_pre_mapped = true;
- else
- req->dma_pre_mapped = false;
-
req->context = skb;
spin_unlock_irqrestore(&port->port_lock_ul, flags);
@@ -863,8 +727,7 @@
if (ret) {
gbam_free_skb_to_pool(port, skb);
- if (printk_ratelimited())
- pr_err("%s: rx queue failed %d\n",
+ printk_ratelimited(KERN_ERR "%s: rx queue failed %d\n",
__func__, ret);
if (port->port_usb)
@@ -878,182 +741,6 @@
spin_unlock_irqrestore(&port->port_lock_ul, flags);
}
-static void gbam_start_endless_rx(struct gbam_port *port)
-{
- struct bam_ch_info *d = &port->data_ch;
- int status;
- struct usb_ep *ep;
- unsigned long flags;
-
- spin_lock_irqsave(&port->port_lock_ul, flags);
- if (!port->port_usb || !d->rx_req) {
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
- pr_err("%s: port->port_usb is NULL", __func__);
- return;
- }
-
- ep = port->port_usb->out;
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
- pr_debug("%s: enqueue\n", __func__);
- status = usb_ep_queue(ep, d->rx_req, GFP_ATOMIC);
- if (status)
- pr_err("%s: error enqueuing transfer, %d\n", __func__, status);
-}
-
-static void gbam_start_endless_tx(struct gbam_port *port)
-{
- struct bam_ch_info *d = &port->data_ch;
- int status;
- struct usb_ep *ep;
- unsigned long flags;
-
- spin_lock_irqsave(&port->port_lock_dl, flags);
- if (!port->port_usb || !d->tx_req) {
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
- pr_err("%s: port->port_usb is NULL", __func__);
- return;
- }
-
- ep = port->port_usb->in;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
- pr_debug("%s: enqueue\n", __func__);
- status = usb_ep_queue(ep, d->tx_req, GFP_ATOMIC);
- if (status)
- pr_err("%s: error enqueuing transfer, %d\n", __func__, status);
-}
-
-static void gbam_stop_endless_rx(struct gbam_port *port)
-{
- struct bam_ch_info *d = &port->data_ch;
- int status;
- unsigned long flags;
- struct usb_ep *ep;
-
- spin_lock_irqsave(&port->port_lock_ul, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
- pr_err("%s: port->port_usb is NULL", __func__);
- return;
- }
-
- ep = port->port_usb->out;
- d->rx_req_dequeued = true;
- spin_unlock_irqrestore(&port->port_lock_ul, flags);
- pr_debug("%s: dequeue\n", __func__);
- status = usb_ep_dequeue(ep, d->rx_req);
- if (status)
- pr_err("%s: error dequeuing transfer, %d\n", __func__, status);
-}
-
-static void gbam_stop_endless_tx(struct gbam_port *port)
-{
- struct bam_ch_info *d = &port->data_ch;
- int status;
- unsigned long flags;
- struct usb_ep *ep;
-
- spin_lock_irqsave(&port->port_lock_dl, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
- pr_err("%s: port->port_usb is NULL", __func__);
- return;
- }
-
- ep = port->port_usb->in;
- d->tx_req_dequeued = true;
- spin_unlock_irqrestore(&port->port_lock_dl, flags);
- pr_debug("%s: dequeue\n", __func__);
- status = usb_ep_dequeue(ep, d->tx_req);
- if (status)
- pr_err("%s: error dequeuing transfer, %d\n", __func__, status);
-}
-
-
-/*
- * This function configured data fifo based on index passed to get bam2bam
- * configuration.
- */
-static void configure_data_fifo(enum usb_ctrl bam_type, u8 idx,
- struct usb_ep *ep, enum usb_bam_pipe_type pipe_type)
-{
- struct u_bam_data_connect_info bam_info;
- struct sps_mem_buffer data_fifo = {0};
-
- if (pipe_type == USB_BAM_PIPE_BAM2BAM) {
- get_bam2bam_connection_info(bam_type, idx,
- &bam_info.usb_bam_pipe_idx,
- NULL, &data_fifo, NULL);
-
- msm_data_fifo_config(ep,
- data_fifo.phys_base,
- data_fifo.size,
- bam_info.usb_bam_pipe_idx);
- }
-}
-
-
-static void gbam_start(void *param, enum usb_bam_pipe_dir dir)
-{
- struct gbam_port *port = param;
- struct usb_gadget *gadget = NULL;
- struct bam_ch_info *d;
- unsigned long flags;
-
- if (port == NULL) {
- pr_err("%s: port is NULL\n", __func__);
- return;
- }
-
- spin_lock_irqsave(&port->port_lock, flags);
- if (port->port_usb == NULL) {
- pr_err("%s: port_usb is NULL, disconnected\n", __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return;
- }
-
- gadget = port->port_usb->gadget;
- d = &port->data_ch;
- spin_unlock_irqrestore(&port->port_lock, flags);
-
- if (gadget == NULL) {
- pr_err("%s: gadget is NULL\n", __func__);
- return;
- }
-
- if (dir == USB_TO_PEER_PERIPHERAL) {
- if (port->data_ch.src_pipe_type == USB_BAM_PIPE_BAM2BAM)
- gbam_start_endless_rx(port);
- else {
- gbam_start_rx(port);
- queue_work(gbam_wq, &d->write_tobam_w);
- }
- } else {
- if (gadget_is_dwc3(gadget) &&
- msm_dwc3_reset_ep_after_lpm(gadget)) {
- configure_data_fifo(d->usb_bam_type,
- d->dst_connection_idx,
- port->port_usb->in, d->dst_pipe_type);
- }
- gbam_start_endless_tx(port);
- }
-}
-
-static void gbam_stop(void *param, enum usb_bam_pipe_dir dir)
-{
- struct gbam_port *port = param;
-
- if (dir == USB_TO_PEER_PERIPHERAL) {
- /*
- * Only handling BAM2BAM, as there is no equivalent to
- * gbam_stop_endless_rx() for the SYS2BAM use case
- */
- if (port->data_ch.src_pipe_type == USB_BAM_PIPE_BAM2BAM)
- gbam_stop_endless_rx(port);
- } else {
- gbam_stop_endless_tx(port);
- }
-}
-
static int _gbam_start_io(struct gbam_port *port, bool in)
{
unsigned long flags;
@@ -1222,52 +909,6 @@
return;
}
-static void gbam2bam_disconnect_work(struct work_struct *w)
-{
- struct gbam_port *port =
- container_of(w, struct gbam_port, disconnect_w);
- struct bam_ch_info *d;
- int ret;
- unsigned long flags;
-
- spin_lock_irqsave(&port->port_lock, flags);
-
- if (!port->is_connected) {
- pr_debug("%s: Port already disconnected. Bailing out.\n",
- __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return;
- }
-
- port->is_connected = false;
- d = &port->data_ch;
-
- /*
- * Unlock the port here and not at the end of this work,
- * because we do not want to activate usb_bam, ipa and
- * tethe bridge logic in atomic context and wait uneeded time.
- * Either way other works will not fire until end of this work
- * and event functions (as bam_data_connect) will not influance
- * while lower layers connect pipes, etc.
- */
- spin_unlock_irqrestore(&port->port_lock, flags);
-
- if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- ret = usb_bam_disconnect_ipa(d->usb_bam_type, &d->ipa_params);
- if (ret)
- pr_err("%s: usb_bam_disconnect_ipa failed: err:%d\n",
- __func__, ret);
- usb_bam_free_fifos(d->usb_bam_type, d->src_connection_idx);
- usb_bam_free_fifos(d->usb_bam_type, d->dst_connection_idx);
- teth_bridge_disconnect(d->ipa_params.src_client);
- /*
- * Decrement usage count which was incremented upon cable
- * connect or cable disconnect in suspended state
- */
- usb_gadget_autopm_put_async(port->gadget);
- }
-}
-
static void gbam_connect_work(struct work_struct *w)
{
struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
@@ -1304,425 +945,6 @@
pr_debug("%s: done\n", __func__);
}
-static void gbam2bam_connect_work(struct work_struct *w)
-{
- struct gbam_port *port = container_of(w, struct gbam_port, connect_w);
- struct usb_gadget *gadget = NULL;
- struct teth_bridge_connect_params connect_params;
- struct teth_bridge_init_params teth_bridge_params;
- struct bam_ch_info *d;
- u32 sps_params;
- int ret;
- unsigned long flags, flags_ul;
-
- spin_lock_irqsave(&port->port_lock, flags);
-
- if (port->last_event == U_BAM_DISCONNECT_E) {
- pr_debug("%s: Port is about to disconnected. Bailing out.\n",
- __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return;
- }
-
- if (port->is_connected) {
- pr_debug("%s: Port already connected. Bail out.\n",
- __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return;
- }
- port->is_connected = true;
-
- spin_lock_irqsave(&port->port_lock_ul, flags_ul);
- spin_lock(&port->port_lock_dl);
- if (!port->port_usb) {
- pr_debug("%s: usb cable is disconnected, exiting\n", __func__);
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return;
- }
-
- gadget = port->port_usb->gadget;
- if (!gadget) {
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
- spin_unlock_irqrestore(&port->port_lock, flags);
- pr_err("%s: port_usb.gadget is NULL, exiting\n", __func__);
- return;
- }
- d = &port->data_ch;
-
- /*
- * Unlock the port here and not at the end of this work,
- * because we do not want to activate usb_bam, ipa and
- * tethe bridge logic in atomic context and wait uneeded time.
- * Either way other works will not fire until end of this work
- * and event functions (as bam_data_connect) will not influance
- * while lower layers connect pipes, etc.
- */
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
-
- d->ipa_params.usb_connection_speed = gadget->speed;
-
- /*
- * Invalidate prod and cons client handles from previous
- * disconnect.
- */
- d->ipa_params.cons_clnt_hdl = -1;
- d->ipa_params.prod_clnt_hdl = -1;
-
- if (usb_bam_get_pipe_type(d->usb_bam_type, d->ipa_params.src_idx,
- &d->src_pipe_type) ||
- usb_bam_get_pipe_type(d->usb_bam_type, d->ipa_params.dst_idx,
- &d->dst_pipe_type)) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- pr_err("%s:usb_bam_get_pipe_type() failed\n", __func__);
- return;
- }
- if (d->dst_pipe_type != USB_BAM_PIPE_BAM2BAM) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- pr_err("%s: no software preparation for DL not using bam2bam\n",
- __func__);
- return;
- }
-
- spin_unlock_irqrestore(&port->port_lock, flags);
- usb_bam_alloc_fifos(d->usb_bam_type, d->src_connection_idx);
- usb_bam_alloc_fifos(d->usb_bam_type, d->dst_connection_idx);
-
- spin_lock_irqsave(&port->port_lock, flags);
- /* check if USB cable is disconnected or not */
- if (!port || !port->port_usb) {
- pr_debug("%s: cable is disconnected.\n",
- __func__);
- spin_unlock_irqrestore(&port->port_lock,
- flags);
- goto free_fifos;
- }
- if (gadget_is_dwc3(gadget)) {
- /* Configure for RX */
- configure_data_fifo(d->usb_bam_type, d->src_connection_idx,
- port->port_usb->out, d->src_pipe_type);
- sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | MSM_PRODUCER |
- d->src_pipe_idx;
- d->rx_req->length = 32*1024;
- d->rx_req->udc_priv = sps_params;
- msm_ep_config(port->port_usb->out, d->rx_req);
-
- /* Configure for TX */
- configure_data_fifo(d->usb_bam_type, d->dst_connection_idx,
- port->port_usb->in, d->dst_pipe_type);
- sps_params = MSM_SPS_MODE | MSM_DISABLE_WB | d->dst_pipe_idx;
- d->tx_req->length = 32*1024;
- d->tx_req->udc_priv = sps_params;
- msm_ep_config(port->port_usb->in, d->tx_req);
-
- } else {
- /* Configure for RX */
- get_bam2bam_connection_info(d->usb_bam_type,
- d->src_connection_idx,
- &d->src_pipe_idx,
- NULL, NULL, NULL);
- sps_params = (MSM_SPS_MODE | d->src_pipe_idx |
- MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
- d->rx_req->udc_priv = sps_params;
-
- /* Configure for TX */
- get_bam2bam_connection_info(d->usb_bam_type,
- d->dst_connection_idx,
- &d->dst_pipe_idx,
- NULL, NULL, NULL);
- sps_params = (MSM_SPS_MODE | d->dst_pipe_idx |
- MSM_VENDOR_ID) & ~MSM_IS_FINITE_TRANSFER;
- d->tx_req->udc_priv = sps_params;
-
- }
-
- teth_bridge_params.client = d->ipa_params.src_client;
- ret = teth_bridge_init(&teth_bridge_params);
- if (ret) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- pr_err("%s:teth_bridge_init() failed\n", __func__);
- goto ep_unconfig;
- }
-
- /* Support for UL using system-to-IPA */
- if (d->src_pipe_type == USB_BAM_PIPE_SYS2BAM) {
- d->ul_params.teth_priv =
- teth_bridge_params.private_data;
- d->ul_params.teth_cb =
- teth_bridge_params.usb_notify_cb;
- d->ipa_params.notify = gbam_ipa_sys2bam_notify_cb;
- d->ipa_params.priv = &d->ul_params;
- d->ipa_params.reset_pipe_after_lpm = false;
-
- } else {
- d->ipa_params.notify =
- teth_bridge_params.usb_notify_cb;
- d->ipa_params.priv =
- teth_bridge_params.private_data;
- d->ipa_params.reset_pipe_after_lpm =
- (gadget_is_dwc3(gadget) &&
- msm_dwc3_reset_ep_after_lpm(gadget));
- }
- d->ipa_params.ipa_ep_cfg.mode.mode = IPA_BASIC;
- d->ipa_params.skip_ep_cfg = teth_bridge_params.skip_ep_cfg;
- d->ipa_params.dir = USB_TO_PEER_PERIPHERAL;
- spin_unlock_irqrestore(&port->port_lock, flags);
- ret = usb_bam_connect_ipa(d->usb_bam_type, &d->ipa_params);
- if (ret) {
- pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
- __func__, ret);
- goto ep_unconfig;
- }
-
- spin_lock_irqsave(&port->port_lock, flags);
- /* check if USB cable is disconnected or not */
- if (port->last_event == U_BAM_DISCONNECT_E) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- pr_debug("%s:%d: cable is disconnected.\n",
- __func__, __LINE__);
- goto ep_unconfig;
- }
-
- /* Remove support for UL using system-to-IPA towards DL */
- if (d->src_pipe_type == USB_BAM_PIPE_SYS2BAM) {
- d->ipa_params.notify = d->ul_params.teth_cb;
- d->ipa_params.priv = d->ul_params.teth_priv;
- }
- if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
- d->ipa_params.reset_pipe_after_lpm =
- (gadget_is_dwc3(gadget) &&
- msm_dwc3_reset_ep_after_lpm(gadget));
- else
- d->ipa_params.reset_pipe_after_lpm = false;
- d->ipa_params.dir = PEER_PERIPHERAL_TO_USB;
- spin_unlock_irqrestore(&port->port_lock, flags);
- ret = usb_bam_connect_ipa(d->usb_bam_type, &d->ipa_params);
- if (ret) {
- pr_err("%s: usb_bam_connect_ipa failed: err:%d\n",
- __func__, ret);
- goto ep_unconfig;
- }
-
- spin_lock_irqsave(&port->port_lock, flags);
- /* check if USB cable is disconnected or not */
- if (port->last_event == U_BAM_DISCONNECT_E) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- pr_debug("%s:%d: cable is disconnected.\n",
- __func__, __LINE__);
- goto ep_unconfig;
- }
-
- spin_unlock_irqrestore(&port->port_lock, flags);
- gqti_ctrl_update_ipa_pipes(port->port_usb, port->port_num,
- d->ipa_params.ipa_prod_ep_idx,
- d->ipa_params.ipa_cons_ep_idx);
-
- connect_params.ipa_usb_pipe_hdl = d->ipa_params.prod_clnt_hdl;
- connect_params.usb_ipa_pipe_hdl = d->ipa_params.cons_clnt_hdl;
- connect_params.tethering_mode = TETH_TETHERING_MODE_RMNET;
- connect_params.client_type = d->ipa_params.src_client;
- ret = teth_bridge_connect(&connect_params);
- if (ret) {
- pr_err("%s:teth_bridge_connect() failed\n", __func__);
- goto ep_unconfig;
- }
-
- /* queue in & out requests */
- if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM) {
- gbam_start_endless_rx(port);
- } else {
- /* The use-case of UL (OUT) ports using sys2bam is based on
- * partial reuse of the system-to-bam_demux code. The following
- * lines perform the branching out of the standard bam2bam flow
- * on the USB side of the UL channel
- */
- if (_gbam_start_io(port, false)) {
- pr_err("%s: _gbam_start_io failed\n", __func__);
- return;
- }
- gbam_start_rx(port);
- }
- gbam_start_endless_tx(port);
-
- pr_debug("%s: done\n", __func__);
- return;
-
-ep_unconfig:
- if (gadget_is_dwc3(gadget)) {
- spin_lock_irqsave(&port->port_lock, flags);
- /* check if USB cable is disconnected or not */
- if (port->port_usb) {
- msm_ep_unconfig(port->port_usb->in);
- msm_ep_unconfig(port->port_usb->out);
- }
- spin_unlock_irqrestore(&port->port_lock, flags);
- }
-free_fifos:
- usb_bam_free_fifos(d->usb_bam_type, d->src_connection_idx);
- usb_bam_free_fifos(d->usb_bam_type, d->dst_connection_idx);
-
-}
-
-static int gbam_wake_cb(void *param)
-{
- struct gbam_port *port = (struct gbam_port *)param;
- struct usb_gadget *gadget;
- unsigned long flags;
- struct usb_function *func;
- int ret;
-
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- pr_debug("%s: usb cable is disconnected, exiting\n",
- __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return -ENODEV;
- }
-
- gadget = port->port_usb->gadget;
- func = port->port_usb->f;
- spin_unlock_irqrestore(&port->port_lock, flags);
-
- pr_debug("%s: woken up by peer\n", __func__);
-
- if ((gadget->speed == USB_SPEED_SUPER) &&
- (func->func_is_suspended))
- ret = usb_func_wakeup(func);
- else
- ret = usb_gadget_wakeup(gadget);
-
- if ((ret == -EBUSY) || (ret == -EAGAIN))
- pr_debug("Remote wakeup is delayed due to LPM exit\n");
- else if (ret)
- pr_err("Failed to wake up the USB core. ret=%d\n", ret);
-
- return ret;
-}
-
-static void gbam2bam_suspend_work(struct work_struct *w)
-{
- struct gbam_port *port = container_of(w, struct gbam_port, suspend_w);
- struct bam_ch_info *d;
- int ret;
- unsigned long flags;
-
- pr_debug("%s: suspend work started\n", __func__);
-
- spin_lock_irqsave(&port->port_lock, flags);
-
- if ((port->last_event == U_BAM_DISCONNECT_E) ||
- (port->last_event == U_BAM_RESUME_E)) {
- pr_debug("%s: Port is about to disconnect/resume. Bail out\n",
- __func__);
- goto exit;
- }
-
- d = &port->data_ch;
-
- ret = usb_bam_register_wake_cb(d->usb_bam_type, d->dst_connection_idx,
- gbam_wake_cb, port);
- if (ret) {
- pr_err("%s(): Failed to register BAM wake callback.\n",
- __func__);
- goto exit;
- }
-
- if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- usb_bam_register_start_stop_cbs(d->usb_bam_type,
- d->dst_connection_idx, gbam_start, gbam_stop, port);
-
- /*
- * release lock here because gbam_start() or
- * gbam_stop() called from usb_bam_suspend()
- * re-acquires port lock.
- */
- spin_unlock_irqrestore(&port->port_lock, flags);
- usb_bam_suspend(d->usb_bam_type, &d->ipa_params);
- spin_lock_irqsave(&port->port_lock, flags);
- }
-
-exit:
- /*
- * Decrement usage count after IPA handshake is done to allow gadget
- * parent to go to lpm. This counter was incremented upon cable connect
- */
- usb_gadget_autopm_put_async(port->gadget);
-
- spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
-static void gbam2bam_resume_work(struct work_struct *w)
-{
- struct gbam_port *port = container_of(w, struct gbam_port, resume_w);
- struct bam_ch_info *d;
- struct usb_gadget *gadget = NULL;
- int ret;
- unsigned long flags;
-
- pr_debug("%s: resume work started\n", __func__);
-
- spin_lock_irqsave(&port->port_lock, flags);
-
- if (port->last_event == U_BAM_DISCONNECT_E || !port->port_usb) {
- pr_debug("%s: usb cable is disconnected, exiting\n",
- __func__);
- goto exit;
- }
-
- d = &port->data_ch;
- gadget = port->port_usb->gadget;
-
- ret = usb_bam_register_wake_cb(d->usb_bam_type, d->dst_connection_idx,
- NULL, NULL);
- if (ret) {
- pr_err("%s(): Failed to register BAM wake callback.\n",
- __func__);
- goto exit;
- }
-
- if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- if (gadget_is_dwc3(gadget) &&
- msm_dwc3_reset_ep_after_lpm(gadget)) {
- if (d->tx_req_dequeued) {
- msm_ep_unconfig(port->port_usb->in);
- configure_data_fifo(d->usb_bam_type,
- d->dst_connection_idx,
- port->port_usb->in, d->dst_pipe_type);
- }
- if (d->rx_req_dequeued) {
- msm_ep_unconfig(port->port_usb->out);
- configure_data_fifo(d->usb_bam_type,
- d->src_connection_idx,
- port->port_usb->out, d->src_pipe_type);
- }
-
- spin_unlock_irqrestore(&port->port_lock, flags);
- if (d->tx_req_dequeued)
- msm_dwc3_reset_dbm_ep(port->port_usb->in);
- if (d->rx_req_dequeued)
- msm_dwc3_reset_dbm_ep(port->port_usb->out);
- spin_lock_irqsave(&port->port_lock, flags);
- if (port->port_usb) {
- if (d->tx_req_dequeued)
- msm_ep_config(port->port_usb->in,
- d->tx_req);
- if (d->rx_req_dequeued)
- msm_ep_config(port->port_usb->out,
- d->rx_req);
- }
- }
- d->tx_req_dequeued = false;
- d->rx_req_dequeued = false;
- usb_bam_resume(d->usb_bam_type, &d->ipa_params);
- }
-
-exit:
- spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
/* BAM data channel ready, allow attempt to open */
static int gbam_data_ch_probe(struct platform_device *pdev)
{
@@ -1734,8 +956,11 @@
pr_debug("%s: name:%s\n", __func__, pdev->name);
- for (i = 0; i < n_bam_ports; i++) {
+ for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
port = bam_ports[i].port;
+ if (!port)
+ continue;
+
d = &port->data_ch;
if (!strcmp(bam_ch_names[i], pdev->name)) {
@@ -1770,9 +995,12 @@
pr_debug("%s: name:%s\n", __func__, pdev->name);
- for (i = 0; i < n_bam_ports; i++) {
+ for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
if (!strcmp(bam_ch_names[i], pdev->name)) {
port = bam_ports[i].port;
+ if (!port)
+ continue;
+
d = &port->data_ch;
spin_lock_irqsave(&port->port_lock_ul, flags);
@@ -1805,10 +1033,10 @@
return 0;
}
-static void gbam_port_free(int portno)
+static void gbam_port_free(enum bam_dmux_func_type func)
{
- struct gbam_port *port = bam_ports[portno].port;
- struct platform_driver *pdrv = &bam_ports[portno].pdrv;
+ struct gbam_port *port = bam_ports[func].port;
+ struct platform_driver *pdrv = &bam_ports[func].pdrv;
if (port)
platform_driver_unregister(pdrv);
@@ -1816,14 +1044,7 @@
kfree(port);
}
-static void gbam2bam_port_free(int portno)
-{
- struct gbam_port *port = bam2bam_ports[portno];
-
- kfree(port);
-}
-
-static int gbam_port_alloc(int portno)
+static int gbam_port_alloc(enum bam_dmux_func_type func)
{
struct gbam_port *port;
struct bam_ch_info *d;
@@ -1833,7 +1054,7 @@
if (!port)
return -ENOMEM;
- port->port_num = portno;
+ port->port_num = func;
/* port initialization */
port->is_connected = false;
@@ -1853,60 +1074,20 @@
skb_queue_head_init(&d->tx_skb_q);
skb_queue_head_init(&d->rx_skb_q);
skb_queue_head_init(&d->rx_skb_idle);
- d->id = bam_ch_ids[portno];
+ d->id = bam_ch_ids[func];
- bam_ports[portno].port = port;
+ bam_ports[func].port = port;
- scnprintf(bam_ch_names[portno], BAM_DMUX_CH_NAME_MAX_LEN,
- "bam_dmux_ch_%d", bam_ch_ids[portno]);
- pdrv = &bam_ports[portno].pdrv;
+ scnprintf(bam_ch_names[func], BAM_DMUX_CH_NAME_MAX_LEN,
+ "bam_dmux_ch_%d", bam_ch_ids[func]);
+ pdrv = &bam_ports[func].pdrv;
pdrv->probe = gbam_data_ch_probe;
pdrv->remove = gbam_data_ch_remove;
- pdrv->driver.name = bam_ch_names[portno];
+ pdrv->driver.name = bam_ch_names[func];
pdrv->driver.owner = THIS_MODULE;
platform_driver_register(pdrv);
- pr_debug("%s: port:%pK portno:%d\n", __func__, port, portno);
-
- return 0;
-}
-
-static int gbam2bam_port_alloc(int portno)
-{
- struct gbam_port *port;
- struct bam_ch_info *d;
-
- port = kzalloc(sizeof(struct gbam_port), GFP_KERNEL);
- if (!port)
- return -ENOMEM;
-
- port->port_num = portno;
-
- /* port initialization */
- port->is_connected = false;
- spin_lock_init(&port->port_lock_ul);
- spin_lock_init(&port->port_lock_dl);
- spin_lock_init(&port->port_lock);
-
- INIT_WORK(&port->connect_w, gbam2bam_connect_work);
- INIT_WORK(&port->disconnect_w, gbam2bam_disconnect_work);
- INIT_WORK(&port->suspend_w, gbam2bam_suspend_work);
- INIT_WORK(&port->resume_w, gbam2bam_resume_work);
-
- /* data ch */
- d = &port->data_ch;
- d->port = port;
- d->ipa_params.src_client = usb_prod[portno];
- d->ipa_params.dst_client = usb_cons[portno];
- bam2bam_ports[portno] = port;
-
- /* UL workaround requirements */
- skb_queue_head_init(&d->rx_skb_q);
- skb_queue_head_init(&d->rx_skb_idle);
- INIT_LIST_HEAD(&d->rx_idle);
- INIT_WORK(&d->write_tobam_w, gbam_data_write_tobam);
-
- pr_debug("%s: port:%pK portno:%d\n", __func__, port, portno);
+ pr_debug("%s: port:%pK portno:%d\n", __func__, port, func);
return 0;
}
@@ -1928,7 +1109,7 @@
if (!buf)
return -ENOMEM;
- for (i = 0; i < n_bam_ports; i++) {
+ for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
port = bam_ports[i].port;
if (!port)
continue;
@@ -1991,7 +1172,7 @@
int i;
unsigned long flags;
- for (i = 0; i < n_bam_ports; i++) {
+ for (i = 0; i < BAM_DMUX_NUM_FUNCS; i++) {
port = bam_ports[i].port;
if (!port)
continue;
@@ -2021,48 +1202,12 @@
return count;
}
-const struct file_operations gbam_stats_ops = {
+static const struct file_operations gbam_stats_ops = {
.read = gbam_read_stats,
.write = gbam_reset_stats,
};
-static ssize_t gbam_rw_write(struct file *file, const char __user *ubuf,
- size_t count, loff_t *ppos)
-{
- struct gbam_port *port = bam2bam_ports[0];
- struct usb_function *func;
- struct usb_gadget *gadget;
- unsigned long flags;
-
- if (!port)
- return -ENODEV;
-
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- pr_debug("%s: usb cable is disconnected, exiting\n",
- __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return -ENODEV;
- }
-
- gadget = port->port_usb->gadget;
- func = port->port_usb->f;
- spin_unlock_irqrestore(&port->port_lock, flags);
-
- if ((gadget->speed == USB_SPEED_SUPER) && (func->func_is_suspended)) {
- pr_debug("%s Initiating usb_func rwakeup\n", __func__);
- usb_func_wakeup(func);
- }
-
- return count;
-}
-
-
-const struct file_operations debug_remote_wakeup_fops = {
- .write = gbam_rw_write,
-};
-
-struct dentry *gbam_dent;
+static struct dentry *gbam_dent;
static void gbam_debugfs_init(void)
{
struct dentry *dfile;
@@ -2070,14 +1215,11 @@
if (gbam_dent)
return;
- gbam_dent = debugfs_create_dir("usb_rmnet", 0);
+ gbam_dent = debugfs_create_dir("usb_rmnet", NULL);
if (!gbam_dent || IS_ERR(gbam_dent))
return;
- debugfs_create_file("remote_wakeup", 0444, gbam_dent, 0,
- &debug_remote_wakeup_fops);
-
- dfile = debugfs_create_file("status", 0444, gbam_dent, 0,
+ dfile = debugfs_create_file("status", 0444, gbam_dent, NULL,
&gbam_stats_ops);
if (!dfile || IS_ERR(dfile)) {
debugfs_remove(gbam_dent);
@@ -2094,29 +1236,16 @@
static inline void gbam_debugfs_remove(void) {}
#endif
-void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
+void gbam_disconnect(struct data_port *gr, enum bam_dmux_func_type func)
{
struct gbam_port *port;
- unsigned long flags, flags_ul, flags_dl;
+ unsigned long flags, flags_ul;
struct bam_ch_info *d;
- pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, port_num);
+ pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, func);
- if (trans == USB_GADGET_XPORT_BAM2BAM) {
- pr_err("%s: invalid xport#%d\n", __func__, trans);
- return;
- }
- if (trans == USB_GADGET_XPORT_BAM_DMUX &&
- port_num >= n_bam_ports) {
- pr_err("%s: invalid bam portno#%d\n",
- __func__, port_num);
- return;
- }
-
- if ((trans == USB_GADGET_XPORT_BAM2BAM_IPA) &&
- port_num >= n_bam2bam_ports) {
- pr_err("%s: invalid bam2bam portno#%d\n",
- __func__, port_num);
+ if (func >= BAM_DMUX_NUM_FUNCS) {
+ pr_err("%s: invalid bam portno#%d\n", __func__, func);
return;
}
@@ -2124,10 +1253,7 @@
pr_err("%s: grmnet port is null\n", __func__);
return;
}
- if (trans == USB_GADGET_XPORT_BAM_DMUX)
- port = bam_ports[port_num].port;
- else
- port = bam2bam_ports[port_num];
+ port = bam_ports[func].port;
if (!port) {
pr_err("%s: NULL port", __func__);
@@ -2142,124 +1268,58 @@
spin_unlock_irqrestore(&port->port_lock, flags);
return;
}
- /*
- * Suspend with remote wakeup enabled. Increment usage
- * count when disconnect happens in suspended state.
- * Corresponding decrement happens in the end of this
- * function if IPA handshake is already done or it is done
- * in disconnect work after finishing IPA handshake.
- */
- if (port->last_event == U_BAM_SUSPEND_E)
- usb_gadget_autopm_get_noresume(port->gadget);
port->port_usb = gr;
- if (trans == USB_GADGET_XPORT_BAM_DMUX)
- gbam_free_buffers(port);
- else if (trans == USB_GADGET_XPORT_BAM2BAM_IPA)
- gbam_free_rx_buffers(port);
+ gbam_free_buffers(port);
spin_lock_irqsave(&port->port_lock_ul, flags_ul);
spin_lock(&port->port_lock_dl);
- port->port_usb = 0;
+ port->port_usb = NULL;
n_tx_req_queued = 0;
spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
usb_ep_disable(gr->in);
- if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- spin_lock_irqsave(&port->port_lock_dl, flags_dl);
- if (d->tx_req) {
- usb_ep_free_request(gr->in, d->tx_req);
- d->tx_req = NULL;
- }
- spin_unlock_irqrestore(&port->port_lock_dl, flags_dl);
- }
/* disable endpoints */
- if (gr->out) {
+ if (gr->out)
usb_ep_disable(gr->out);
- if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- spin_lock_irqsave(&port->port_lock_ul, flags_ul);
- if (d->rx_req) {
- usb_ep_free_request(gr->out, d->rx_req);
- d->rx_req = NULL;
- }
- spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
- }
- }
-
- /*
- * Set endless flag to false as USB Endpoint is already
- * disable.
- */
- if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
-
- if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
- gr->in->endless = false;
-
- if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM && gr->out)
- gr->out->endless = false;
- }
gr->in->driver_data = NULL;
if (gr->out)
gr->out->driver_data = NULL;
port->last_event = U_BAM_DISCONNECT_E;
- /* Disable usb irq for CI gadget. It will be enabled in
- * usb_bam_disconnect_pipe() after disconnecting all pipes
- * and USB BAM reset is done.
- */
- if (!gadget_is_dwc3(port->gadget) &&
- (trans == USB_GADGET_XPORT_BAM2BAM_IPA))
- msm_usb_irq_disable(true);
-
queue_work(gbam_wq, &port->disconnect_w);
spin_unlock_irqrestore(&port->port_lock, flags);
}
-int gbam_connect(struct grmnet *gr, u8 port_num,
- enum transport_type trans, u8 src_connection_idx,
- u8 dst_connection_idx)
+int gbam_connect(struct data_port *gr, enum bam_dmux_func_type func)
{
struct gbam_port *port;
struct bam_ch_info *d;
int ret;
unsigned long flags, flags_ul;
- pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, port_num);
+ pr_debug("%s: grmnet:%pK port#%d\n", __func__, gr, func);
if (!gr) {
pr_err("%s: grmnet port is null\n", __func__);
return -ENODEV;
}
- if (!gr->gadget) {
+ if (!gr->cdev->gadget) {
pr_err("%s: gadget handle not passed\n", __func__);
return -EINVAL;
}
- if (trans == USB_GADGET_XPORT_BAM2BAM) {
- pr_err("%s: invalid xport#%d\n", __func__, trans);
- return -EINVAL;
- }
-
- if (trans == USB_GADGET_XPORT_BAM_DMUX && port_num >= n_bam_ports) {
- pr_err("%s: invalid portno#%d\n", __func__, port_num);
+ if (func >= BAM_DMUX_NUM_FUNCS) {
+ pr_err("%s: invalid portno#%d\n", __func__, func);
return -ENODEV;
}
- if ((trans == USB_GADGET_XPORT_BAM2BAM_IPA)
- && port_num >= n_bam2bam_ports) {
- pr_err("%s: invalid portno#%d\n", __func__, port_num);
- return -ENODEV;
- }
-
- if (trans == USB_GADGET_XPORT_BAM_DMUX)
- port = bam_ports[port_num].port;
- else
- port = bam2bam_ports[port_num];
+ port = bam_ports[func].port;
if (!port) {
pr_err("%s: NULL port", __func__);
@@ -2269,108 +1329,28 @@
spin_lock_irqsave(&port->port_lock, flags);
d = &port->data_ch;
- d->trans = trans;
spin_lock_irqsave(&port->port_lock_ul, flags_ul);
spin_lock(&port->port_lock_dl);
port->port_usb = gr;
- port->gadget = port->port_usb->gadget;
+ port->gadget = port->port_usb->cdev->gadget;
- if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- d->rx_req = usb_ep_alloc_request(port->port_usb->out,
- GFP_ATOMIC);
- if (!d->rx_req) {
- pr_err("%s: RX request allocation failed\n", __func__);
- d->rx_req = NULL;
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return -ENOMEM;
- }
-
- d->rx_req->context = port;
- d->rx_req->complete = gbam_endless_rx_complete;
- d->rx_req->length = 0;
- d->rx_req->no_interrupt = 1;
-
- d->tx_req = usb_ep_alloc_request(port->port_usb->in,
- GFP_ATOMIC);
- if (!d->tx_req) {
- pr_err("%s: TX request allocation failed\n", __func__);
- d->tx_req = NULL;
- usb_ep_free_request(port->port_usb->out, d->rx_req);
- d->rx_req = NULL;
- spin_unlock(&port->port_lock_dl);
- spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
- spin_unlock_irqrestore(&port->port_lock, flags);
- return -ENOMEM;
- }
-
- d->tx_req->context = port;
- d->tx_req->complete = gbam_endless_tx_complete;
- d->tx_req->length = 0;
- d->tx_req->no_interrupt = 1;
- }
-
- if (d->trans == USB_GADGET_XPORT_BAM_DMUX) {
- d->to_host = 0;
- d->to_modem = 0;
- d->pending_pkts_with_bam = 0;
- d->pending_bytes_with_bam = 0;
- d->tohost_drp_cnt = 0;
- d->tomodem_drp_cnt = 0;
- d->rx_flow_control_disable = 0;
- d->rx_flow_control_enable = 0;
- d->rx_flow_control_triggered = 0;
- d->max_num_pkts_pending_with_bam = 0;
- d->max_bytes_pending_with_bam = 0;
- d->delayed_bam_mux_write_done = 0;
- }
+ d->to_host = 0;
+ d->to_modem = 0;
+ d->pending_pkts_with_bam = 0;
+ d->pending_bytes_with_bam = 0;
+ d->tohost_drp_cnt = 0;
+ d->tomodem_drp_cnt = 0;
+ d->rx_flow_control_disable = 0;
+ d->rx_flow_control_enable = 0;
+ d->rx_flow_control_triggered = 0;
+ d->max_num_pkts_pending_with_bam = 0;
+ d->max_bytes_pending_with_bam = 0;
+ d->delayed_bam_mux_write_done = 0;
spin_unlock(&port->port_lock_dl);
spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
- if (d->trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
- d->src_connection_idx = src_connection_idx;
- d->dst_connection_idx = dst_connection_idx;
- d->usb_bam_type = usb_bam_get_bam_type(gr->gadget->name);
- d->ipa_params.src_pipe = &(d->src_pipe_idx);
- d->ipa_params.dst_pipe = &(d->dst_pipe_idx);
- d->ipa_params.src_idx = src_connection_idx;
- d->ipa_params.dst_idx = dst_connection_idx;
-
- /*
- * Query pipe type using IPA src/dst index with
- * usbbam driver. It is being set either as
- * BAM2BAM or SYS2BAM.
- */
- if (usb_bam_get_pipe_type(d->usb_bam_type,
- d->ipa_params.src_idx, &d->src_pipe_type) ||
- usb_bam_get_pipe_type(d->usb_bam_type,
- d->ipa_params.dst_idx, &d->dst_pipe_type)) {
- pr_err("%s:usb_bam_get_pipe_type() failed\n",
- __func__);
- ret = -EINVAL;
- usb_ep_free_request(port->port_usb->out, d->rx_req);
- d->rx_req = NULL;
- usb_ep_free_request(port->port_usb->in, d->tx_req);
- d->tx_req = NULL;
- goto exit;
- }
- /*
- * Check for pipe_type. If it is BAM2BAM, then it is required
- * to disable Xfer complete and Xfer not ready interrupts for
- * that particular endpoint. Hence it set endless flag based
- * it which is considered into UDC driver while enabling
- * USB Endpoint.
- */
- if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
- port->port_usb->in->endless = true;
-
- if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
- port->port_usb->out->endless = true;
- }
-
ret = usb_ep_enable(gr->in);
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:IN ep:%pK",
@@ -2379,11 +1359,6 @@
d->rx_req = NULL;
usb_ep_free_request(port->port_usb->in, d->tx_req);
d->tx_req = NULL;
- if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
- port->port_usb->in->endless = false;
-
- if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
- port->port_usb->out->endless = false;
goto exit;
}
gr->in->driver_data = port;
@@ -2398,30 +1373,18 @@
if (ret) {
pr_err("%s: usb_ep_enable failed eptype:OUT ep:%pK",
__func__, gr->out);
- gr->in->driver_data = 0;
+ gr->in->driver_data = NULL;
usb_ep_disable(gr->in);
usb_ep_free_request(port->port_usb->out, d->rx_req);
d->rx_req = NULL;
usb_ep_free_request(port->port_usb->in, d->tx_req);
d->tx_req = NULL;
- if (d->dst_pipe_type == USB_BAM_PIPE_BAM2BAM)
- port->port_usb->in->endless = false;
-
- if (d->src_pipe_type == USB_BAM_PIPE_BAM2BAM)
- port->port_usb->out->endless = false;
goto exit;
}
gr->out->driver_data = port;
}
port->last_event = U_BAM_CONNECT_E;
- /*
- * Increment usage count upon cable connect. Decrement after IPA
- * handshake is done in disconnect work (due to cable disconnect)
- * or in suspend work.
- */
- if (trans == USB_GADGET_XPORT_BAM2BAM_IPA)
- usb_gadget_autopm_get_noresume(port->gadget);
queue_work(gbam_wq, &port->connect_w);
ret = 0;
@@ -2430,24 +1393,14 @@
return ret;
}
-void gbam_data_flush_workqueue(void)
+int gbam_setup(enum bam_dmux_func_type func)
{
- pr_debug("%s(): Flushing workqueue\n", __func__);
- flush_workqueue(gbam_wq);
-}
-
-int gbam_setup(unsigned int no_bam_port)
-{
- int i;
int ret;
- int bam_port_start = n_bam_ports;
- int total_bam_ports = bam_port_start + no_bam_port;
- pr_debug("%s: requested BAM ports:%d\n", __func__, no_bam_port);
+ pr_debug("%s: requested BAM port:%d\n", __func__, func);
- if (!no_bam_port || total_bam_ports > BAM_N_PORTS) {
- pr_err("%s: Invalid num of ports count:%d\n",
- __func__, no_bam_port);
+ if (func >= BAM_DMUX_NUM_FUNCS) {
+ pr_err("%s: Invalid num of ports count:%d\n", __func__, func);
return -EINVAL;
}
@@ -2461,171 +1414,54 @@
}
}
- for (i = bam_port_start; i < (bam_port_start + no_bam_port); i++) {
- n_bam_ports++;
- pr_debug("gbam_port_alloc called for %d\n", i);
- ret = gbam_port_alloc(i);
- if (ret) {
- n_bam_ports--;
- pr_err("%s: Unable to alloc port:%d\n", __func__, i);
- goto free_bam_ports;
- }
+ ret = gbam_port_alloc(func);
+ if (ret) {
+ pr_err("%s: Unable to alloc port:%d\n", __func__, func);
+ goto destroy_wq;
}
gbam_debugfs_init();
- return bam_port_start;
+ return 0;
-free_bam_ports:
- for (i = 0; i < n_bam_ports; i++)
- gbam_port_free(i);
+destroy_wq:
destroy_workqueue(gbam_wq);
return ret;
}
-int gbam2bam_setup(unsigned int no_bam2bam_port)
-{
- int i;
- int ret;
- int bam2bam_port_start = n_bam2bam_ports;
- int total_bam2bam_ports = bam2bam_port_start + no_bam2bam_port;
-
- pr_debug("%s: requested BAM2BAM ports:%d\n", __func__, no_bam2bam_port);
-
- if (!no_bam2bam_port || total_bam2bam_ports > BAM2BAM_N_PORTS) {
- pr_err("%s: Invalid num of ports count:%d\n",
- __func__, no_bam2bam_port);
- return -EINVAL;
- }
-
- if (!gbam_wq) {
- gbam_wq = alloc_workqueue("k_gbam", WQ_UNBOUND |
- WQ_MEM_RECLAIM, 1);
- if (!gbam_wq) {
- pr_err("%s: Unable to create workqueue gbam_wq\n",
- __func__);
- return -ENOMEM;
- }
- }
-
- for (i = bam2bam_port_start; i < (bam2bam_port_start +
- no_bam2bam_port); i++) {
- n_bam2bam_ports++;
- ret = gbam2bam_port_alloc(i);
- if (ret) {
- n_bam2bam_ports--;
- pr_err("%s: Unable to alloc port:%d\n", __func__, i);
- goto free_bam2bam_ports;
- }
- }
-
- gbam_debugfs_init();
-
- return bam2bam_port_start;
-
-free_bam2bam_ports:
- for (i = 0; i < n_bam2bam_ports; i++)
- gbam2bam_port_free(i);
- destroy_workqueue(gbam_wq);
-
- return ret;
-}
-
-void gbam_cleanup(void)
+void gbam_cleanup(enum bam_dmux_func_type func)
{
gbam_debugfs_remove();
-}
-
-void gbam_suspend(struct grmnet *gr, u8 port_num, enum transport_type trans)
-{
- struct gbam_port *port;
- struct bam_ch_info *d;
- unsigned long flags;
-
- if (trans != USB_GADGET_XPORT_BAM2BAM_IPA)
- return;
-
- port = bam2bam_ports[port_num];
-
- if (!port) {
- pr_err("%s: NULL port", __func__);
- return;
- }
-
- spin_lock_irqsave(&port->port_lock, flags);
-
- d = &port->data_ch;
-
- pr_debug("%s: suspended port %d\n", __func__, port_num);
-
- port->last_event = U_BAM_SUSPEND_E;
- queue_work(gbam_wq, &port->suspend_w);
-
- spin_unlock_irqrestore(&port->port_lock, flags);
-}
-
-void gbam_resume(struct grmnet *gr, u8 port_num, enum transport_type trans)
-{
- struct gbam_port *port;
- struct bam_ch_info *d;
- unsigned long flags;
-
- if (trans != USB_GADGET_XPORT_BAM2BAM_IPA)
- return;
-
- port = bam2bam_ports[port_num];
-
- if (!port) {
- pr_err("%s: NULL port", __func__);
- return;
- }
-
- spin_lock_irqsave(&port->port_lock, flags);
-
- d = &port->data_ch;
-
- pr_debug("%s: resumed port %d\n", __func__, port_num);
-
- port->last_event = U_BAM_RESUME_E;
- /*
- * Increment usage count here to disallow gadget parent suspend.
- * This counter will decrement after IPA handshake is done in
- * disconnect work (due to cable disconnect) or in bam_disconnect
- * in suspended state.
- */
- usb_gadget_autopm_get_noresume(port->gadget);
- queue_work(gbam_wq, &port->resume_w);
-
- spin_unlock_irqrestore(&port->port_lock, flags);
+ gbam_port_free(func);
}
int gbam_mbim_connect(struct usb_gadget *g, struct usb_ep *in,
struct usb_ep *out)
{
- struct grmnet *gr;
+ struct data_port *gr;
gr = kzalloc(sizeof(*gr), GFP_ATOMIC);
if (!gr)
return -ENOMEM;
gr->in = in;
gr->out = out;
- gr->gadget = g;
+ gr->cdev->gadget = g;
- return gbam_connect(gr, 0, USB_GADGET_XPORT_BAM_DMUX, 0, 0);
+ return gbam_connect(gr, BAM_DMUX_FUNC_MBIM);
}
void gbam_mbim_disconnect(void)
{
- struct gbam_port *port = bam_ports[0].port;
- struct grmnet *gr = port->port_usb;
+ struct gbam_port *port = bam_ports[BAM_DMUX_FUNC_MBIM].port;
+ struct data_port *gr = port->port_usb;
if (!gr) {
pr_err("%s: port_usb is NULL\n", __func__);
return;
}
- gbam_disconnect(gr, 0, USB_GADGET_XPORT_BAM_DMUX);
+ gbam_disconnect(gr, BAM_DMUX_FUNC_MBIM);
kfree(gr);
}
@@ -2633,13 +1469,7 @@
{
int ret = 0;
- /*
- * MBIM requires only 1 USB_GADGET_XPORT_BAM_DMUX
- * port. The port is always 0 and is shared
- * between RMNET and MBIM.
- */
- if (!n_bam_ports)
- ret = gbam_setup(1);
+ ret = gbam_setup(BAM_DMUX_FUNC_MBIM);
return ret;
}
diff --git a/drivers/usb/gadget/function/u_ctrl_qti.c b/drivers/usb/gadget/function/u_ctrl_qti.c
index 21839a3e..4ab7bc4 100644
--- a/drivers/usb/gadget/function/u_ctrl_qti.c
+++ b/drivers/usb/gadget/function/u_ctrl_qti.c
@@ -17,6 +17,8 @@
#include <linux/cdev.h>
#include <linux/debugfs.h>
+#include <soc/qcom/bam_dmux.h>
+
#include "u_rmnet.h"
#include "f_qdss.h"
@@ -206,7 +208,8 @@
qti_ctrl_queue_notify(port);
}
-int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf)
+int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf,
+ enum data_xport_type dxport)
{
struct qti_ctrl_port *port;
struct grmnet *g_rmnet = NULL;
@@ -226,8 +229,16 @@
spin_lock_irqsave(&port->lock, flags);
port->port_type = qport;
- port->ep_type = DATA_EP_TYPE_HSUSB;
- port->intf = intf;
+ if (dxport == BAM_DMUX) {
+ port->ep_type = DATA_EP_TYPE_BAM_DMUX;
+ port->intf = (qport == QTI_PORT_RMNET) ?
+ BAM_DMUX_USB_RMNET_0 : BAM_DMUX_USB_DPL;
+ port->ipa_prod_idx = 0;
+ port->ipa_cons_idx = 0;
+ } else {
+ port->ep_type = DATA_EP_TYPE_HSUSB;
+ port->intf = intf;
+ }
if (gr) {
port->port_usb = gr;
diff --git a/drivers/usb/gadget/function/u_data_ipa.c b/drivers/usb/gadget/function/u_data_ipa.c
index f379028..32e8cc9 100644
--- a/drivers/usb/gadget/function/u_data_ipa.c
+++ b/drivers/usb/gadget/function/u_data_ipa.c
@@ -23,7 +23,6 @@
#include <linux/usb_bam.h>
#include "u_data_ipa.h"
-#include "u_rmnet.h"
struct ipa_data_ch_info {
struct usb_request *rx_req;
@@ -45,7 +44,7 @@
u8 src_connection_idx;
u8 dst_connection_idx;
enum usb_ctrl usb_bam_type;
- struct gadget_ipa_port *port_usb;
+ struct data_port *port_usb;
struct usb_gadget *gadget;
atomic_t pipe_connect_notified;
struct usb_bam_connect_ipa_params ipa_params;
@@ -299,7 +298,7 @@
* switch is being trigger. This API performs restoring USB endpoint operation
* and disable USB endpoint used for accelerated path.
*/
-void ipa_data_disconnect(struct gadget_ipa_port *gp, enum ipa_func_type func)
+void ipa_data_disconnect(struct data_port *gp, enum ipa_func_type func)
{
struct ipa_data_ch_info *port;
unsigned long flags;
@@ -402,7 +401,7 @@
{
struct ipa_data_ch_info *port = container_of(w, struct ipa_data_ch_info,
connect_w);
- struct gadget_ipa_port *gport;
+ struct data_port *gport;
struct usb_gadget *gadget = NULL;
struct teth_bridge_connect_params connect_params;
struct teth_bridge_init_params teth_bridge_params;
@@ -730,7 +729,7 @@
* initiate USB BAM IPA connection. This API is enabling accelerated endpoints
* and schedule connect_work() which establishes USB IPA BAM communication.
*/
-int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func,
+int ipa_data_connect(struct data_port *gp, enum ipa_func_type func,
u8 src_connection_idx, u8 dst_connection_idx)
{
struct ipa_data_ch_info *port;
@@ -939,7 +938,7 @@
* It is being used to initiate USB BAM IPA suspend functionality
* for USB bus suspend functionality.
*/
-void ipa_data_suspend(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_suspend(struct data_port *gp, enum ipa_func_type func,
bool remote_wakeup_enabled)
{
struct ipa_data_ch_info *port;
@@ -1050,7 +1049,7 @@
* It is being used to initiate USB resume functionality
* for USB bus resume case.
*/
-void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_resume(struct data_port *gp, enum ipa_func_type func,
bool remote_wakeup_enabled)
{
struct ipa_data_ch_info *port;
diff --git a/drivers/usb/gadget/function/u_data_ipa.h b/drivers/usb/gadget/function/u_data_ipa.h
index 70d4293..d2d419b 100644
--- a/drivers/usb/gadget/function/u_data_ipa.h
+++ b/drivers/usb/gadget/function/u_data_ipa.h
@@ -34,19 +34,6 @@
/* Max Number of IPA data ports supported */
#define IPA_N_PORTS USB_IPA_NUM_FUNCS
-struct gadget_ipa_port {
- struct usb_composite_dev *cdev;
- struct usb_function *func;
- int rx_buffer_size;
- struct usb_ep *in;
- struct usb_ep *out;
- int ipa_consumer_ep;
- int ipa_producer_ep;
- const struct usb_endpoint_descriptor *in_ep_desc_backup;
- const struct usb_endpoint_descriptor *out_ep_desc_backup;
-
-};
-
struct ipa_function_bind_info {
struct usb_string *string_defs;
int data_str_idx;
@@ -85,16 +72,16 @@
};
void ipa_data_port_select(enum ipa_func_type func);
-void ipa_data_disconnect(struct gadget_ipa_port *gp, enum ipa_func_type func);
-int ipa_data_connect(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_disconnect(struct data_port *gp, enum ipa_func_type func);
+int ipa_data_connect(struct data_port *gp, enum ipa_func_type func,
u8 src_connection_idx, u8 dst_connection_idx);
int ipa_data_setup(enum ipa_func_type func);
void ipa_data_free(enum ipa_func_type func);
void ipa_data_flush_workqueue(void);
-void ipa_data_resume(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_resume(struct data_port *gp, enum ipa_func_type func,
bool remote_wakeup_enabled);
-void ipa_data_suspend(struct gadget_ipa_port *gp, enum ipa_func_type func,
+void ipa_data_suspend(struct data_port *gp, enum ipa_func_type func,
bool remote_wakeup_enabled);
void ipa_data_set_ul_max_xfer_size(u32 ul_max_xfer_size);
@@ -109,11 +96,34 @@
void ipa_data_stop_rndis_ipa(enum ipa_func_type func);
+#ifdef CONFIG_USB_F_QCRNDIS
void *rndis_qc_get_ipa_priv(void);
void *rndis_qc_get_ipa_rx_cb(void);
bool rndis_qc_get_skip_ep_config(void);
void *rndis_qc_get_ipa_tx_cb(void);
void rndis_ipa_reset_trigger(void);
+#else
+static inline void *rndis_qc_get_ipa_priv(void)
+{
+ return NULL;
+}
+static inline void *rndis_qc_get_ipa_rx_cb(void)
+{
+ return NULL;
+}
+static inline bool rndis_qc_get_skip_ep_config(void)
+{
+ return true;
+}
+static inline void *rndis_qc_get_ipa_tx_cb(void)
+{
+ return NULL;
+}
+static inline void rndis_ipa_reset_trigger(void)
+{
+}
+#endif /* CONFIG_USB_F_QCRNDIS */
+
#if IS_ENABLED(CONFIG_USB_CONFIGFS_RMNET_BAM)
void gqti_ctrl_update_ipa_pipes(void *gr, enum qti_port_type qport,
u32 ipa_prod, u32 ipa_cons);
diff --git a/drivers/usb/gadget/function/u_rmnet.h b/drivers/usb/gadget/function/u_rmnet.h
index 0126932..f639722 100644
--- a/drivers/usb/gadget/function/u_rmnet.h
+++ b/drivers/usb/gadget/function/u_rmnet.h
@@ -20,12 +20,32 @@
#include "f_qdss.h"
+enum bam_dmux_func_type {
+ BAM_DMUX_FUNC_RMNET,
+ BAM_DMUX_FUNC_MBIM,
+ BAM_DMUX_FUNC_DPL,
+ BAM_DMUX_NUM_FUNCS,
+};
+
struct rmnet_ctrl_pkt {
void *buf;
int len;
struct list_head list;
};
+struct data_port {
+ struct usb_composite_dev *cdev;
+ struct usb_function *func;
+ int rx_buffer_size;
+ struct usb_ep *in;
+ struct usb_ep *out;
+ int ipa_consumer_ep;
+ int ipa_producer_ep;
+ const struct usb_endpoint_descriptor *in_ep_desc_backup;
+ const struct usb_endpoint_descriptor *out_ep_desc_backup;
+
+};
+
struct grmnet {
/* to usb host, aka laptop, windows pc etc. Will
* be filled by usb driver of rmnet functionality
@@ -49,7 +69,23 @@
NR_CTRL_CLIENTS
};
-int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf);
+enum data_xport_type {
+ BAM_DMUX,
+ BAM2BAM_IPA,
+ NR_XPORT_TYPES
+};
+
+int gbam_connect(struct data_port *gr, enum bam_dmux_func_type func);
+void gbam_disconnect(struct data_port *gr, enum bam_dmux_func_type func);
+void gbam_cleanup(enum bam_dmux_func_type func);
+int gbam_setup(enum bam_dmux_func_type func);
+int gbam_mbim_connect(struct usb_gadget *g, struct usb_ep *in,
+ struct usb_ep *out);
+void gbam_mbim_disconnect(void);
+int gbam_mbim_setup(void);
+
+int gqti_ctrl_connect(void *gr, enum qti_port_type qport, unsigned int intf,
+ enum data_xport_type dxport);
void gqti_ctrl_disconnect(void *gr, enum qti_port_type qport);
int gqti_ctrl_init(void);
void gqti_ctrl_cleanup(void);
diff --git a/drivers/usb/phy/phy-msm-qusb-v2.c b/drivers/usb/phy/phy-msm-qusb-v2.c
index ad4c0a3..bfe50ac 100644
--- a/drivers/usb/phy/phy-msm-qusb-v2.c
+++ b/drivers/usb/phy/phy-msm-qusb-v2.c
@@ -71,6 +71,7 @@
#define SQ_CTRL1_CHIRP_DISABLE 0x20
#define SQ_CTRL2_CHIRP_DISABLE 0x80
+#define PORT_TUNE1_OVERRIDE_VAL 0xc5
#define DEBUG_CTRL1_OVERRIDE_VAL 0x09
/* PERIPH_SS_PHY_REFGEN_NORTH_BG_CTRL register bits */
@@ -151,6 +152,7 @@
struct hrtimer timer;
int soc_min_rev;
+ bool host_chirp_erratum;
};
#ifdef CONFIG_NVMEM
@@ -198,6 +200,9 @@
/* Reads the SoC version */
static int qusb_phy_get_socrev(struct device *dev, struct qusb_phy *qphy)
{
+ if (!qphy->host_chirp_erratum)
+ return 0;
+
qphy->soc_min_rev = qfprom_read(dev, "minor_rev");
if (qphy->soc_min_rev < 0)
dev_err(dev, "failed getting soc_min_rev, err : %d\n",
@@ -475,6 +480,15 @@
qusb_phy_write_seq(qphy->base, qphy->qusb_phy_host_init_seq,
qphy->host_init_seq_len, 0);
+ /* If soc revision is mentioned and host_chirp_erratum flag is set
+ * then override TUNE1 and DEBUG_CTRL1
+ */
+ if (qphy->soc_min_rev && qphy->host_chirp_erratum) {
+ writel_relaxed(PORT_TUNE1_OVERRIDE_VAL,
+ qphy->base + qphy->phy_reg[PORT_TUNE1]);
+ writel_relaxed(DEBUG_CTRL1_OVERRIDE_VAL,
+ qphy->base + qphy->phy_reg[DEBUG_CTRL1]);
+ }
/* Ensure above write is completed before turning ON ref clk */
wmb();
@@ -560,11 +574,6 @@
writel_relaxed(BIAS_CTRL_2_OVERRIDE_VAL,
qphy->base + qphy->phy_reg[BIAS_CTRL_2]);
- /* if soc revision is mentioned override DEBUG_CTRL1 value */
- if (qphy->soc_min_rev)
- writel_relaxed(DEBUG_CTRL1_OVERRIDE_VAL,
- qphy->base + qphy->phy_reg[DEBUG_CTRL1]);
-
/* ensure above writes are completed before re-enabling PHY */
wmb();
@@ -1170,6 +1179,9 @@
return -ENOMEM;
}
+ qphy->host_chirp_erratum = of_property_read_bool(dev->of_node,
+ "qcom,host-chirp-erratum");
+
ret = of_property_read_u32_array(dev->of_node, "qcom,vdd-voltage-level",
(u32 *) qphy->vdd_levels,
ARRAY_SIZE(qphy->vdd_levels));
diff --git a/include/linux/hdcp_qseecom.h b/include/linux/hdcp_qseecom.h
index 20f5cba..08f30a46 100644
--- a/include/linux/hdcp_qseecom.h
+++ b/include/linux/hdcp_qseecom.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, 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
@@ -181,11 +181,9 @@
/**
* struct hdcp_client_ops - call back functions to display transport layer
* @wakeup: wake up display transport layer with a new command
- * @notify_lvl_change notify of encryption level changes
*/
struct hdcp_client_ops {
int (*wakeup)(struct hdcp_wakeup_data *data);
- void (*notify_lvl_change)(void *client_ctx, int min_lvl);
};
/**
@@ -219,6 +217,4 @@
bool hdcp1_check_if_supported_load_app(void);
int hdcp1_set_keys(uint32_t *aksv_msb, uint32_t *aksv_lsb);
int hdcp1_set_enc(bool enable);
-void hdcp1_cache_repeater_topology(void *hdcp1_cached_tp);
-void hdcp1_notify_topology(void);
#endif /* __HDCP_QSEECOM_H */
diff --git a/include/linux/msm_hdcp.h b/include/linux/msm_hdcp.h
new file mode 100644
index 0000000..e25d242
--- /dev/null
+++ b/include/linux/msm_hdcp.h
@@ -0,0 +1,26 @@
+/* Copyright (c) 2018, 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_HDCP_H
+#define __MSM_HDCP_H
+#include <linux/types.h>
+#include "video/msm_hdmi_hdcp_mgr.h"
+
+void msm_hdcp_notify_topology(struct device *dev);
+void msm_hdcp_cache_repeater_topology(struct device *dev,
+ struct HDCP_V2V1_MSG_TOPOLOGY *tp);
+void msm_hdcp_register_cb(struct device *dev, void *ctx,
+ void (*cb)(void *ctx, int data));
+
+#endif /* __MSM_HDCP_H */
+
+
diff --git a/include/linux/qpnp/qpnp-adc.h b/include/linux/qpnp/qpnp-adc.h
index 9a079a6..a2a0152 100644
--- a/include/linux/qpnp/qpnp-adc.h
+++ b/include/linux/qpnp/qpnp-adc.h
@@ -388,6 +388,8 @@
* %SCALE_DIE_TEMP: Conversion for die temp.
* %SCALE_I_DEFAULT: Default scaling to convert raw adc code to current (uA).
* %SCALE_USBIN_I: Conversion for USB input current.
+ * %SCALE_BATT_THERM_TEMP_QRD: Conversion to temperature(decidegC) based on btm
+ * parameters for QRD.
* %SCALE_NONE: Do not use this scaling type.
*/
enum qpnp_adc_scale_fn_type {
@@ -410,6 +412,7 @@
SCALE_DIE_TEMP,
SCALE_I_DEFAULT,
SCALE_USBIN_I,
+ SCALE_BATT_THERM_TEMP_QRD,
SCALE_NONE,
};
@@ -1432,6 +1435,23 @@
const struct qpnp_vadc_chan_properties *chan_prop,
struct qpnp_vadc_result *chan_rslt);
/**
+ * qpnp_adc_batt_therm_qrd() - Scales the pre-calibrated digital output
+ * of an ADC to the ADC reference and compensates for the
+ * gain and offset. Returns the temperature in decidegC for QRD.
+ * @dev: Structure device for qpnp vadc
+ * @adc_code: pre-calibrated digital output of the ADC.
+ * @adc_prop: adc properties of the pm8xxx adc such as bit resolution,
+ * reference voltage.
+ * @chan_prop: individual channel properties to compensate the i/p scaling,
+ * slope and offset.
+ * @chan_rslt: physical result to be stored.
+ */
+int32_t qpnp_adc_batt_therm_qrd(struct qpnp_vadc_chip *dev,
+ int32_t adc_code,
+ const struct qpnp_adc_properties *adc_prop,
+ const struct qpnp_vadc_chan_properties *chan_prop,
+ struct qpnp_vadc_result *chan_rslt);
+/**
* qpnp_adc_scale_batt_therm() - Scales the pre-calibrated digital output
* of an ADC to the ADC reference and compensates for the
* gain and offset. Returns the temperature in decidegC.
@@ -2033,6 +2053,12 @@
const struct qpnp_vadc_chan_properties *chan_prop,
struct qpnp_vadc_result *chan_rslt)
{ return -ENXIO; }
+static inline int32_t qpnp_adc_batt_therm_qrd(struct qpnp_vadc_chip *vadc,
+ int32_t adc_code,
+ const struct qpnp_adc_properties *adc_prop,
+ const struct qpnp_vadc_chan_properties *chan_prop,
+ struct qpnp_vadc_result *chan_rslt)
+{ return -ENXIO; }
static inline int32_t qpnp_adc_scale_batt_therm(struct qpnp_vadc_chip *vadc,
int32_t adc_code,
const struct qpnp_adc_properties *adc_prop,
diff --git a/include/linux/slimbus/slimbus.h b/include/linux/slimbus/slimbus.h
index 53af941..4b5dc54 100644
--- a/include/linux/slimbus/slimbus.h
+++ b/include/linux/slimbus/slimbus.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, 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
@@ -601,7 +601,7 @@
int (*framer_handover)(struct slim_controller *ctrl,
struct slim_framer *new_framer);
int (*port_xfer)(struct slim_controller *ctrl,
- u8 pn, phys_addr_t iobuf, u32 len,
+ u8 pn, void *buf, u32 len,
struct completion *comp);
enum slim_port_err (*port_xfer_status)(struct slim_controller *ctr,
u8 pn, phys_addr_t *done_buf, u32 *done_len);
@@ -869,7 +869,7 @@
* Client will call slim_port_get_xfer_status to get error and/or number of
* bytes transferred if used asynchronously.
*/
-extern int slim_port_xfer(struct slim_device *sb, u32 ph, phys_addr_t iobuf,
+extern int slim_port_xfer(struct slim_device *sb, u32 ph, void *buf,
u32 len, struct completion *comp);
/*
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 52bc890..33c1dae 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -393,6 +393,8 @@
* temperature.
* @set_trip_temp: a pointer to a function that sets the trip temperature on
* hardware.
+ * @get_trip_temp: a pointer to a function that gets the trip temperature on
+ * hardware.
*/
struct thermal_zone_of_device_ops {
int (*get_temp)(void *, int *);
@@ -400,6 +402,7 @@
int (*set_trips)(void *, int, int);
int (*set_emul_temp)(void *, int);
int (*set_trip_temp)(void *, int, int);
+ int (*get_trip_temp)(void *, int, int *);
};
/**
diff --git a/include/linux/usb_bam.h b/include/linux/usb_bam.h
index 84d7549..e5d4c04 100644
--- a/include/linux/usb_bam.h
+++ b/include/linux/usb_bam.h
@@ -426,7 +426,7 @@
*
* @return true when producer granted, false when prodcuer is released.
*/
-bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx);
+bool usb_bam_get_prod_granted(enum usb_ctrl bam_type);
/* Allocates memory for data fifo and descriptor fifos. */
int usb_bam_alloc_fifos(enum usb_ctrl cur_bam, u8 idx);
@@ -519,7 +519,7 @@
return -ENODEV;
}
-static inline bool usb_bam_get_prod_granted(enum usb_ctrl bam_type, u8 idx)
+static inline bool usb_bam_get_prod_granted(enum usb_ctrl bam_type)
{
return false;
}
diff --git a/include/sound/rawmidi.h b/include/sound/rawmidi.h
index f730b91..9e1aa1a 100644
--- a/include/sound/rawmidi.h
+++ b/include/sound/rawmidi.h
@@ -78,6 +78,7 @@
size_t xruns; /* over/underruns counter */
/* misc */
spinlock_t lock;
+ struct mutex realloc_mutex;
wait_queue_head_t sleep;
/* event handler (new bytes, input only) */
void (*event)(struct snd_rawmidi_substream *substream);
diff --git a/include/uapi/media/msm_camera.h b/include/uapi/media/msm_camera.h
index d282586..693fd21 100644
--- a/include/uapi/media/msm_camera.h
+++ b/include/uapi/media/msm_camera.h
@@ -14,9 +14,12 @@
#ifndef __UAPI_MSM_CAMERA_H
#define __UAPI_MSM_CAMERA_H
+#define CAM_API_V1
+
#include <linux/videodev2.h>
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/media.h>
#include <linux/msm_ion.h>
@@ -1986,8 +1989,7 @@
#define QCAMERA_NAME "qcamera"
#define QCAMERA_SERVER_NAME "qcamera_server"
-#define QCAMERA_DEVICE_GROUP_ID 1
-#define QCAMERA_VNODE_GROUP_ID 2
+#define QCAMERA_VNODE_GROUP_ID MEDIA_ENT_F_IO_V4L
enum msm_cam_subdev_type {
CSIPHY_DEV,
diff --git a/include/uapi/media/msmb_camera.h b/include/uapi/media/msmb_camera.h
index 58aff97..8bb2f8c 100644
--- a/include/uapi/media/msmb_camera.h
+++ b/include/uapi/media/msmb_camera.h
@@ -4,6 +4,7 @@
#include <linux/videodev2.h>
#include <linux/types.h>
#include <linux/ioctl.h>
+#include <linux/media.h>
#define MSM_CAM_LOGSYNC_FILE_NAME "logsync"
#define MSM_CAM_LOGSYNC_FILE_BASEDIR "camera"
@@ -26,33 +27,36 @@
#define MSM_CAM_V4L2_IOCTL_DAEMON_DISABLED \
_IOW('V', BASE_VIDIOC_PRIVATE + 35, struct msm_v4l2_event_data)
-#define QCAMERA_DEVICE_GROUP_ID 1
-#define QCAMERA_VNODE_GROUP_ID 2
+#define QCAMERA_VNODE_GROUP_ID MEDIA_ENT_F_IO_V4L
#define MSM_CAMERA_NAME "msm_camera"
#define MSM_CONFIGURATION_NAME "msm_config"
-#define MSM_CAMERA_SUBDEV_CSIPHY 0
-#define MSM_CAMERA_SUBDEV_CSID 1
-#define MSM_CAMERA_SUBDEV_ISPIF 2
-#define MSM_CAMERA_SUBDEV_VFE 3
-#define MSM_CAMERA_SUBDEV_AXI 4
-#define MSM_CAMERA_SUBDEV_VPE 5
-#define MSM_CAMERA_SUBDEV_SENSOR 6
-#define MSM_CAMERA_SUBDEV_ACTUATOR 7
-#define MSM_CAMERA_SUBDEV_EEPROM 8
-#define MSM_CAMERA_SUBDEV_CPP 9
-#define MSM_CAMERA_SUBDEV_CCI 10
-#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_CAMERA_SUBDEV_OIS 15
-#define MSM_CAMERA_SUBDEV_FLASH 16
-#define MSM_CAMERA_SUBDEV_IR_LED 17
-#define MSM_CAMERA_SUBDEV_IR_CUT 18
-#define MSM_CAMERA_SUBDEV_EXT 19
-#define MSM_CAMERA_SUBDEV_TOF 20
-#define MSM_CAMERA_SUBDEV_LASER_LED 21
+//#define MSM_CAMERA_SUBDEV_BASE (MEDIA_ENT_F_OLD_SUBDEV_BASE + 1)
+#define MSM_CAMERA_SUBDEV_BASE (MEDIA_ENT_F_OLD_BASE + 0xF00)
+#define MSM_CAMERA_SUBDEV_CSIPHY (MSM_CAMERA_SUBDEV_BASE + 0)
+//#define MSM_CAMERA_SUBDEV_CSID (MSM_CAMERA_SUBDEV_BASE + 1)
+#define MSM_CAMERA_SUBDEV_CSID (MSM_CAMERA_SUBDEV_BASE + 13)
+#define MSM_CAMERA_SUBDEV_ISPIF (MSM_CAMERA_SUBDEV_BASE + 2)
+#define MSM_CAMERA_SUBDEV_VFE (MSM_CAMERA_SUBDEV_BASE + 3)
+#define MSM_CAMERA_SUBDEV_AXI (MSM_CAMERA_SUBDEV_BASE + 4)
+#define MSM_CAMERA_SUBDEV_VPE (MSM_CAMERA_SUBDEV_BASE + 5)
+#define MSM_CAMERA_SUBDEV_SENSOR (MSM_CAMERA_SUBDEV_BASE + 6)
+#define MSM_CAMERA_SUBDEV_ACTUATOR (MSM_CAMERA_SUBDEV_BASE + 7)
+#define MSM_CAMERA_SUBDEV_EEPROM (MSM_CAMERA_SUBDEV_BASE + 8)
+#define MSM_CAMERA_SUBDEV_CPP (MSM_CAMERA_SUBDEV_BASE + 9)
+#define MSM_CAMERA_SUBDEV_CCI (MSM_CAMERA_SUBDEV_BASE + 10)
+#define MSM_CAMERA_SUBDEV_LED_FLASH (MSM_CAMERA_SUBDEV_BASE + 11)
+#define MSM_CAMERA_SUBDEV_STROBE_FLASH (MSM_CAMERA_SUBDEV_BASE + 12)
+#define MSM_CAMERA_SUBDEV_BUF_MNGR (MSM_CAMERA_SUBDEV_BASE + 1)
+//#define MSM_CAMERA_SUBDEV_BUF_MNGR (MSM_CAMERA_SUBDEV_BASE + 13)
+#define MSM_CAMERA_SUBDEV_SENSOR_INIT (MSM_CAMERA_SUBDEV_BASE + 14)
+#define MSM_CAMERA_SUBDEV_OIS (MSM_CAMERA_SUBDEV_BASE + 15)
+#define MSM_CAMERA_SUBDEV_FLASH (MSM_CAMERA_SUBDEV_BASE + 16)
+#define MSM_CAMERA_SUBDEV_IR_LED (MSM_CAMERA_SUBDEV_BASE + 17)
+#define MSM_CAMERA_SUBDEV_IR_CUT (MSM_CAMERA_SUBDEV_BASE + 18)
+#define MSM_CAMERA_SUBDEV_EXT (MSM_CAMERA_SUBDEV_BASE + 19)
+#define MSM_CAMERA_SUBDEV_TOF (MSM_CAMERA_SUBDEV_BASE + 20)
+#define MSM_CAMERA_SUBDEV_LASER_LED (MSM_CAMERA_SUBDEV_BASE + 21)
#define MSM_MAX_CAMERA_SENSORS 5
/* The below macro is defined to put an upper limit on maximum
diff --git a/include/uapi/video/msm_hdmi_hdcp_mgr.h b/include/uapi/video/msm_hdmi_hdcp_mgr.h
index 85fa918..1c19d4a 100644
--- a/include/uapi/video/msm_hdmi_hdcp_mgr.h
+++ b/include/uapi/video/msm_hdmi_hdcp_mgr.h
@@ -1,4 +1,4 @@
-#ifndef _UAPI__HDMI_HDCP_MGR_H
+#ifndef _UAPI__MSM_HDMI_HDCP_MGR_H
#define _UAPI__MSM_HDMI_HDCP_MGR_H
enum DS_TYPE { /* type of downstream device */
diff --git a/kernel/sched/energy.c b/kernel/sched/energy.c
index 420cb52..77d8361 100644
--- a/kernel/sched/energy.c
+++ b/kernel/sched/energy.c
@@ -150,6 +150,7 @@
int cpu;
unsigned long *max_frequencies = NULL;
int ret;
+ bool is_sge_valid = false;
if (!sched_is_energy_aware())
return 0;
@@ -248,6 +249,7 @@
sge_l0->cap_states[i].power);
}
+ is_sge_valid = true;
dev_info(&pdev->dev,
"cpu=%d eff=%d [freq=%ld cap=%ld power_d0=%ld] -> [freq=%ld cap=%ld power_d0=%ld]\n",
cpu, efficiency,
@@ -271,7 +273,8 @@
kfree(max_frequencies);
- walt_sched_energy_populated_callback();
+ if (is_sge_valid)
+ walt_sched_energy_populated_callback();
dev_info(&pdev->dev, "Sched-energy-costs capacity updated\n");
return 0;
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 16f8124..5143801 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -115,6 +115,7 @@
return -ENOMEM;
runtime->substream = substream;
spin_lock_init(&runtime->lock);
+ mutex_init(&runtime->realloc_mutex);
init_waitqueue_head(&runtime->sleep);
INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
runtime->event = NULL;
@@ -636,8 +637,10 @@
struct snd_rawmidi_params * params)
{
char *newbuf;
+ char *oldbuf;
struct snd_rawmidi_runtime *runtime = substream->runtime;
-
+ unsigned long flags;
+
if (substream->append && substream->use_count > 1)
return -EBUSY;
snd_rawmidi_drain_output(substream);
@@ -648,13 +651,22 @@
return -EINVAL;
}
if (params->buffer_size != runtime->buffer_size) {
- newbuf = krealloc(runtime->buffer, params->buffer_size,
+ mutex_lock(&runtime->realloc_mutex);
+ newbuf = __krealloc(runtime->buffer, params->buffer_size,
GFP_KERNEL);
- if (!newbuf)
+ if (!newbuf) {
+ mutex_unlock(&runtime->realloc_mutex);
return -ENOMEM;
+ }
+ spin_lock_irqsave(&runtime->lock, flags);
+ oldbuf = runtime->buffer;
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
runtime->avail = runtime->buffer_size;
+ spin_unlock_irqrestore(&runtime->lock, flags);
+ if (oldbuf != newbuf)
+ kfree(oldbuf);
+ mutex_unlock(&runtime->realloc_mutex);
}
runtime->avail_min = params->avail_min;
substream->active_sensing = !params->no_active_sensing;
@@ -666,7 +678,9 @@
struct snd_rawmidi_params * params)
{
char *newbuf;
+ char *oldbuf;
struct snd_rawmidi_runtime *runtime = substream->runtime;
+ unsigned long flags;
snd_rawmidi_drain_input(substream);
if (params->buffer_size < 32 || params->buffer_size > 1024L * 1024L) {
@@ -676,12 +690,21 @@
return -EINVAL;
}
if (params->buffer_size != runtime->buffer_size) {
- newbuf = krealloc(runtime->buffer, params->buffer_size,
+ mutex_lock(&runtime->realloc_mutex);
+ newbuf = __krealloc(runtime->buffer, params->buffer_size,
GFP_KERNEL);
- if (!newbuf)
+ if (!newbuf) {
+ mutex_unlock(&runtime->realloc_mutex);
return -ENOMEM;
+ }
+ spin_lock_irqsave(&runtime->lock, flags);
+ oldbuf = runtime->buffer;
runtime->buffer = newbuf;
runtime->buffer_size = params->buffer_size;
+ spin_unlock_irqrestore(&runtime->lock, flags);
+ if (oldbuf != newbuf)
+ kfree(oldbuf);
+ mutex_unlock(&runtime->realloc_mutex);
}
runtime->avail_min = params->avail_min;
return 0;
@@ -954,6 +977,8 @@
unsigned long appl_ptr;
spin_lock_irqsave(&runtime->lock, flags);
+ if (userbuf)
+ mutex_lock(&runtime->realloc_mutex);
while (count > 0 && runtime->avail) {
count1 = runtime->buffer_size - runtime->appl_ptr;
if (count1 > count)
@@ -973,6 +998,7 @@
spin_unlock_irqrestore(&runtime->lock, flags);
if (copy_to_user(userbuf + result,
runtime->buffer + appl_ptr, count1)) {
+ mutex_unlock(&runtime->realloc_mutex);
return result > 0 ? result : -EFAULT;
}
spin_lock_irqsave(&runtime->lock, flags);
@@ -981,6 +1007,8 @@
count -= count1;
}
spin_unlock_irqrestore(&runtime->lock, flags);
+ if (userbuf)
+ mutex_unlock(&runtime->realloc_mutex);
return result;
}
@@ -1245,10 +1273,14 @@
return -EINVAL;
result = 0;
+ if (userbuf)
+ mutex_lock(&runtime->realloc_mutex);
spin_lock_irqsave(&runtime->lock, flags);
if (substream->append) {
if ((long)runtime->avail < count) {
spin_unlock_irqrestore(&runtime->lock, flags);
+ if (userbuf)
+ mutex_unlock(&runtime->realloc_mutex);
return -EAGAIN;
}
}
@@ -1284,6 +1316,8 @@
__end:
count1 = runtime->avail < runtime->buffer_size;
spin_unlock_irqrestore(&runtime->lock, flags);
+ if (userbuf)
+ mutex_unlock(&runtime->realloc_mutex);
if (count1)
snd_rawmidi_output_trigger(substream, 1);
return result;