summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt30
-rw-r--r--arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts4
-rw-r--r--arch/arm/boot/dts/qcom/msm-pm660.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm-pmi8998.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/msm8998.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-gpu.dtsi271
-rw-r--r--arch/arm/boot/dts/qcom/sdm630-qrd.dtsi80
-rw-r--r--arch/arm/boot/dts/qcom/sdm630.dtsi3
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-coresight.dtsi1
-rw-r--r--arch/arm/boot/dts/qcom/sdm660-mdss.dtsi2
-rw-r--r--arch/arm/boot/dts/qcom/sdm660.dtsi2
-rw-r--r--arch/arm/configs/sdm660-perf_defconfig1
-rw-r--r--arch/arm/configs/sdm660_defconfig2
-rw-r--r--arch/arm/include/asm/cacheflush.h3
-rw-r--r--arch/arm/include/asm/device.h2
-rw-r--r--arch/arm/include/asm/dma-iommu.h3
-rw-r--r--arch/arm/include/asm/dma-mapping.h7
-rw-r--r--arch/arm/include/asm/glue-cache.h6
-rw-r--r--arch/arm/mm/dma-mapping.c26
-rw-r--r--arch/arm/mm/dma.h3
-rw-r--r--arch/arm64/configs/msm-perf_defconfig5
-rw-r--r--arch/arm64/configs/msm_defconfig5
-rw-r--r--arch/arm64/configs/msmcortex_mediabox_defconfig8
-rw-r--r--arch/arm64/configs/sdm660_defconfig1
-rw-r--r--drivers/base/firmware_class.c3
-rw-r--r--drivers/char/adsprpc.c1
-rw-r--r--drivers/crypto/msm/ice.c13
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_sspp.h12
-rw-r--r--drivers/gpu/drm/msm/sde/sde_plane.c71
-rw-r--r--drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c6
-rw-r--r--drivers/iommu/dma-mapping-fast.c11
-rw-r--r--drivers/iommu/io-pgtable-fast.c48
-rw-r--r--drivers/iommu/iommu-debug.c38
-rw-r--r--drivers/leds/leds-qpnp-flash-v2.c2
-rw-r--r--drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c40
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c16
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c8
-rw-r--r--drivers/media/platform/msm/vidc/msm_smem.c22
-rw-r--r--drivers/media/platform/msm/vidc/msm_vdec.c64
-rw-r--r--drivers/media/platform/msm/vidc/msm_venc.c166
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc.c13
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c23
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_debug.c6
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_internal.h6
-rw-r--r--drivers/net/wireless/ath/ath10k/snoc.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c90
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c3
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.c7
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c21
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c16
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c36
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h27
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c66
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h23
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa.c2
-rw-r--r--drivers/power/supply/qcom/fg-core.h18
-rw-r--r--drivers/power/supply/qcom/qpnp-fg-gen3.c128
-rw-r--r--drivers/soc/qcom/icnss.c43
-rw-r--r--drivers/soc/qcom/peripheral-loader.c31
-rw-r--r--drivers/usb/dwc3/core.c2
-rw-r--r--drivers/usb/pd/policy_engine.c88
-rw-r--r--include/sound/apr_audio-v2.h162
-rw-r--r--include/sound/q6afe-v2.h4
-rw-r--r--include/sound/q6asm-v2.h6
-rw-r--r--net/core/skbuff.c3
-rw-r--r--sound/soc/codecs/wcd934x/wcd934x.c56
-rw-r--r--sound/soc/msm/msm8998.c326
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c63
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c580
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c131
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c197
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h4
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c46
-rw-r--r--sound/soc/msm/qdsp6v2/q6afe.c160
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c86
75 files changed, 2812 insertions, 657 deletions
diff --git a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
index 8adfeebb1580..af80de7f5f1f 100644
--- a/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/supply/qcom/qpnp-fg-gen3.txt
@@ -215,6 +215,12 @@ First Level Node - FG Gen3 device
capacity learning cycle. If this is not specified, then
the default value is 0. Unit is in decipercentage.
+- qcom,battery-thermal-coefficients
+ Usage: optional
+ Value type: <u8>
+ Definition: Byte array of battery thermal coefficients.
+ This should be exactly 3 bytes in length.
+
- qcom,fg-jeita-hyst-temp
Usage: optional
Value type: <u32>
@@ -320,6 +326,27 @@ First Level Node - FG Gen3 device
to be configured in conjunction with the charger side
configuration for proper functionality.
+- qcom,slope-limit-temp-threshold
+ Usage: optional
+ Value type: <u32>
+ Definition: Battery temperature threshold to decide when slope limit
+ coefficients should be applied along with charging status.
+ Unit is in decidegC.
+
+- qcom,slope-limit-coeffs
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: A list of integers which holds the slope limit coefficients
+ in the following order. Allowed size is 4. Possible values
+ are from 0 to 31. Unit is in decipercentage.
+ Element 0 - Low temperature discharging
+ Element 1 - Low temperature charging
+ Element 2 - High temperature discharging
+ Element 3 - High temperature charging
+ These coefficients have to be specified along with the
+ property "qcom,slope-limit-temp-threshold" to make dynamic
+ slope limit adjustment functional.
+
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
@@ -354,6 +381,9 @@ pmi8998_fg: qpnp,fg {
qcom,ki-coeff-soc-dischg = <30 60 90>;
qcom,ki-coeff-med-dischg = <800 1000 1400>;
qcom,ki-coeff-hi-dischg = <1200 1500 2100>;
+ qcom,slope-limit-temp-threshold = <100>;
+ qcom,slope-limit-coeffs = <10 11 12 13>;
+ qcom,battery-thermal-coefficients = [9d 50 ff];
status = "okay";
qcom,fg-batt-soc@4000 {
diff --git a/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts b/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts
index f84708d73bd8..6288031fdd50 100644
--- a/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts
+++ b/arch/arm/boot/dts/qcom/apq8998-v2.1-mediabox.dts
@@ -21,10 +21,6 @@
qcom,board-id = <8 1>;
};
-&pil_modem {
- status = "disabled";
-};
-
&msm_ath10k_wlan {
status = "ok";
};
diff --git a/arch/arm/boot/dts/qcom/msm-pm660.dtsi b/arch/arm/boot/dts/qcom/msm-pm660.dtsi
index ca5b22cd34ee..131ad649ef8b 100644
--- a/arch/arm/boot/dts/qcom/msm-pm660.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pm660.dtsi
@@ -607,6 +607,8 @@
qcom,lra-high-z = "opt1";
qcom,lra-auto-res-mode = "qwd";
qcom,lra-res-cal-period = <4>;
+ qcom,correct-lra-drive-freq;
+ qcom,misc-trim-error-rc19p2-clk-reg-present;
};
};
};
diff --git a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
index 932757fa0bb4..c21c136907d4 100644
--- a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi
@@ -646,6 +646,8 @@
qcom,lra-high-z = "opt1";
qcom,lra-auto-res-mode = "qwd";
qcom,lra-res-cal-period = <4>;
+ qcom,correct-lra-drive-freq;
+ qcom,misc-trim-error-rc19p2-clk-reg-present;
};
flash_led: qcom,leds@d300 {
diff --git a/arch/arm/boot/dts/qcom/msm8998.dtsi b/arch/arm/boot/dts/qcom/msm8998.dtsi
index 8acbb6600415..697b049235bd 100644
--- a/arch/arm/boot/dts/qcom/msm8998.dtsi
+++ b/arch/arm/boot/dts/qcom/msm8998.dtsi
@@ -1750,7 +1750,7 @@
tx-fifo-resize;
snps,nominal-elastic-buffer;
snps,disable-clk-gating;
- snps,hird_thresh = <0x10>;
+ snps,hird-threshold = /bits/ 8 <0x10>;
snps,num-gsi-evt-buffs = <0x3>;
};
diff --git a/arch/arm/boot/dts/qcom/sdm630-gpu.dtsi b/arch/arm/boot/dts/qcom/sdm630-gpu.dtsi
new file mode 100644
index 000000000000..eec0862e5ee3
--- /dev/null
+++ b/arch/arm/boot/dts/qcom/sdm630-gpu.dtsi
@@ -0,0 +1,271 @@
+/* Copyright (c) 2017, 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.
+ */
+
+&soc {
+ pil_gpu: qcom,kgsl-hyp {
+ compatible = "qcom,pil-tz-generic";
+ qcom,pas-id = <13>;
+ qcom,firmware-name = "a508_zap";
+ };
+
+ msm_bus: qcom,kgsl-busmon{
+ label = "kgsl-busmon";
+ compatible = "qcom,kgsl-busmon";
+ };
+
+ gpubw: qcom,gpubw {
+ compatible = "qcom,devbw";
+ governor = "bw_vbif";
+ qcom,src-dst-ports = <26 512>;
+ /*
+ * active-only flag is used while registering the bus
+ * governor. It helps release the bus vote when the CPU
+ * subsystem is inactive
+ */
+ qcom,active-only;
+ /*
+ * IB votes in MBPS, derived using below formula
+ * IB = (DDR frequency * DDR bus width in Bytes * Dual rate)
+ * Note: IB vote is per DDR channel vote
+ */
+ qcom,bw-tbl =
+ < 0 /* off */ >,
+ < 381 /* 100 MHz */ >,
+ < 572 /* 150 MHz */ >,
+ < 762 /* 200 MHz */ >,
+ < 1144 /* 300 MHz */ >,
+ < 1571 /* 412 MHz */ >,
+ < 2086 /* 547 MHz */ >,
+ < 2597 /* 681 MHz */ >,
+ < 2929 /* 768 MHz */ >,
+ < 3879 /* 1017 MHz */ >,
+ < 4943 /* 1296 MHz */ >,
+ < 5161 /* 1353 MHz */ >;
+ };
+
+ msm_gpu: qcom,kgsl-3d0@5000000 {
+ label = "kgsl-3d0";
+ compatible = "qcom,kgsl-3d0", "qcom,kgsl-3d";
+ status = "ok";
+ reg = <0x5000000 0x40000>;
+ reg-names = "kgsl_3d0_reg_memory";
+ interrupts = <0 300 0>;
+ interrupt-names = "kgsl_3d0_irq";
+ qcom,id = <0>;
+
+ qcom,chipid = <0x05000800>;
+
+ qcom,initial-pwrlevel = <5>;
+
+ /* <HZ/12> */
+ qcom,idle-timeout = <80>;
+
+ qcom,highest-bank-bit = <14>;
+
+ /* size in bytes */
+ qcom,snapshot-size = <1048576>;
+
+ clocks = <&clock_gfx GPUCC_GFX3D_CLK>,
+ <&clock_gcc GCC_GPU_CFG_AHB_CLK>,
+ <&clock_gfx GPUCC_RBBMTIMER_CLK>,
+ <&clock_gcc GCC_GPU_BIMC_GFX_CLK>,
+ <&clock_gcc GCC_BIMC_GFX_CLK>,
+ <&clock_gpu GPUCC_RBCPR_CLK>;
+
+ clock-names = "core_clk", "iface_clk", "rbbmtimer_clk",
+ "mem_clk", "alt_mem_iface_clk", "rbcpr_clk";
+
+ /* Bus Scale Settings */
+ qcom,gpubw-dev = <&gpubw>;
+ qcom,bus-control;
+ /* GPU to BIMC bus width, VBIF data transfer in 1 cycle */
+ qcom,bus-width = <32>;
+ qcom,msm-bus,name = "grp3d";
+ qcom,msm-bus,num-cases = <14>;
+ qcom,msm-bus,num-paths = <1>;
+ qcom,msm-bus,vectors-KBps =
+ <26 512 0 0>,
+ <26 512 0 400000>, /* 1 bus=100 */
+ <26 512 0 600000>, /* 2 bus=150 */
+ <26 512 0 800000>, /* 3 bus=200 */
+ <26 512 0 1200000>, /* 4 bus=300 */
+ <26 512 0 1648000>, /* 5 bus=412 */
+ <26 512 0 2188000>, /* 6 bus=547 */
+ <26 512 0 2724000>, /* 7 bus=681 */
+ <26 512 0 3072000>, /* 8 bus=768 */
+ <26 512 0 4068000>, /* 9 bus=1017 */
+ <26 512 0 5184000>, /* 10 bus=1296 */
+ <26 512 0 5412000>; /* 11 bus=1353 */
+
+ /* GDSC regulator names */
+ regulator-names = "vddcx", "vdd";
+ /* GDSC oxili regulators */
+ vddcx-supply = <&gdsc_gpu_cx>;
+ vdd-supply = <&gdsc_gpu_gx>;
+
+ /* CPU latency parameter */
+ qcom,pm-qos-active-latency = <349>;
+ qcom,pm-qos-wakeup-latency = <349>;
+
+ /* Quirks */
+ qcom,gpu-quirk-dp2clockgating-disable;
+ qcom,gpu-quirk-lmloadkill-disable;
+
+ /* Enable context aware freq. scaling */
+ qcom,enable-ca-jump;
+
+ /* Context aware jump busy penalty in us */
+ qcom,ca-busy-penalty = <12000>;
+
+ /* Context aware jump target power level */
+ qcom,ca-target-pwrlevel = <4>;
+
+ /* GPU Mempools */
+ qcom,gpu-mempools {
+ #address-cells= <1>;
+ #size-cells = <0>;
+ compatible = "qcom,gpu-mempools";
+
+ qcom,mempool-max-pages = <32768>;
+
+ /* 4K Page Pool configuration */
+ qcom,gpu-mempool@0 {
+ reg = <0>;
+ qcom,mempool-page-size = <4096>;
+ };
+ /* 64K Page Pool configuration */
+ qcom,gpu-mempool@1 {
+ reg = <1>;
+ qcom,mempool-page-size = <65536>;
+ };
+ };
+
+ /* Power levels */
+ qcom,gpu-pwrlevels {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "qcom,gpu-pwrlevels";
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@0 {
+ reg = <0>;
+ qcom,gpu-freq = <775000000>;
+ qcom,bus-freq = <11>;
+ qcom,bus-min = <10>;
+ qcom,bus-max = <11>;
+ };
+
+ /* TURBO */
+ qcom,gpu-pwrlevel@1 {
+ reg = <1>;
+ qcom,gpu-freq = <700000000>;
+ qcom,bus-freq = <10>;
+ qcom,bus-min = <9>;
+ qcom,bus-max = <11>;
+ };
+
+ /* NOM_L1 */
+ qcom,gpu-pwrlevel@2 {
+ reg = <2>;
+ qcom,gpu-freq = <647000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <8>;
+ qcom,bus-max = <9>;
+ };
+
+ /* NOM */
+ qcom,gpu-pwrlevel@3 {
+ reg = <3>;
+ qcom,gpu-freq = <588000000>;
+ qcom,bus-freq = <9>;
+ qcom,bus-min = <7>;
+ qcom,bus-max = <9>;
+ };
+
+ /* SVS_L1 */
+ qcom,gpu-pwrlevel@4 {
+ reg = <4>;
+ qcom,gpu-freq = <465000000>;
+ qcom,bus-freq = <8>;
+ qcom,bus-min = <6>;
+ qcom,bus-max = <9>;
+ };
+
+ /* SVS */
+ qcom,gpu-pwrlevel@5 {
+ reg = <5>;
+ qcom,gpu-freq = <370000000>;
+ qcom,bus-freq = <5>;
+ qcom,bus-min = <4>;
+ qcom,bus-max = <7>;
+ };
+
+ /* Low SVS */
+ qcom,gpu-pwrlevel@6 {
+ reg = <6>;
+ qcom,gpu-freq = <240000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <3>;
+ qcom,bus-max = <5>;
+ };
+
+ /* Min SVS */
+ qcom,gpu-pwrlevel@7 {
+ reg = <7>;
+ qcom,gpu-freq = <160000000>;
+ qcom,bus-freq = <3>;
+ qcom,bus-min = <2>;
+ qcom,bus-max = <4>;
+ };
+
+ /* XO */
+ qcom,gpu-pwrlevel@8 {
+ reg = <8>;
+ qcom,gpu-freq = <19200000>;
+ qcom,bus-freq = <0>;
+ qcom,bus-min = <0>;
+ qcom,bus-max = <0>;
+ };
+ };
+ };
+
+ kgsl_msm_iommu: qcom,kgsl-iommu {
+ compatible = "qcom,kgsl-smmu-v2";
+
+ reg = <0x05040000 0x10000>;
+ qcom,protect = <0x40000 0x10000>;
+ qcom,micro-mmu-control = <0x6000>;
+
+ clocks = <&clock_gcc GCC_GPU_CFG_AHB_CLK>,
+ <&clock_gcc GCC_GPU_BIMC_GFX_CLK>,
+ <&clock_gcc GCC_BIMC_GFX_CLK>;
+
+ clock-names = "iface_clk", "mem_clk", "alt_mem_iface_clk";
+
+ qcom,secure_align_mask = <0xfff>;
+ qcom,retention;
+ qcom,hyp_secure_alloc;
+
+ gfx3d_user: gfx3d_user {
+ compatible = "qcom,smmu-kgsl-cb";
+ label = "gfx3d_user";
+ iommus = <&kgsl_smmu 0>;
+ qcom,gpu-offset = <0x48000>;
+ };
+
+ gfx3d_secure: gfx3d_secure {
+ compatible = "qcom,smmu-kgsl-cb";
+ iommus = <&kgsl_smmu 2>;
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi
index 6779d80d76cf..59afb993fb83 100644
--- a/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630-qrd.dtsi
@@ -20,5 +20,85 @@
pinctrl-0 = <&uart_console_active>;
};
+&ufsphy1 {
+ vdda-phy-supply = <&pm660l_l1>;
+ vdda-pll-supply = <&pm660_l10>;
+ vddp-ref-clk-supply = <&pm660_l1>;
+ vdda-phy-max-microamp = <51400>;
+ vdda-pll-max-microamp = <14200>;
+ vddp-ref-clk-max-microamp = <100>;
+ vddp-ref-clk-always-on;
+ status = "ok";
+};
+
+&ufs1 {
+ vdd-hba-supply = <&gdsc_ufs>;
+ vdd-hba-fixed-regulator;
+ vcc-supply = <&pm660l_l4>;
+ vccq2-supply = <&pm660_l8>;
+ vcc-max-microamp = <500000>;
+ vccq2-max-microamp = <600000>;
+ status = "ok";
+};
+
+&sdhc_1 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l4>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <200 570000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660_l8>;
+ qcom,vdd-io-always-on;
+ qcom,vdd-io-lpm-sup;
+ qcom,vdd-io-voltage-level = <1800000 1800000>;
+ qcom,vdd-io-current-level = <200 325000>;
+
+ pinctrl-names = "active", "sleep";
+ pinctrl-0 = <&sdc1_clk_on &sdc1_cmd_on &sdc1_data_on &sdc1_rclk_on>;
+ pinctrl-1 = <&sdc1_clk_off &sdc1_cmd_off &sdc1_data_off &sdc1_rclk_off>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000 192000000
+ 384000000>;
+
+ qcom,nonremovable;
+ qcom,bus-speed-mode = "HS400_1p8v", "HS200_1p8v", "DDR_1p8v";
+
+ status = "ok";
+};
+
+&sdhc_2 {
+ /* device core power supply */
+ vdd-supply = <&pm660l_l5>;
+ qcom,vdd-voltage-level = <2950000 2950000>;
+ qcom,vdd-current-level = <15000 800000>;
+
+ /* device communication power supply */
+ vdd-io-supply = <&pm660l_l2>;
+ qcom,vdd-io-voltage-level = <1800000 2950000>;
+ qcom,vdd-io-current-level = <200 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>;
+
+ #address-cells = <0>;
+ interrupt-parent = <&sdhc_2>;
+ interrupts = <0 1 2>;
+ #interrupt-cells = <1>;
+ interrupt-map-mask = <0xffffffff>;
+ interrupt-map = <0 &intc 0 0 125 0
+ 1 &intc 0 0 221 0
+ 2 &tlmm 54 0>;
+ interrupt-names = "hc_irq", "pwr_irq", "status_irq";
+ cd-gpios = <&tlmm 54 0x1>;
+
+ qcom,clk-rates = <400000 20000000 25000000 50000000 100000000
+ 200000000>;
+ qcom,bus-speed-mode = "SDR12", "SDR25", "SDR50", "DDR50", "SDR104";
+
+ status = "ok";
+};
+
&soc {
};
diff --git a/arch/arm/boot/dts/qcom/sdm630.dtsi b/arch/arm/boot/dts/qcom/sdm630.dtsi
index 15b62afc0347..302a9a197128 100644
--- a/arch/arm/boot/dts/qcom/sdm630.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm630.dtsi
@@ -1247,7 +1247,7 @@
dcc: dcc@10b3000 {
compatible = "qcom,dcc";
reg = <0x10b3000 0x1000>,
- <0x10b4000 0x800>;
+ <0x10b4000 0x2000>;
reg-names = "dcc-base", "dcc-ram-base";
clocks = <&clock_gcc GCC_DCC_AHB_CLK>;
@@ -1913,6 +1913,7 @@
#include "msm-arm-smmu-630.dtsi"
#include "msm-audio.dtsi"
#include "sdm660-audio.dtsi"
+#include "sdm630-gpu.dtsi"
#include "sdm660-camera.dtsi"
#include "sdm630-pm.dtsi"
#include "sdm660-vidc.dtsi"
diff --git a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi
index 431da5036a4b..dce86a7ceec3 100644
--- a/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-coresight.dtsi
@@ -25,6 +25,7 @@
arm,buffer-size = <0x400000>;
arm,sg-enable;
+ arm,default-sink;
coresight-ctis = <&cti0 &cti8>;
diff --git a/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi b/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi
index ec79dd63e4d2..32ffde6eca24 100644
--- a/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660-mdss.dtsi
@@ -494,7 +494,7 @@
qcom,aux-cfg-settings = [00 13 00 00 0a 28 0a 03 b7 03];
qcom,logical2physical-lane-map = [00 01 02 03];
qcom,phy-register-offset = <0x4>;
- qcom,max-pclk-frequency-khz = <593470>;
+ qcom,max-pclk-frequency-khz = <300000>;
qcom,core-supply-entries {
#address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/sdm660.dtsi b/arch/arm/boot/dts/qcom/sdm660.dtsi
index 6077699ebea9..4d8a72fea6a8 100644
--- a/arch/arm/boot/dts/qcom/sdm660.dtsi
+++ b/arch/arm/boot/dts/qcom/sdm660.dtsi
@@ -1614,7 +1614,7 @@
dcc: dcc@10b3000 {
compatible = "qcom,dcc";
reg = <0x10b3000 0x1000>,
- <0x10b4000 0x800>;
+ <0x10b4000 0x2000>;
reg-names = "dcc-base", "dcc-ram-base";
clocks = <&clock_gcc GCC_DCC_AHB_CLK>;
diff --git a/arch/arm/configs/sdm660-perf_defconfig b/arch/arm/configs/sdm660-perf_defconfig
index 013bada10783..73c12f90016c 100644
--- a/arch/arm/configs/sdm660-perf_defconfig
+++ b/arch/arm/configs/sdm660-perf_defconfig
@@ -498,6 +498,7 @@ CONFIG_MSM_MMCC_660=y
CONFIG_CLOCK_CPU_OSM=y
CONFIG_QCOM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_IOMMU_IO_PGTABLE_FAST=y
CONFIG_ARM_SMMU=y
CONFIG_IOMMU_DEBUG=y
CONFIG_IOMMU_DEBUG_TRACKING=y
diff --git a/arch/arm/configs/sdm660_defconfig b/arch/arm/configs/sdm660_defconfig
index 22da2099accc..5c8dbe8e8302 100644
--- a/arch/arm/configs/sdm660_defconfig
+++ b/arch/arm/configs/sdm660_defconfig
@@ -499,6 +499,8 @@ CONFIG_MSM_MMCC_660=y
CONFIG_CLOCK_CPU_OSM=y
CONFIG_QCOM_MDSS_PLL=y
CONFIG_REMOTE_SPINLOCK_MSM=y
+CONFIG_IOMMU_IO_PGTABLE_FAST=y
+CONFIG_IOMMU_IO_PGTABLE_FAST_SELFTEST=y
CONFIG_ARM_SMMU=y
CONFIG_IOMMU_DEBUG=y
CONFIG_IOMMU_DEBUG_TRACKING=y
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 2e2d1657e604..012a3aafcf33 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -178,6 +178,9 @@ extern void __cpuc_flush_dcache_area(void *, size_t);
* is visible to DMA, or data written by DMA to system memory is
* visible to the CPU.
*/
+extern void __dma_map_area(const void *, size_t, int);
+extern void __dma_unmap_area(const void *, size_t, int);
+
extern void dmac_inv_range(const void *, const void *);
extern void dmac_clean_range(const void *, const void *);
extern void dmac_flush_range(const void *, const void *);
diff --git a/arch/arm/include/asm/device.h b/arch/arm/include/asm/device.h
index 4111592f0130..d8a572f9c187 100644
--- a/arch/arm/include/asm/device.h
+++ b/arch/arm/include/asm/device.h
@@ -7,7 +7,7 @@
#define ASMARM_DEVICE_H
struct dev_archdata {
- struct dma_map_ops *dma_ops;
+ const struct dma_map_ops *dma_ops;
#ifdef CONFIG_DMABOUNCE
struct dmabounce_device_info *dmabounce;
#endif
diff --git a/arch/arm/include/asm/dma-iommu.h b/arch/arm/include/asm/dma-iommu.h
index b4e74af0abb7..74643f5b41c4 100644
--- a/arch/arm/include/asm/dma-iommu.h
+++ b/arch/arm/include/asm/dma-iommu.h
@@ -8,6 +8,7 @@
#include <linux/dma-debug.h>
#include <linux/kmemcheck.h>
#include <linux/kref.h>
+#include <linux/dma-mapping-fast.h>
struct dma_iommu_mapping {
/* iommu specific data */
@@ -22,6 +23,8 @@ struct dma_iommu_mapping {
spinlock_t lock;
struct kref kref;
+
+ struct dma_fast_smmu_mapping *fast;
};
#ifdef CONFIG_ARM_DMA_USE_IOMMU
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index ccb3aa64640d..05ff03aead43 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -17,14 +17,14 @@
extern struct dma_map_ops arm_dma_ops;
extern struct dma_map_ops arm_coherent_dma_ops;
-static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
+static inline const struct dma_map_ops *__generic_dma_ops(struct device *dev)
{
if (dev && dev->archdata.dma_ops)
return dev->archdata.dma_ops;
return &arm_dma_ops;
}
-static inline struct dma_map_ops *get_dma_ops(struct device *dev)
+static inline const struct dma_map_ops *get_dma_ops(struct device *dev)
{
if (xen_initial_domain())
return xen_dma_ops;
@@ -32,7 +32,8 @@ static inline struct dma_map_ops *get_dma_ops(struct device *dev)
return __generic_dma_ops(dev);
}
-static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
+static inline void set_dma_ops(struct device *dev,
+ const struct dma_map_ops *ops)
{
BUG_ON(!dev);
dev->archdata.dma_ops = ops;
diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h
index 1f442995cdbf..7a4893e61866 100644
--- a/arch/arm/include/asm/glue-cache.h
+++ b/arch/arm/include/asm/glue-cache.h
@@ -161,6 +161,12 @@ static inline void nop_dma_unmap_area(const void *s, size_t l, int f) { }
#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
#define dmac_inv_range __glue(_CACHE, _dma_inv_range)
#define dmac_clean_range __glue(_CACHE, _dma_clean_range)
+#define dmac_map_area __glue(_CACHE, _dma_map_area)
+#define dmac_unmap_area __glue(_CACHE, _dma_unmap_area)
+
+#define __dma_map_area dmac_map_area
+#define __dma_unmap_area dmac_unmap_area
+#define __dma_flush_range dmac_flush_range
#endif
#endif
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 330061d3d081..b58d8e0d9ed1 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -29,6 +29,7 @@
#include <linux/sizes.h>
#include <linux/cma.h>
#include <linux/msm_dma_iommu_mapping.h>
+#include <linux/dma-mapping-fast.h>
#include <asm/memory.h>
#include <asm/highmem.h>
@@ -1019,7 +1020,7 @@ static void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir, struct dma_attrs *attrs)
{
- struct dma_map_ops *ops = get_dma_ops(dev);
+ const struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i, j;
@@ -1053,7 +1054,7 @@ int arm_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
enum dma_data_direction dir, struct dma_attrs *attrs)
{
- struct dma_map_ops *ops = get_dma_ops(dev);
+ const struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i;
@@ -1072,7 +1073,7 @@ void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
- struct dma_map_ops *ops = get_dma_ops(dev);
+ const struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i;
@@ -1091,7 +1092,7 @@ void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
void arm_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nents, enum dma_data_direction dir)
{
- struct dma_map_ops *ops = get_dma_ops(dev);
+ const struct dma_map_ops *ops = get_dma_ops(dev);
struct scatterlist *s;
int i;
@@ -1988,7 +1989,7 @@ static void arm_iommu_sync_single_for_device(struct device *dev,
__dma_page_cpu_to_dev(page, offset, size, dir);
}
-struct dma_map_ops iommu_ops = {
+const struct dma_map_ops iommu_ops = {
.alloc = arm_iommu_alloc_attrs,
.free = arm_iommu_free_attrs,
.mmap = arm_iommu_mmap_attrs,
@@ -2007,7 +2008,7 @@ struct dma_map_ops iommu_ops = {
.set_dma_mask = arm_dma_set_mask,
};
-struct dma_map_ops iommu_coherent_ops = {
+const struct dma_map_ops iommu_coherent_ops = {
.alloc = arm_iommu_alloc_attrs,
.free = arm_iommu_free_attrs,
.mmap = arm_iommu_mmap_attrs,
@@ -2166,6 +2167,11 @@ int arm_iommu_attach_device(struct device *dev,
{
int err;
int s1_bypass = 0;
+ int is_fast = 0;
+
+ iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
+ if (is_fast)
+ return fast_smmu_attach_device(dev, mapping);
err = __arm_iommu_attach_device(dev, mapping);
if (err)
@@ -2182,6 +2188,7 @@ EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
static void __arm_iommu_detach_device(struct device *dev)
{
struct dma_iommu_mapping *mapping;
+ int is_fast;
mapping = to_dma_iommu_mapping(dev);
if (!mapping) {
@@ -2191,6 +2198,9 @@ static void __arm_iommu_detach_device(struct device *dev)
if (msm_dma_unmap_all_for_dev(dev))
dev_warn(dev, "IOMMU detach with outstanding mappings\n");
+ iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_FAST, &is_fast);
+ if (is_fast)
+ return fast_smmu_detach_device(dev, mapping);
iommu_detach_device(mapping->domain, dev);
kref_put(&mapping->kref, release_iommu_mapping);
@@ -2226,7 +2236,7 @@ void arm_iommu_detach_device(struct device *dev)
}
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
-static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
+static const struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
{
return coherent ? &iommu_coherent_ops : &iommu_ops;
}
@@ -2289,7 +2299,7 @@ static struct dma_map_ops *arm_get_dma_map_ops(bool coherent)
void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
struct iommu_ops *iommu, bool coherent)
{
- struct dma_map_ops *dma_ops;
+ const struct dma_map_ops *dma_ops;
dev->archdata.dma_coherent = coherent;
if (arm_setup_iommu_dma_ops(dev, dma_base, size, iommu))
diff --git a/arch/arm/mm/dma.h b/arch/arm/mm/dma.h
index 70ea6852f94e..29c54f7d81f3 100644
--- a/arch/arm/mm/dma.h
+++ b/arch/arm/mm/dma.h
@@ -4,9 +4,6 @@
#include <asm/glue-cache.h>
#ifndef MULTI_CACHE
-#define dmac_map_area __glue(_CACHE,_dma_map_area)
-#define dmac_unmap_area __glue(_CACHE,_dma_unmap_area)
-
/*
* These are private to the dma-mapping API. Do not use directly.
* Their sole purpose is to ensure that data held in the cache
diff --git a/arch/arm64/configs/msm-perf_defconfig b/arch/arm64/configs/msm-perf_defconfig
index 176bd7fad9a9..03c5bc89b6f5 100644
--- a/arch/arm64/configs/msm-perf_defconfig
+++ b/arch/arm64/configs/msm-perf_defconfig
@@ -345,6 +345,7 @@ CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_WCD9335_CODEC=y
+CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
@@ -394,7 +395,7 @@ CONFIG_MSM_VIDC_VMEM=y
CONFIG_MSM_VIDC_GOVERNORS=y
CONFIG_MSM_SDE_ROTATOR=y
CONFIG_QCOM_KGSL=y
-CONFIG_DRM=y
+CONFIG_FB=y
CONFIG_FB_MSM=y
CONFIG_FB_MSM_MDSS=y
CONFIG_FB_MSM_MDSS_WRITEBACK=y
@@ -518,6 +519,7 @@ CONFIG_MSM_IPC_ROUTER_MHI_XPRT=y
CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SPM=y
+CONFIG_QCOM_SCM=y
CONFIG_QCOM_SCM_XPU=y
CONFIG_QCOM_WATCHDOG_V2=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
@@ -562,6 +564,7 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
diff --git a/arch/arm64/configs/msm_defconfig b/arch/arm64/configs/msm_defconfig
index a7d2b895e08c..b4ddd9a2bed5 100644
--- a/arch/arm64/configs/msm_defconfig
+++ b/arch/arm64/configs/msm_defconfig
@@ -332,6 +332,7 @@ CONFIG_THERMAL_TSENS8974=y
CONFIG_THERMAL_QPNP_ADC_TM=y
CONFIG_MFD_SPMI_PMIC=y
CONFIG_WCD9335_CODEC=y
+CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_RPM_SMD=y
CONFIG_REGULATOR_QPNP=y
@@ -382,7 +383,7 @@ CONFIG_MSM_VIDC_VMEM=y
CONFIG_MSM_VIDC_GOVERNORS=y
CONFIG_MSM_SDE_ROTATOR=y
CONFIG_QCOM_KGSL=y
-CONFIG_DRM=y
+CONFIG_FB=y
CONFIG_FB_MSM=y
CONFIG_FB_MSM_MDSS=y
CONFIG_FB_MSM_MDSS_WRITEBACK=y
@@ -519,6 +520,7 @@ CONFIG_MSM_IPC_ROUTER_MHI_XPRT=y
CONFIG_MSM_IPC_ROUTER_GLINK_XPRT=y
CONFIG_MSM_GLINK_PKT=y
CONFIG_MSM_SPM=y
+CONFIG_QCOM_SCM=y
CONFIG_QCOM_SCM_XPU=y
CONFIG_QCOM_WATCHDOG_V2=y
CONFIG_QCOM_MEMORY_DUMP_V2=y
@@ -568,6 +570,7 @@ CONFIG_EXT4_FS_ICE_ENCRYPTION=y
CONFIG_FUSE_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
CONFIG_TMPFS_POSIX_ACL=y
CONFIG_ECRYPT_FS=y
CONFIG_ECRYPT_FS_MESSAGING=y
diff --git a/arch/arm64/configs/msmcortex_mediabox_defconfig b/arch/arm64/configs/msmcortex_mediabox_defconfig
index d0fdb7206d5b..06b4554ec362 100644
--- a/arch/arm64/configs/msmcortex_mediabox_defconfig
+++ b/arch/arm64/configs/msmcortex_mediabox_defconfig
@@ -225,6 +225,10 @@ CONFIG_BTFM_SLIM_WCN3990=y
CONFIG_CFG80211=y
CONFIG_CFG80211_INTERNAL_REGDB=y
# CONFIG_CFG80211_CRDA_SUPPORT is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=m
+CONFIG_MAC80211_MESH=y
+CONFIG_MAC80211_LEDS=y
CONFIG_RFKILL=y
CONFIG_NFC_NQ=y
CONFIG_IPC_ROUTER=y
@@ -274,6 +278,9 @@ CONFIG_USB_USBNET=y
CONFIG_WCNSS_MEM_PRE_ALLOC=y
CONFIG_ATH_CARDS=y
CONFIG_WIL6210=m
+CONFIG_ATH10K=m
+CONFIG_ATH10K_TARGET_SNOC=m
+CONFIG_ATH10K_SNOC=y
CONFIG_CLD_LL_CORE=y
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_KEYRESET=y
@@ -472,7 +479,6 @@ CONFIG_LEDS_QPNP=y
CONFIG_LEDS_QPNP_FLASH_V2=y
CONFIG_LEDS_QPNP_WLED=y
CONFIG_LEDS_SYSCON=y
-CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_LEDS_TRIGGER_CPU=y
CONFIG_SWITCH=y
diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig
index ef8bac8e2947..af8902054b8a 100644
--- a/arch/arm64/configs/sdm660_defconfig
+++ b/arch/arm64/configs/sdm660_defconfig
@@ -59,6 +59,7 @@ CONFIG_CLEANCACHE=y
CONFIG_CMA=y
CONFIG_CMA_DEBUGFS=y
CONFIG_ZSMALLOC=y
+CONFIG_FORCE_ALLOC_FROM_DMA_ZONE=y
CONFIG_PROCESS_RECLAIM=y
CONFIG_SECCOMP=y
CONFIG_ARMV8_DEPRECATED=y
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 152c81ca50ea..87a48268b663 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -840,7 +840,8 @@ static ssize_t firmware_direct_write(struct file *filp, struct kobject *kobj,
mutex_lock(&fw_lock);
fw = fw_priv->fw;
- if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->buf->status)) {
+ if (!fw || !fw_priv->buf ||
+ test_bit(FW_STATUS_DONE, &fw_priv->buf->status)) {
retval = -ENODEV;
goto out;
}
diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c
index 0345e977a2d4..88bd6afdeea5 100644
--- a/drivers/char/adsprpc.c
+++ b/drivers/char/adsprpc.c
@@ -1981,6 +1981,7 @@ static int fastrpc_session_alloc_locked(struct fastrpc_channel_ctx *chan,
if (err)
goto bail;
chan->session[0].dev = me->dev;
+ chan->session[0].smmu.dev = me->dev;
}
*session = &chan->session[idx];
diff --git a/drivers/crypto/msm/ice.c b/drivers/crypto/msm/ice.c
index a5e5ad34db16..ab21334d5813 100644
--- a/drivers/crypto/msm/ice.c
+++ b/drivers/crypto/msm/ice.c
@@ -53,6 +53,8 @@
#define QCOM_SDCC_ICE_DEV "icesdcc"
#define QCOM_ICE_TYPE_NAME_LEN 8
#define QCOM_ICE_MAX_BIST_CHECK_COUNT 100
+#define QCOM_ICE_UFS 10
+#define QCOM_ICE_SDCC 20
struct ice_clk_info {
struct list_head list;
@@ -838,7 +840,7 @@ static int qcom_ice_restore_config(void)
return ret;
}
-static int qcom_ice_restore_key_config(void)
+static int qcom_ice_restore_key_config(struct ice_device *ice_dev)
{
struct scm_desc desc = {0};
int ret = -1;
@@ -846,7 +848,12 @@ static int qcom_ice_restore_key_config(void)
/* For ice 3, key configuration needs to be restored in case of reset */
desc.arginfo = TZ_OS_KS_RESTORE_KEY_CONFIG_ID_PARAM_ID;
- desc.args[0] = 10; /* UFS_ICE */
+
+ if (!strcmp(ice_dev->ice_instance_type, "sdcc"))
+ desc.args[0] = QCOM_ICE_SDCC;
+
+ if (!strcmp(ice_dev->ice_instance_type, "ufs"))
+ desc.args[0] = QCOM_ICE_UFS;
ret = scm_call2(TZ_OS_KS_RESTORE_KEY_CONFIG_ID, &desc);
@@ -1135,7 +1142,7 @@ static int qcom_ice_finish_power_collapse(struct ice_device *ice_dev)
* restore it
*/
} else if (ICE_REV(ice_dev->ice_hw_version, MAJOR) > 2) {
- err = qcom_ice_restore_key_config();
+ err = qcom_ice_restore_key_config(ice_dev);
if (err)
goto out;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h
index 743f5e72d1a8..ceb48282081d 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.h
+++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.h
@@ -64,6 +64,18 @@ enum sde_hw_filter {
SDE_SCALE_FILTER_MAX
};
+enum sde_hw_filter_alpa {
+ SDE_SCALE_ALPHA_PIXEL_REP,
+ SDE_SCALE_ALPHA_BIL
+};
+
+enum sde_hw_filter_yuv {
+ SDE_SCALE_2D_4X4,
+ SDE_SCALE_2D_CIR,
+ SDE_SCALE_1D_SEP,
+ SDE_SCALE_BIL
+};
+
struct sde_hw_sharp_cfg {
u32 strength;
u32 edge_thr;
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 3ca74926cfac..b3de45302dea 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -60,6 +60,9 @@
#define SDE_PLANE_DIRTY_SHARPEN 0x4
#define SDE_PLANE_DIRTY_ALL 0xFFFFFFFF
+#define SDE_QSEED3_DEFAULT_PRELOAD_H 0x4
+#define SDE_QSEED3_DEFAULT_PRELOAD_V 0x3
+
/**
* enum sde_plane_qos - Different qos configurations for each pipe
*
@@ -615,6 +618,73 @@ static void _sde_plane_setup_scaler3(struct sde_plane *psde,
const struct sde_format *fmt,
uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
{
+ uint32_t decimated, i;
+
+ if (!psde || !scale_cfg || !fmt || !chroma_subsmpl_h ||
+ !chroma_subsmpl_v) {
+ SDE_ERROR("psde %pK scale_cfg %pK fmt %pK smp_h %d smp_v %d\n"
+ , psde, scale_cfg, fmt, chroma_subsmpl_h,
+ chroma_subsmpl_v);
+ return;
+ }
+
+ memset(scale_cfg, 0, sizeof(*scale_cfg));
+
+ decimated = DECIMATED_DIMENSION(src_w,
+ psde->pipe_cfg.horz_decimation);
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_0] =
+ mult_frac((1 << PHASE_STEP_SHIFT), decimated, dst_w);
+ decimated = DECIMATED_DIMENSION(src_h,
+ psde->pipe_cfg.vert_decimation);
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_0] =
+ mult_frac((1 << PHASE_STEP_SHIFT), decimated, dst_h);
+
+
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_1_2] =
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_0] / chroma_subsmpl_v;
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_1_2] =
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_0] / chroma_subsmpl_h;
+
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_2] =
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_1_2];
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_2] =
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_1_2];
+
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_3] =
+ scale_cfg->phase_step_x[SDE_SSPP_COMP_0];
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_3] =
+ scale_cfg->phase_step_y[SDE_SSPP_COMP_0];
+
+ for (i = 0; i < SDE_MAX_PLANES; i++) {
+ scale_cfg->src_width[i] = DECIMATED_DIMENSION(src_w,
+ psde->pipe_cfg.horz_decimation);
+ scale_cfg->src_height[i] = DECIMATED_DIMENSION(src_h,
+ psde->pipe_cfg.vert_decimation);
+ if (SDE_FORMAT_IS_YUV(fmt))
+ scale_cfg->src_width[i] &= ~0x1;
+ if (i == SDE_SSPP_COMP_1_2 || i == SDE_SSPP_COMP_2) {
+ scale_cfg->src_width[i] /= chroma_subsmpl_h;
+ scale_cfg->src_height[i] /= chroma_subsmpl_v;
+ }
+ scale_cfg->preload_x[i] = SDE_QSEED3_DEFAULT_PRELOAD_H;
+ scale_cfg->preload_y[i] = SDE_QSEED3_DEFAULT_PRELOAD_V;
+ psde->pixel_ext.num_ext_pxls_top[i] =
+ scale_cfg->src_height[i];
+ psde->pixel_ext.num_ext_pxls_left[i] =
+ scale_cfg->src_width[i];
+ }
+ if (!(SDE_FORMAT_IS_YUV(fmt)) && (src_h == dst_h)
+ && (src_w == dst_w))
+ return;
+
+ scale_cfg->dst_width = dst_w;
+ scale_cfg->dst_height = dst_h;
+ scale_cfg->y_rgb_filter_cfg = SDE_SCALE_BIL;
+ scale_cfg->uv_filter_cfg = SDE_SCALE_BIL;
+ scale_cfg->alpha_filter_cfg = SDE_SCALE_ALPHA_BIL;
+ scale_cfg->lut_flag = 0;
+ scale_cfg->blend_cfg = 1;
+ scale_cfg->enable = 1;
}
/**
@@ -901,6 +971,7 @@ static void _sde_plane_setup_scaler(struct sde_plane *psde,
error = _sde_plane_setup_scaler3_lut(psde, pstate);
if (error || !psde->pixel_ext_usr) {
+ memset(pe, 0, sizeof(struct sde_hw_pixel_ext));
/* calculate default config for QSEED3 */
_sde_plane_setup_scaler3(psde,
psde->pipe_cfg.src_rect.w,
diff --git a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c
index f936f3c2ebb1..563ce16885b3 100644
--- a/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c
+++ b/drivers/input/touchscreen/synaptics_dsx_2.6/synaptics_dsx_i2c.c
@@ -445,11 +445,11 @@ static int synaptics_rmi4_i2c_write(struct synaptics_rmi4_data *rmi4_data,
struct i2c_client *i2c = to_i2c_client(rmi4_data->pdev->dev.parent);
struct i2c_msg msg[1];
+ mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex);
+
retval = synaptics_rmi4_i2c_alloc_buf(rmi4_data, length + 1);
if (retval < 0)
- return retval;
-
- mutex_lock(&rmi4_data->rmi4_io_ctrl_mutex);
+ goto exit;
retval = synaptics_rmi4_i2c_set_page(rmi4_data, addr);
if (retval != PAGE_SELECT_LEN) {
diff --git a/drivers/iommu/dma-mapping-fast.c b/drivers/iommu/dma-mapping-fast.c
index 004f34ecbff8..df5140d23015 100644
--- a/drivers/iommu/dma-mapping-fast.c
+++ b/drivers/iommu/dma-mapping-fast.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, 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
@@ -17,7 +17,8 @@
#include <linux/vmalloc.h>
#include <asm/cacheflush.h>
#include <asm/dma-iommu.h>
-
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
/* some redundant definitions... :( TODO: move to io-pgtable-fast.h */
#define FAST_PAGE_SHIFT 12
@@ -632,7 +633,7 @@ static void __fast_smmu_mapped_over_stale(struct dma_fast_smmu_mapping *fast,
dev_err(fast->dev, "Mapped over stale tlb at %pa\n", &iova);
dev_err(fast->dev, "bitmap (failure at idx %lu):\n", bitmap_idx);
dev_err(fast->dev, "ptep: %p pmds: %p diff: %lu\n", ptep,
- fast->pgtbl_pmds, ptep - fast->pgtbl_pmds);
+ fast->pgtbl_pmds, bitmap_idx);
print_hex_dump(KERN_ERR, "bmap: ", DUMP_PREFIX_ADDRESS,
32, 8, fast->bitmap, fast->bitmap_size, false);
}
@@ -682,7 +683,7 @@ static const struct dma_map_ops fast_smmu_dma_ops = {
* fast_smmu_attach_device function.
*/
static struct dma_fast_smmu_mapping *__fast_smmu_create_mapping_sized(
- dma_addr_t base, size_t size)
+ dma_addr_t base, u64 size)
{
struct dma_fast_smmu_mapping *fast;
@@ -725,7 +726,7 @@ int fast_smmu_attach_device(struct device *dev,
int atomic_domain = 1;
struct iommu_domain *domain = mapping->domain;
struct iommu_pgtbl_info info;
- size_t size = mapping->bits << PAGE_SHIFT;
+ u64 size = (u64)mapping->bits << PAGE_SHIFT;
if (mapping->base + size > (SZ_1G * 4ULL))
return -EINVAL;
diff --git a/drivers/iommu/io-pgtable-fast.c b/drivers/iommu/io-pgtable-fast.c
index a71fcdbb1899..ba0af42f8df3 100644
--- a/drivers/iommu/io-pgtable-fast.c
+++ b/drivers/iommu/io-pgtable-fast.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
#include <linux/types.h>
#include <linux/io-pgtable-fast.h>
#include <asm/cacheflush.h>
+#include <linux/vmalloc.h>
#include "io-pgtable.h"
@@ -263,11 +264,18 @@ static size_t av8l_fast_unmap(struct io_pgtable_ops *ops, unsigned long iova,
return size;
}
+#if defined(CONFIG_ARM64)
+#define FAST_PGDNDX(va) (((va) & 0x7fc0000000) >> 27)
+#elif defined(CONFIG_ARM)
+#define FAST_PGDNDX(va) (((va) & 0xc0000000) >> 27)
+#endif
+
static phys_addr_t av8l_fast_iova_to_phys(struct io_pgtable_ops *ops,
unsigned long iova)
{
struct av8l_fast_io_pgtable *data = iof_pgtable_ops_to_data(ops);
av8l_fast_iopte pte, *pgdp, *pudp, *pmdp;
+ unsigned long pgd;
phys_addr_t phys;
const unsigned long pts = AV8L_FAST_PTE_TYPE_SHIFT;
const unsigned long ptm = AV8L_FAST_PTE_TYPE_MASK;
@@ -277,8 +285,9 @@ static phys_addr_t av8l_fast_iova_to_phys(struct io_pgtable_ops *ops,
/* TODO: clean up some of these magic numbers... */
- pgdp = (av8l_fast_iopte *)
- (((unsigned long)data->pgd) | ((iova & 0x7fc0000000) >> 27));
+ pgd = (unsigned long)data->pgd | FAST_PGDNDX(iova);
+ pgdp = (av8l_fast_iopte *)pgd;
+
pte = *pgdp;
if (((pte >> pts) & ptm) != ptt)
return 0;
@@ -464,6 +473,9 @@ av8l_fast_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
reg |= (64ULL - cfg->ias) << AV8L_FAST_TCR_T0SZ_SHIFT;
reg |= AV8L_FAST_TCR_EPD1_FAULT << AV8L_FAST_TCR_EPD1_SHIFT;
+#if defined(CONFIG_ARM)
+ reg |= ARM_32_LPAE_TCR_EAE;
+#endif
cfg->av8l_fast_cfg.tcr = reg;
/* MAIRs */
@@ -549,7 +561,7 @@ static bool av8l_fast_range_has_specific_mapping(struct io_pgtable_ops *ops,
const phys_addr_t phys_start,
const size_t size)
{
- unsigned long iova = iova_start;
+ u64 iova = iova_start;
phys_addr_t phys = phys_start;
while (iova < (iova_start + size)) {
@@ -565,11 +577,12 @@ static bool av8l_fast_range_has_specific_mapping(struct io_pgtable_ops *ops,
static int __init av8l_fast_positive_testing(void)
{
int failed = 0;
- unsigned long iova;
+ u64 iova;
struct io_pgtable_ops *ops;
struct io_pgtable_cfg cfg;
struct av8l_fast_io_pgtable *data;
av8l_fast_iopte *pmds;
+ u64 max = SZ_1G * 4ULL - 1;
cfg = (struct io_pgtable_cfg) {
.quirks = 0,
@@ -589,19 +602,18 @@ static int __init av8l_fast_positive_testing(void)
pmds = data->pmds;
/* map the entire 4GB VA space with 4K map calls */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_4K) {
+ for (iova = 0; iova < max; iova += SZ_4K) {
if (WARN_ON(ops->map(ops, iova, iova, SZ_4K, IOMMU_READ))) {
failed++;
continue;
}
}
-
if (WARN_ON(!av8l_fast_range_has_specific_mapping(ops, 0, 0,
- SZ_1G * 4UL)))
+ max)))
failed++;
/* unmap it all */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_4K) {
+ for (iova = 0; iova < max; iova += SZ_4K) {
if (WARN_ON(ops->unmap(ops, iova, SZ_4K) != SZ_4K))
failed++;
}
@@ -610,7 +622,7 @@ static int __init av8l_fast_positive_testing(void)
av8l_fast_clear_stale_ptes(pmds, false);
/* map the entire 4GB VA space with 8K map calls */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_8K) {
+ for (iova = 0; iova < max; iova += SZ_8K) {
if (WARN_ON(ops->map(ops, iova, iova, SZ_8K, IOMMU_READ))) {
failed++;
continue;
@@ -618,11 +630,11 @@ static int __init av8l_fast_positive_testing(void)
}
if (WARN_ON(!av8l_fast_range_has_specific_mapping(ops, 0, 0,
- SZ_1G * 4UL)))
+ max)))
failed++;
/* unmap it all with 8K unmap calls */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_8K) {
+ for (iova = 0; iova < max; iova += SZ_8K) {
if (WARN_ON(ops->unmap(ops, iova, SZ_8K) != SZ_8K))
failed++;
}
@@ -631,7 +643,7 @@ static int __init av8l_fast_positive_testing(void)
av8l_fast_clear_stale_ptes(pmds, false);
/* map the entire 4GB VA space with 16K map calls */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_16K) {
+ for (iova = 0; iova < max; iova += SZ_16K) {
if (WARN_ON(ops->map(ops, iova, iova, SZ_16K, IOMMU_READ))) {
failed++;
continue;
@@ -639,11 +651,11 @@ static int __init av8l_fast_positive_testing(void)
}
if (WARN_ON(!av8l_fast_range_has_specific_mapping(ops, 0, 0,
- SZ_1G * 4UL)))
+ max)))
failed++;
/* unmap it all */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_16K) {
+ for (iova = 0; iova < max; iova += SZ_16K) {
if (WARN_ON(ops->unmap(ops, iova, SZ_16K) != SZ_16K))
failed++;
}
@@ -652,7 +664,7 @@ static int __init av8l_fast_positive_testing(void)
av8l_fast_clear_stale_ptes(pmds, false);
/* map the entire 4GB VA space with 64K map calls */
- for (iova = 0; iova < SZ_1G * 4UL; iova += SZ_64K) {
+ for (iova = 0; iova < max; iova += SZ_64K) {
if (WARN_ON(ops->map(ops, iova, iova, SZ_64K, IOMMU_READ))) {
failed++;
continue;
@@ -660,11 +672,11 @@ static int __init av8l_fast_positive_testing(void)
}
if (WARN_ON(!av8l_fast_range_has_specific_mapping(ops, 0, 0,
- SZ_1G * 4UL)))
+ max)))
failed++;
/* unmap it all at once */
- if (WARN_ON(ops->unmap(ops, 0, SZ_1G * 4UL) != SZ_1G * 4UL))
+ if (WARN_ON(ops->unmap(ops, 0, max) != max))
failed++;
free_io_pgtable_ops(ops);
diff --git a/drivers/iommu/iommu-debug.c b/drivers/iommu/iommu-debug.c
index 937ce3f6279c..75fcde6e2c20 100644
--- a/drivers/iommu/iommu-debug.c
+++ b/drivers/iommu/iommu-debug.c
@@ -839,7 +839,7 @@ static int iommu_debug_profiling_fast_dma_api_show(struct seq_file *s,
if (!virt)
goto out;
- mapping = arm_iommu_create_mapping(&platform_bus_type, 0, SZ_1G * 4UL);
+ mapping = arm_iommu_create_mapping(&platform_bus_type, 0, SZ_1G * 4ULL);
if (!mapping) {
seq_puts(s, "fast_smmu_create_mapping failed\n");
goto out_kfree;
@@ -939,8 +939,8 @@ static const struct file_operations iommu_debug_profiling_fast_dma_api_fops = {
static int __tlb_stress_sweep(struct device *dev, struct seq_file *s)
{
int i, ret = 0;
- unsigned long iova;
- const unsigned long max = SZ_1G * 4UL;
+ u64 iova;
+ const u64 max = SZ_1G * 4ULL - 1;
void *virt;
phys_addr_t phys;
dma_addr_t dma_addr;
@@ -1012,8 +1012,8 @@ static int __tlb_stress_sweep(struct device *dev, struct seq_file *s)
}
/* we're all full again. unmap everything. */
- for (dma_addr = 0; dma_addr < max; dma_addr += SZ_8K)
- dma_unmap_single(dev, dma_addr, SZ_8K, DMA_TO_DEVICE);
+ for (iova = 0; iova < max; iova += SZ_8K)
+ dma_unmap_single(dev, (dma_addr_t)iova, SZ_8K, DMA_TO_DEVICE);
out:
free_pages((unsigned long)virt, get_order(SZ_8K));
@@ -1046,7 +1046,7 @@ static int __rand_va_sweep(struct device *dev, struct seq_file *s,
const size_t size)
{
u64 iova;
- const unsigned long max = SZ_1G * 4UL;
+ const u64 max = SZ_1G * 4ULL - 1;
int i, remapped, unmapped, ret = 0;
void *virt;
dma_addr_t dma_addr, dma_addr2;
@@ -1078,9 +1078,9 @@ static int __rand_va_sweep(struct device *dev, struct seq_file *s,
fib_init(&fib);
for (iova = get_next_fib(&fib) * size;
iova < max - size;
- iova = get_next_fib(&fib) * size) {
- dma_addr = iova;
- dma_addr2 = max - size - iova;
+ iova = (u64)get_next_fib(&fib) * size) {
+ dma_addr = (dma_addr_t)(iova);
+ dma_addr2 = (dma_addr_t)((max + 1) - size - iova);
if (dma_addr == dma_addr2) {
WARN(1,
"%s test needs update! The random number sequence is folding in on itself and should be changed.\n",
@@ -1106,8 +1106,8 @@ static int __rand_va_sweep(struct device *dev, struct seq_file *s,
ret = -EINVAL;
}
- for (dma_addr = 0; dma_addr < max; dma_addr += size)
- dma_unmap_single(dev, dma_addr, size, DMA_TO_DEVICE);
+ for (iova = 0; iova < max; iova += size)
+ dma_unmap_single(dev, (dma_addr_t)iova, size, DMA_TO_DEVICE);
out:
free_pages((unsigned long)virt, get_order(size));
@@ -1135,10 +1135,11 @@ static int __check_mapping(struct device *dev, struct iommu_domain *domain,
static int __full_va_sweep(struct device *dev, struct seq_file *s,
const size_t size, struct iommu_domain *domain)
{
- unsigned long iova;
+ u64 iova;
dma_addr_t dma_addr;
void *virt;
phys_addr_t phys;
+ const u64 max = SZ_1G * 4ULL - 1;
int ret = 0, i;
virt = (void *)__get_free_pages(GFP_KERNEL, get_order(size));
@@ -1153,7 +1154,7 @@ static int __full_va_sweep(struct device *dev, struct seq_file *s,
}
phys = virt_to_phys(virt);
- for (iova = 0, i = 0; iova < SZ_1G * 4UL; iova += size, ++i) {
+ for (iova = 0, i = 0; iova < max; iova += size, ++i) {
unsigned long expected = iova;
dma_addr = dma_map_single(dev, virt, size, DMA_TO_DEVICE);
@@ -1201,8 +1202,8 @@ static int __full_va_sweep(struct device *dev, struct seq_file *s,
}
out:
- for (dma_addr = 0; dma_addr < SZ_1G * 4UL; dma_addr += size)
- dma_unmap_single(dev, dma_addr, size, DMA_TO_DEVICE);
+ for (iova = 0; iova < max; iova += size)
+ dma_unmap_single(dev, (dma_addr_t)iova, size, DMA_TO_DEVICE);
free_pages((unsigned long)virt, get_order(size));
return ret;
@@ -1391,7 +1392,8 @@ static int __apply_to_new_mapping(struct seq_file *s,
int ret = -EINVAL, fast = 1;
phys_addr_t pt_phys;
- mapping = arm_iommu_create_mapping(&platform_bus_type, 0, SZ_1G * 4UL);
+ mapping = arm_iommu_create_mapping(&platform_bus_type, 0,
+ (SZ_1G * 4ULL));
if (!mapping)
goto out;
@@ -1460,7 +1462,9 @@ static int iommu_debug_functional_arm_dma_api_show(struct seq_file *s,
size_t sizes[] = {SZ_4K, SZ_64K, SZ_2M, SZ_1M * 12, 0};
int ret = -EINVAL;
- mapping = arm_iommu_create_mapping(&platform_bus_type, 0, SZ_1G * 4UL);
+ /* Make the size equal to MAX_ULONG */
+ mapping = arm_iommu_create_mapping(&platform_bus_type, 0,
+ (SZ_1G * 4ULL - 1));
if (!mapping)
goto out;
diff --git a/drivers/leds/leds-qpnp-flash-v2.c b/drivers/leds/leds-qpnp-flash-v2.c
index 08809a93d4b2..54d395d5e78d 100644
--- a/drivers/leds/leds-qpnp-flash-v2.c
+++ b/drivers/leds/leds-qpnp-flash-v2.c
@@ -1076,6 +1076,8 @@ static int qpnp_flash_led_switch_set(struct flash_switch_data *snode, bool on)
pr_err("trigger lmh mitigation failed, rc=%d\n", rc);
return rc;
}
+ /* Wait for LMH mitigation to take effect */
+ udelay(500);
}
if (led->trigger_chgr) {
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
index 09de276e8418..df9691be0c28 100644
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
@@ -1746,11 +1746,38 @@ void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev)
static int msm_isp_process_iommu_page_fault(struct vfe_device *vfe_dev)
{
int rc = vfe_dev->buf_mgr->pagefault_debug_disable;
+ uint32_t irq_status0, irq_status1;
+ uint32_t overflow_mask;
+ unsigned long irq_flags;
- pr_err("%s:%d] VFE%d Handle Page fault!\n", __func__,
- __LINE__, vfe_dev->pdev->id);
-
- msm_isp_halt_send_error(vfe_dev, ISP_EVENT_IOMMU_P_FAULT);
+ /* Check if any overflow bit is set */
+ vfe_dev->hw_info->vfe_ops.core_ops.
+ get_overflow_mask(&overflow_mask);
+ vfe_dev->hw_info->vfe_ops.irq_ops.
+ read_irq_status(vfe_dev, &irq_status0, &irq_status1);
+ overflow_mask &= irq_status1;
+ spin_lock_irqsave(
+ &vfe_dev->common_data->common_dev_data_lock, irq_flags);
+ if (overflow_mask ||
+ atomic_read(&vfe_dev->error_info.overflow_state) !=
+ NO_OVERFLOW) {
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock, irq_flags);
+ pr_err_ratelimited("%s: overflow detected during IOMMU\n",
+ __func__);
+ /* Don't treat the Overflow + Page fault scenario as fatal.
+ * Instead try to do a recovery. Using an existing event as
+ * as opposed to creating a new event.
+ */
+ msm_isp_halt_send_error(vfe_dev, ISP_EVENT_PING_PONG_MISMATCH);
+ } else {
+ spin_unlock_irqrestore(
+ &vfe_dev->common_data->common_dev_data_lock, irq_flags);
+ pr_err("%s:%d] VFE%d Handle Page fault! vfe_dev %pK\n",
+ __func__, __LINE__, vfe_dev->pdev->id, vfe_dev);
+ vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 0);
+ msm_isp_halt_send_error(vfe_dev, ISP_EVENT_IOMMU_P_FAULT);
+ }
if (vfe_dev->buf_mgr->pagefault_debug_disable == 0) {
vfe_dev->buf_mgr->pagefault_debug_disable = 1;
@@ -1859,6 +1886,7 @@ int msm_isp_process_overflow_irq(
vfe_dev->recovery_irq1_mask = vfe_dev->irq1_mask;
vfe_dev->hw_info->vfe_ops.core_ops.
set_halt_restart_mask(vfe_dev);
+ vfe_dev->hw_info->vfe_ops.axi_ops.halt(vfe_dev, 0);
/* mask off other vfe if dual vfe is used */
if (vfe_dev->is_split) {
int other_vfe_id;
@@ -1875,6 +1903,7 @@ int msm_isp_process_overflow_irq(
temp_vfe->recovery_irq1_mask = temp_vfe->irq1_mask;
temp_vfe->hw_info->vfe_ops.core_ops.
set_halt_restart_mask(temp_vfe);
+ temp_vfe->hw_info->vfe_ops.axi_ops.halt(temp_vfe, 0);
}
/* reset irq status so skip further process */
@@ -2143,7 +2172,8 @@ static void msm_vfe_iommu_fault_handler(struct iommu_domain *domain,
if (vfe_dev->vfe_open_cnt > 0) {
atomic_set(&vfe_dev->error_info.overflow_state,
HALT_ENFORCED);
- pr_err("%s: fault address is %lx\n", __func__, iova);
+ pr_err_ratelimited("%s: fault address is %lx\n",
+ __func__, iova);
msm_isp_process_iommu_page_fault(vfe_dev);
} else {
pr_err("%s: no handling, vfe open cnt = %d\n",
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 1cf2c54aa8b8..7885149440f9 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
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
@@ -1770,6 +1770,17 @@ static void msm_cpp_do_timeout_work(struct work_struct *work)
goto end;
}
+ for (i = 0; i < queue_len; i++) {
+ processed_frame[i] = cpp_timer.data.processed_frame[i];
+ if (!processed_frame[i]) {
+ pr_warn("process frame null , queue len %d", queue_len);
+ msm_cpp_flush_queue_and_release_buffer(cpp_dev,
+ queue_len);
+ msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8);
+ goto end;
+ }
+ }
+
atomic_set(&cpp_timer.used, 1);
pr_warn("Starting timer to fire in %d ms. (jiffies=%lu)\n",
CPP_CMD_TIMEOUT_MS, jiffies);
@@ -1778,9 +1789,6 @@ static void msm_cpp_do_timeout_work(struct work_struct *work)
msm_cpp_set_micro_irq_mask(cpp_dev, 1, 0x8);
- for (i = 0; i < MAX_CPP_PROCESSING_FRAME; i++)
- processed_frame[i] = cpp_timer.data.processed_frame[i];
-
for (i = 0; i < queue_len; i++) {
pr_warn("Rescheduling for identity=0x%x, frame_id=%03d\n",
processed_frame[i]->identity,
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 39811aa84e8e..cd48f871eb79 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
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2017, 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
@@ -528,6 +528,12 @@ static int32_t msm_actuator_piezo_move_focus(
return -EFAULT;
}
+ if (dest_step_position > a_ctrl->total_steps) {
+ pr_err("Step pos greater than total steps = %d\n",
+ dest_step_position);
+ return -EFAULT;
+ }
+
a_ctrl->i2c_tbl_index = 0;
a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
(num_steps *
diff --git a/drivers/media/platform/msm/vidc/msm_smem.c b/drivers/media/platform/msm/vidc/msm_smem.c
index 44c5c08f074c..c9dfb52861bc 100644
--- a/drivers/media/platform/msm/vidc/msm_smem.c
+++ b/drivers/media/platform/msm/vidc/msm_smem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -75,6 +75,14 @@ static int get_device_address(struct smem_client *smem_client,
goto mem_map_failed;
}
+ /* Check if the dmabuf size matches expected size */
+ if (buf->size < *buffer_size) {
+ rc = -EINVAL;
+ dprintk(VIDC_ERR,
+ "Size mismatch! Dmabuf size: %zu Expected Size: %lu",
+ buf->size, *buffer_size);
+ goto mem_buf_size_mismatch;
+ }
/* Prepare a dma buf for dma on the given device */
attach = dma_buf_attach(buf, cb->dev);
if (IS_ERR_OR_NULL(attach)) {
@@ -143,6 +151,7 @@ mem_map_sg_failed:
dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL);
mem_map_table_failed:
dma_buf_detach(buf, attach);
+mem_buf_size_mismatch:
mem_buf_attach_failed:
dma_buf_put(buf);
mem_map_failed:
@@ -193,12 +202,12 @@ static void put_device_address(struct smem_client *smem_client,
}
}
-static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset,
+static int ion_user_to_kernel(struct smem_client *client, int fd, u32 size,
struct msm_smem *mem, enum hal_buffer buffer_type)
{
struct ion_handle *hndl;
ion_phys_addr_t iova = 0;
- unsigned long buffer_size = 0;
+ unsigned long buffer_size = size;
int rc = 0;
unsigned long align = SZ_4K;
unsigned long ion_flags = 0;
@@ -207,10 +216,11 @@ static int ion_user_to_kernel(struct smem_client *client, int fd, u32 offset,
dprintk(VIDC_DBG, "%s ion handle: %pK\n", __func__, hndl);
if (IS_ERR_OR_NULL(hndl)) {
dprintk(VIDC_ERR, "Failed to get handle: %pK, %d, %d, %pK\n",
- client, fd, offset, hndl);
+ client, fd, size, hndl);
rc = -ENOMEM;
goto fail_import_fd;
}
+
mem->kvaddr = NULL;
rc = ion_handle_get_flags(client->clnt, hndl, &ion_flags);
if (rc) {
@@ -430,7 +440,7 @@ static void ion_delete_client(struct smem_client *client)
ion_client_destroy(client->clnt);
}
-struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
+struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 size,
enum hal_buffer buffer_type)
{
struct smem_client *client = clt;
@@ -447,7 +457,7 @@ struct msm_smem *msm_smem_user_to_kernel(void *clt, int fd, u32 offset,
}
switch (client->mem_type) {
case SMEM_ION:
- rc = ion_user_to_kernel(clt, fd, offset, mem, buffer_type);
+ rc = ion_user_to_kernel(clt, fd, size, mem, buffer_type);
break;
default:
dprintk(VIDC_ERR, "Mem type not supported\n");
diff --git a/drivers/media/platform/msm/vidc/msm_vdec.c b/drivers/media/platform/msm/vidc/msm_vdec.c
index a20252f08f44..b7e2c297a1ad 100644
--- a/drivers/media/platform/msm/vidc/msm_vdec.c
+++ b/drivers/media/platform/msm/vidc/msm_vdec.c
@@ -704,7 +704,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "YCbCr Semiplanar 4:2:0",
.description = "Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12,
- .num_planes = 2,
.get_frame_size = get_frame_size_nv12,
.type = CAPTURE_PORT,
},
@@ -712,7 +711,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "UBWC YCbCr Semiplanar 4:2:0",
.description = "UBWC Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12_UBWC,
- .num_planes = 2,
.get_frame_size = get_frame_size_nv12_ubwc,
.type = CAPTURE_PORT,
},
@@ -720,7 +718,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "UBWC YCbCr Semiplanar 4:2:0 10bit",
.description = "UBWC Y/CbCr 4:2:0 10bit",
.fourcc = V4L2_PIX_FMT_NV12_TP10_UBWC,
- .num_planes = 2,
.get_frame_size = get_frame_size_nv12_ubwc_10bit,
.type = CAPTURE_PORT,
},
@@ -728,7 +725,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "Mpeg4",
.description = "Mpeg4 compressed format",
.fourcc = V4L2_PIX_FMT_MPEG4,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -736,7 +732,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "Mpeg2",
.description = "Mpeg2 compressed format",
.fourcc = V4L2_PIX_FMT_MPEG2,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -744,7 +739,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "H263",
.description = "H263 compressed format",
.fourcc = V4L2_PIX_FMT_H263,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -752,7 +746,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "VC1",
.description = "VC-1 compressed format",
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_G,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -760,7 +753,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "VC1 SP",
.description = "VC-1 compressed format G",
.fourcc = V4L2_PIX_FMT_VC1_ANNEX_L,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -768,7 +760,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "H264",
.description = "H264 compressed format",
.fourcc = V4L2_PIX_FMT_H264,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -776,7 +767,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "H264_MVC",
.description = "H264_MVC compressed format",
.fourcc = V4L2_PIX_FMT_H264_MVC,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -784,7 +774,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "HEVC",
.description = "HEVC compressed format",
.fourcc = V4L2_PIX_FMT_HEVC,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -792,7 +781,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "HEVC_HYBRID",
.description = "HEVC compressed format",
.fourcc = V4L2_PIX_FMT_HEVC_HYBRID,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -800,7 +788,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "VP8",
.description = "VP8 compressed format",
.fourcc = V4L2_PIX_FMT_VP8,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -808,7 +795,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "VP9",
.description = "VP9 compressed format",
.fourcc = V4L2_PIX_FMT_VP9,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed_full_yuv,
.type = OUTPUT_PORT,
},
@@ -816,7 +802,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "DIVX 311",
.description = "DIVX 311 compressed format",
.fourcc = V4L2_PIX_FMT_DIVX_311,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
},
@@ -824,7 +809,6 @@ struct msm_vidc_format vdec_formats[] = {
.name = "DIVX",
.description = "DIVX 4/5/6 compressed format",
.fourcc = V4L2_PIX_FMT_DIVX,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = OUTPUT_PORT,
}
@@ -896,10 +880,10 @@ int msm_vdec_prepare_buf(struct msm_vidc_inst *inst,
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (b->length != inst->fmts[CAPTURE_PORT].num_planes) {
+ if (b->length != inst->prop.num_planes[CAPTURE_PORT]) {
dprintk(VIDC_ERR,
"Planes mismatch: needed: %d, allocated: %d\n",
- inst->fmts[CAPTURE_PORT].num_planes,
+ inst->prop.num_planes[CAPTURE_PORT],
b->length);
rc = -EINVAL;
break;
@@ -975,10 +959,10 @@ int msm_vdec_release_buf(struct msm_vidc_inst *inst,
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (b->length != inst->fmts[CAPTURE_PORT].num_planes) {
+ if (b->length != inst->prop.num_planes[CAPTURE_PORT]) {
dprintk(VIDC_ERR,
"Planes mismatch: needed: %d, to release: %d\n",
- inst->fmts[CAPTURE_PORT].num_planes, b->length);
+ inst->prop.num_planes[CAPTURE_PORT], b->length);
rc = -EINVAL;
break;
}
@@ -1090,6 +1074,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
struct hfi_device *hdev;
int rc = 0, i = 0, stride = 0, scanlines = 0, color_format = 0;
unsigned int *plane_sizes = NULL, extra_idx = 0;
+ int num_planes = 0;
if (!inst || !f || !inst->core || !inst->core->device) {
dprintk(VIDC_ERR,
@@ -1106,7 +1091,9 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
return -ENOTSUPP;
f->fmt.pix_mp.pixelformat = fmt->fourcc;
- f->fmt.pix_mp.num_planes = fmt->num_planes;
+ f->fmt.pix_mp.num_planes = inst->prop.num_planes[fmt->type];
+ num_planes = inst->prop.num_planes[fmt->type];
+
if (inst->in_reconfig) {
inst->prop.height[OUTPUT_PORT] = inst->reconfig_height;
inst->prop.width[OUTPUT_PORT] = inst->reconfig_width;
@@ -1126,7 +1113,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
plane_sizes = &inst->bufq[OUTPUT_PORT].vb2_bufq.plane_sizes[0];
- for (i = 0; i < fmt->num_planes; ++i) {
+ for (i = 0; i < num_planes; ++i) {
if (!plane_sizes[i]) {
f->fmt.pix_mp.plane_fmt[i].sizeimage =
get_frame_size(inst, fmt, f->type, i);
@@ -1169,7 +1156,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->prop.height[CAPTURE_PORT],
inst->prop.width[CAPTURE_PORT]);
- extra_idx = EXTRADATA_IDX(fmt->num_planes);
+ extra_idx = EXTRADATA_IDX(num_planes);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
VENUS_EXTRADATA_SIZE(
@@ -1177,7 +1164,7 @@ int msm_vdec_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->prop.width[CAPTURE_PORT]);
}
- for (i = 0; i < fmt->num_planes; ++i)
+ for (i = 0; i < num_planes; ++i)
inst->bufq[CAPTURE_PORT].vb2_bufq.plane_sizes[i] =
f->fmt.pix_mp.plane_fmt[i].sizeimage;
@@ -1276,7 +1263,7 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->fmts[fmt->type].get_frame_size(0,
f->fmt.pix_mp.height, f->fmt.pix_mp.width);
- extra_idx = EXTRADATA_IDX(inst->fmts[fmt->type].num_planes);
+ extra_idx = EXTRADATA_IDX(inst->prop.num_planes[fmt->type]);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
VENUS_EXTRADATA_SIZE(
@@ -1284,8 +1271,8 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
inst->prop.width[CAPTURE_PORT]);
}
- f->fmt.pix_mp.num_planes = inst->fmts[fmt->type].num_planes;
- for (i = 0; i < inst->fmts[fmt->type].num_planes; ++i) {
+ f->fmt.pix_mp.num_planes = inst->prop.num_planes[fmt->type];
+ for (i = 0; i < inst->prop.num_planes[fmt->type]; ++i) {
inst->bufq[CAPTURE_PORT].vb2_bufq.plane_sizes[i] =
f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
@@ -1346,14 +1333,14 @@ int msm_vdec_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
msm_comm_try_set_prop(inst, HAL_PARAM_FRAME_SIZE, &frame_sz);
max_input_size = get_frame_size(
-inst, &inst->fmts[fmt->type], f->type, 0);
+ inst, &inst->fmts[fmt->type], f->type, 0);
if (f->fmt.pix_mp.plane_fmt[0].sizeimage > max_input_size ||
!f->fmt.pix_mp.plane_fmt[0].sizeimage) {
f->fmt.pix_mp.plane_fmt[0].sizeimage = max_input_size;
}
- f->fmt.pix_mp.num_planes = inst->fmts[fmt->type].num_planes;
- for (i = 0; i < inst->fmts[fmt->type].num_planes; ++i) {
+ f->fmt.pix_mp.num_planes = inst->prop.num_planes[fmt->type];
+ for (i = 0; i < inst->prop.num_planes[fmt->type]; ++i) {
inst->bufq[OUTPUT_PORT].vb2_bufq.plane_sizes[i] =
f->fmt.pix_mp.plane_fmt[i].sizeimage;
}
@@ -1467,7 +1454,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- *num_planes = inst->fmts[OUTPUT_PORT].num_planes;
+ *num_planes = inst->prop.num_planes[OUTPUT_PORT];
if (*num_buffers < MIN_NUM_OUTPUT_BUFFERS ||
*num_buffers > MAX_NUM_OUTPUT_BUFFERS)
*num_buffers = MIN_NUM_OUTPUT_BUFFERS;
@@ -1480,7 +1467,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
dprintk(VIDC_DBG, "Getting bufreqs on capture plane\n");
- *num_planes = inst->fmts[CAPTURE_PORT].num_planes;
+ *num_planes = inst->prop.num_planes[CAPTURE_PORT];
rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
if (rc) {
dprintk(VIDC_ERR, "Failed to open instance\n");
@@ -1564,8 +1551,7 @@ static int msm_vdec_queue_setup(struct vb2_queue *q,
break;
}
- extra_idx =
- EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
+ extra_idx = EXTRADATA_IDX(*num_planes);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
sizes[extra_idx] =
VENUS_EXTRADATA_SIZE(
@@ -1944,8 +1930,14 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
}
inst->prop.height[CAPTURE_PORT] = DEFAULT_HEIGHT;
inst->prop.width[CAPTURE_PORT] = DEFAULT_WIDTH;
+ inst->prop.num_planes[CAPTURE_PORT] = 2;
+ inst->fmts[CAPTURE_PORT] = vdec_formats[0];
+
inst->prop.height[OUTPUT_PORT] = DEFAULT_HEIGHT;
inst->prop.width[OUTPUT_PORT] = DEFAULT_WIDTH;
+ inst->prop.num_planes[OUTPUT_PORT] = 1;
+ inst->fmts[OUTPUT_PORT] = vdec_formats[2];
+
inst->capability.height.min = MIN_SUPPORTED_HEIGHT;
inst->capability.height.max = DEFAULT_HEIGHT;
inst->capability.width.min = MIN_SUPPORTED_WIDTH;
@@ -1958,10 +1950,6 @@ int msm_vdec_inst_init(struct msm_vidc_inst *inst)
inst->buffer_mode_set[CAPTURE_PORT] = HAL_BUFFER_MODE_STATIC;
inst->prop.fps = DEFAULT_FPS;
inst->operating_rate = 0;
- memcpy(&inst->fmts[OUTPUT_PORT], &vdec_formats[2],
- sizeof(struct msm_vidc_format));
- memcpy(&inst->fmts[CAPTURE_PORT], &vdec_formats[0],
- sizeof(struct msm_vidc_format));
return rc;
}
diff --git a/drivers/media/platform/msm/vidc/msm_venc.c b/drivers/media/platform/msm/vidc/msm_venc.c
index c909511db251..ce6736509d61 100644
--- a/drivers/media/platform/msm/vidc/msm_venc.c
+++ b/drivers/media/platform/msm/vidc/msm_venc.c
@@ -1343,7 +1343,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "YCbCr Semiplanar 4:2:0",
.description = "Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12,
- .num_planes = 1,
.get_frame_size = get_frame_size_nv12,
.type = OUTPUT_PORT,
},
@@ -1351,7 +1350,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "UBWC YCbCr Semiplanar 4:2:0",
.description = "UBWC Y/CbCr 4:2:0",
.fourcc = V4L2_PIX_FMT_NV12_UBWC,
- .num_planes = 1,
.get_frame_size = get_frame_size_nv12_ubwc,
.type = OUTPUT_PORT,
},
@@ -1359,7 +1357,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "RGBA 8:8:8:8",
.description = "RGBA 8:8:8:8",
.fourcc = V4L2_PIX_FMT_RGB32,
- .num_planes = 1,
.get_frame_size = get_frame_size_rgba,
.type = OUTPUT_PORT,
},
@@ -1367,7 +1364,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "UBWC RGBA 8:8:8:8",
.description = "UBWC RGBA 8:8:8:8",
.fourcc = V4L2_PIX_FMT_RGBA8888_UBWC,
- .num_planes = 1,
.get_frame_size = get_frame_size_rgba_ubwc,
.type = OUTPUT_PORT,
},
@@ -1375,7 +1371,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "Mpeg4",
.description = "Mpeg4 compressed format",
.fourcc = V4L2_PIX_FMT_MPEG4,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1383,7 +1378,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "H263",
.description = "H263 compressed format",
.fourcc = V4L2_PIX_FMT_H263,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1391,7 +1385,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "H264",
.description = "H264 compressed format",
.fourcc = V4L2_PIX_FMT_H264,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1399,7 +1392,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "VP8",
.description = "VP8 compressed format",
.fourcc = V4L2_PIX_FMT_VP8,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1407,7 +1399,6 @@ static struct msm_vidc_format venc_formats[] = {
.name = "HEVC",
.description = "HEVC compressed format",
.fourcc = V4L2_PIX_FMT_HEVC,
- .num_planes = 1,
.get_frame_size = get_frame_size_compressed,
.type = CAPTURE_PORT,
},
@@ -1415,57 +1406,71 @@ static struct msm_vidc_format venc_formats[] = {
.name = "YCrCb Semiplanar 4:2:0",
.description = "Y/CrCb 4:2:0",
.fourcc = V4L2_PIX_FMT_NV21,
- .num_planes = 1,
.get_frame_size = get_frame_size_nv21,
.type = OUTPUT_PORT,
},
};
-static void msm_venc_update_plane_count(struct msm_vidc_inst *inst, int type)
+static int msm_venc_set_csc(struct msm_vidc_inst *inst)
{
- struct v4l2_ctrl *ctrl = NULL;
- u32 extradata = 0;
+ int rc = 0;
+ int count = 0;
+ struct hal_vpe_color_space_conversion vpe_csc;
- if (!inst)
- return;
+ while (count < HAL_MAX_MATRIX_COEFFS) {
+ if (count < HAL_MAX_BIAS_COEFFS)
+ vpe_csc.csc_bias[count] =
+ vpe_csc_601_to_709_bias_coeff[count];
+ if (count < HAL_MAX_LIMIT_COEFFS)
+ vpe_csc.csc_limit[count] =
+ vpe_csc_601_to_709_limit_coeff[count];
+ vpe_csc.csc_matrix[count] =
+ vpe_csc_601_to_709_matrix_coeff[count];
+ count = count + 1;
+ }
+ rc = msm_comm_try_set_prop(inst,
+ HAL_PARAM_VPE_COLOR_SPACE_CONVERSION, &vpe_csc);
+ if (rc)
+ dprintk(VIDC_ERR, "Setting VPE coefficients failed\n");
- inst->fmts[type].num_planes = 1;
+ return rc;
+}
- ctrl = v4l2_ctrl_find(&inst->ctrl_handler,
- V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA);
+static void msm_venc_register_extradata(
+ struct msm_vidc_inst *inst, u32 extradata) {
+ struct session_prop *prop = NULL;
- if (ctrl)
- extradata = v4l2_ctrl_g_ctrl(ctrl);
+ if (!inst)
+ return;
- if (type == CAPTURE_PORT) {
- switch (extradata) {
+ prop = &inst->prop;
+ switch (extradata) {
case V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO:
case V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB:
case V4L2_MPEG_VIDC_EXTRADATA_METADATA_FILLER:
case V4L2_MPEG_VIDC_EXTRADATA_LTR:
case V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI:
- inst->fmts[CAPTURE_PORT].num_planes = 2;
- default:
+ prop->extradata[CAPTURE_PORT] |= extradata;
+ prop->num_planes[CAPTURE_PORT] = 2;
+ dprintk(VIDC_DBG, "Output Extradata: %#x",
+ prop->extradata[CAPTURE_PORT]);
break;
- }
- } else if (type == OUTPUT_PORT) {
- switch (extradata) {
case V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP:
case V4L2_MPEG_VIDC_EXTRADATA_DIGITAL_ZOOM:
case V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO:
case V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS:
case V4L2_MPEG_VIDC_EXTRADATA_ROI_QP:
case V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO:
- inst->fmts[OUTPUT_PORT].num_planes = 2;
+ prop->extradata[OUTPUT_PORT] |= extradata;
+ prop->num_planes[OUTPUT_PORT] = 2;
+ dprintk(VIDC_DBG, "Input Extradata: %#x",
+ prop->extradata[OUTPUT_PORT]);
break;
default:
- break;
- }
+ dprintk(VIDC_ERR, "Unknown extradata: %d", extradata);
}
}
-static int msm_venc_set_csc(struct msm_vidc_inst *inst);
-
static int msm_venc_queue_setup(struct vb2_queue *q,
const void *parg,
unsigned int *num_buffers,
@@ -1508,7 +1513,7 @@ static int msm_venc_queue_setup(struct vb2_queue *q,
switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- *num_planes = 1;
+ *num_planes = inst->prop.num_planes[CAPTURE_PORT];
buff_req = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
if (buff_req) {
@@ -1534,9 +1539,6 @@ static int msm_venc_queue_setup(struct vb2_queue *q,
temp, *num_buffers);
}
- msm_venc_update_plane_count(inst, CAPTURE_PORT);
- *num_planes = inst->fmts[CAPTURE_PORT].num_planes;
-
for (i = 0; i < *num_planes; i++) {
int extra_idx = EXTRADATA_IDX(*num_planes);
@@ -1571,7 +1573,7 @@ static int msm_venc_queue_setup(struct vb2_queue *q,
break;
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
- *num_planes = 1;
+ *num_planes = inst->prop.num_planes[OUTPUT_PORT];
*num_buffers = inst->buff_req.buffer[0].buffer_count_actual =
max(*num_buffers, inst->buff_req.buffer[0].
@@ -1593,9 +1595,6 @@ static int msm_venc_queue_setup(struct vb2_queue *q,
dprintk(VIDC_DBG, "actual input buffer count set to fw = %d\n",
*num_buffers);
- msm_venc_update_plane_count(inst, OUTPUT_PORT);
- *num_planes = inst->fmts[OUTPUT_PORT].num_planes;
-
rc = call_hfi_op(hdev, session_set_property, inst->session,
property_id, &new_buf_count);
if (rc)
@@ -1610,7 +1609,7 @@ static int msm_venc_queue_setup(struct vb2_queue *q,
inst->prop.width[OUTPUT_PORT]);
extra_idx =
- EXTRADATA_IDX(inst->fmts[OUTPUT_PORT].num_planes);
+ EXTRADATA_IDX(*num_planes);
if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
buff_req_buffer = get_buff_req_buffer(inst,
HAL_BUFFER_EXTRADATA_INPUT);
@@ -2992,6 +2991,7 @@ static int try_set_ctrl(struct msm_vidc_inst *inst, struct v4l2_ctrl *ctrl)
!!(inst->flags & VIDC_SECURE));
break;
case V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA:
+ msm_venc_register_extradata(inst, (u32)ctrl->val);
property_id = HAL_PARAM_INDEX_EXTRADATA;
extra.index = msm_comm_get_hal_extradata_index(ctrl->val);
extra.enable = 1;
@@ -3633,8 +3633,14 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
}
inst->prop.height[CAPTURE_PORT] = DEFAULT_HEIGHT;
inst->prop.width[CAPTURE_PORT] = DEFAULT_WIDTH;
+ inst->prop.num_planes[CAPTURE_PORT] = 1;
+ inst->fmts[CAPTURE_PORT] = venc_formats[4];
+
inst->prop.height[OUTPUT_PORT] = DEFAULT_HEIGHT;
inst->prop.width[OUTPUT_PORT] = DEFAULT_WIDTH;
+ inst->prop.num_planes[OUTPUT_PORT] = 1;
+ inst->fmts[OUTPUT_PORT] = venc_formats[0];
+
inst->capability.height.min = MIN_SUPPORTED_HEIGHT;
inst->capability.height.max = DEFAULT_HEIGHT;
inst->capability.width.min = MIN_SUPPORTED_WIDTH;
@@ -3648,10 +3654,6 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
inst->prop.fps = DEFAULT_FPS;
inst->capability.pixelprocess_capabilities = 0;
inst->operating_rate = 0;
- memcpy(&inst->fmts[CAPTURE_PORT], &venc_formats[4],
- sizeof(struct msm_vidc_format));
- memcpy(&inst->fmts[OUTPUT_PORT], &venc_formats[0],
- sizeof(struct msm_vidc_format));
return rc;
}
@@ -3720,37 +3722,13 @@ int msm_venc_enum_fmt(struct msm_vidc_inst *inst, struct v4l2_fmtdesc *f)
return rc;
}
-static int msm_venc_set_csc(struct msm_vidc_inst *inst)
-{
- int rc = 0;
- int count = 0;
- struct hal_vpe_color_space_conversion vpe_csc;
-
- while (count < HAL_MAX_MATRIX_COEFFS) {
- if (count < HAL_MAX_BIAS_COEFFS)
- vpe_csc.csc_bias[count] =
- vpe_csc_601_to_709_bias_coeff[count];
- if (count < HAL_MAX_LIMIT_COEFFS)
- vpe_csc.csc_limit[count] =
- vpe_csc_601_to_709_limit_coeff[count];
- vpe_csc.csc_matrix[count] =
- vpe_csc_601_to_709_matrix_coeff[count];
- count = count + 1;
- }
- rc = msm_comm_try_set_prop(inst,
- HAL_PARAM_VPE_COLOR_SPACE_CONVERSION, &vpe_csc);
- if (rc)
- dprintk(VIDC_ERR, "Setting VPE coefficients failed\n");
-
- return rc;
-}
-
int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
{
struct msm_vidc_format *fmt = NULL;
int rc = 0;
- int i;
+ int extra_idx = 0;
struct hfi_device *hdev;
+
if (!inst || !f) {
dprintk(VIDC_ERR,
"Invalid input, inst = %pK, format = %pK\n", inst, f);
@@ -3777,9 +3755,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
-
- msm_venc_update_plane_count(inst, CAPTURE_PORT);
- fmt->num_planes = inst->fmts[CAPTURE_PORT].num_planes;
+ f->fmt.pix_mp.num_planes = inst->prop.num_planes[CAPTURE_PORT];
rc = msm_comm_try_state(inst, MSM_VIDC_OPEN_DONE);
if (rc) {
@@ -3833,10 +3809,7 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
}
memcpy(&inst->fmts[fmt->type], fmt,
sizeof(struct msm_vidc_format));
-
- msm_venc_update_plane_count(inst, OUTPUT_PORT);
- fmt->num_planes = inst->fmts[OUTPUT_PORT].num_planes;
-
+ f->fmt.pix_mp.num_planes = inst->prop.num_planes[OUTPUT_PORT];
msm_comm_set_color_format(inst, HAL_BUFFER_INPUT, fmt->fourcc);
} else {
dprintk(VIDC_ERR, "%s - Unsupported buf type: %d\n",
@@ -3845,8 +3818,6 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
goto exit;
}
- f->fmt.pix_mp.num_planes = fmt->num_planes;
-
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
struct hal_frame_size frame_sz = {0};
struct hal_buffer_requirements *bufreq = NULL;
@@ -3872,16 +3843,23 @@ int msm_venc_s_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
bufreq = get_buff_req_buffer(inst, HAL_BUFFER_OUTPUT);
f->fmt.pix_mp.plane_fmt[0].sizeimage =
bufreq ? bufreq->buffer_size : 0;
+
+ extra_idx = EXTRADATA_IDX(inst->prop.num_planes[fmt->type]);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ bufreq = get_buff_req_buffer(inst,
+ HAL_BUFFER_EXTRADATA_OUTPUT);
+ f->fmt.pix_mp.plane_fmt[extra_idx].sizeimage =
+ bufreq ? bufreq->buffer_size : 0;
+ }
+
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
struct hal_buffer_requirements *bufreq = NULL;
- int extra_idx = 0;
- for (i = 0; i < inst->fmts[fmt->type].num_planes; ++i) {
- f->fmt.pix_mp.plane_fmt[i].sizeimage =
- inst->fmts[fmt->type].get_frame_size(i,
- f->fmt.pix_mp.height, f->fmt.pix_mp.width);
- }
- extra_idx = EXTRADATA_IDX(inst->fmts[fmt->type].num_planes);
+ f->fmt.pix_mp.plane_fmt[0].sizeimage =
+ inst->fmts[fmt->type].get_frame_size(0,
+ f->fmt.pix_mp.height, f->fmt.pix_mp.width);
+
+ extra_idx = EXTRADATA_IDX(inst->prop.num_planes[fmt->type]);
if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
bufreq = get_buff_req_buffer(inst,
HAL_BUFFER_EXTRADATA_INPUT);
@@ -3919,14 +3897,12 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
fmt = &inst->fmts[CAPTURE_PORT];
height = inst->prop.height[CAPTURE_PORT];
width = inst->prop.width[CAPTURE_PORT];
- msm_venc_update_plane_count(inst, CAPTURE_PORT);
- num_planes = inst->fmts[CAPTURE_PORT].num_planes;
+ num_planes = inst->prop.num_planes[CAPTURE_PORT];
} else if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
fmt = &inst->fmts[OUTPUT_PORT];
height = inst->prop.height[OUTPUT_PORT];
width = inst->prop.width[OUTPUT_PORT];
- msm_venc_update_plane_count(inst, OUTPUT_PORT);
- num_planes = inst->fmts[OUTPUT_PORT].num_planes;
+ num_planes = inst->prop.num_planes[OUTPUT_PORT];
} else {
dprintk(VIDC_ERR, "Invalid type: %x\n", f->type);
return -ENOTSUPP;
@@ -4027,10 +4003,10 @@ int msm_venc_prepare_buf(struct msm_vidc_inst *inst,
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
- if (b->length != inst->fmts[CAPTURE_PORT].num_planes) {
+ if (b->length != inst->prop.num_planes[CAPTURE_PORT]) {
dprintk(VIDC_ERR,
"Planes mismatch: needed: %d, allocated: %d\n",
- inst->fmts[CAPTURE_PORT].num_planes,
+ inst->prop.num_planes[CAPTURE_PORT],
b->length);
rc = -EINVAL;
break;
@@ -4098,10 +4074,10 @@ int msm_venc_release_buf(struct msm_vidc_inst *inst,
break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: {
if (b->length !=
- inst->fmts[CAPTURE_PORT].num_planes) {
+ inst->prop.num_planes[CAPTURE_PORT]) {
dprintk(VIDC_ERR,
"Planes mismatch: needed: %d, to release: %d\n",
- inst->fmts[CAPTURE_PORT].num_planes,
+ inst->prop.num_planes[CAPTURE_PORT],
b->length);
rc = -EINVAL;
break;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc.c b/drivers/media/platform/msm/vidc/msm_vidc.c
index 662dcf7c8303..ec3246ed9d67 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc.c
@@ -364,7 +364,7 @@ static struct msm_smem *map_buffer(struct msm_vidc_inst *inst,
struct msm_smem *handle = NULL;
handle = msm_comm_smem_user_to_kernel(inst,
p->reserved[0],
- p->reserved[1],
+ p->length,
buffer_type);
if (!handle) {
dprintk(VIDC_ERR,
@@ -433,8 +433,10 @@ int map_and_register_buf(struct msm_vidc_inst *inst, struct v4l2_buffer *b)
goto exit;
}
- dprintk(VIDC_DBG, "[MAP] Create binfo = %pK fd = %d type = %d\n",
- binfo, b->m.planes[0].reserved[0], b->type);
+ dprintk(VIDC_DBG,
+ "[MAP] Create binfo = %pK fd = %d size = %d type = %d\n",
+ binfo, b->m.planes[0].reserved[0],
+ b->m.planes[0].length, b->type);
for (i = 0; i < b->length; ++i) {
rc = 0;
@@ -686,7 +688,7 @@ static bool valid_v4l2_buffer(struct v4l2_buffer *b,
MAX_PORT_NUM;
return port != MAX_PORT_NUM &&
- inst->fmts[port].num_planes == b->length;
+ inst->prop.num_planes[port] == b->length;
}
int msm_vidc_prepare_buf(void *instance, struct v4l2_buffer *b)
@@ -1317,9 +1319,6 @@ static void cleanup_instance(struct msm_vidc_inst *inst)
"Failed to release output buffers\n");
}
- if (inst->extradata_handle)
- msm_comm_smem_free(inst, inst->extradata_handle);
-
debugfs_remove_recursive(inst->debugfs_root);
mutex_lock(&inst->pending_getpropq.lock);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 50ea4a200dfa..1365bec268cf 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -898,12 +898,12 @@ static int wait_for_sess_signal_receipt(struct msm_vidc_inst *inst,
if (!rc) {
dprintk(VIDC_ERR, "Wait interrupted or timed out: %d\n",
SESSION_MSG_INDEX(cmd));
- msm_comm_kill_session(inst);
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dprintk(VIDC_ERR,
"sess resp timeout can potentially crash the system\n");
msm_comm_print_debug_info(inst);
BUG_ON(inst->core->resources.debug_timeout);
+ msm_comm_kill_session(inst);
rc = -EIO;
} else {
rc = 0;
@@ -1217,7 +1217,8 @@ static void handle_event_change(enum hal_command_response cmd, void *data)
"V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT due to bit-depth change\n");
}
- if (inst->pic_struct != event_notify->pic_struct) {
+ if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_NV12 &&
+ inst->pic_struct != event_notify->pic_struct) {
inst->pic_struct = event_notify->pic_struct;
event = V4L2_EVENT_SEQ_CHANGED_INSUFFICIENT;
ptr[2] |= V4L2_EVENT_PICSTRUCT_FLAG;
@@ -1693,19 +1694,11 @@ static void handle_sys_error(enum hal_command_response cmd, void *data)
dprintk(VIDC_ERR,
"SYS_ERROR can potentially crash the system\n");
- /*
- * For SYS_ERROR, there will not be any inst pointer.
- * Just grab one of the inst from instances list and
- * use it.
- */
-
mutex_lock(&core->lock);
- inst = list_first_entry_or_null(&core->instances,
- struct msm_vidc_inst, list);
+ list_for_each_entry(inst, &core->instances, list)
+ msm_comm_print_inst_info(inst);
mutex_unlock(&core->lock);
- msm_comm_print_debug_info(inst);
-
BUG_ON(core->resources.debug_timeout);
}
@@ -2079,7 +2072,7 @@ static void handle_fbd(enum hal_command_response cmd, void *data)
ns_to_timeval(time_usec * NSEC_PER_USEC);
vbuf->flags = 0;
extra_idx =
- EXTRADATA_IDX(inst->fmts[CAPTURE_PORT].num_planes);
+ EXTRADATA_IDX(inst->prop.num_planes[CAPTURE_PORT]);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES) {
vb->planes[extra_idx].m.userptr =
(unsigned long)fill_buf_done->extra_data_buffer;
@@ -3639,7 +3632,7 @@ static void populate_frame_data(struct vidc_frame_data *data,
data->buffer_type = msm_comm_get_hal_output_buffer(inst);
}
- extra_idx = EXTRADATA_IDX(inst->fmts[port].num_planes);
+ extra_idx = EXTRADATA_IDX(inst->prop.num_planes[port]);
if (extra_idx && extra_idx < VIDEO_MAX_PLANES &&
vb->planes[extra_idx].m.userptr) {
data->extradata_addr = vb->planes[extra_idx].m.userptr;
@@ -4065,7 +4058,6 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
__func__, inst,
SESSION_MSG_INDEX(HAL_SESSION_PROPERTY_INFO));
inst->state = MSM_VIDC_CORE_INVALID;
- msm_comm_kill_session(inst);
call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data);
dprintk(VIDC_ERR,
"SESS_PROP timeout can potentially crash the system\n");
@@ -4073,6 +4065,7 @@ int msm_comm_try_get_prop(struct msm_vidc_inst *inst, enum hal_property ptype,
msm_comm_print_debug_info(inst);
BUG_ON(inst->core->resources.debug_timeout);
+ msm_comm_kill_session(inst);
rc = -ETIMEDOUT;
goto exit;
} else {
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_debug.c b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
index 2e1df75cb248..1248a1c08103 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_debug.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_debug.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -290,7 +290,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
write_str(&dbg_buf, "capability: %s\n", i == OUTPUT_PORT ?
"Output" : "Capture");
write_str(&dbg_buf, "name : %s\n", inst->fmts[i].name);
- write_str(&dbg_buf, "planes : %d\n", inst->fmts[i].num_planes);
+ write_str(&dbg_buf, "planes : %d\n", inst->prop.num_planes[i]);
write_str(
&dbg_buf, "type: %s\n", inst->fmts[i].type == OUTPUT_PORT ?
"Output" : "Capture");
@@ -311,7 +311,7 @@ static ssize_t inst_info_read(struct file *file, char __user *buf,
write_str(&dbg_buf, "count: %u\n",
inst->bufq[i].vb2_bufq.num_buffers);
- for (j = 0; j < inst->fmts[i].num_planes; j++)
+ for (j = 0; j < inst->prop.num_planes[i]; j++)
write_str(&dbg_buf, "size for plane %d: %u\n", j,
inst->bufq[i].vb2_bufq.plane_sizes[j]);
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_internal.h b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
index 3ad85f53a8b0..690a61f4824f 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_internal.h
+++ b/drivers/media/platform/msm/vidc/msm_vidc_internal.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -143,7 +143,6 @@ struct msm_vidc_format {
char name[MAX_NAME_LENGTH];
u8 description[32];
u32 fourcc;
- int num_planes;
int type;
u32 (*get_frame_size)(int plane, u32 height, u32 width);
};
@@ -165,6 +164,8 @@ struct msm_video_device {
struct session_prop {
u32 width[MAX_PORT_NUM];
u32 height[MAX_PORT_NUM];
+ u32 num_planes[MAX_PORT_NUM];
+ u32 extradata[MAX_PORT_NUM];
u32 fps;
u32 bitrate;
};
@@ -276,7 +277,6 @@ struct msm_vidc_inst {
struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1];
struct v4l2_ctrl **cluster;
struct v4l2_fh event_handler;
- struct msm_smem *extradata_handle;
bool in_reconfig;
u32 reconfig_width;
u32 reconfig_height;
diff --git a/drivers/net/wireless/ath/ath10k/snoc.c b/drivers/net/wireless/ath/ath10k/snoc.c
index 487c243e18ec..4fd8e260d80e 100644
--- a/drivers/net/wireless/ath/ath10k/snoc.c
+++ b/drivers/net/wireless/ath/ath10k/snoc.c
@@ -1365,6 +1365,10 @@ static int __init ath10k_snoc_init(void)
{
int ret;
+ if (!icnss_is_fw_ready()) {
+ pr_err("failed to get fw ready indication\n");
+ return -EAGAIN;
+ }
ret = platform_driver_register(&ath10k_snoc_driver);
if (ret)
pr_err("failed to register ath10k snoc driver: %d\n",
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 0a3928a8fe90..ca06394c48bb 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -21,6 +21,10 @@
#define WIL_MAX_ROC_DURATION_MS 5000
+bool disable_ap_sme;
+module_param(disable_ap_sme, bool, S_IRUGO);
+MODULE_PARM_DESC(disable_ap_sme, " let user space handle AP mode SME");
+
#define CHAN60G(_channel, _flags) { \
.band = IEEE80211_BAND_60GHZ, \
.center_freq = 56160 + (2160 * (_channel)), \
@@ -147,9 +151,16 @@ wil_mgmt_stypes[NUM_NL80211_IFTYPES] = {
},
[NL80211_IFTYPE_AP] = {
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
+ BIT(IEEE80211_STYPE_PROBE_RESP >> 4) |
+ BIT(IEEE80211_STYPE_ASSOC_RESP >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4),
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
- BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
+ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
+ BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
+ BIT(IEEE80211_STYPE_DISASSOC >> 4) |
+ BIT(IEEE80211_STYPE_AUTH >> 4) |
+ BIT(IEEE80211_STYPE_DEAUTH >> 4) |
+ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4)
},
[NL80211_IFTYPE_P2P_CLIENT] = {
.tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
@@ -1411,6 +1422,28 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
return 0;
}
+static int wil_cfg80211_add_station(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 *mac,
+ struct station_parameters *params)
+{
+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+
+ wil_dbg_misc(wil, "add station %pM aid %d\n", mac, params->aid);
+
+ if (!disable_ap_sme) {
+ wil_err(wil, "not supported with AP SME enabled\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (params->aid > WIL_MAX_DMG_AID) {
+ wil_err(wil, "invalid aid\n");
+ return -EINVAL;
+ }
+
+ return wmi_new_sta(wil, mac, params->aid);
+}
+
static int wil_cfg80211_del_station(struct wiphy *wiphy,
struct net_device *dev,
struct station_del_parameters *params)
@@ -1427,6 +1460,52 @@ static int wil_cfg80211_del_station(struct wiphy *wiphy,
return 0;
}
+static int wil_cfg80211_change_station(struct wiphy *wiphy,
+ struct net_device *dev,
+ const u8 *mac,
+ struct station_parameters *params)
+{
+ struct wil6210_priv *wil = wiphy_to_wil(wiphy);
+ int authorize;
+ int cid, i;
+ struct vring_tx_data *txdata = NULL;
+
+ wil_dbg_misc(wil, "change station %pM mask 0x%x set 0x%x\n", mac,
+ params->sta_flags_mask, params->sta_flags_set);
+
+ if (!disable_ap_sme) {
+ wil_dbg_misc(wil, "not supported with AP SME enabled\n");
+ return -EOPNOTSUPP;
+ }
+
+ if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
+ return 0;
+
+ cid = wil_find_cid(wil, mac);
+ if (cid < 0) {
+ wil_err(wil, "station not found\n");
+ return -ENOLINK;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++)
+ if (wil->vring2cid_tid[i][0] == cid) {
+ txdata = &wil->vring_tx_data[i];
+ break;
+ }
+
+ if (!txdata) {
+ wil_err(wil, "vring data not found\n");
+ return -ENOLINK;
+ }
+
+ authorize = params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED);
+ txdata->dot1x_open = authorize ? 1 : 0;
+ wil_dbg_misc(wil, "cid %d vring %d authorize %d\n", cid, i,
+ txdata->dot1x_open);
+
+ return 0;
+}
+
/* probe_client handling */
static void wil_probe_client_handle(struct wil6210_priv *wil,
struct wil_probe_client_req *req)
@@ -1610,7 +1689,9 @@ static struct cfg80211_ops wil_cfg80211_ops = {
.change_beacon = wil_cfg80211_change_beacon,
.start_ap = wil_cfg80211_start_ap,
.stop_ap = wil_cfg80211_stop_ap,
+ .add_station = wil_cfg80211_add_station,
.del_station = wil_cfg80211_del_station,
+ .change_station = wil_cfg80211_change_station,
.probe_client = wil_cfg80211_probe_client,
.change_bss = wil_cfg80211_change_bss,
/* P2P device */
@@ -1631,10 +1712,11 @@ static void wil_wiphy_init(struct wiphy *wiphy)
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_DEVICE) |
BIT(NL80211_IFTYPE_MONITOR);
- wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
- WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
+ wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
WIPHY_FLAG_PS_ON_BY_DEFAULT;
+ if (!disable_ap_sme)
+ wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
__func__, wiphy->flags);
wiphy->probe_resp_offload =
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index d3e420f1b26b..865bb11e2a07 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -1705,6 +1705,7 @@ static const struct dbg_off dbg_wil_off[] = {
WIL_FIELD(recovery_count, S_IRUGO, doff_u32),
WIL_FIELD(ap_isolate, S_IRUGO, doff_u32),
WIL_FIELD(discovery_mode, S_IRUGO | S_IWUSR, doff_u8),
+ WIL_FIELD(chip_revision, S_IRUGO, doff_u8),
{},
};
diff --git a/drivers/net/wireless/ath/wil6210/fw.c b/drivers/net/wireless/ath/wil6210/fw.c
index 82aae2d705b4..540fc20984d8 100644
--- a/drivers/net/wireless/ath/wil6210/fw.c
+++ b/drivers/net/wireless/ath/wil6210/fw.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014-2015,2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,8 +19,9 @@
#include "wil6210.h"
#include "fw.h"
-MODULE_FIRMWARE(WIL_FW_NAME);
-MODULE_FIRMWARE(WIL_FW2_NAME);
+MODULE_FIRMWARE(WIL_FW_NAME_DEFAULT);
+MODULE_FIRMWARE(WIL_FW_NAME_SPARROW_PLUS);
+MODULE_FIRMWARE(WIL_BOARD_FILE_NAME);
static
void wil_memset_toio_32(volatile void __iomem *dst, u32 val,
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
index 8f40eb301924..f4901587c005 100644
--- a/drivers/net/wireless/ath/wil6210/fw_inc.c
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2014-2017 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -537,3 +537,22 @@ out:
release_firmware(fw);
return rc;
}
+
+/**
+ * wil_fw_verify_file_exists - checks if firmware file exist
+ *
+ * @wil: driver context
+ * @name: firmware file name
+ *
+ * return value - boolean, true for success, false for failure
+ */
+bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name)
+{
+ const struct firmware *fw;
+ int rc;
+
+ rc = request_firmware(&fw, name, wil_to_dev(wil));
+ if (!rc)
+ release_firmware(fw);
+ return rc != -ENOENT;
+}
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index eb1fd9dd09ba..32e217e7159e 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -176,8 +176,12 @@ __acquires(&sta->tid_rx_lock) __releases(&sta->tid_rx_lock)
sta->status);
/* inform upper/lower layers */
if (sta->status != wil_sta_unused) {
- if (!from_event)
- wmi_disconnect_sta(wil, sta->addr, reason_code, true);
+ if (!from_event) {
+ bool del_sta = (wdev->iftype == NL80211_IFTYPE_AP) ?
+ disable_ap_sme : false;
+ wmi_disconnect_sta(wil, sta->addr, reason_code,
+ true, del_sta);
+ }
switch (wdev->iftype) {
case NL80211_IFTYPE_AP:
@@ -943,16 +947,16 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
wil_set_oob_mode(wil, oob_mode);
if (load_fw) {
- wil_info(wil, "Use firmware <%s> + board <%s>\n", WIL_FW_NAME,
- WIL_FW2_NAME);
+ wil_info(wil, "Use firmware <%s> + board <%s>\n",
+ wil->wil_fw_name, WIL_BOARD_FILE_NAME);
wil_halt_cpu(wil);
memset(wil->fw_version, 0, sizeof(wil->fw_version));
/* Loading f/w from the file */
- rc = wil_request_firmware(wil, WIL_FW_NAME, true);
+ rc = wil_request_firmware(wil, wil->wil_fw_name, true);
if (rc)
return rc;
- rc = wil_request_firmware(wil, WIL_FW2_NAME, true);
+ rc = wil_request_firmware(wil, WIL_BOARD_FILE_NAME, true);
if (rc)
return rc;
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index fdbc51ae1e1a..c97263b45cbd 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -36,18 +36,38 @@ static int wil6210_pm_notify(struct notifier_block *notify_block,
static
void wil_set_capabilities(struct wil6210_priv *wil)
{
- u32 rev_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
+ u32 jtag_id = wil_r(wil, RGF_USER_JTAG_DEV_ID);
+ u8 chip_revision = (wil_r(wil, RGF_USER_REVISION_ID) &
+ RGF_USER_REVISION_ID_MASK);
bitmap_zero(wil->hw_capabilities, hw_capability_last);
bitmap_zero(wil->fw_capabilities, WMI_FW_CAPABILITY_MAX);
-
- switch (rev_id) {
- case JTAG_DEV_ID_SPARROW_B0:
- wil->hw_name = "Sparrow B0";
- wil->hw_version = HW_VER_SPARROW_B0;
+ wil->wil_fw_name = WIL_FW_NAME_DEFAULT;
+ wil->chip_revision = chip_revision;
+
+ switch (jtag_id) {
+ case JTAG_DEV_ID_SPARROW:
+ switch (chip_revision) {
+ case REVISION_ID_SPARROW_D0:
+ wil->hw_name = "Sparrow D0";
+ wil->hw_version = HW_VER_SPARROW_D0;
+ if (wil_fw_verify_file_exists(wil,
+ WIL_FW_NAME_SPARROW_PLUS))
+ wil->wil_fw_name = WIL_FW_NAME_SPARROW_PLUS;
+ break;
+ case REVISION_ID_SPARROW_B0:
+ wil->hw_name = "Sparrow B0";
+ wil->hw_version = HW_VER_SPARROW_B0;
+ break;
+ default:
+ wil->hw_name = "Unknown";
+ wil->hw_version = HW_VER_UNKNOWN;
+ break;
+ }
break;
default:
- wil_err(wil, "Unknown board hardware 0x%08x\n", rev_id);
+ wil_err(wil, "Unknown board hardware, chip_id 0x%08x, chip_revision 0x%08x\n",
+ jtag_id, chip_revision);
wil->hw_name = "Unknown";
wil->hw_version = HW_VER_UNKNOWN;
}
@@ -55,7 +75,7 @@ void wil_set_capabilities(struct wil6210_priv *wil)
wil_info(wil, "Board hardware is %s\n", wil->hw_name);
/* extract FW capabilities from file without loading the FW */
- wil_request_firmware(wil, WIL_FW_NAME, false);
+ wil_request_firmware(wil, wil->wil_fw_name, false);
}
void wil_disable_irq(struct wil6210_priv *wil)
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index b9727ebe79ac..19de0ebb48f7 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -34,10 +34,12 @@ extern int agg_wsize;
extern u32 vring_idle_trsh;
extern bool rx_align_2;
extern bool debug_fw;
+extern bool disable_ap_sme;
#define WIL_NAME "wil6210"
-#define WIL_FW_NAME "wil6210.fw" /* code */
-#define WIL_FW2_NAME "wil6210.brd" /* board & radio parameters */
+#define WIL_FW_NAME_DEFAULT "wil6210.fw" /* code Sparrow B0 */
+#define WIL_FW_NAME_SPARROW_PLUS "wil6210_sparrow_plus.fw" /* code Sparrow D0 */
+#define WIL_BOARD_FILE_NAME "wil6210.brd" /* board & radio parameters */
#define WIL_DEFAULT_BUS_REQUEST_KBPS 128000 /* ~1Gbps */
#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
@@ -100,6 +102,9 @@ static inline u32 wil_mtu2macbuf(u32 mtu)
#define WIL6210_RX_HIGH_TRSH_INIT (0)
#define WIL6210_RX_HIGH_TRSH_DEFAULT \
(1 << (WIL_RX_RING_SIZE_ORDER_DEFAULT - 3))
+#define WIL_MAX_DMG_AID 254 /* for DMG only 1-254 allowed (see
+ * 802.11REVmc/D5.0, section 9.4.1.8)
+ */
/* Hardware definitions begin */
/*
@@ -254,7 +259,12 @@ struct RGF_ICR {
#define BIT_CAF_OSC_DIG_XTAL_STABLE BIT(0)
#define RGF_USER_JTAG_DEV_ID (0x880b34) /* device ID */
- #define JTAG_DEV_ID_SPARROW_B0 (0x2632072f)
+ #define JTAG_DEV_ID_SPARROW (0x2632072f)
+
+#define RGF_USER_REVISION_ID (0x88afe4)
+#define RGF_USER_REVISION_ID_MASK (3)
+ #define REVISION_ID_SPARROW_B0 (0x0)
+ #define REVISION_ID_SPARROW_D0 (0x3)
/* crash codes for FW/Ucode stored here */
#define RGF_FW_ASSERT_CODE (0x91f020)
@@ -262,7 +272,8 @@ struct RGF_ICR {
enum {
HW_VER_UNKNOWN,
- HW_VER_SPARROW_B0, /* JTAG_DEV_ID_SPARROW_B0 */
+ HW_VER_SPARROW_B0, /* REVISION_ID_SPARROW_B0 */
+ HW_VER_SPARROW_D0, /* REVISION_ID_SPARROW_D0 */
};
/* popular locations */
@@ -588,7 +599,9 @@ struct wil6210_priv {
DECLARE_BITMAP(status, wil_status_last);
u8 fw_version[ETHTOOL_FWVERS_LEN];
u32 hw_version;
+ u8 chip_revision;
const char *hw_name;
+ const char *wil_fw_name;
DECLARE_BITMAP(hw_capabilities, hw_capability_last);
DECLARE_BITMAP(fw_capabilities, WMI_FW_CAPABILITY_MAX);
u8 n_mids; /* number of additional MIDs as reported by FW */
@@ -824,8 +837,8 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
int wmi_rxon(struct wil6210_priv *wil, bool on);
int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
-int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
- bool full_disconnect);
+int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
+ u16 reason, bool full_disconnect, bool del_sta);
int wmi_addba(struct wil6210_priv *wil, u8 ringid, u8 size, u16 timeout);
int wmi_delba_tx(struct wil6210_priv *wil, u8 ringid, u16 reason);
int wmi_delba_rx(struct wil6210_priv *wil, u8 cidxtid, u16 reason);
@@ -835,6 +848,7 @@ int wmi_ps_dev_profile_cfg(struct wil6210_priv *wil,
enum wmi_ps_profile_type ps_profile);
int wmi_set_mgmt_retry(struct wil6210_priv *wil, u8 retry_short);
int wmi_get_mgmt_retry(struct wil6210_priv *wil, u8 *retry_short);
+int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid);
int wil_addba_rx_request(struct wil6210_priv *wil, u8 cidxtid,
u8 dialog_token, __le16 ba_param_set,
__le16 ba_timeout, __le16 ba_seq_ctrl);
@@ -928,6 +942,7 @@ int wil_iftype_nl2wmi(enum nl80211_iftype type);
int wil_ioctl(struct wil6210_priv *wil, void __user *data, int cmd);
int wil_request_firmware(struct wil6210_priv *wil, const char *name,
bool load);
+bool wil_fw_verify_file_exists(struct wil6210_priv *wil, const char *name);
int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 0bddc9d9c632..ef6472fb1f7e 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -556,7 +556,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
wil_err(wil, "%s: config tx vring failed for CID %d, rc (%d)\n",
__func__, evt->cid, rc);
wmi_disconnect_sta(wil, wil->sta[evt->cid].addr,
- WLAN_REASON_UNSPECIFIED, false);
+ WLAN_REASON_UNSPECIFIED, false, false);
} else {
wil_info(wil, "%s: successful connection to CID %d\n",
__func__, evt->cid);
@@ -584,8 +584,12 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
}
} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
(wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
- if (rc)
+ if (rc) {
+ if (disable_ap_sme)
+ /* notify new_sta has failed */
+ cfg80211_del_sta(ndev, evt->bssid, GFP_KERNEL);
goto out;
+ }
memset(&sinfo, 0, sizeof(sinfo));
@@ -688,6 +692,7 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
{
struct wmi_vring_en_event *evt = d;
u8 vri = evt->vring_index;
+ struct wireless_dev *wdev = wil_to_wdev(wil);
wil_dbg_wmi(wil, "Enable vring %d\n", vri);
@@ -695,7 +700,12 @@ static void wmi_evt_vring_en(struct wil6210_priv *wil, int id, void *d, int len)
wil_err(wil, "Enable for invalid vring %d\n", vri);
return;
}
- wil->vring_tx_data[vri].dot1x_open = true;
+
+ if (wdev->iftype != NL80211_IFTYPE_AP || !disable_ap_sme)
+ /* in AP mode with disable_ap_sme, this is done by
+ * wil_cfg80211_change_station()
+ */
+ wil->vring_tx_data[vri].dot1x_open = true;
if (vri == wil->bcast_vring) /* no BA for bcast */
return;
if (agg_wsize >= 0)
@@ -1102,6 +1112,7 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
.pcp_max_assoc_sta = max_assoc_sta,
.hidden_ssid = hidden_ssid,
.is_go = is_go,
+ .disable_ap_sme = disable_ap_sme,
};
struct {
struct wmi_cmd_hdr wmi;
@@ -1119,6 +1130,13 @@ int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype,
cmd.pcp_max_assoc_sta = WIL6210_MAX_CID;
}
+ if (disable_ap_sme &&
+ !test_bit(WMI_FW_CAPABILITY_DISABLE_AP_SME,
+ wil->fw_capabilities)) {
+ wil_err(wil, "disable_ap_sme not supported by FW\n");
+ return -EOPNOTSUPP;
+ }
+
/*
* Processing time may be huge, in case of secure AP it takes about
* 3500ms for FW to start AP
@@ -1489,12 +1507,15 @@ int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_bb, u32 *t_rf)
return 0;
}
-int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
- bool full_disconnect)
+int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac,
+ u16 reason, bool full_disconnect, bool del_sta)
{
int rc;
u16 reason_code;
- struct wmi_disconnect_sta_cmd cmd = {
+ struct wmi_disconnect_sta_cmd disc_sta_cmd = {
+ .disconnect_reason = cpu_to_le16(reason),
+ };
+ struct wmi_del_sta_cmd del_sta_cmd = {
.disconnect_reason = cpu_to_le16(reason),
};
struct {
@@ -1502,12 +1523,19 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason,
struct wmi_disconnect_event evt;
} __packed reply;
- ether_addr_copy(cmd.dst_mac, mac);
-
wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
- rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd),
- WMI_DISCONNECT_EVENTID, &reply, sizeof(reply), 1000);
+ if (del_sta) {
+ ether_addr_copy(del_sta_cmd.dst_mac, mac);
+ rc = wmi_call(wil, WMI_DEL_STA_CMDID, &del_sta_cmd,
+ sizeof(del_sta_cmd), WMI_DISCONNECT_EVENTID,
+ &reply, sizeof(reply), 1000);
+ } else {
+ ether_addr_copy(disc_sta_cmd.dst_mac, mac);
+ rc = wmi_call(wil, WMI_DISCONNECT_STA_CMDID, &disc_sta_cmd,
+ sizeof(disc_sta_cmd), WMI_DISCONNECT_EVENTID,
+ &reply, sizeof(reply), 1000);
+ }
/* failure to disconnect in reasonable time treated as FW error */
if (rc) {
wil_fw_error_recovery(wil);
@@ -1719,6 +1747,24 @@ int wmi_abort_scan(struct wil6210_priv *wil)
return rc;
}
+int wmi_new_sta(struct wil6210_priv *wil, const u8 *mac, u8 aid)
+{
+ int rc;
+ struct wmi_new_sta_cmd cmd = {
+ .aid = aid,
+ };
+
+ wil_dbg_wmi(wil, "new sta %pM, aid %d\n", mac, aid);
+
+ ether_addr_copy(cmd.dst_mac, mac);
+
+ rc = wmi_send(wil, WMI_NEW_STA_CMDID, &cmd, sizeof(cmd));
+ if (rc)
+ wil_err(wil, "Failed to send new sta (%d)\n", rc);
+
+ return rc;
+}
+
void wmi_event_flush(struct wil6210_priv *wil)
{
ulong flags;
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index d93a4d490d24..9c4a0bdc51f3 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2016 Qualcomm Atheros, Inc.
+ * Copyright (c) 2012-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2006-2012 Wilocity
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -56,6 +56,7 @@ enum wmi_fw_capability {
WMI_FW_CAPABILITY_PS_CONFIG = 1,
WMI_FW_CAPABILITY_RF_SECTORS = 2,
WMI_FW_CAPABILITY_MGMT_RETRY_LIMIT = 3,
+ WMI_FW_CAPABILITY_DISABLE_AP_SME = 4,
WMI_FW_CAPABILITY_MAX,
};
@@ -187,6 +188,8 @@ enum wmi_command_id {
WMI_AOA_MEAS_CMDID = 0x923,
WMI_SET_MGMT_RETRY_LIMIT_CMDID = 0x930,
WMI_GET_MGMT_RETRY_LIMIT_CMDID = 0x931,
+ WMI_NEW_STA_CMDID = 0x935,
+ WMI_DEL_STA_CMDID = 0x936,
WMI_TOF_SESSION_START_CMDID = 0x991,
WMI_TOF_GET_CAPABILITIES_CMDID = 0x992,
WMI_TOF_SET_LCR_CMDID = 0x993,
@@ -543,7 +546,8 @@ struct wmi_pcp_start_cmd {
u8 pcp_max_assoc_sta;
u8 hidden_ssid;
u8 is_go;
- u8 reserved0[7];
+ u8 reserved0[6];
+ u8 disable_ap_sme;
u8 network_type;
u8 channel;
u8 disable_sec_offload;
@@ -902,6 +906,18 @@ struct wmi_set_mgmt_retry_limit_cmd {
u8 reserved[3];
} __packed;
+/* WMI_NEW_STA_CMDID */
+struct wmi_new_sta_cmd {
+ u8 dst_mac[WMI_MAC_LEN];
+ u8 aid;
+} __packed;
+
+/* WMI_DEL_STA_CMDID */
+struct wmi_del_sta_cmd {
+ u8 dst_mac[WMI_MAC_LEN];
+ __le16 disconnect_reason;
+} __packed;
+
enum wmi_tof_burst_duration {
WMI_TOF_BURST_DURATION_250_USEC = 2,
WMI_TOF_BURST_DURATION_500_USEC = 3,
@@ -1292,7 +1308,7 @@ struct wmi_connect_event {
u8 assoc_info[0];
} __packed;
-/* WMI_DISCONNECT_EVENTID */
+/* disconnect_reason */
enum wmi_disconnect_reason {
WMI_DIS_REASON_NO_NETWORK_AVAIL = 0x01,
/* bmiss */
@@ -1310,6 +1326,7 @@ enum wmi_disconnect_reason {
WMI_DIS_REASON_IBSS_MERGE = 0x0E,
};
+/* WMI_DISCONNECT_EVENTID */
struct wmi_disconnect_event {
/* reason code, see 802.11 spec. */
__le16 protocol_reason_status;
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa.c b/drivers/platform/msm/ipa/ipa_v2/ipa.c
index 1e79fd954969..fde087f07226 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa.c
@@ -1827,7 +1827,7 @@ static int ipa_q6_clean_q6_tables(void)
u32 max_cmds = ipa_get_max_flt_rt_cmds(ipa_ctx->ipa_num_pipes);
mem.base = dma_alloc_coherent(ipa_ctx->pdev, 4, &mem.phys_base,
- GFP_KERNEL);
+ GFP_ATOMIC);
if (!mem.base) {
IPAERR("failed to alloc DMA buff of size 4\n");
return -ENOMEM;
diff --git a/drivers/power/supply/qcom/fg-core.h b/drivers/power/supply/qcom/fg-core.h
index 0d3fcc2ede86..c146654e438b 100644
--- a/drivers/power/supply/qcom/fg-core.h
+++ b/drivers/power/supply/qcom/fg-core.h
@@ -71,6 +71,10 @@
#define KI_COEFF_MAX 62200
#define KI_COEFF_SOC_LEVELS 3
+#define SLOPE_LIMIT_COEFF_MAX 31
+
+#define BATT_THERM_NUM_COEFFS 3
+
/* Debug flag definitions */
enum fg_debug_flag {
FG_IRQ = BIT(0), /* Show interrupts */
@@ -164,6 +168,7 @@ enum fg_sram_param_id {
FG_SRAM_KI_COEFF_HI_DISCHG,
FG_SRAM_ESR_TIGHT_FILTER,
FG_SRAM_ESR_BROAD_FILTER,
+ FG_SRAM_SLOPE_LIMIT,
FG_SRAM_MAX,
};
@@ -202,6 +207,14 @@ enum wa_flags {
PMI8998_V1_REV_WA = BIT(0),
};
+enum slope_limit_status {
+ LOW_TEMP_DISCHARGE = 0,
+ LOW_TEMP_CHARGE,
+ HIGH_TEMP_DISCHARGE,
+ HIGH_TEMP_CHARGE,
+ SLOPE_LIMIT_NUM_COEFFS,
+};
+
/* DT parameters for FG device */
struct fg_dt_props {
bool force_load_profile;
@@ -234,10 +247,13 @@ struct fg_dt_props {
int esr_broad_flt_upct;
int esr_tight_lt_flt_upct;
int esr_broad_lt_flt_upct;
+ int slope_limit_temp;
int jeita_thresholds[NUM_JEITA_LEVELS];
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
int ki_coeff_hi_dischg[KI_COEFF_SOC_LEVELS];
+ int slope_limit_coeffs[SLOPE_LIMIT_NUM_COEFFS];
+ u8 batt_therm_coeffs[BATT_THERM_NUM_COEFFS];
};
/* parameters from battery profile */
@@ -341,6 +357,7 @@ struct fg_chip {
int maint_soc;
int delta_soc;
int last_msoc;
+ enum slope_limit_status slope_limit_sts;
bool profile_available;
bool profile_loaded;
bool battery_missing;
@@ -352,6 +369,7 @@ struct fg_chip {
bool soc_reporting_ready;
bool esr_flt_cold_temp_en;
bool bsoc_delta_irq_en;
+ bool slope_limit_en;
struct completion soc_update;
struct completion soc_ready;
struct delayed_work profile_load_work;
diff --git a/drivers/power/supply/qcom/qpnp-fg-gen3.c b/drivers/power/supply/qcom/qpnp-fg-gen3.c
index fdb458efd560..1fd092c550f3 100644
--- a/drivers/power/supply/qcom/qpnp-fg-gen3.c
+++ b/drivers/power/supply/qcom/qpnp-fg-gen3.c
@@ -31,6 +31,8 @@
#define FG_MEM_INFO_PMI8998 0x0D
/* SRAM address and offset in ascending order */
+#define SLOPE_LIMIT_WORD 3
+#define SLOPE_LIMIT_OFFSET 0
#define CUTOFF_VOLT_WORD 5
#define CUTOFF_VOLT_OFFSET 0
#define SYS_TERM_CURR_WORD 6
@@ -220,6 +222,8 @@ static struct fg_sram_param pmi8998_v1_sram_params[] = {
1, 512, 1000000, 0, fg_encode_default, NULL),
PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
1, 512, 1000000, 0, fg_encode_default, NULL),
+ PARAM(SLOPE_LIMIT, SLOPE_LIMIT_WORD, SLOPE_LIMIT_OFFSET, 1, 8192, 1000,
+ 0, fg_encode_default, NULL),
};
static struct fg_sram_param pmi8998_v2_sram_params[] = {
@@ -286,6 +290,8 @@ static struct fg_sram_param pmi8998_v2_sram_params[] = {
1, 512, 1000000, 0, fg_encode_default, NULL),
PARAM(ESR_BROAD_FILTER, ESR_FILTER_WORD, ESR_UPD_BROAD_OFFSET,
1, 512, 1000000, 0, fg_encode_default, NULL),
+ PARAM(SLOPE_LIMIT, SLOPE_LIMIT_WORD, SLOPE_LIMIT_OFFSET, 1, 8192, 1000,
+ 0, fg_encode_default, NULL),
};
static struct fg_alg_flag pmi8998_v1_alg_flags[] = {
@@ -1770,6 +1776,48 @@ static int fg_adjust_recharge_soc(struct fg_chip *chip)
return 0;
}
+static int fg_slope_limit_config(struct fg_chip *chip, int batt_temp)
+{
+ enum slope_limit_status status;
+ int rc;
+ u8 buf;
+
+ if (!chip->slope_limit_en)
+ return 0;
+
+ if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING ||
+ chip->charge_status == POWER_SUPPLY_STATUS_FULL) {
+ if (batt_temp < chip->dt.slope_limit_temp)
+ status = LOW_TEMP_CHARGE;
+ else
+ status = HIGH_TEMP_CHARGE;
+ } else {
+ if (batt_temp < chip->dt.slope_limit_temp)
+ status = LOW_TEMP_DISCHARGE;
+ else
+ status = HIGH_TEMP_DISCHARGE;
+ }
+
+ if (chip->slope_limit_sts == status)
+ return 0;
+
+ fg_encode(chip->sp, FG_SRAM_SLOPE_LIMIT,
+ chip->dt.slope_limit_coeffs[status], &buf);
+ rc = fg_sram_write(chip, chip->sp[FG_SRAM_SLOPE_LIMIT].addr_word,
+ chip->sp[FG_SRAM_SLOPE_LIMIT].addr_byte, &buf,
+ chip->sp[FG_SRAM_SLOPE_LIMIT].len, FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in configuring slope_limit coefficient, rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ chip->slope_limit_sts = status;
+ fg_dbg(chip, FG_STATUS, "Slope limit status: %d value: %x\n", status,
+ buf);
+ return 0;
+}
+
static int fg_esr_filter_config(struct fg_chip *chip, int batt_temp)
{
u8 esr_tight_lt_flt, esr_broad_lt_flt;
@@ -1918,7 +1966,7 @@ static void status_change_work(struct work_struct *work)
struct fg_chip *chip = container_of(work,
struct fg_chip, status_change_work);
union power_supply_propval prop = {0, };
- int rc;
+ int rc, batt_temp;
if (!batt_psy_initialized(chip)) {
fg_dbg(chip, FG_STATUS, "Charger not available?!\n");
@@ -1971,6 +2019,14 @@ static void status_change_work(struct work_struct *work)
if (rc < 0)
pr_err("Error in adjusting FCC for ESR, rc=%d\n", rc);
+ rc = fg_get_battery_temp(chip, &batt_temp);
+ if (!rc) {
+ rc = fg_slope_limit_config(chip, batt_temp);
+ if (rc < 0)
+ pr_err("Error in configuring slope limiter rc:%d\n",
+ rc);
+ }
+
fg_batt_avg_update(chip);
out:
@@ -2986,6 +3042,21 @@ static int fg_hw_init(struct fg_chip *chip)
}
}
+ /*
+ * configure battery thermal coefficients c1,c2,c3
+ * if its value is not zero.
+ */
+ if (chip->dt.batt_therm_coeffs[0] > 0) {
+ rc = fg_write(chip, BATT_INFO_THERM_C1(chip),
+ chip->dt.batt_therm_coeffs, BATT_THERM_NUM_COEFFS);
+ if (rc < 0) {
+ pr_err("Error in writing battery thermal coefficients, rc=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
+
if (chip->dt.recharge_soc_thr > 0 && chip->dt.recharge_soc_thr < 100) {
rc = fg_set_recharge_soc(chip, chip->dt.recharge_soc_thr);
if (rc < 0) {
@@ -3221,6 +3292,10 @@ static irqreturn_t fg_delta_batt_temp_irq_handler(int irq, void *data)
if (rc < 0)
pr_err("Error in configuring ESR filter rc:%d\n", rc);
+ rc = fg_slope_limit_config(chip, batt_temp);
+ if (rc < 0)
+ pr_err("Error in configuring slope limiter rc:%d\n", rc);
+
if (!batt_psy_initialized(chip)) {
chip->last_batt_temp = batt_temp;
return IRQ_HANDLED;
@@ -3458,6 +3533,40 @@ static int fg_register_interrupts(struct fg_chip *chip)
return 0;
}
+static int fg_parse_slope_limit_coefficients(struct fg_chip *chip)
+{
+ struct device_node *node = chip->dev->of_node;
+ int rc, i;
+
+ rc = of_property_read_u32(node, "qcom,slope-limit-temp-threshold",
+ &chip->dt.slope_limit_temp);
+ if (rc < 0)
+ return 0;
+
+ rc = of_property_count_elems_of_size(node, "qcom,slope-limit-coeffs",
+ sizeof(u32));
+ if (rc != SLOPE_LIMIT_NUM_COEFFS)
+ return -EINVAL;
+
+ rc = of_property_read_u32_array(node, "qcom,slope-limit-coeffs",
+ chip->dt.slope_limit_coeffs, SLOPE_LIMIT_NUM_COEFFS);
+ if (rc < 0) {
+ pr_err("Error in reading qcom,slope-limit-coeffs, rc=%d\n", rc);
+ return rc;
+ }
+
+ for (i = 0; i < SLOPE_LIMIT_NUM_COEFFS; i++) {
+ if (chip->dt.slope_limit_coeffs[i] > SLOPE_LIMIT_COEFF_MAX ||
+ chip->dt.slope_limit_coeffs[i] < 0) {
+ pr_err("Incorrect slope limit coefficient\n");
+ return -EINVAL;
+ }
+ }
+
+ chip->slope_limit_en = true;
+ return 0;
+}
+
static int fg_parse_ki_coefficients(struct fg_chip *chip)
{
struct device_node *node = chip->dev->of_node;
@@ -3720,6 +3829,18 @@ static int fg_parse_dt(struct fg_chip *chip)
rc);
}
+ if (of_property_count_elems_of_size(node,
+ "qcom,battery-thermal-coefficients",
+ sizeof(u8)) == BATT_THERM_NUM_COEFFS) {
+ rc = of_property_read_u8_array(node,
+ "qcom,battery-thermal-coefficients",
+ chip->dt.batt_therm_coeffs,
+ BATT_THERM_NUM_COEFFS);
+ if (rc < 0)
+ pr_warn("Error reading battery thermal coefficients, rc:%d\n",
+ rc);
+ }
+
rc = of_property_read_u32(node, "qcom,fg-esr-timer-charging", &temp);
if (rc < 0)
chip->dt.esr_timer_charging = -EINVAL;
@@ -3846,6 +3967,11 @@ static int fg_parse_dt(struct fg_chip *chip)
chip->dt.esr_broad_lt_flt_upct = DEFAULT_ESR_BROAD_LT_FLT_UPCT;
else
chip->dt.esr_broad_lt_flt_upct = temp;
+
+ rc = fg_parse_slope_limit_coefficients(chip);
+ if (rc < 0)
+ pr_err("Error in parsing slope limit coeffs, rc=%d\n", rc);
+
return 0;
}
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 7a5a53695329..768871ffa9a7 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -77,15 +77,6 @@ module_param(qmi_timeout, ulong, 0600);
ipc_log_string(icnss_ipc_log_context, _x); \
} while (0)
-#ifdef CONFIG_ICNSS_DEBUG
-#define icnss_ipc_log_long_string(_x...) do { \
- if (icnss_ipc_log_long_context) \
- ipc_log_string(icnss_ipc_log_long_context, _x); \
- } while (0)
-#else
-#define icnss_ipc_log_long_string(_x...)
-#endif
-
#define icnss_pr_err(_fmt, ...) do { \
pr_err(_fmt, ##__VA_ARGS__); \
icnss_ipc_log_string("ERR: " pr_fmt(_fmt), \
@@ -110,12 +101,6 @@ module_param(qmi_timeout, ulong, 0600);
##__VA_ARGS__); \
} while (0)
-#define icnss_reg_dbg(_fmt, ...) do { \
- pr_debug(_fmt, ##__VA_ARGS__); \
- icnss_ipc_log_long_string("REG: " pr_fmt(_fmt), \
- ##__VA_ARGS__); \
- } while (0)
-
#ifdef CONFIG_ICNSS_DEBUG
#define ICNSS_ASSERT(_condition) do { \
if (!(_condition)) { \
@@ -157,10 +142,6 @@ module_param(dynamic_feature_mask, ullong, 0600);
void *icnss_ipc_log_context;
-#ifdef CONFIG_ICNSS_DEBUG
-void *icnss_ipc_log_long_context;
-#endif
-
#define ICNSS_EVENT_PENDING 2989
#define ICNSS_EVENT_SYNC BIT(0)
@@ -4034,26 +4015,6 @@ static struct platform_driver icnss_driver = {
},
};
-#ifdef CONFIG_ICNSS_DEBUG
-static void __init icnss_ipc_log_long_context_init(void)
-{
- icnss_ipc_log_long_context = ipc_log_context_create(NUM_REG_LOG_PAGES,
- "icnss_long", 0);
- if (!icnss_ipc_log_long_context)
- icnss_pr_err("Unable to create register log context\n");
-}
-
-static void __exit icnss_ipc_log_long_context_destroy(void)
-{
- ipc_log_context_destroy(icnss_ipc_log_long_context);
- icnss_ipc_log_long_context = NULL;
-}
-#else
-
-static void __init icnss_ipc_log_long_context_init(void) { }
-static void __exit icnss_ipc_log_long_context_destroy(void) { }
-#endif
-
static int __init icnss_initialize(void)
{
icnss_ipc_log_context = ipc_log_context_create(NUM_LOG_PAGES,
@@ -4061,8 +4022,6 @@ static int __init icnss_initialize(void)
if (!icnss_ipc_log_context)
icnss_pr_err("Unable to create log context\n");
- icnss_ipc_log_long_context_init();
-
return platform_driver_register(&icnss_driver);
}
@@ -4071,8 +4030,6 @@ static void __exit icnss_exit(void)
platform_driver_unregister(&icnss_driver);
ipc_log_context_destroy(icnss_ipc_log_context);
icnss_ipc_log_context = NULL;
-
- icnss_ipc_log_long_context_destroy();
}
diff --git a/drivers/soc/qcom/peripheral-loader.c b/drivers/soc/qcom/peripheral-loader.c
index 2244c64d28af..4d9767b6f8a3 100644
--- a/drivers/soc/qcom/peripheral-loader.c
+++ b/drivers/soc/qcom/peripheral-loader.c
@@ -583,11 +583,35 @@ static int pil_init_mmap(struct pil_desc *desc, const struct pil_mdt *mdt)
return pil_init_entry_addr(priv, mdt);
}
+struct pil_map_fw_info {
+ void *region;
+ struct dma_attrs attrs;
+ phys_addr_t base_addr;
+ struct device *dev;
+};
+
static void pil_release_mmap(struct pil_desc *desc)
{
struct pil_priv *priv = desc->priv;
struct pil_seg *p, *tmp;
u64 zero = 0ULL;
+ u8 __iomem *buf;
+
+ struct pil_map_fw_info map_fw_info = {
+ .attrs = desc->attrs,
+ .region = priv->region,
+ .base_addr = priv->region_start,
+ .dev = desc->dev,
+ };
+
+ void *map_data = desc->map_data ? desc->map_data : &map_fw_info;
+
+ /* Clear memory so that unauthorized ELF code is not left behind */
+ buf = desc->map_fw_mem(priv->region_start, (priv->region_end -
+ priv->region_start), map_data);
+ pil_memset_io(buf, 0, (priv->region_end - priv->region_start));
+ desc->unmap_fw_mem(buf, (priv->region_end - priv->region_start),
+ map_data);
if (priv->info) {
__iowrite32_copy(&priv->info->start, &zero,
@@ -603,13 +627,6 @@ static void pil_release_mmap(struct pil_desc *desc)
#define IOMAP_SIZE SZ_1M
-struct pil_map_fw_info {
- void *region;
- struct dma_attrs attrs;
- phys_addr_t base_addr;
- struct device *dev;
-};
-
static void *map_fw_mem(phys_addr_t paddr, size_t size, void *data)
{
struct pil_map_fw_info *info = data;
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 2ac9b28e036f..5b648460e621 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -1079,7 +1079,7 @@ static int dwc3_probe(struct platform_device *pdev)
dwc->regs_size = resource_size(res);
/* default to highest possible threshold */
- lpm_nyet_threshold = 0xff;
+ lpm_nyet_threshold = 0xf;
/* default to -3.5dB de-emphasis */
tx_de_emphasis = 1;
diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c
index 611750e209f9..087cd9fecfe9 100644
--- a/drivers/usb/pd/policy_engine.c
+++ b/drivers/usb/pd/policy_engine.c
@@ -309,7 +309,7 @@ struct usbpd {
spinlock_t rx_lock;
u32 received_pdos[7];
- int src_cap_id;
+ u16 src_cap_id;
u8 selected_pdo;
u8 requested_pdo;
u32 rdo; /* can be either source or sink */
@@ -338,8 +338,10 @@ struct usbpd {
enum power_role current_pr;
bool in_pr_swap;
bool pd_phy_opened;
- struct completion swap_complete;
+ bool send_request;
+ struct completion is_ready;
+ struct mutex swap_lock;
struct dual_role_phy_instance *dual_role;
struct dual_role_phy_desc dr_desc;
bool send_pr_swap;
@@ -463,6 +465,9 @@ static inline void pd_reset_protocol(struct usbpd *pd)
*/
pd->rx_msgid = -1;
pd->tx_msgid = 0;
+ pd->send_request = false;
+ pd->send_pr_swap = false;
+ pd->send_dr_swap = false;
}
static int pd_send_msg(struct usbpd *pd, u8 hdr_type, const u32 *data,
@@ -842,7 +847,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
}
kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
- complete(&pd->swap_complete);
+ complete(&pd->is_ready);
dual_role_instance_changed(pd->dual_role);
break;
@@ -977,7 +982,7 @@ static void usbpd_set_state(struct usbpd *pd, enum usbpd_state next_state)
case PE_SNK_READY:
pd->in_explicit_contract = true;
kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
- complete(&pd->swap_complete);
+ complete(&pd->is_ready);
dual_role_instance_changed(pd->dual_role);
break;
@@ -1546,9 +1551,9 @@ static void usbpd_sm(struct work_struct *w)
pd->hard_reset_recvd = false;
pd->caps_count = 0;
pd->hard_reset_count = 0;
- pd->src_cap_id = 0;
pd->requested_voltage = 0;
pd->requested_current = 0;
+ pd->selected_pdo = pd->requested_pdo = 0;
memset(&pd->received_pdos, 0, sizeof(pd->received_pdos));
rx_msg_cleanup(pd);
@@ -1616,8 +1621,12 @@ static void usbpd_sm(struct work_struct *w)
POWER_SUPPLY_PROP_PD_IN_HARD_RESET, &val);
pd->in_pr_swap = false;
+ pd->in_explicit_contract = false;
+ pd->selected_pdo = pd->requested_pdo = 0;
+ pd->rdo = 0;
rx_msg_cleanup(pd);
reset_vdm_state(pd);
+ kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
if (pd->current_pr == PR_SINK) {
usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
@@ -1840,8 +1849,10 @@ static void usbpd_sm(struct work_struct *w)
pd_send_hard_reset(pd);
pd->in_explicit_contract = false;
+ pd->rdo = 0;
rx_msg_cleanup(pd);
reset_vdm_state(pd);
+ kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
pd->current_state = PE_SRC_TRANSITION_TO_DEFAULT;
kick_sm(pd, PS_HARD_RESET_TIME);
@@ -2075,6 +2086,9 @@ static void usbpd_sm(struct work_struct *w)
vconn_swap(pd);
} else if (IS_DATA(rx_msg, MSG_VDM)) {
handle_vdm_rx(pd, rx_msg);
+ } else if (pd->send_request) {
+ pd->send_request = false;
+ usbpd_set_state(pd, PE_SNK_SELECT_CAPABILITY);
} else if (pd->send_pr_swap && is_sink_tx_ok(pd)) {
pd->send_pr_swap = false;
ret = pd_send_msg(pd, MSG_PR_SWAP, NULL, 0, SOP_MSG);
@@ -2158,7 +2172,10 @@ static void usbpd_sm(struct work_struct *w)
pd_send_hard_reset(pd);
pd->in_explicit_contract = false;
+ pd->selected_pdo = pd->requested_pdo = 0;
+ pd->rdo = 0;
reset_vdm_state(pd);
+ kobject_uevent(&pd->dev.kobj, KOBJ_CHANGE);
usbpd_set_state(pd, PE_SNK_TRANSITION_TO_DEFAULT);
break;
@@ -2540,17 +2557,21 @@ static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role,
return -EAGAIN;
}
- reinit_completion(&pd->swap_complete);
+ mutex_lock(&pd->swap_lock);
+ reinit_completion(&pd->is_ready);
pd->send_dr_swap = true;
kick_sm(pd, 0);
/* wait for operation to complete */
- if (!wait_for_completion_timeout(&pd->swap_complete,
+ if (!wait_for_completion_timeout(&pd->is_ready,
msecs_to_jiffies(100))) {
usbpd_err(&pd->dev, "data_role swap timed out\n");
+ mutex_unlock(&pd->swap_lock);
return -ETIMEDOUT;
}
+ mutex_unlock(&pd->swap_lock);
+
if ((*val == DUAL_ROLE_PROP_DR_HOST &&
pd->current_dr != DR_DFP) ||
(*val == DUAL_ROLE_PROP_DR_DEVICE &&
@@ -2591,17 +2612,21 @@ static int usbpd_dr_set_property(struct dual_role_phy_instance *dual_role,
return -EAGAIN;
}
- reinit_completion(&pd->swap_complete);
+ mutex_lock(&pd->swap_lock);
+ reinit_completion(&pd->is_ready);
pd->send_pr_swap = true;
kick_sm(pd, 0);
/* wait for operation to complete */
- if (!wait_for_completion_timeout(&pd->swap_complete,
+ if (!wait_for_completion_timeout(&pd->is_ready,
msecs_to_jiffies(2000))) {
usbpd_err(&pd->dev, "power_role swap timed out\n");
+ mutex_unlock(&pd->swap_lock);
return -ETIMEDOUT;
}
+ mutex_unlock(&pd->swap_lock);
+
if ((*val == DUAL_ROLE_PROP_PR_SRC &&
pd->current_pr != PR_SRC) ||
(*val == DUAL_ROLE_PROP_PR_SNK &&
@@ -2864,36 +2889,62 @@ static ssize_t select_pdo_store(struct device *dev,
int pdo, uv = 0, ua = 0;
int ret;
+ mutex_lock(&pd->swap_lock);
+
/* Only allowed if we are already in explicit sink contract */
if (pd->current_state != PE_SNK_READY || !is_sink_tx_ok(pd)) {
usbpd_err(&pd->dev, "select_pdo: Cannot select new PDO yet\n");
- return -EBUSY;
+ ret = -EBUSY;
+ goto out;
}
ret = sscanf(buf, "%d %d %d %d", &src_cap_id, &pdo, &uv, &ua);
if (ret != 2 && ret != 4) {
usbpd_err(&pd->dev, "select_pdo: Must specify <src cap id> <PDO> [<uV> <uA>]\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (src_cap_id != pd->src_cap_id) {
usbpd_err(&pd->dev, "select_pdo: src_cap_id mismatch. Requested:%d, current:%d\n",
src_cap_id, pd->src_cap_id);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
if (pdo < 1 || pdo > 7) {
usbpd_err(&pd->dev, "select_pdo: invalid PDO:%d\n", pdo);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out;
}
ret = pd_select_pdo(pd, pdo, uv, ua);
if (ret)
- return ret;
+ goto out;
- usbpd_set_state(pd, PE_SNK_SELECT_CAPABILITY);
+ reinit_completion(&pd->is_ready);
+ pd->send_request = true;
+ kick_sm(pd, 0);
- return size;
+ /* wait for operation to complete */
+ if (!wait_for_completion_timeout(&pd->is_ready,
+ msecs_to_jiffies(1000))) {
+ usbpd_err(&pd->dev, "select_pdo: request timed out\n");
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+
+ /* determine if request was accepted/rejected */
+ if (pd->selected_pdo != pd->requested_pdo ||
+ pd->current_voltage != pd->requested_voltage) {
+ usbpd_err(&pd->dev, "select_pdo: request rejected\n");
+ ret = -EINVAL;
+ }
+
+out:
+ pd->send_request = false;
+ mutex_unlock(&pd->swap_lock);
+ return ret ? ret : size;
}
static ssize_t select_pdo_show(struct device *dev,
@@ -3123,6 +3174,7 @@ struct usbpd *usbpd_create(struct device *parent)
INIT_WORK(&pd->sm_work, usbpd_sm);
hrtimer_init(&pd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
pd->timer.function = pd_timeout;
+ mutex_init(&pd->swap_lock);
pd->usb_psy = power_supply_get_by_name("usb");
if (!pd->usb_psy) {
@@ -3166,7 +3218,7 @@ struct usbpd *usbpd_create(struct device *parent)
pd->num_sink_caps = device_property_read_u32_array(parent,
"qcom,default-sink-caps", NULL, 0);
- if (pd->num_sink_caps) {
+ if (pd->num_sink_caps > 0) {
int i;
u32 sink_caps[14];
@@ -3233,7 +3285,7 @@ struct usbpd *usbpd_create(struct device *parent)
spin_lock_init(&pd->rx_lock);
INIT_LIST_HEAD(&pd->rx_q);
INIT_LIST_HEAD(&pd->svid_handlers);
- init_completion(&pd->swap_complete);
+ init_completion(&pd->is_ready);
pd->psy_nb.notifier_call = psy_changed;
ret = power_supply_reg_notifier(&pd->psy_nb);
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 3d3a2022bc04..ddc21d0c1bbb 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -1818,11 +1818,14 @@ struct afe_port_data_cmd_rt_proxy_port_read_v2 {
#define AFE_PORT_SAMPLE_RATE_16K 16000
#define AFE_PORT_SAMPLE_RATE_48K 48000
#define AFE_PORT_SAMPLE_RATE_96K 96000
+#define AFE_PORT_SAMPLE_RATE_176P4K 176400
#define AFE_PORT_SAMPLE_RATE_192K 192000
+#define AFE_PORT_SAMPLE_RATE_352P8K 352800
#define AFE_LINEAR_PCM_DATA 0x0
#define AFE_NON_LINEAR_DATA 0x1
#define AFE_LINEAR_PCM_DATA_PACKED_60958 0x2
#define AFE_NON_LINEAR_DATA_PACKED_60958 0x3
+#define AFE_GENERIC_COMPRESSED 0x8
/* This param id is used to configure I2S interface */
#define AFE_PARAM_ID_I2S_CONFIG 0x0001020D
@@ -2755,25 +2758,31 @@ struct afe_param_id_tdm_cfg {
- #AFE_PORT_SAMPLE_RATE_16K
- #AFE_PORT_SAMPLE_RATE_24K
- #AFE_PORT_SAMPLE_RATE_32K
- - #AFE_PORT_SAMPLE_RATE_48K @tablebulletend */
+ - #AFE_PORT_SAMPLE_RATE_48K
+ - #AFE_PORT_SAMPLE_RATE_176P4K
+ - #AFE_PORT_SAMPLE_RATE_352P8K @tablebulletend
+ */
u32 bit_width;
/**< Bit width of the sample.
- @values 16, 24 */
+ * @values 16, 24, 32
+ */
u16 data_format;
- /**< Data format: linear and compressed
-
+ /**< Data format: linear ,compressed, generic compresssed
@values
- #AFE_LINEAR_PCM_DATA
- - #AFE_NON_LINEAR_DATA @tablebulletend */
+ - #AFE_NON_LINEAR_DATA
+ - #AFE_GENERIC_COMPRESSED
+ */
u16 sync_mode;
/**< TDM synchronization setting.
@values (short, long, slot) sync mode
- #AFE_PORT_TDM_SHORT_SYNC_BIT_MODE
- #AFE_PORT_TDM_LONG_SYNC_MODE
- - #AFE_PORT_TDM_SHORT_SYNC_SLOT_MODE @tablebulletend */
+ - #AFE_PORT_TDM_SHORT_SYNC_SLOT_MODE @tablebulletend
+ */
u16 sync_src;
/**< Synchronization source.
@@ -3629,7 +3638,7 @@ struct afe_lpass_core_shared_clk_config_command {
#define DEFAULT_COPP_TOPOLOGY 0x00010314
#define DEFAULT_POPP_TOPOLOGY 0x00010BE4
#define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY 0x0001076B
-#define COMPRESS_PASSTHROUGH_NONE_TOPOLOGY 0x00010774
+#define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY 0x00010774
#define VPM_TX_SM_ECNS_COPP_TOPOLOGY 0x00010F71
#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72
#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75
@@ -3935,6 +3944,8 @@ struct asm_softvolume_params {
#define ASM_MEDIA_FMT_EVRCWB_FS 0x00010BF0
+#define ASM_MEDIA_FMT_GENERIC_COMPRESSED 0x00013212
+
#define ASM_MAX_EQ_BANDS 12
#define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2 0x00010D98
@@ -3944,6 +3955,40 @@ u32 fmt_blk_size;
/* Media format block size in bytes.*/
} __packed;
+struct asm_generic_compressed_fmt_blk_t {
+ struct apr_hdr hdr;
+ struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
+
+ /*
+ * Channel mapping array of bitstream output.
+ * Channel[i] mapping describes channel i inside the buffer, where
+ * i < num_channels. All valid used channels must be
+ * present at the beginning of the array.
+ */
+ uint8_t channel_mapping[8];
+
+ /*
+ * Number of channels of the incoming bitstream.
+ * Supported values: 1,2,3,4,5,6,7,8
+ */
+ uint16_t num_channels;
+
+ /*
+ * Nominal bits per sample value of the incoming bitstream.
+ * Supported values: 16, 32
+ */
+ uint16_t bits_per_sample;
+
+ /*
+ * Nominal sampling rate of the incoming bitstream.
+ * Supported values: 8000, 11025, 16000, 22050, 24000, 32000,
+ * 44100, 48000, 88200, 96000, 176400, 192000,
+ * 352800, 384000
+ */
+ uint32_t sampling_rate;
+
+} __packed;
+
struct asm_multi_channel_pcm_fmt_blk_v2 {
struct apr_hdr hdr;
struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
@@ -9992,6 +10037,108 @@ struct afe_port_group_create {
union afe_port_group_config data;
} __packed;
+/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to specify
+ * the timing statistics of the corresponding device interface.
+ * Client can periodically query for the device time statistics to help adjust
+ * the PLL based on the drift value. The get param command must be sent to
+ * AFE port ID corresponding to device interface
+
+ * This parameter ID supports following get param commands:
+ * #AFE_PORT_CMD_GET_PARAM_V2 and
+ * #AFE_PORT_CMD_GET_PARAM_V3.
+ */
+#define AFE_PARAM_ID_DEV_TIMING_STATS 0x000102AD
+
+/* Version information used to handle future additions to AFE device
+ * interface timing statistics (for backward compatibility).
+ */
+#define AFE_API_VERSION_DEV_TIMING_STATS 0x1
+
+/* Enumeration for specifying a sink(Rx) device */
+#define AFE_SINK_DEVICE 0x0
+
+/* Enumeration for specifying a source(Tx) device */
+#define AFE_SOURCE_DEVICE 0x1
+
+/* Enumeration for specifying the drift reference is of type AV Timer */
+#define AFE_REF_TIMER_TYPE_AVTIMER 0x0
+
+/* Message payload structure for the
+ * AFE_PARAM_ID_DEV_TIMING_STATS parameter.
+ */
+struct afe_param_id_dev_timing_stats {
+ /* Minor version used to track the version of device interface timing
+ * statistics. Currently, the supported version is 1.
+ * @values #AFE_API_VERSION_DEV_TIMING_STATS
+ */
+ u32 minor_version;
+
+ /* Indicates the device interface direction as either
+ * source (Tx) or sink (Rx).
+ * @values
+ * #AFE_SINK_DEVICE
+ * #AFE_SOURCE_DEVICE
+ */
+ u16 device_direction;
+
+ /* Reference timer for drift accumulation and time stamp information.
+ * @values
+ * #AFE_REF_TIMER_TYPE_AVTIMER @tablebulletend
+ */
+ u16 reference_timer;
+
+ /*
+ * Flag to indicate if resync is required on the client side for
+ * drift correction. Flag is set to TRUE for the first get_param
+ * response after device interface starts. This flag value can be
+ * used by client to identify if device interface restart has
+ * happened and if any re-sync is required at their end for drift
+ * correction.
+ * @values
+ * 0: FALSE (Resync not required)
+ * 1: TRUE (Resync required) @tablebulletend
+ */
+ u32 resync_flag;
+
+ /* Accumulated drift value in microseconds. This value is updated
+ * every 100th ms.
+ * Positive drift value indicates AV timer is running faster than device
+ * Negative drift value indicates AV timer is running slower than device
+ * @values Any valid int32 number
+ */
+ s32 acc_drift_value;
+
+ /* Lower 32 bits of the 64-bit absolute timestamp of reference
+ * timer in microseconds.
+
+ * This timestamp corresponds to the time when the drift values
+ * are accumlated for every 100th ms.
+ * @values Any valid uint32 number
+ */
+ u32 ref_timer_abs_ts_lsw;
+
+ /* Upper 32 bits of the 64-bit absolute timestamp of reference
+ * timer in microseconds.
+ * This timestamp corresponds to the time when the drift values
+ * are accumlated for every 100th ms.
+ * @values Any valid uint32 number
+ */
+ u32 ref_timer_abs_ts_msw;
+} __packed;
+
+struct afe_av_dev_drift_get_param {
+ struct apr_hdr hdr;
+ struct afe_port_cmd_get_param_v2 get_param;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_param_id_dev_timing_stats timing_stats;
+} __packed;
+
+struct afe_av_dev_drift_get_param_resp {
+ uint32_t status;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_param_id_dev_timing_stats timing_stats;
+} __packed;
+
/* Command for Matrix or Stream Router */
#define ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2 0x00010DCE
/* Module for AVSYNC */
@@ -10203,6 +10350,7 @@ enum {
COMPRESSED_PASSTHROUGH_CONVERT,
COMPRESSED_PASSTHROUGH_DSD,
LISTEN,
+ COMPRESSED_PASSTHROUGH_GEN,
};
#define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770
diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h
index e4033e712804..b1c3b0baf4b3 100644
--- a/include/sound/q6afe-v2.h
+++ b/include/sound/q6afe-v2.h
@@ -364,6 +364,8 @@ int afe_send_custom_tdm_header_cfg(
struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg,
u16 port_id);
int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
- u32 rate);
+ u32 rate, u16 num_groups);
void afe_set_routing_callback(routing_cb);
+int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
+ u16 port);
#endif /* __Q6AFE_V2_H__ */
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 9a3db9aaa25e..76bb795119c2 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -54,6 +54,7 @@
#define FORMAT_DTS 0x001c
#define FORMAT_DSD 0x001d
#define FORMAT_APTX 0x001e
+#define FORMAT_GEN_COMPR 0x001f
#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
@@ -500,6 +501,11 @@ int q6asm_media_format_block_multi_ch_pcm_v2(
uint32_t rate, uint32_t channels,
bool use_default_chmap, char *channel_map,
uint16_t bits_per_sample);
+int q6asm_media_format_block_gen_compr(
+ struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ bool use_default_chmap, char *channel_map,
+ uint16_t bits_per_sample);
int q6asm_media_format_block_multi_ch_pcm_v3(struct audio_client *ac,
uint32_t rate, uint32_t channels,
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 432de7089d0e..5dd643d524d6 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -422,6 +422,9 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev, unsigned int len,
len += NET_SKB_PAD;
+ if (IS_ENABLED(CONFIG_FORCE_ALLOC_FROM_DMA_ZONE))
+ gfp_mask |= GFP_DMA;
+
if ((len > SKB_WITH_OVERHEAD(PAGE_SIZE)) ||
(gfp_mask & (__GFP_DIRECT_RECLAIM | GFP_DMA))) {
skb = __alloc_skb(len, gfp_mask, SKB_ALLOC_RX, NUMA_NO_NODE);
diff --git a/sound/soc/codecs/wcd934x/wcd934x.c b/sound/soc/codecs/wcd934x/wcd934x.c
index e0b149cf1f7e..4fe9e2d50f7a 100644
--- a/sound/soc/codecs/wcd934x/wcd934x.c
+++ b/sound/soc/codecs/wcd934x/wcd934x.c
@@ -8098,13 +8098,8 @@ static struct snd_soc_dai_driver tavil_dai[] = {
static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil)
{
- struct snd_soc_codec *codec = tavil->codec;
-
- if (!codec)
- return;
-
mutex_lock(&tavil->power_lock);
- dev_dbg(codec->dev, "%s: Entering power gating function, %d\n",
+ dev_dbg(tavil->dev, "%s: Entering power gating function, %d\n",
__func__, tavil->power_active_ref);
if (tavil->power_active_ref > 0)
@@ -8113,16 +8108,16 @@ static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil)
wcd9xxx_set_power_state(tavil->wcd9xxx,
WCD_REGION_POWER_COLLAPSE_BEGIN,
WCD9XXX_DIG_CORE_REGION_1);
- snd_soc_update_bits(codec, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
- 0x04, 0x04);
- snd_soc_update_bits(codec, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
- 0x01, 0x00);
- snd_soc_update_bits(codec, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
- 0x02, 0x00);
+ regmap_update_bits(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04, 0x04);
+ regmap_update_bits(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x01, 0x00);
+ regmap_update_bits(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x02, 0x00);
wcd9xxx_set_power_state(tavil->wcd9xxx, WCD_REGION_POWER_DOWN,
WCD9XXX_DIG_CORE_REGION_1);
exit:
- dev_dbg(codec->dev, "%s: Exiting power gating function, %d\n",
+ dev_dbg(tavil->dev, "%s: Exiting power gating function, %d\n",
__func__, tavil->power_active_ref);
mutex_unlock(&tavil->power_lock);
}
@@ -8131,34 +8126,32 @@ static void tavil_codec_power_gate_work(struct work_struct *work)
{
struct tavil_priv *tavil;
struct delayed_work *dwork;
- struct snd_soc_codec *codec;
dwork = to_delayed_work(work);
tavil = container_of(dwork, struct tavil_priv, power_gate_work);
- codec = tavil->codec;
-
- if (!codec)
- return;
tavil_codec_power_gate_digital_core(tavil);
}
/* called under power_lock acquisition */
-static int tavil_dig_core_remove_power_collapse(struct snd_soc_codec *codec)
+static int tavil_dig_core_remove_power_collapse(struct tavil_priv *tavil)
{
- struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
-
- snd_soc_write(codec, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
- snd_soc_write(codec, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
- snd_soc_update_bits(codec, WCD934X_CODEC_RPM_RST_CTL, 0x02, 0x00);
- snd_soc_update_bits(codec, WCD934X_CODEC_RPM_RST_CTL, 0x02, 0x02);
- snd_soc_write(codec, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
+ regmap_write(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x05);
+ regmap_write(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x07);
+ regmap_update_bits(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_RST_CTL, 0x02, 0x00);
+ regmap_update_bits(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_RST_CTL, 0x02, 0x02);
+ regmap_write(tavil->wcd9xxx->regmap,
+ WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x03);
wcd9xxx_set_power_state(tavil->wcd9xxx,
WCD_REGION_POWER_COLLAPSE_REMOVE,
WCD9XXX_DIG_CORE_REGION_1);
- regcache_mark_dirty(codec->component.regmap);
- regcache_sync_region(codec->component.regmap,
+ regcache_mark_dirty(tavil->wcd9xxx->regmap);
+ regcache_sync_region(tavil->wcd9xxx->regmap,
WCD934X_DIG_CORE_REG_MIN,
WCD934X_DIG_CORE_REG_MAX);
@@ -8168,7 +8161,6 @@ static int tavil_dig_core_remove_power_collapse(struct snd_soc_codec *codec)
static int tavil_dig_core_power_collapse(struct tavil_priv *tavil,
int req_state)
{
- struct snd_soc_codec *codec;
int cur_state;
/* Exit if feature is disabled */
@@ -8189,10 +8181,6 @@ static int tavil_dig_core_power_collapse(struct tavil_priv *tavil,
goto unlock_mutex;
}
- codec = tavil->codec;
- if (!codec)
- goto unlock_mutex;
-
if (req_state == POWER_COLLAPSE) {
if (tavil->power_active_ref == 0) {
schedule_delayed_work(&tavil->power_gate_work,
@@ -8210,7 +8198,7 @@ static int tavil_dig_core_power_collapse(struct tavil_priv *tavil,
tavil->wcd9xxx,
WCD9XXX_DIG_CORE_REGION_1);
if (cur_state == WCD_REGION_POWER_DOWN) {
- tavil_dig_core_remove_power_collapse(codec);
+ tavil_dig_core_remove_power_collapse(tavil);
} else {
mutex_unlock(&tavil->power_lock);
cancel_delayed_work_sync(
diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c
index 83ae4c14d8ba..e6fa1143af02 100644
--- a/sound/soc/msm/msm8998.c
+++ b/sound/soc/msm/msm8998.c
@@ -159,6 +159,21 @@ struct msm_wsa881x_dev_info {
u32 index;
};
+enum pinctrl_pin_state {
+ STATE_DISABLE = 0, /* All pins are in sleep state */
+ STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */
+ STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */
+};
+
+struct msm_pinctrl_info {
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *mi2s_disable;
+ struct pinctrl_state *tdm_disable;
+ struct pinctrl_state *mi2s_active;
+ struct pinctrl_state *tdm_active;
+ enum pinctrl_pin_state curr_state;
+};
+
struct msm_asoc_mach_data {
u32 mclk_freq;
int us_euro_gpio; /* used by gpio driver API */
@@ -166,6 +181,7 @@ struct msm_asoc_mach_data {
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
struct snd_info_entry *codec_root;
+ struct msm_pinctrl_info pinctrl_info;
};
struct msm_asoc_wcd93xx_codec {
@@ -174,6 +190,9 @@ struct msm_asoc_wcd93xx_codec {
void (*mbhc_hs_detect_exit)(struct snd_soc_codec *codec);
};
+static const char *const pin_states[] = {"sleep", "i2s-active",
+ "tdm-active"};
+
enum {
TDM_0 = 0,
TDM_1,
@@ -3993,6 +4012,275 @@ done:
return ret;
}
+static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info,
+ enum pinctrl_pin_state new_state)
+{
+ int ret = 0;
+ int curr_state = 0;
+
+ if (pinctrl_info == NULL) {
+ pr_err("%s: pinctrl_info is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ curr_state = pinctrl_info->curr_state;
+ pinctrl_info->curr_state = new_state;
+ pr_debug("%s: curr_state = %s new_state = %s\n", __func__,
+ pin_states[curr_state], pin_states[pinctrl_info->curr_state]);
+
+ if (curr_state == pinctrl_info->curr_state) {
+ pr_debug("%s: Already in same state\n", __func__);
+ goto err;
+ }
+
+ if (curr_state != STATE_DISABLE &&
+ pinctrl_info->curr_state != STATE_DISABLE) {
+ pr_debug("%s: state already active cannot switch\n", __func__);
+ ret = -EIO;
+ goto err;
+ }
+
+ switch (pinctrl_info->curr_state) {
+ case STATE_MI2S_ACTIVE:
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_active);
+ if (ret) {
+ pr_err("%s: MI2S state select failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ case STATE_TDM_ACTIVE:
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->tdm_active);
+ if (ret) {
+ pr_err("%s: TDM state select failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ case STATE_DISABLE:
+ if (curr_state == STATE_MI2S_ACTIVE) {
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_disable);
+ } else {
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->tdm_disable);
+ }
+ if (ret) {
+ pr_err("%s: state disable failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ default:
+ pr_err("%s: TLMM pin state is invalid\n", __func__);
+ return -EINVAL;
+ }
+
+err:
+ return ret;
+}
+
+static void msm_release_pinctrl(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ if (pinctrl_info->pinctrl) {
+ devm_pinctrl_put(pinctrl_info->pinctrl);
+ pinctrl_info->pinctrl = NULL;
+ }
+}
+
+static int msm_get_pinctrl(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = NULL;
+ struct pinctrl *pinctrl;
+ int ret;
+
+ pinctrl_info = &pdata->pinctrl_info;
+
+ if (pinctrl_info == NULL) {
+ pr_err("%s: pinctrl_info is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR_OR_NULL(pinctrl)) {
+ pr_err("%s: Unable to get pinctrl handle\n", __func__);
+ return -EINVAL;
+ }
+ pinctrl_info->pinctrl = pinctrl;
+
+ /* get all the states handles from Device Tree */
+ pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl,
+ "quat-mi2s-sleep");
+ if (IS_ERR(pinctrl_info->mi2s_disable)) {
+ pr_err("%s: could not get mi2s_disable pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl,
+ "quat-mi2s-active");
+ if (IS_ERR(pinctrl_info->mi2s_active)) {
+ pr_err("%s: could not get mi2s_active pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl,
+ "quat-tdm-sleep");
+ if (IS_ERR(pinctrl_info->tdm_disable)) {
+ pr_err("%s: could not get tdm_disable pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl,
+ "quat-tdm-active");
+ if (IS_ERR(pinctrl_info->tdm_active)) {
+ pr_err("%s: could not get tdm_active pinstate\n",
+ __func__);
+ goto err;
+ }
+ /* Reset the TLMM pins to a default state */
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_disable);
+ if (ret != 0) {
+ pr_err("%s: Disable TLMM pins failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ pinctrl_info->curr_state = STATE_DISABLE;
+
+ return 0;
+
+err:
+ devm_pinctrl_put(pinctrl);
+ pinctrl_info->pinctrl = NULL;
+ return -EINVAL;
+}
+
+static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
+ } else {
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
+ __func__, cpu_dai->id, channels->max, rate->max,
+ params_format(params));
+
+ return 0;
+}
+
+static int msm8998_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int channels, slot_width, slots;
+ unsigned int slot_mask;
+ unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ /*2 slot config - bits 0 and 1 set for the first two slots */
+ slot_mask = 0x0000FFFF >> (16-slots);
+ slot_width = 32;
+ channels = slots;
+
+ pr_debug("%s: slot_width %d slots %d\n", __func__, slot_width, slots);
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ pr_debug("%s: slot_width %d\n", __func__, slot_width);
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ 0, NULL, channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ pr_err("%s: invalid use case, err:%d\n",
+ __func__, ret);
+ }
+
+end:
+ return ret;
+}
+
+static int msm8998_tdm_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
+ if (ret)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+
+ return ret;
+}
+
+static void msm8998_tdm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+ if (ret)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+
+}
+
+static struct snd_soc_ops msm8998_tdm_be_ops = {
+ .hw_params = msm8998_tdm_snd_hw_params,
+ .startup = msm8998_tdm_snd_startup,
+ .shutdown = msm8998_tdm_snd_shutdown
+};
+
static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
{
int ret = 0;
@@ -4000,6 +4288,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int index = cpu_dai->id;
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
dev_dbg(rtd->card->dev,
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
@@ -4013,6 +4304,15 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
__func__, cpu_dai->id);
goto done;
}
+ if (index == QUAT_MI2S) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_MI2S_ACTIVE);
+ if (ret) {
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ goto done;
+ }
+ }
+
/*
* Muxtex protection in case the same MI2S
* interface using for both TX and RX so
@@ -4065,6 +4365,9 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
int ret;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
int index = rtd->cpu_dai->id;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
pr_debug("%s(): substream = %s stream = %d\n", __func__,
substream->name, substream->stream);
@@ -4083,6 +4386,13 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
}
}
mutex_unlock(&mi2s_intf_conf[index].lock);
+
+ if (index == QUAT_MI2S) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+ if (ret)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ }
}
static struct snd_soc_ops msm_mi2s_be_ops = {
@@ -5210,8 +5520,8 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = {
.no_pcm = 1,
.dpcm_playback = 1,
.be_id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
- .be_hw_params_fixup = msm_be_hw_params_fixup,
- .ops = &msm_tdm_be_ops,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &msm8998_tdm_be_ops,
.ignore_suspend = 1,
},
{
@@ -6883,6 +7193,17 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
ret);
+ /* Parse pinctrl info from devicetree */
+ ret = msm_get_pinctrl(pdev);
+ if (!ret) {
+ pr_debug("%s: pinctrl parsing successful\n", __func__);
+ } else {
+ dev_dbg(&pdev->dev,
+ "%s: Parsing pinctrl failed with %d. Cannot use Ports\n",
+ __func__, ret);
+ ret = 0;
+ }
+
i2s_auxpcm_init(pdev);
is_initial_boot = true;
@@ -6900,6 +7221,7 @@ err:
gpio_free(pdata->us_euro_gpio);
pdata->us_euro_gpio = 0;
}
+ msm_release_pinctrl(pdev);
devm_kfree(&pdev->dev, pdata);
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c
index 69a9e14c47de..46e2f7109b5a 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-hdmi-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
@@ -124,6 +124,45 @@ static const struct soc_enum hdmi_config_enum[] = {
SOC_ENUM_SINGLE_EXT(2, hdmi_format),
};
+static int msm_dai_q6_ext_disp_drift_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+ uinfo->count = sizeof(struct afe_param_id_dev_timing_stats);
+
+ return 0;
+}
+
+static int msm_dai_q6_ext_disp_drift_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = -EINVAL;
+ struct afe_param_id_dev_timing_stats timing_stats;
+ struct snd_soc_dai *dai = kcontrol->private_data;
+ struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev);
+
+ if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+ pr_err("%s: afe port not started. status_mask = %ld\n",
+ __func__, *dai_data->status_mask);
+ goto done;
+ }
+
+ memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats));
+ ret = afe_get_av_dev_drift(&timing_stats, dai->id);
+ if (ret) {
+ pr_err("%s: Error getting AFE Drift for port %d, err=%d\n",
+ __func__, dai->id, ret);
+
+ ret = -EINVAL;
+ goto done;
+ }
+
+ memcpy(ucontrol->value.bytes.data, (void *)&timing_stats,
+ sizeof(struct afe_param_id_dev_timing_stats));
+done:
+ return ret;
+}
+
static const struct snd_kcontrol_new hdmi_config_controls[] = {
SOC_ENUM_EXT("HDMI RX Format", hdmi_config_enum[0],
msm_dai_q6_ext_disp_format_get,
@@ -132,6 +171,13 @@ static const struct snd_kcontrol_new hdmi_config_controls[] = {
HDMI_RX_CA_MAX, 0, 1,
msm_dai_q6_ext_disp_ca_get,
msm_dai_q6_ext_disp_ca_put),
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "HDMI RX Drift",
+ .info = msm_dai_q6_ext_disp_drift_info,
+ .get = msm_dai_q6_ext_disp_drift_get,
+ },
};
static const struct snd_kcontrol_new display_port_config_controls[] = {
@@ -142,6 +188,13 @@ static const struct snd_kcontrol_new display_port_config_controls[] = {
HDMI_RX_CA_MAX, 0, 1,
msm_dai_q6_ext_disp_ca_get,
msm_dai_q6_ext_disp_ca_put),
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ,
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+ .name = "DISPLAY Port RX Drift",
+ .info = msm_dai_q6_ext_disp_drift_info,
+ .get = msm_dai_q6_ext_disp_drift_get,
+ },
};
/* Current implementation assumes hw_param is called once
@@ -299,6 +352,10 @@ static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai)
kcontrol = &hdmi_config_controls[1];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
+
+ kcontrol = &hdmi_config_controls[2];
+ rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(kcontrol, dai));
} else if (dai->driver->id == DISPLAY_PORT_RX) {
kcontrol = &display_port_config_controls[0];
rc = snd_ctl_add(dai->component->card->snd_card,
@@ -307,6 +364,10 @@ static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai)
kcontrol = &display_port_config_controls[1];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
+
+ kcontrol = &display_port_config_controls[2];
+ rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(kcontrol, dai));
} else {
dev_err(dai->dev, "%s: Invalid id:%d\n",
__func__, dai->driver->id);
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index f081ef066bdd..19e2fad2920d 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -219,6 +219,7 @@ struct msm_dai_q6_tdm_dai_data {
u32 rate;
u32 channels;
u32 bitwidth;
+ u32 num_group_ports;
struct afe_clk_set clk_set; /* hold LPASS clock config. */
union afe_port_group_config group_cfg; /* hold tdm group config */
struct afe_tdm_port_config port_cfg; /* hold tdm config */
@@ -260,6 +261,7 @@ static const struct soc_enum sb_config_enum[] = {
static const char *const tdm_data_format[] = {
"LPCM",
"Compr",
+ "Gen Compr"
};
static const char *const tdm_header_type[] = {
@@ -269,8 +271,8 @@ static const char *const tdm_header_type[] = {
};
static const struct soc_enum tdm_config_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, tdm_data_format),
- SOC_ENUM_SINGLE_EXT(3, tdm_header_type),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_data_format), tdm_data_format),
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tdm_header_type), tdm_header_type),
};
static DEFINE_MUTEX(tdm_mutex);
@@ -298,6 +300,8 @@ static struct afe_param_id_group_device_tdm_cfg tdm_group_cfg = {
0xFF,
};
+static u32 num_tdm_group_ports;
+
static struct afe_clk_set tdm_clk_set = {
AFE_API_VERSION_CLOCK_SET,
Q6AFE_LPASS_CLK_ID_QUAD_TDM_EBIT,
@@ -4981,7 +4985,6 @@ static struct platform_driver msm_dai_q6_spdif_driver = {
static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
{
int rc = 0;
- u32 num_ports = 0;
const uint32_t *port_id_array = NULL;
uint32_t array_length = 0;
int i = 0;
@@ -5004,18 +5007,19 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
rc = of_property_read_u32(pdev->dev.of_node,
"qcom,msm-cpudai-tdm-group-num-ports",
- &num_ports);
+ &num_tdm_group_ports);
if (rc) {
dev_err(&pdev->dev, "%s: Group Num Ports from DT file %s\n",
__func__, "qcom,msm-cpudai-tdm-group-num-ports");
goto rtn;
}
dev_dbg(&pdev->dev, "%s: Group Num Ports from DT file 0x%x\n",
- __func__, num_ports);
+ __func__, num_tdm_group_ports);
- if (num_ports > AFE_GROUP_DEVICE_NUM_PORTS) {
+ if (num_tdm_group_ports > AFE_GROUP_DEVICE_NUM_PORTS) {
dev_err(&pdev->dev, "%s Group Num Ports %d greater than Max %d\n",
- __func__, num_ports, AFE_GROUP_DEVICE_NUM_PORTS);
+ __func__, num_tdm_group_ports,
+ AFE_GROUP_DEVICE_NUM_PORTS);
rc = -EINVAL;
goto rtn;
}
@@ -5029,18 +5033,19 @@ static int msm_dai_tdm_q6_probe(struct platform_device *pdev)
rc = -EINVAL;
goto rtn;
}
- if (array_length != sizeof(uint32_t) * num_ports) {
+ if (array_length != sizeof(uint32_t) * num_tdm_group_ports) {
dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n",
- __func__, array_length, sizeof(uint32_t) * num_ports);
+ __func__, array_length,
+ sizeof(uint32_t) * num_tdm_group_ports);
rc = -EINVAL;
goto rtn;
}
- for (i = 0; i < num_ports; i++)
+ for (i = 0; i < num_tdm_group_ports; i++)
tdm_group_cfg.port_id[i] =
(u16)be32_to_cpu(port_id_array[i]);
/* Unused index should be filled with 0 or AFE_PORT_INVALID */
- for (i = num_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++)
+ for (i = num_tdm_group_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++)
tdm_group_cfg.port_id[i] =
AFE_PORT_INVALID;
@@ -5107,7 +5112,20 @@ static int msm_dai_q6_tdm_data_format_put(struct snd_kcontrol *kcontrol,
struct msm_dai_q6_tdm_dai_data *dai_data = kcontrol->private_data;
int value = ucontrol->value.integer.value[0];
- dai_data->port_cfg.tdm.data_format = value;
+ switch (value) {
+ case 0:
+ dai_data->port_cfg.tdm.data_format = AFE_LINEAR_PCM_DATA;
+ break;
+ case 1:
+ dai_data->port_cfg.tdm.data_format = AFE_NON_LINEAR_DATA;
+ break;
+ case 2:
+ dai_data->port_cfg.tdm.data_format = AFE_GENERIC_COMPRESSED;
+ break;
+ default:
+ pr_err("%s: data_format invalid\n", __func__);
+ break;
+ }
pr_debug("%s: data_format = %d\n",
__func__, dai_data->port_cfg.tdm.data_format);
return 0;
@@ -6047,6 +6065,9 @@ static int msm_dai_q6_tdm_set_tdm_slot(struct snd_soc_dai *dai,
/* HW only supports 16 and 8 slots configuration */
switch (slots) {
+ case 2:
+ cap_mask = 0x03;
+ break;
case 8:
cap_mask = 0xFF;
break;
@@ -6465,17 +6486,25 @@ static int msm_dai_q6_tdm_prepare(struct snd_pcm_substream *substream,
__func__, dai->id);
goto rtn;
}
- rc = afe_port_group_enable(group_id,
- &dai_data->group_cfg, true);
- if (IS_ERR_VALUE(rc)) {
- dev_err(dai->dev, "%s: fail to enable AFE group 0x%x\n",
+
+ /*
+ * if only one port, don't do group enable as there
+ * is no group need for only one port
+ */
+ if (dai_data->num_group_ports > 1) {
+ rc = afe_port_group_enable(group_id,
+ &dai_data->group_cfg, true);
+ if (IS_ERR_VALUE(rc)) {
+ dev_err(dai->dev,
+ "%s: fail to enable AFE group 0x%x\n",
__func__, group_id);
- goto rtn;
+ goto rtn;
+ }
}
}
rc = afe_tdm_port_start(dai->id, &dai_data->port_cfg,
- dai_data->rate);
+ dai_data->rate, dai_data->num_group_ports);
if (IS_ERR_VALUE(rc)) {
if (atomic_read(group_ref) == 0) {
afe_port_group_enable(group_id,
@@ -6569,13 +6598,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM0 Playback",
.aif_name = "PRI_TDM_RX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX,
@@ -6587,13 +6618,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM1 Playback",
.aif_name = "PRI_TDM_RX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_1,
@@ -6605,13 +6638,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM2 Playback",
.aif_name = "PRI_TDM_RX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_2,
@@ -6623,13 +6658,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM3 Playback",
.aif_name = "PRI_TDM_RX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_3,
@@ -6641,13 +6678,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM4 Playback",
.aif_name = "PRI_TDM_RX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_4,
@@ -6659,13 +6698,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM5 Playback",
.aif_name = "PRI_TDM_RX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_5,
@@ -6677,13 +6718,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM6 Playback",
.aif_name = "PRI_TDM_RX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_6,
@@ -6695,13 +6738,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM7 Playback",
.aif_name = "PRI_TDM_RX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_RX_7,
@@ -6713,13 +6758,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM0 Capture",
.aif_name = "PRI_TDM_TX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX,
@@ -6731,13 +6778,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM1 Capture",
.aif_name = "PRI_TDM_TX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_1,
@@ -6749,13 +6798,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM2 Capture",
.aif_name = "PRI_TDM_TX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_2,
@@ -6767,13 +6818,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM3 Capture",
.aif_name = "PRI_TDM_TX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_3,
@@ -6785,13 +6838,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM4 Capture",
.aif_name = "PRI_TDM_TX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_4,
@@ -6803,13 +6858,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM5 Capture",
.aif_name = "PRI_TDM_TX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_5,
@@ -6821,13 +6878,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM6 Capture",
.aif_name = "PRI_TDM_TX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_6,
@@ -6839,13 +6898,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Primary TDM7 Capture",
.aif_name = "PRI_TDM_TX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_PRIMARY_TDM_TX_7,
@@ -6857,13 +6918,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM0 Playback",
.aif_name = "SEC_TDM_RX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX,
@@ -6875,13 +6938,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM1 Playback",
.aif_name = "SEC_TDM_RX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_1,
@@ -6893,13 +6958,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM2 Playback",
.aif_name = "SEC_TDM_RX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_2,
@@ -6911,13 +6978,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM3 Playback",
.aif_name = "SEC_TDM_RX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_3,
@@ -6929,13 +6998,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM4 Playback",
.aif_name = "SEC_TDM_RX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_4,
@@ -6947,13 +7018,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM5 Playback",
.aif_name = "SEC_TDM_RX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_5,
@@ -6965,13 +7038,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM6 Playback",
.aif_name = "SEC_TDM_RX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_6,
@@ -6983,13 +7058,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM7 Playback",
.aif_name = "SEC_TDM_RX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_RX_7,
@@ -7001,13 +7078,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM0 Capture",
.aif_name = "SEC_TDM_TX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX,
@@ -7019,13 +7098,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM1 Capture",
.aif_name = "SEC_TDM_TX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_1,
@@ -7037,13 +7118,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM2 Capture",
.aif_name = "SEC_TDM_TX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_2,
@@ -7055,13 +7138,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM3 Capture",
.aif_name = "SEC_TDM_TX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_3,
@@ -7073,13 +7158,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM4 Capture",
.aif_name = "SEC_TDM_TX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_4,
@@ -7091,13 +7178,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM5 Capture",
.aif_name = "SEC_TDM_TX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_5,
@@ -7109,13 +7198,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM6 Capture",
.aif_name = "SEC_TDM_TX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_6,
@@ -7127,13 +7218,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Secondary TDM7 Capture",
.aif_name = "SEC_TDM_TX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_SECONDARY_TDM_TX_7,
@@ -7145,13 +7238,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM0 Playback",
.aif_name = "TERT_TDM_RX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX,
@@ -7163,13 +7258,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM1 Playback",
.aif_name = "TERT_TDM_RX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_1,
@@ -7181,13 +7278,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM2 Playback",
.aif_name = "TERT_TDM_RX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_2,
@@ -7199,13 +7298,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM3 Playback",
.aif_name = "TERT_TDM_RX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_3,
@@ -7217,13 +7318,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM4 Playback",
.aif_name = "TERT_TDM_RX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_4,
@@ -7235,13 +7338,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM5 Playback",
.aif_name = "TERT_TDM_RX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_5,
@@ -7253,13 +7358,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM6 Playback",
.aif_name = "TERT_TDM_RX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_6,
@@ -7271,13 +7378,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM7 Playback",
.aif_name = "TERT_TDM_RX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_RX_7,
@@ -7289,13 +7398,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM0 Capture",
.aif_name = "TERT_TDM_TX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX,
@@ -7307,13 +7418,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM1 Capture",
.aif_name = "TERT_TDM_TX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_1,
@@ -7325,13 +7438,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM2 Capture",
.aif_name = "TERT_TDM_TX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_2,
@@ -7343,13 +7458,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM3 Capture",
.aif_name = "TERT_TDM_TX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_3,
@@ -7361,13 +7478,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM4 Capture",
.aif_name = "TERT_TDM_TX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_4,
@@ -7379,13 +7498,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM5 Capture",
.aif_name = "TERT_TDM_TX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_5,
@@ -7397,13 +7518,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM6 Capture",
.aif_name = "TERT_TDM_TX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_6,
@@ -7415,13 +7538,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Tertiary TDM7 Capture",
.aif_name = "TERT_TDM_TX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_TERTIARY_TDM_TX_7,
@@ -7433,13 +7558,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM0 Playback",
.aif_name = "QUAT_TDM_RX_0",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
- SNDRV_PCM_RATE_16000,
+ SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX,
@@ -7451,13 +7578,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM1 Playback",
.aif_name = "QUAT_TDM_RX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_1,
@@ -7469,13 +7598,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM2 Playback",
.aif_name = "QUAT_TDM_RX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_2,
@@ -7487,13 +7618,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM3 Playback",
.aif_name = "QUAT_TDM_RX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_3,
@@ -7505,13 +7638,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM4 Playback",
.aif_name = "QUAT_TDM_RX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_4,
@@ -7523,13 +7658,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM5 Playback",
.aif_name = "QUAT_TDM_RX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_5,
@@ -7541,13 +7678,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM6 Playback",
.aif_name = "QUAT_TDM_RX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_6,
@@ -7559,13 +7698,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM7 Playback",
.aif_name = "QUAT_TDM_RX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_RX_7,
@@ -7577,13 +7718,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM0 Capture",
.aif_name = "QUAT_TDM_TX_0",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX,
@@ -7595,13 +7738,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM1 Capture",
.aif_name = "QUAT_TDM_TX_1",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_1,
@@ -7613,13 +7758,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM2 Capture",
.aif_name = "QUAT_TDM_TX_2",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_2,
@@ -7631,13 +7778,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM3 Capture",
.aif_name = "QUAT_TDM_TX_3",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_3,
@@ -7649,13 +7798,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM4 Capture",
.aif_name = "QUAT_TDM_TX_4",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_4,
@@ -7667,13 +7818,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM5 Capture",
.aif_name = "QUAT_TDM_TX_5",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_5,
@@ -7685,13 +7838,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM6 Capture",
.aif_name = "QUAT_TDM_TX_6",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_6,
@@ -7703,13 +7858,15 @@ static struct snd_soc_dai_driver msm_dai_q6_tdm_dai[] = {
.stream_name = "Quaternary TDM7 Capture",
.aif_name = "QUAT_TDM_TX_7",
.rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
- SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000,
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |
+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_352800,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
- SNDRV_PCM_FMTBIT_S24_LE,
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 352800,
},
.ops = &msm_dai_q6_tdm_ops,
.id = AFE_PORT_ID_QUATERNARY_TDM_TX_7,
@@ -7902,6 +8059,9 @@ static int msm_dai_q6_tdm_dev_probe(struct platform_device *pdev)
dai_data->clk_set = tdm_clk_set;
/* copy static group cfg per parent node */
dai_data->group_cfg.tdm_cfg = tdm_group_cfg;
+ /* copy static num group ports per parent node */
+ dai_data->num_group_ports = num_tdm_group_ports;
+
dev_set_drvdata(&pdev->dev, dai_data);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c
index 1fdb878a1a1f..33c5b6486cca 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-noirq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, 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
@@ -139,6 +139,17 @@ static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
.mask = 0,
};
+static unsigned long msm_pcm_fe_topology[MSM_FRONTEND_DAI_MAX];
+
+/* default value is DTS (i.e read from device tree) */
+static char const *msm_pcm_fe_topology_text[] = {
+ "DTS", "ULL", "ULL_PP", "LL" };
+
+static const struct soc_enum msm_pcm_fe_topology_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(msm_pcm_fe_topology_text),
+ msm_pcm_fe_topology_text),
+};
+
static void event_handler(uint32_t opcode,
uint32_t token, uint32_t *payload, void *priv)
{
@@ -258,6 +269,8 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
uint16_t bits_per_sample;
int ret;
int dir = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? IN : OUT;
+ unsigned long topology;
+ int perf_mode;
pdata = (struct msm_plat_data *)
dev_get_drvdata(soc_prtd->platform->dev);
@@ -268,11 +281,24 @@ static int msm_pcm_hw_params(struct snd_pcm_substream *substream,
return ret;
}
+ topology = msm_pcm_fe_topology[soc_prtd->dai_link->be_id];
+
+ if (!strcmp(msm_pcm_fe_topology_text[topology], "ULL_PP"))
+ perf_mode = ULL_POST_PROCESSING_PCM_MODE;
+ else if (!strcmp(msm_pcm_fe_topology_text[topology], "ULL"))
+ perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
+ else if (!strcmp(msm_pcm_fe_topology_text[topology], "LL"))
+ perf_mode = LOW_LATENCY_PCM_MODE;
+ else
+ /* use the default from the device tree */
+ perf_mode = pdata->perf_mode;
+
+
/* need to set LOW_LATENCY_PCM_MODE for capture since
* push mode does not support ULL
*/
prtd->audio_client->perf_mode = (dir == IN) ?
- pdata->perf_mode :
+ perf_mode :
LOW_LATENCY_PCM_MODE;
/* rate and channels are sent to audio driver */
@@ -721,6 +747,93 @@ static int msm_pcm_add_chmap_control(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int msm_pcm_fe_topology_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ const struct soc_enum *e = &msm_pcm_fe_topology_enum[0];
+
+ return snd_ctl_enum_info(uinfo, 1, e->items, e->texts);
+}
+
+static int msm_pcm_fe_topology_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned long fe_id = kcontrol->private_value;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: %lu topology %s\n", __func__, fe_id,
+ msm_pcm_fe_topology_text[msm_pcm_fe_topology[fe_id]]);
+ ucontrol->value.enumerated.item[0] = msm_pcm_fe_topology[fe_id];
+ return 0;
+}
+
+static int msm_pcm_fe_topology_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ unsigned long fe_id = kcontrol->private_value;
+ unsigned int item;
+
+ if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+ pr_err("%s Received out of bound fe_id %lu\n", __func__, fe_id);
+ return -EINVAL;
+ }
+
+ item = ucontrol->value.enumerated.item[0];
+ if (item >= ARRAY_SIZE(msm_pcm_fe_topology_text)) {
+ pr_err("%s Received out of bound topology %lu\n", __func__,
+ fe_id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: %lu new topology %s\n", __func__, fe_id,
+ msm_pcm_fe_topology_text[item]);
+ msm_pcm_fe_topology[fe_id] = item;
+ return 0;
+}
+
+static int msm_pcm_add_fe_topology_control(struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = "PCM_Dev";
+ const char *deviceNo = "NN";
+ const char *topo_text = "Topology";
+ char *mixer_str = NULL;
+ int ctl_len;
+ int ret;
+ struct snd_kcontrol_new topology_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .name = "?",
+ .info = msm_pcm_fe_topology_info,
+ .get = msm_pcm_fe_topology_get,
+ .put = msm_pcm_fe_topology_put,
+ .private_value = 0,
+ },
+ };
+
+ ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
+ strlen(topo_text) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+
+ if (!mixer_str)
+ return -ENOMEM;
+
+ snprintf(mixer_str, ctl_len, "%s %d %s", mixer_ctl_name,
+ rtd->pcm->device, topo_text);
+
+ topology_control[0].name = mixer_str;
+ topology_control[0].private_value = rtd->dai_link->be_id;
+ ret = snd_soc_add_platform_controls(rtd->platform, topology_control,
+ ARRAY_SIZE(topology_control));
+ msm_pcm_fe_topology[rtd->dai_link->be_id] = 0;
+ kfree(mixer_str);
+ return ret;
+}
+
static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
@@ -741,6 +854,12 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add pcm Volume Control %d\n",
__func__, ret);
}
+
+ ret = msm_pcm_add_fe_topology_control(rtd);
+ if (ret) {
+ pr_err("%s: Could not add pcm topology control %d\n",
+ __func__, ret);
+ }
pcm->nonatomic = true;
exit:
return ret;
@@ -778,8 +897,12 @@ static int msm_pcm_probe(struct platform_device *pdev)
rc = of_property_read_string(pdev->dev.of_node,
"qcom,latency-level", &latency_level);
- if (!rc && !strcmp(latency_level, "ultra"))
- perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
+ if (!rc) {
+ if (!strcmp(latency_level, "ultra"))
+ perf_mode = ULTRA_LOW_LATENCY_PCM_MODE;
+ else if (!strcmp(latency_level, "ull-pp"))
+ perf_mode = ULL_POST_PROCESSING_PCM_MODE;
+ }
}
pdata = devm_kzalloc(&pdev->dev,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
index e2f662f26cff..e14f410bd310 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.c
@@ -110,7 +110,7 @@ static struct snd_pcm_hardware msm_pcm_hardware_playback = {
/* Conventional and unconventional sample rate supported */
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000,
- 88200, 96000, 176400, 192000, 384000
+ 88200, 96000, 176400, 192000, 352800, 384000
};
static struct snd_pcm_hw_constraint_list constraints_sample_rates = {
@@ -285,6 +285,7 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
struct msm_plat_data *pdata;
struct snd_pcm_hw_params *params;
int ret;
+ uint32_t fmt_type = FORMAT_LINEAR_PCM;
uint16_t bits_per_sample;
uint16_t sample_word_size;
@@ -333,38 +334,67 @@ static int msm_pcm_playback_prepare(struct snd_pcm_substream *substream)
sample_word_size = 16;
break;
}
+ if (prtd->compress_enable) {
+ fmt_type = FORMAT_GEN_COMPR;
+ pr_debug("%s: Compressed enabled!\n", __func__);
+ ret = q6asm_open_write_compressed(prtd->audio_client, fmt_type,
+ COMPRESSED_PASSTHROUGH_GEN);
+ if (ret < 0) {
+ pr_err("%s: q6asm_open_write_compressed failed (%d)\n",
+ __func__, ret);
+ q6asm_audio_client_free(prtd->audio_client);
+ prtd->audio_client = NULL;
+ return -ENOMEM;
+ }
+ } else {
+ ret = q6asm_open_write_v4(prtd->audio_client,
+ fmt_type, bits_per_sample);
- ret = q6asm_open_write_v4(prtd->audio_client,
- FORMAT_LINEAR_PCM, bits_per_sample);
+ if (ret < 0) {
+ pr_err("%s: q6asm_open_write_v4 failed (%d)\n",
+ __func__, ret);
+ q6asm_audio_client_free(prtd->audio_client);
+ prtd->audio_client = NULL;
+ return -ENOMEM;
+ }
- if (ret < 0) {
- pr_err("%s: q6asm_open_write_v2 failed\n", __func__);
- q6asm_audio_client_free(prtd->audio_client);
- prtd->audio_client = NULL;
- return -ENOMEM;
+ ret = q6asm_send_cal(prtd->audio_client);
+ if (ret < 0)
+ pr_debug("%s : Send cal failed : %d", __func__, ret);
}
-
- ret = q6asm_send_cal(prtd->audio_client);
- if (ret < 0)
- pr_debug("%s : Send cal failed : %d", __func__, ret);
-
pr_debug("%s: session ID %d\n", __func__,
prtd->audio_client->session);
prtd->session_id = prtd->audio_client->session;
- ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
+
+ if (prtd->compress_enable) {
+ ret = msm_pcm_routing_reg_phy_compr_stream(
+ soc_prtd->dai_link->be_id,
+ prtd->audio_client->perf_mode,
+ prtd->session_id,
+ SNDRV_PCM_STREAM_PLAYBACK,
+ COMPRESSED_PASSTHROUGH_GEN);
+ } else {
+ ret = msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
prtd->audio_client->perf_mode,
prtd->session_id, substream->stream);
+ }
if (ret) {
pr_err("%s: stream reg failed ret:%d\n", __func__, ret);
return ret;
}
-
- ret = q6asm_media_format_block_multi_ch_pcm_v4(
+ if (prtd->compress_enable) {
+ ret = q6asm_media_format_block_gen_compr(
+ prtd->audio_client, runtime->rate,
+ runtime->channels, !prtd->set_channel_map,
+ prtd->channel_map, bits_per_sample);
+ } else {
+ ret = q6asm_media_format_block_multi_ch_pcm_v4(
prtd->audio_client, runtime->rate,
runtime->channels, !prtd->set_channel_map,
prtd->channel_map, bits_per_sample,
sample_word_size, ASM_LITTLE_ENDIAN,
DEFAULT_QF);
+ }
if (ret < 0)
pr_info("%s: CMD Format block failed\n", __func__);
@@ -1091,6 +1121,136 @@ static int msm_pcm_add_volume_control(struct snd_soc_pcm_runtime *rtd)
return 0;
}
+static int msm_pcm_compress_ctl_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 0x2000;
+ return 0;
+}
+
+static int msm_pcm_compress_ctl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
+ struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
+ struct snd_pcm_substream *substream;
+ struct msm_audio *prtd;
+
+ if (!pdata) {
+ pr_err("%s pdata is NULL\n", __func__);
+ return -ENODEV;
+ }
+ substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ if (!substream) {
+ pr_err("%s substream not found\n", __func__);
+ return -EINVAL;
+ }
+ if (!substream->runtime) {
+ pr_err("%s substream runtime not found\n", __func__);
+ return 0;
+ }
+ prtd = substream->runtime->private_data;
+ if (prtd)
+ ucontrol->value.integer.value[0] = prtd->compress_enable;
+ return 0;
+}
+
+static int msm_pcm_compress_ctl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int rc = 0;
+ struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(comp);
+ struct msm_plat_data *pdata = dev_get_drvdata(platform->dev);
+ struct snd_pcm_substream *substream;
+ struct msm_audio *prtd;
+ int compress = ucontrol->value.integer.value[0];
+
+ if (!pdata) {
+ pr_err("%s pdata is NULL\n", __func__);
+ return -ENODEV;
+ }
+ substream = pdata->pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ pr_debug("%s: compress : 0x%x\n", __func__, compress);
+ if (!substream) {
+ pr_err("%s substream not found\n", __func__);
+ return -EINVAL;
+ }
+ if (!substream->runtime) {
+ pr_err("%s substream runtime not found\n", __func__);
+ return 0;
+ }
+ prtd = substream->runtime->private_data;
+ if (prtd) {
+ pr_debug("%s: setting compress flag to 0x%x\n",
+ __func__, compress);
+ prtd->compress_enable = compress;
+ }
+ return rc;
+}
+
+static int msm_pcm_add_compress_control(struct snd_soc_pcm_runtime *rtd)
+{
+ const char *mixer_ctl_name = "Playback ";
+ const char *mixer_ctl_end_name = " Compress";
+ const char *deviceNo = "NN";
+ char *mixer_str = NULL;
+ int ctl_len;
+ int ret = 0;
+ struct msm_plat_data *pdata;
+ struct snd_kcontrol_new pcm_compress_control[1] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "?",
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = msm_pcm_compress_ctl_info,
+ .get = msm_pcm_compress_ctl_get,
+ .put = msm_pcm_compress_ctl_put,
+ .private_value = 0,
+ }
+ };
+
+ if (!rtd) {
+ pr_err("%s: NULL rtd\n", __func__);
+ return -EINVAL;
+ }
+
+ ctl_len = strlen(mixer_ctl_name) + strlen(deviceNo) +
+ strlen(mixer_ctl_end_name) + 1;
+ mixer_str = kzalloc(ctl_len, GFP_KERNEL);
+
+ if (!mixer_str)
+ return -ENOMEM;
+
+ snprintf(mixer_str, ctl_len, "%s%d%s", mixer_ctl_name,
+ rtd->pcm->device, mixer_ctl_end_name);
+
+ pcm_compress_control[0].name = mixer_str;
+ pcm_compress_control[0].private_value = rtd->dai_link->be_id;
+ pr_debug("%s: Registering new mixer ctl %s\n", __func__, mixer_str);
+ pdata = dev_get_drvdata(rtd->platform->dev);
+ if (pdata) {
+ if (!pdata->pcm) {
+ pdata->pcm = rtd->pcm;
+ snd_soc_add_platform_controls(rtd->platform,
+ pcm_compress_control,
+ ARRAY_SIZE
+ (pcm_compress_control));
+ pr_debug("%s: add control success plt = %pK\n",
+ __func__, rtd->platform);
+ }
+ } else {
+ pr_err("%s: NULL pdata\n", __func__);
+ ret = -EINVAL;
+ }
+ kfree(mixer_str);
+ return ret;
+}
+
static int msm_pcm_chmap_ctl_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1381,6 +1541,11 @@ static int msm_asoc_pcm_new(struct snd_soc_pcm_runtime *rtd)
pr_err("%s: Could not add pcm Volume Control %d\n",
__func__, ret);
+ ret = msm_pcm_add_compress_control(rtd);
+ if (ret)
+ pr_err("%s: Could not add pcm Compress Control %d\n",
+ __func__, ret);
+
return ret;
}
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
index 8fe31394eef0..f5ff63f34b82 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-q6-v2.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -109,6 +109,7 @@ struct msm_audio {
int cmd_interrupt;
bool meta_data_mode;
uint32_t volume;
+ bool compress_enable;
/* array of frame info */
struct msm_audio_in_frame_info in_frame_info[CAPTURE_MAX_NUM_PERIODS];
};
@@ -123,6 +124,7 @@ struct output_meta_data_st {
struct msm_plat_data {
int perf_mode;
+ struct snd_pcm *pcm;
};
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index e93d46b5f30f..cfade420c509 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1143,8 +1143,10 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
topology = msm_routing_get_adm_topology(fe_id,
session_type,
i);
- if (passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
- topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY;
+ if ((passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
+ || (passthr_mode ==
+ COMPRESSED_PASSTHROUGH_GEN))
+ topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY;
pr_debug("%s: Before adm open topology %d\n", __func__,
topology);
@@ -1194,7 +1196,9 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
num_copps++;
}
}
- if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD) {
+ if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD
+ && passthr_mode !=
+ COMPRESSED_PASSTHROUGH_GEN) {
msm_routing_send_device_pp_params(
msm_bedais[i].port_id,
copp_idx);
@@ -12175,6 +12179,42 @@ static const struct snd_soc_dapm_route intercon[] = {
{"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
{"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"PRI_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"PRI_TDM_RX_0", NULL, "PRI_TDM_RX_0 Audio Mixer"},
+
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SEC_TDM_RX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SEC_TDM_RX_0", NULL, "SEC_TDM_RX_0 Audio Mixer"},
+
{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c
index be5437a186ea..bc1d21a826b5 100644
--- a/sound/soc/msm/qdsp6v2/q6afe.c
+++ b/sound/soc/msm/qdsp6v2/q6afe.c
@@ -113,6 +113,7 @@ struct afe_ctl {
struct audio_cal_info_sp_ex_vi_ftm_cfg ex_ftm_cfg;
struct afe_sp_th_vi_get_param_resp th_vi_resp;
struct afe_sp_ex_vi_get_param_resp ex_vi_resp;
+ struct afe_av_dev_drift_get_param_resp av_dev_drift_resp;
int vi_tx_port;
int vi_rx_port;
uint32_t afe_sample_rates[AFE_MAX_PORTS];
@@ -189,6 +190,38 @@ static void afe_callback_debug_print(struct apr_client_data *data)
__func__, data->opcode, data->payload_size);
}
+static void av_dev_drift_afe_cb_handler(uint32_t *payload,
+ uint32_t payload_size)
+{
+ u32 param_id;
+ struct afe_av_dev_drift_get_param_resp *resp =
+ (struct afe_av_dev_drift_get_param_resp *) payload;
+
+ if (!(&(resp->pdata))) {
+ pr_err("%s: Error: resp pdata is NULL\n", __func__);
+ return;
+ }
+
+ param_id = resp->pdata.param_id;
+ if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
+ if (payload_size < sizeof(this_afe.av_dev_drift_resp)) {
+ pr_err("%s: Error: received size %d, resp size %zu\n",
+ __func__, payload_size,
+ sizeof(this_afe.av_dev_drift_resp));
+ return;
+ }
+ memcpy(&this_afe.av_dev_drift_resp, payload,
+ sizeof(this_afe.av_dev_drift_resp));
+ if (!this_afe.av_dev_drift_resp.status) {
+ atomic_set(&this_afe.state, 0);
+ } else {
+ pr_debug("%s: av_dev_drift_resp status: %d", __func__,
+ this_afe.av_dev_drift_resp.status);
+ atomic_set(&this_afe.state, -1);
+ }
+ }
+}
+
static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size)
{
u32 param_id;
@@ -309,10 +342,7 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
}
afe_callback_debug_print(data);
if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2) {
- u8 *payload = data->payload;
-
- if (rtac_make_afe_callback(data->payload, data->payload_size))
- return 0;
+ uint32_t *payload = data->payload;
if (!payload || (data->token >= AFE_MAX_PORTS)) {
pr_err("%s: Error: size %d payload %pK token %d\n",
@@ -320,9 +350,19 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
payload, data->token);
return -EINVAL;
}
- if (sp_make_afe_callback(data->payload, data->payload_size))
- return -EINVAL;
+ if (payload[2] == AFE_PARAM_ID_DEV_TIMING_STATS) {
+ av_dev_drift_afe_cb_handler(data->payload,
+ data->payload_size);
+ } else {
+ if (rtac_make_afe_callback(data->payload,
+ data->payload_size))
+ return 0;
+
+ if (sp_make_afe_callback(data->payload,
+ data->payload_size))
+ return -EINVAL;
+ }
wake_up(&this_afe.wait[data->token]);
} else if (data->payload_size) {
uint32_t *payload;
@@ -1181,6 +1221,7 @@ static int afe_send_hw_delay(u16 port_id, u32 rate)
pr_debug("%s:\n", __func__);
+ memset(&delay_entry, 0, sizeof(delay_entry));
delay_entry.sample_rate = rate;
if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry);
@@ -2541,7 +2582,7 @@ fail_cmd:
}
int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
- u32 rate)
+ u32 rate, u16 num_groups)
{
struct afe_audioif_config_command config;
int ret = 0;
@@ -2581,9 +2622,10 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id);
}
- /* Also send the topology id here: */
+ /* Also send the topology id here if multiple ports: */
port_index = afe_get_port_index(port_id);
- if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
+ if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE) &&
+ num_groups > 1) {
/* One time call: only for first time */
afe_send_custom_topology();
afe_send_port_topology_id(port_id);
@@ -2645,11 +2687,14 @@ int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
ret = -EINVAL;
goto fail_cmd;
}
-
- ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping, port_id);
- if (ret < 0) {
- pr_err("%s: afe send failed %d\n", __func__, ret);
- goto fail_cmd;
+ /* slot mapping is not need if there is only one group */
+ if (num_groups > 1) {
+ ret = afe_send_slot_mapping_cfg(&tdm_port->slot_mapping,
+ port_id);
+ if (ret < 0) {
+ pr_err("%s: afe send failed %d\n", __func__, ret);
+ goto fail_cmd;
+ }
}
if (tdm_port->custom_tdm_header.header_type) {
@@ -2763,6 +2808,11 @@ static int q6afe_send_enc_config(u16 port_id,
}
memset(&config, 0, sizeof(config));
index = q6audio_get_port_index(port_id);
+ if (index < 0) {
+ pr_err("%s: Invalid index number: %d\n", __func__, index);
+ return -EINVAL;
+ }
+
config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
config.hdr.pkt_size = sizeof(config);
@@ -6163,6 +6213,88 @@ done:
return ret;
}
+int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
+ u16 port)
+{
+ int ret = -EINVAL;
+ int index = 0;
+ struct afe_av_dev_drift_get_param av_dev_drift;
+
+ if (!timing_stats) {
+ pr_err("%s: Invalid params\n", __func__);
+ goto exit;
+ }
+
+ ret = q6audio_validate_port(port);
+ if (ret < 0) {
+ pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ index = q6audio_get_port_index(port);
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: Invalid AFE port index[%d]\n",
+ __func__, index);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param));
+
+ av_dev_drift.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift);
+ av_dev_drift.hdr.src_port = 0;
+ av_dev_drift.hdr.dest_port = 0;
+ av_dev_drift.hdr.token = index;
+ av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
+ av_dev_drift.get_param.mem_map_handle = 0;
+ av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
+ av_dev_drift.get_param.payload_address_lsw = 0;
+ av_dev_drift.get_param.payload_address_msw = 0;
+ av_dev_drift.get_param.payload_size = sizeof(av_dev_drift)
+ - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr);
+ av_dev_drift.get_param.port_id = q6audio_get_port_id(port);
+ av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
+ av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats);
+ atomic_set(&this_afe.status, 0);
+ atomic_set(&this_afe.state, 1);
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift);
+ if (ret < 0) {
+ pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
+ __func__, port, av_dev_drift.get_param.param_id, ret);
+ goto exit;
+ }
+
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ if (atomic_read(&this_afe.status) > 0) {
+ pr_err("%s: config cmd failed [%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&this_afe.status)));
+ ret = adsp_err_get_lnx_err_code(
+ atomic_read(&this_afe.status));
+ goto exit;
+ }
+
+ memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats,
+ sizeof(this_afe.av_dev_drift_resp.timing_stats));
+ ret = 0;
+exit:
+ return ret;
+}
+
int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
{
int ret = -EINVAL;
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 74fbe984e6e9..d55c28fab652 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -2490,6 +2490,10 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
case FORMAT_DSD:
open.fmt_id = ASM_MEDIA_FMT_DSD;
break;
+ case FORMAT_GEN_COMPR:
+ open.fmt_id = ASM_MEDIA_FMT_GENERIC_COMPRESSED;
+ break;
+
default:
pr_err("%s: Invalid format[%d]\n", __func__, format);
rc = -EINVAL;
@@ -2498,7 +2502,8 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
/*Below flag indicates the DSP that Compressed audio input
stream is not IEC 61937 or IEC 60958 packetizied*/
if (passthrough_flag == COMPRESSED_PASSTHROUGH ||
- passthrough_flag == COMPRESSED_PASSTHROUGH_DSD) {
+ passthrough_flag == COMPRESSED_PASSTHROUGH_DSD ||
+ passthrough_flag == COMPRESSED_PASSTHROUGH_GEN) {
open.flags = 0x0;
pr_debug("%s: Flag 0 COMPRESSED_PASSTHROUGH\n", __func__);
} else if (passthrough_flag == COMPRESSED_PASSTHROUGH_CONVERT) {
@@ -2665,6 +2670,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
case FORMAT_APTX:
open.dec_fmt_id = ASM_MEDIA_FMT_APTX;
break;
+ case FORMAT_GEN_COMPR:
+ open.dec_fmt_id = ASM_MEDIA_FMT_GENERIC_COMPRESSED;
+ break;
default:
pr_err("%s: Invalid format 0x%x\n", __func__, format);
rc = -EINVAL;
@@ -5191,6 +5199,82 @@ int q6asm_media_format_block_multi_ch_pcm_v4(struct audio_client *ac,
}
EXPORT_SYMBOL(q6asm_media_format_block_multi_ch_pcm_v4);
+/*
+ * q6asm_media_format_block_gen_compr - set up generic compress format params
+ *
+ * @ac: Client session handle
+ * @rate: sample rate
+ * @channels: number of channels
+ * @use_default_chmap: true if default channel map to be used
+ * @channel_map: input channel map
+ * @bits_per_sample: bit width of gen compress stream
+ */
+int q6asm_media_format_block_gen_compr(struct audio_client *ac,
+ uint32_t rate, uint32_t channels,
+ bool use_default_chmap, char *channel_map,
+ uint16_t bits_per_sample)
+{
+ struct asm_generic_compressed_fmt_blk_t fmt;
+ u8 *channel_mapping;
+ int rc = 0;
+
+ pr_debug("%s: session[%d]rate[%d]ch[%d]bps[%d]\n",
+ __func__, ac->session, rate,
+ channels, bits_per_sample);
+
+ memset(&fmt, 0, sizeof(fmt));
+ q6asm_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE);
+
+ fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+ fmt.fmt_blk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
+ sizeof(fmt.fmt_blk);
+ fmt.num_channels = channels;
+ fmt.bits_per_sample = bits_per_sample;
+ fmt.sampling_rate = rate;
+
+ channel_mapping = fmt.channel_mapping;
+
+ memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+ if (use_default_chmap) {
+ if (q6asm_map_channels(channel_mapping, channels, false)) {
+ pr_err("%s: map channels failed %d\n",
+ __func__, channels);
+ return -EINVAL;
+ }
+ } else {
+ memcpy(channel_mapping, channel_map,
+ PCM_FORMAT_MAX_NUM_CHANNEL);
+ }
+
+ atomic_set(&ac->cmd_state, -1);
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+ if (rc < 0) {
+ pr_err("%s: Comamnd open failed %d\n", __func__, rc);
+ rc = -EINVAL;
+ goto fail_cmd;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout. waited for format update\n", __func__);
+ rc = -ETIMEDOUT;
+ goto fail_cmd;
+ }
+
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ }
+ return 0;
+fail_cmd:
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_media_format_block_gen_compr);
+
static int __q6asm_media_format_block_multi_aac(struct audio_client *ac,
struct asm_aac_cfg *cfg, int stream_id)
{