diff options
133 files changed, 5509 insertions, 561 deletions
diff --git a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt index e42c348aad26..102857a13a86 100644 --- a/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt +++ b/Documentation/devicetree/bindings/sound/qcom-audio-dev.txt @@ -2703,12 +2703,12 @@ Required properties: The size of the array is determined by the value in msm-cpudai-mi2s-group-num-ports. Each group supports up to 4 ports: - Secondary RX: 4160, 4162, 4164, 4174, - Secondary TX: 4161, 4163, 4165, 4175, - Tertiary RX: 4168, 4170, 4172, 4176, - Tertiary TX: 4169, 4171, 4173, 4177, - Quaternary RX: 4102, 4128, 4130, 4132, - Quaternary TX: 4103, 4129, 4131, 4133, + Secondary RX: 4160, 4162, 4164, 4166, + Secondary TX: 4161, 4163, 4165, 4167, + Tertiary RX: 4168, 4170, 4172, 4174, + Tertiary TX: 4169, 4171, 4173, 4175, + Quaternary RX: 4128, 4130, 4132, 4134, + Quaternary TX: 4129, 4131, 4133, 4135, - qcom,msm-cpudai-mi2s-channel-mode: group mi2s line channel mode. I2S_SD0 : 0x1 @@ -1,6 +1,6 @@ VERSION = 4 PATCHLEVEL = 4 -SUBLEVEL = 166 +SUBLEVEL = 167 EXTRAVERSION = NAME = Blurry Fish Butt @@ -814,6 +814,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) # disable pointer signed / unsigned warnings in gcc 4.0 KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign) +# disable stringop warnings in gcc 8+ +KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation) + # disable invalid "can't wrap" optimizations for signed / pointers KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index c4ee25e88a7b..e983f410135a 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -96,7 +96,7 @@ endmenu choice prompt "ARC Instruction Set" - default ISA_ARCOMPACT + default ISA_ARCV2 config ISA_ARCOMPACT bool "ARCompact ISA" diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 9d64eacdd2aa..fffaff9c7b2c 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -12,7 +12,7 @@ ifeq ($(CROSS_COMPILE),) CROSS_COMPILE := arc-linux- endif -KBUILD_DEFCONFIG := nsim_700_defconfig +KBUILD_DEFCONFIG := nsim_hs_defconfig cflags-y += -fno-common -pipe -fno-builtin -mmedium-calls -D__linux__ cflags-$(CONFIG_ISA_ARCOMPACT) += -mA7 diff --git a/arch/arc/configs/axs101_defconfig b/arch/arc/configs/axs101_defconfig index dbee1934dfc6..3023f91c77c2 100644 --- a/arch/arc/configs/axs101_defconfig +++ b/arch/arc/configs/axs101_defconfig @@ -17,6 +17,7 @@ CONFIG_PERF_EVENTS=y # CONFIG_VM_EVENT_COUNTERS is not set # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set +CONFIG_ISA_ARCOMPACT=y CONFIG_MODULES=y CONFIG_PARTITION_ADVANCED=y CONFIG_ARC_PLAT_AXS10X=y @@ -97,6 +98,7 @@ CONFIG_NTFS_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set diff --git a/arch/arc/configs/axs103_defconfig b/arch/arc/configs/axs103_defconfig index 561eac854cc3..f18107185f53 100644 --- a/arch/arc/configs/axs103_defconfig +++ b/arch/arc/configs/axs103_defconfig @@ -103,6 +103,7 @@ CONFIG_NTFS_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set diff --git a/arch/arc/configs/axs103_smp_defconfig b/arch/arc/configs/axs103_smp_defconfig index aa4f261b6508..6e1dd8521d2a 100644 --- a/arch/arc/configs/axs103_smp_defconfig +++ b/arch/arc/configs/axs103_smp_defconfig @@ -104,6 +104,7 @@ CONFIG_NTFS_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set diff --git a/arch/arc/configs/nsim_700_defconfig b/arch/arc/configs/nsim_700_defconfig index 138f9d887957..86e5a62556a8 100644 --- a/arch/arc/configs/nsim_700_defconfig +++ b/arch/arc/configs/nsim_700_defconfig @@ -16,6 +16,7 @@ CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set +CONFIG_ISA_ARCOMPACT=y CONFIG_KPROBES=y CONFIG_MODULES=y # CONFIG_LBDAF is not set diff --git a/arch/arc/configs/nsimosci_defconfig b/arch/arc/configs/nsimosci_defconfig index 31e1d95764ff..a4d7b919224a 100644 --- a/arch/arc/configs/nsimosci_defconfig +++ b/arch/arc/configs/nsimosci_defconfig @@ -17,6 +17,7 @@ CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set +CONFIG_ISA_ARCOMPACT=y CONFIG_KPROBES=y CONFIG_MODULES=y # CONFIG_LBDAF is not set @@ -69,5 +70,6 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_TMPFS=y # CONFIG_MISC_FILESYSTEMS is not set CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set diff --git a/arch/arc/configs/nsimosci_hs_defconfig b/arch/arc/configs/nsimosci_hs_defconfig index fcae66683ca0..b3fb49c8bd14 100644 --- a/arch/arc/configs/nsimosci_hs_defconfig +++ b/arch/arc/configs/nsimosci_hs_defconfig @@ -69,5 +69,6 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_TMPFS=y # CONFIG_MISC_FILESYSTEMS is not set CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set diff --git a/arch/arc/configs/nsimosci_hs_smp_defconfig b/arch/arc/configs/nsimosci_hs_smp_defconfig index b01b659168ea..710c167bbdd8 100644 --- a/arch/arc/configs/nsimosci_hs_smp_defconfig +++ b/arch/arc/configs/nsimosci_hs_smp_defconfig @@ -88,6 +88,7 @@ CONFIG_EXT2_FS_XATTR=y CONFIG_TMPFS=y # CONFIG_MISC_FILESYSTEMS is not set CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y # CONFIG_ENABLE_WARN_DEPRECATED is not set # CONFIG_ENABLE_MUST_CHECK is not set CONFIG_FTRACE=y diff --git a/arch/arc/configs/tb10x_defconfig b/arch/arc/configs/tb10x_defconfig index 3b4dc9cebcf1..7469b754ac77 100644 --- a/arch/arc/configs/tb10x_defconfig +++ b/arch/arc/configs/tb10x_defconfig @@ -19,6 +19,7 @@ CONFIG_KALLSYMS_ALL=y # CONFIG_AIO is not set CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set +CONFIG_ISA_ARCOMPACT=y CONFIG_SLAB=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y diff --git a/arch/arc/configs/vdk_hs38_defconfig b/arch/arc/configs/vdk_hs38_defconfig index a07f20de221b..772073e5ba04 100644 --- a/arch/arc/configs/vdk_hs38_defconfig +++ b/arch/arc/configs/vdk_hs38_defconfig @@ -89,6 +89,7 @@ CONFIG_NTFS_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set diff --git a/arch/arc/configs/vdk_hs38_smp_defconfig b/arch/arc/configs/vdk_hs38_smp_defconfig index f36c047b33ca..50e215a163ff 100644 --- a/arch/arc/configs/vdk_hs38_smp_defconfig +++ b/arch/arc/configs/vdk_hs38_smp_defconfig @@ -91,6 +91,7 @@ CONFIG_NTFS_FS=y CONFIG_TMPFS=y CONFIG_JFFS2_FS=y CONFIG_NFS_FS=y +CONFIG_NFS_V3_ACL=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y # CONFIG_ENABLE_WARN_DEPRECATED is not set diff --git a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi index 1a9a24cec1ba..f484eea9f01a 100644 --- a/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi +++ b/arch/arm/boot/dts/qcom/apq8096-auto-dragonboard.dtsi @@ -767,13 +767,13 @@ "msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160", "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164", - "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4161", + "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161", "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165", - "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4168", + "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168", "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172", - "msm-dai-q6-mi2s.4176", "msm-dai-q6-mi2s.4169", + "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169", "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173", - "msm-dai-q6-mi2s.4177", "msm-dai-q6-mi2s.4128", + "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128", "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132", "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129", "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133", diff --git a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi index b2f9becfff35..db99055e095f 100644 --- a/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-agave-adp.dtsi @@ -1144,13 +1144,13 @@ "msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160", "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164", - "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4161", + "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161", "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165", - "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4168", + "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168", "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172", - "msm-dai-q6-mi2s.4176", "msm-dai-q6-mi2s.4169", + "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169", "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173", - "msm-dai-q6-mi2s.4177", "msm-dai-q6-mi2s.4128", + "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128", "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132", "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129", "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133", @@ -1465,7 +1465,6 @@ &usb2s { status = "ok"; qcom,no-wakeup-src-in-hostmode; - qcom,disable-host-mode-pm; }; &usb3 { @@ -1474,7 +1473,6 @@ vdda33-supply = <&pm8994_l24>; vdda18-supply = <&pm8994_l12>; qcom,no-wakeup-src-in-hostmode; - qcom,disable-host-mode-pm; }; &blsp1_uart2 { diff --git a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi index 859bbfd6012f..b0ff859d560f 100644 --- a/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-auto-cdp.dtsi @@ -997,13 +997,13 @@ "msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160", "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164", - "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4161", + "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161", "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165", - "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4168", + "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168", "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172", - "msm-dai-q6-mi2s.4176", "msm-dai-q6-mi2s.4169", + "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169", "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173", - "msm-dai-q6-mi2s.4177", "msm-dai-q6-mi2s.4128", + "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128", "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132", "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129", "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133", @@ -1296,7 +1296,6 @@ status = "ok"; vbus_dwc3-supply = <&usb2_otg_switch>; qcom,no-wakeup-src-in-hostmode; - qcom,disable-host-mode-pm; dwc3@7600000 { dr_mode = "host"; }; @@ -1308,7 +1307,6 @@ vdda33-supply = <&pm8994_l24>; vdda18-supply = <&pm8994_l12>; qcom,no-wakeup-src-in-hostmode; - qcom,disable-host-mode-pm; }; &blsp1_uart2 { @@ -1459,11 +1457,6 @@ / { reserved-memory { - lk_mem: lk_pool@0x91600000 { - reg = <0 0x91600000 0 0x00600000>; - label = "lk_pool"; - }; - early_camera_mem: early_camera_mem@b3fff000 { reg = <0 0xb3fff000 0 0x800000>; label = "early_camera_mem"; @@ -1492,3 +1485,10 @@ &ssc_sensors { status = "disabled"; }; + +&soc { + early_domain: early_domain { + compatible = "qcom,early_domain"; + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi index 085f94d7f5b3..4367a876a64d 100644 --- a/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996-mmxf-adp.dtsi @@ -592,13 +592,13 @@ "msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160", "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164", - "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4161", + "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161", "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165", - "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4168", + "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168", "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172", - "msm-dai-q6-mi2s.4176", "msm-dai-q6-mi2s.4169", + "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169", "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173", - "msm-dai-q6-mi2s.4177", "msm-dai-q6-mi2s.4128", + "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128", "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132", "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129", "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133", diff --git a/arch/arm/boot/dts/qcom/msm8996.dtsi b/arch/arm/boot/dts/qcom/msm8996.dtsi index 6e2d9a8bf1fc..aa1d28a082a8 100644 --- a/arch/arm/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm/boot/dts/qcom/msm8996.dtsi @@ -3564,7 +3564,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4354>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4160 4162 4164 4174>; + qcom,msm-cpudai-mi2s-group-port-id = <4160 4162 4164 4166>; qcom,msm-cpudai-mi2s-channel-mode = <2>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <12288000>; @@ -3592,7 +3592,7 @@ dai_sec_mi2s_rx_4:qcom,msm-dai-q6-mi2s-sec-rx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4174>; + qcom,msm-cpudai-mi2s-dev-id = <4166>; qcom,msm-cpudai-mi2s-dev-channel-mode = <2>; qcom,msm-cpudai-mi2s-data-align = <0>; }; @@ -3602,7 +3602,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4355>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4161 4163 4165 4175>; + qcom,msm-cpudai-mi2s-group-port-id = <4161 4163 4165 4167>; qcom,msm-cpudai-mi2s-channel-mode = <1>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <12288000>; @@ -3630,7 +3630,7 @@ dai_sec_mi2s_tx_4:qcom,msm-dai-q6-mi2s-sec-tx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4175>; + qcom,msm-cpudai-mi2s-dev-id = <4167>; qcom,msm-cpudai-mi2s-dev-channel-mode = <1>; qcom,msm-cpudai-mi2s-data-align = <0>; }; @@ -3640,7 +3640,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4356>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4168 4170 4172 4176>; + qcom,msm-cpudai-mi2s-group-port-id = <4168 4170 4172 4174>; qcom,msm-cpudai-mi2s-channel-mode = <5>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <3072000>; @@ -3668,7 +3668,7 @@ dai_tert_mi2s_rx_4:qcom,msm-dai-q6-mi2s-tert-rx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4176>; + qcom,msm-cpudai-mi2s-dev-id = <4174>; qcom,msm-cpudai-mi2s-dev-channel-mode = <2>; qcom,msm-cpudai-mi2s-data-align = <0>; }; @@ -3678,7 +3678,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4357>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4169 4171 4173 4177>; + qcom,msm-cpudai-mi2s-group-port-id = <4169 4171 4173 4175>; qcom,msm-cpudai-mi2s-channel-mode = <5>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <3072000>; @@ -3706,7 +3706,7 @@ dai_tert_mi2s_tx_4:qcom,msm-dai-q6-mi2s-tert-tx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4177>; + qcom,msm-cpudai-mi2s-dev-id = <4175>; qcom,msm-cpudai-mi2s-dev-channel-mode = <2>; qcom,msm-cpudai-mi2s-data-align = <0>; }; diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi index 9026474e40e3..1aec20a24824 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-audio-common.dtsi @@ -86,13 +86,13 @@ "msm-dai-q6-tdm.36915", "msm-dai-q6-tdm.36917", "msm-dai-q6-tdm.36919", "msm-dai-q6-mi2s.4160", "msm-dai-q6-mi2s.4162", "msm-dai-q6-mi2s.4164", - "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4161", + "msm-dai-q6-mi2s.4166", "msm-dai-q6-mi2s.4161", "msm-dai-q6-mi2s.4163", "msm-dai-q6-mi2s.4165", - "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4168", + "msm-dai-q6-mi2s.4167", "msm-dai-q6-mi2s.4168", "msm-dai-q6-mi2s.4170", "msm-dai-q6-mi2s.4172", - "msm-dai-q6-mi2s.4176", "msm-dai-q6-mi2s.4169", + "msm-dai-q6-mi2s.4174", "msm-dai-q6-mi2s.4169", "msm-dai-q6-mi2s.4171", "msm-dai-q6-mi2s.4173", - "msm-dai-q6-mi2s.4177", "msm-dai-q6-mi2s.4128", + "msm-dai-q6-mi2s.4175", "msm-dai-q6-mi2s.4128", "msm-dai-q6-mi2s.4130", "msm-dai-q6-mi2s.4132", "msm-dai-q6-mi2s.4134", "msm-dai-q6-mi2s.4129", "msm-dai-q6-mi2s.4131", "msm-dai-q6-mi2s.4133", @@ -277,7 +277,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4354>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4160 4162 4164 4174>; + qcom,msm-cpudai-mi2s-group-port-id = <4160 4162 4164 4166>; qcom,msm-cpudai-mi2s-channel-mode = <2>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <12288000>; @@ -305,7 +305,7 @@ dai_sec_mi2s_rx_4:qcom,msm-dai-q6-mi2s-sec-rx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4174>; + qcom,msm-cpudai-mi2s-dev-id = <4166>; qcom,msm-cpudai-mi2s-dev-channel-mode = <2>; qcom,msm-cpudai-mi2s-data-align = <0>; }; @@ -315,7 +315,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4355>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4161 4163 4165 4175>; + qcom,msm-cpudai-mi2s-group-port-id = <4161 4163 4165 4167>; qcom,msm-cpudai-mi2s-channel-mode = <1>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <12288000>; @@ -343,7 +343,7 @@ dai_sec_mi2s_tx_4:qcom,msm-dai-q6-mi2s-sec-tx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4175>; + qcom,msm-cpudai-mi2s-dev-id = <4167>; qcom,msm-cpudai-mi2s-dev-channel-mode = <1>; qcom,msm-cpudai-mi2s-data-align = <0>; }; @@ -353,7 +353,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4356>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4168 4170 4172 4176>; + qcom,msm-cpudai-mi2s-group-port-id = <4168 4170 4172 4174>; qcom,msm-cpudai-mi2s-channel-mode = <5>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <3072000>; @@ -381,7 +381,7 @@ dai_tert_mi2s_rx_4:qcom,msm-dai-q6-mi2s-tert-rx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4176>; + qcom,msm-cpudai-mi2s-dev-id = <4174>; qcom,msm-cpudai-mi2s-dev-channel-mode = <2>; qcom,msm-cpudai-mi2s-data-align = <0>; }; @@ -391,7 +391,7 @@ compatible = "qcom,msm-dai-group-mi2s"; qcom,msm-cpudai-mi2s-group-id = <4357>; qcom,msm-cpudai-mi2s-group-num-ports = <4>; - qcom,msm-cpudai-mi2s-group-port-id = <4169 4171 4173 4177>; + qcom,msm-cpudai-mi2s-group-port-id = <4169 4171 4173 4175>; qcom,msm-cpudai-mi2s-channel-mode = <5>; qcom,msm-cpudai-mi2s-sync-mode = <1>; qcom,msm-cpudai-mi2s-mclk = <3072000>; @@ -419,7 +419,7 @@ dai_tert_mi2s_tx_4:qcom,msm-dai-q6-mi2s-tert-tx-4 { compatible = "qcom,msm-dai-group-mi2s-dev"; - qcom,msm-cpudai-mi2s-dev-id = <4177>; + qcom,msm-cpudai-mi2s-dev-id = <4175>; qcom,msm-cpudai-mi2s-dev-channel-mode = <2>; qcom,msm-cpudai-mi2s-data-align = <0>; }; diff --git a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi index faaf00b6ac25..b7505743986e 100644 --- a/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi +++ b/arch/arm/boot/dts/qcom/vplatform-lfv-msm8996-usb.dtsi @@ -88,7 +88,6 @@ resets = <&clock_virt USB_30_BCR>; reset-names = "core_reset"; - qcom,disable-host-mode-pm; dwc3@6a00000 { compatible = "snps,dwc3"; diff --git a/arch/arm64/configs/cuttlefish_defconfig b/arch/arm64/configs/cuttlefish_defconfig index d77d20e5a728..c620078b587c 100644 --- a/arch/arm64/configs/cuttlefish_defconfig +++ b/arch/arm64/configs/cuttlefish_defconfig @@ -227,6 +227,7 @@ CONFIG_USB_USBNET=y # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set +CONFIG_VIRT_WIFI=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_KEYRESET=y # CONFIG_INPUT_KEYBOARD is not set diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index 47bc45a67e9b..032a497356f3 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -51,7 +51,7 @@ static inline unsigned long mips_get_syscall_arg(unsigned long *arg, #ifdef CONFIG_64BIT case 4: case 5: case 6: case 7: #ifdef CONFIG_MIPS32_O32 - if (test_thread_flag(TIF_32BIT_REGS)) + if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) return get_user(*arg, (int *)usp + n); else #endif diff --git a/arch/mips/ralink/mt7620.c b/arch/mips/ralink/mt7620.c index c5f45fc96c74..9c19f5493b85 100644 --- a/arch/mips/ralink/mt7620.c +++ b/arch/mips/ralink/mt7620.c @@ -81,7 +81,7 @@ static struct rt2880_pmx_func pcie_rst_grp[] = { }; static struct rt2880_pmx_func nd_sd_grp[] = { FUNC("nand", MT7620_GPIO_MODE_NAND, 45, 15), - FUNC("sd", MT7620_GPIO_MODE_SD, 45, 15) + FUNC("sd", MT7620_GPIO_MODE_SD, 47, 13) }; static struct rt2880_pmx_group mt7620a_pinmux_data[] = { diff --git a/arch/x86/configs/x86_64_cuttlefish_defconfig b/arch/x86/configs/x86_64_cuttlefish_defconfig index c5ccb61274c5..8e4a038e9ac2 100644 --- a/arch/x86/configs/x86_64_cuttlefish_defconfig +++ b/arch/x86/configs/x86_64_cuttlefish_defconfig @@ -247,6 +247,7 @@ CONFIG_USB_USBNET=y # CONFIG_USB_NET_CDC_SUBSET is not set # CONFIG_USB_NET_ZAURUS is not set CONFIG_MAC80211_HWSIM=y +CONFIG_VIRT_WIFI=y CONFIG_INPUT_EVDEV=y CONFIG_INPUT_KEYRESET=y # CONFIG_INPUT_KEYBOARD is not set diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 2b71f2c03b9e..a5b533aea958 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -4174,9 +4174,9 @@ static void mmu_pte_write_flush_tlb(struct kvm_vcpu *vcpu, bool zap_page, } static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa, - const u8 *new, int *bytes) + int *bytes) { - u64 gentry; + u64 gentry = 0; int r; /* @@ -4188,22 +4188,12 @@ static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa, /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ *gpa &= ~(gpa_t)7; *bytes = 8; - r = kvm_vcpu_read_guest(vcpu, *gpa, &gentry, 8); - if (r) - gentry = 0; - new = (const u8 *)&gentry; } - switch (*bytes) { - case 4: - gentry = *(const u32 *)new; - break; - case 8: - gentry = *(const u64 *)new; - break; - default: - gentry = 0; - break; + if (*bytes == 4 || *bytes == 8) { + r = kvm_vcpu_read_guest_atomic(vcpu, *gpa, &gentry, *bytes); + if (r) + gentry = 0; } return gentry; @@ -4313,8 +4303,6 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, pgprintk("%s: gpa %llx bytes %d\n", __func__, gpa, bytes); - gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, new, &bytes); - /* * No need to care whether allocation memory is successful * or not since pte prefetch is skiped if it does not have @@ -4323,6 +4311,9 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, mmu_topup_memory_caches(vcpu); spin_lock(&vcpu->kvm->mmu_lock); + + gentry = mmu_pte_write_fetch_gpte(vcpu, &gpa, &bytes); + ++vcpu->kvm->stat.mmu_pte_write; kvm_mmu_audit(vcpu, AUDIT_PRE_PTE_WRITE); diff --git a/arch/xtensa/kernel/asm-offsets.c b/arch/xtensa/kernel/asm-offsets.c index b123ace3b67c..cbefed1800c1 100644 --- a/arch/xtensa/kernel/asm-offsets.c +++ b/arch/xtensa/kernel/asm-offsets.c @@ -90,14 +90,14 @@ int main(void) DEFINE(THREAD_SP, offsetof (struct task_struct, thread.sp)); DEFINE(THREAD_CPENABLE, offsetof (struct thread_info, cpenable)); #if XTENSA_HAVE_COPROCESSORS - DEFINE(THREAD_XTREGS_CP0, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP1, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP2, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP3, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP4, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP5, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP6, offsetof (struct thread_info, xtregs_cp)); - DEFINE(THREAD_XTREGS_CP7, offsetof (struct thread_info, xtregs_cp)); + DEFINE(THREAD_XTREGS_CP0, offsetof(struct thread_info, xtregs_cp.cp0)); + DEFINE(THREAD_XTREGS_CP1, offsetof(struct thread_info, xtregs_cp.cp1)); + DEFINE(THREAD_XTREGS_CP2, offsetof(struct thread_info, xtregs_cp.cp2)); + DEFINE(THREAD_XTREGS_CP3, offsetof(struct thread_info, xtregs_cp.cp3)); + DEFINE(THREAD_XTREGS_CP4, offsetof(struct thread_info, xtregs_cp.cp4)); + DEFINE(THREAD_XTREGS_CP5, offsetof(struct thread_info, xtregs_cp.cp5)); + DEFINE(THREAD_XTREGS_CP6, offsetof(struct thread_info, xtregs_cp.cp6)); + DEFINE(THREAD_XTREGS_CP7, offsetof(struct thread_info, xtregs_cp.cp7)); #endif DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); diff --git a/arch/xtensa/kernel/process.c b/arch/xtensa/kernel/process.c index 17a378c15a15..26516094dbd4 100644 --- a/arch/xtensa/kernel/process.c +++ b/arch/xtensa/kernel/process.c @@ -83,18 +83,21 @@ void coprocessor_release_all(struct thread_info *ti) void coprocessor_flush_all(struct thread_info *ti) { - unsigned long cpenable; + unsigned long cpenable, old_cpenable; int i; preempt_disable(); + RSR_CPENABLE(old_cpenable); cpenable = ti->cpenable; + WSR_CPENABLE(cpenable); for (i = 0; i < XCHAL_CP_MAX; i++) { if ((cpenable & 1) != 0 && coprocessor_owner[i] == ti) coprocessor_flush(ti, i); cpenable >>= 1; } + WSR_CPENABLE(old_cpenable); preempt_enable(); } diff --git a/build.config.cuttlefish.aarch64 b/build.config.cuttlefish.aarch64 index 40e9a3bd8d0d..e36bae42443e 100644 --- a/build.config.cuttlefish.aarch64 +++ b/build.config.cuttlefish.aarch64 @@ -6,7 +6,7 @@ DEFCONFIG=cuttlefish_defconfig EXTRA_CMDS='' KERNEL_DIR=common POST_DEFCONFIG_CMDS="check_defconfig" -CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin +CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin FILES=" arch/arm64/boot/Image.gz diff --git a/build.config.cuttlefish.x86_64 b/build.config.cuttlefish.x86_64 index ce8c226a1db4..0a77fa871e83 100644 --- a/build.config.cuttlefish.x86_64 +++ b/build.config.cuttlefish.x86_64 @@ -6,7 +6,7 @@ DEFCONFIG=x86_64_cuttlefish_defconfig EXTRA_CMDS='' KERNEL_DIR=common POST_DEFCONFIG_CMDS="check_defconfig" -CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r328903/bin +CLANG_PREBUILT_BIN=prebuilts-master/clang/host/linux-x86/clang-r346389b/bin LINUX_GCC_CROSS_COMPILE_PREBUILTS_BIN=prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9/bin FILES=" arch/x86/boot/bzImage diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 644b9abcc67f..f22e4abba9b4 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3138,7 +3138,6 @@ static void binder_transaction(struct binder_proc *proc, t->buffer = NULL; goto err_binder_alloc_buf_failed; } - t->buffer->allow_user_free = 0; t->buffer->debug_id = t->debug_id; t->buffer->transaction = t; t->buffer->target_node = target_node; @@ -3634,14 +3633,18 @@ static int binder_thread_write(struct binder_proc *proc, buffer = binder_alloc_prepare_to_free(&proc->alloc, data_ptr); - if (buffer == NULL) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx no match\n", - proc->pid, thread->pid, (u64)data_ptr); - break; - } - if (!buffer->allow_user_free) { - binder_user_error("%d:%d BC_FREE_BUFFER u%016llx matched unreturned buffer\n", - proc->pid, thread->pid, (u64)data_ptr); + if (IS_ERR_OR_NULL(buffer)) { + if (PTR_ERR(buffer) == -EPERM) { + binder_user_error( + "%d:%d BC_FREE_BUFFER u%016llx matched unreturned or currently freeing buffer\n", + proc->pid, thread->pid, + (u64)data_ptr); + } else { + binder_user_error( + "%d:%d BC_FREE_BUFFER u%016llx no match\n", + proc->pid, thread->pid, + (u64)data_ptr); + } break; } binder_debug(BINDER_DEBUG_FREE_BUFFER, diff --git a/drivers/android/binder_alloc.c b/drivers/android/binder_alloc.c index 1d9db2ef26bd..baecb4bf9d9b 100644 --- a/drivers/android/binder_alloc.c +++ b/drivers/android/binder_alloc.c @@ -149,14 +149,12 @@ static struct binder_buffer *binder_alloc_prepare_to_free_locked( else { /* * Guard against user threads attempting to - * free the buffer twice + * free the buffer when in use by kernel or + * after it's already been freed. */ - if (buffer->free_in_progress) { - pr_err("%d:%d FREE_BUFFER u%016llx user freed buffer twice\n", - alloc->pid, current->pid, (u64)user_ptr); - return NULL; - } - buffer->free_in_progress = 1; + if (!buffer->allow_user_free) + return ERR_PTR(-EPERM); + buffer->allow_user_free = 0; return buffer; } } @@ -463,7 +461,7 @@ static struct binder_buffer *binder_alloc_new_buf_locked( rb_erase(best_fit, &alloc->free_buffers); buffer->free = 0; - buffer->free_in_progress = 0; + buffer->allow_user_free = 0; binder_insert_allocated_buffer_locked(alloc, buffer); binder_alloc_debug(BINDER_DEBUG_BUFFER_ALLOC, "%d: binder_alloc_buf size %zd got %pK\n", diff --git a/drivers/android/binder_alloc.h b/drivers/android/binder_alloc.h index 9ef64e563856..fb3238c74c8a 100644 --- a/drivers/android/binder_alloc.h +++ b/drivers/android/binder_alloc.h @@ -50,8 +50,7 @@ struct binder_buffer { unsigned free:1; unsigned allow_user_free:1; unsigned async_transaction:1; - unsigned free_in_progress:1; - unsigned debug_id:28; + unsigned debug_id:29; struct binder_transaction *transaction; diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index be26f625bb3e..941ace052130 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c @@ -1781,6 +1781,12 @@ static void atc_free_chan_resources(struct dma_chan *chan) atchan->descs_allocated = 0; atchan->status = 0; + /* + * Free atslave allocated in at_dma_xlate() + */ + kfree(chan->private); + chan->private = NULL; + dev_vdbg(chan2dev(chan), "free_chan_resources: done\n"); } @@ -1815,7 +1821,7 @@ static struct dma_chan *at_dma_xlate(struct of_phandle_args *dma_spec, dma_cap_zero(mask); dma_cap_set(DMA_SLAVE, mask); - atslave = devm_kzalloc(&dmac_pdev->dev, sizeof(*atslave), GFP_KERNEL); + atslave = kzalloc(sizeof(*atslave), GFP_KERNEL); if (!atslave) return NULL; @@ -2146,6 +2152,8 @@ static int at_dma_remove(struct platform_device *pdev) struct resource *io; at_dma_off(atdma); + if (pdev->dev.of_node) + of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&atdma->dma_common); dma_pool_destroy(atdma->memset_pool); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 498a94069e6b..1acebd64fded 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -557,7 +557,8 @@ int ast_driver_unload(struct drm_device *dev) drm_mode_config_cleanup(dev); ast_mm_fini(ast); - pci_iounmap(dev->pdev, ast->ioregs); + if (ast->ioregs != ast->regs + AST_IO_MM_OFFSET) + pci_iounmap(dev->pdev, ast->ioregs); pci_iounmap(dev->pdev, ast->regs); kfree(ast); return 0; diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index acd38344b302..764094dd30dd 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -99,7 +99,7 @@ void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe) /* Wait for for the pipe enable to take effect. */ for (count = 0; count < COUNT_MAX; count++) { temp = REG_READ(map->conf); - if ((temp & PIPEACONF_PIPE_STATE) == 1) + if (temp & PIPEACONF_PIPE_STATE) break; } } diff --git a/drivers/gpu/drm/msm/sde/sde_connector.c b/drivers/gpu/drm/msm/sde/sde_connector.c index 5f6b93931c35..1bc3d0a926eb 100644 --- a/drivers/gpu/drm/msm/sde/sde_connector.c +++ b/drivers/gpu/drm/msm/sde/sde_connector.c @@ -17,10 +17,6 @@ #include "sde_connector.h" #include "sde_backlight.h" #include "sde_splash.h" -#include <linux/workqueue.h> -#include <linux/atomic.h> -#include <linux/cpu.h> -#include <linux/device.h> #define SDE_DEBUG_CONN(c, fmt, ...) SDE_DEBUG("conn%d " fmt,\ (c) ? (c)->base.base.id : -1, ##__VA_ARGS__) @@ -55,8 +51,6 @@ static const struct drm_prop_enum_list hpd_clock_state[] = { {SDE_MODE_HPD_OFF, "OFF"}, }; -static struct work_struct cpu_up_work; - int sde_connector_get_info(struct drm_connector *connector, struct msm_display_info *info) { @@ -574,25 +568,11 @@ void sde_connector_prepare_fence(struct drm_connector *connector) sde_fence_prepare(&to_sde_connector(connector)->retire_fence); } -static void wake_up_cpu(struct work_struct *work) -{ - struct device *cpu_dev = NULL; - - cpu_dev = get_cpu_device(1); - if (!cpu_dev) { - pr_err("Could not get cpu1 device\n"); - return; - } - if (!device_online(cpu_dev)) - pr_info("cpu1 is online\n"); -} - void sde_connector_complete_commit(struct drm_connector *connector) { struct drm_device *dev; struct msm_drm_private *priv; struct sde_connector *c_conn; - static atomic_t cpu_up_scheduled = ATOMIC_INIT(0); if (!connector) { SDE_ERROR("invalid connector\n"); @@ -607,8 +587,7 @@ void sde_connector_complete_commit(struct drm_connector *connector) /* * After LK totally exits, LK's early splash resource - * should be released, cpu1 is hot-plugged in case LK's - * early domain has reserved it. + * should be released. */ if (sde_splash_get_lk_complete_status(priv->kms)) { c_conn = to_sde_connector(connector); @@ -616,11 +595,8 @@ void sde_connector_complete_commit(struct drm_connector *connector) sde_splash_free_resource(priv->kms, &priv->phandle, c_conn->connector_type, c_conn->display); - if (atomic_add_unless(&cpu_up_scheduled, 1, 1)) { - INIT_WORK(&cpu_up_work, wake_up_cpu); - schedule_work(&cpu_up_work); - } } + } static int sde_connector_dpms(struct drm_connector *connector, diff --git a/drivers/gpu/drm/msm/sde/sde_splash.c b/drivers/gpu/drm/msm/sde/sde_splash.c index 3ea93b654ce8..ebb02dba6d5d 100644 --- a/drivers/gpu/drm/msm/sde/sde_splash.c +++ b/drivers/gpu/drm/msm/sde/sde_splash.c @@ -14,7 +14,7 @@ #include <linux/of_address.h> #include <linux/debugfs.h> #include <linux/memblock.h> - +#include <soc/qcom/early_domain.h> #include "msm_drv.h" #include "msm_mmu.h" #include "sde_kms.h" @@ -66,49 +66,6 @@ static void _sde_splash_free_bootup_memory_to_system(phys_addr_t phys, free_reserved_page(pfn_to_page(pfn_idx)); } -static int _sde_splash_parse_dt_get_lk_pool_node(struct drm_device *dev, - struct sde_splash_info *sinfo) -{ - struct device_node *parent, *node; - struct resource r; - int ret = 0; - - if (!sinfo) - return -EINVAL; - - parent = of_find_node_by_path("/reserved-memory"); - if (!parent) - return -EINVAL; - - node = of_find_node_by_name(parent, "lk_pool"); - if (!node) { - SDE_ERROR("mem reservation for lk_pool is not presented\n"); - ret = -EINVAL; - goto parent_node_err; - } - - /* find the mode */ - if (of_address_to_resource(node, 0, &r)) { - ret = -EINVAL; - goto child_node_err; - } - - sinfo->lk_pool_paddr = (dma_addr_t)r.start; - sinfo->lk_pool_size = r.end - r.start; - - DRM_INFO("lk_pool: addr:%pK, size:%pK\n", - (void *)sinfo->lk_pool_paddr, - (void *)sinfo->lk_pool_size); - -child_node_err: - of_node_put(node); - -parent_node_err: - of_node_put(parent); - - return ret; -} - static int _sde_splash_parse_dt_get_display_node(struct drm_device *dev, struct sde_splash_info *sinfo) { @@ -183,10 +140,9 @@ error: return -ENOMEM; } -static bool _sde_splash_lk_check(struct sde_hw_intr *intr) +static bool _sde_splash_lk_check(void) { - return (SDE_LK_RUNNING_VALUE == SDE_REG_READ(&intr->hw, - SCRATCH_REGISTER_1)) ? true : false; + return get_early_service_status(EARLY_DISPLAY); } /** @@ -194,10 +150,9 @@ static bool _sde_splash_lk_check(struct sde_hw_intr *intr) * * Function to stop early splash in LK. */ -static inline void _sde_splash_notify_lk_stop_splash(struct sde_hw_intr *intr) +static inline void _sde_splash_notify_lk_stop_splash(void) { - /* write splash stop signal to scratch register*/ - SDE_REG_WRITE(&intr->hw, SCRATCH_REGISTER_1, SDE_LK_STOP_SPLASH_VALUE); + request_early_service_shutdown(EARLY_DISPLAY); } static int _sde_splash_gem_new(struct drm_device *dev, @@ -502,12 +457,6 @@ int sde_splash_parse_memory_dt(struct drm_device *dev) SDE_ERROR("get display node failed\n"); return -EINVAL; } - - if (_sde_splash_parse_dt_get_lk_pool_node(dev, sinfo)) { - SDE_ERROR("get LK pool node failed\n"); - return -EINVAL; - } - return 0; } @@ -781,9 +730,8 @@ bool sde_splash_get_lk_complete_status(struct msm_kms *kms) if (sde_kms->splash_info.handoff && !sde_kms->splash_info.display_splash_enabled && - SDE_LK_EXIT_VALUE == SDE_REG_READ(&intr->hw, - SCRATCH_REGISTER_1)) { - SDE_DEBUG("LK totoally exits\n"); + !_sde_splash_lk_check()) { + SDE_DEBUG("LK totally exits\n"); return true; } @@ -841,10 +789,6 @@ int sde_splash_free_resource(struct msm_kms *kms, _sde_splash_destroy_splash_node(sinfo); - /* free lk_pool heap memory */ - _sde_splash_free_bootup_memory_to_system(sinfo->lk_pool_paddr, - sinfo->lk_pool_size); - /* withdraw data bus vote */ sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); @@ -857,12 +801,12 @@ int sde_splash_free_resource(struct msm_kms *kms, sde_power_resource_enable(phandle, sde_kms->core_client, false); - /* send uevent to notify user to recycle resource */ - _sde_splash_sent_pipe_update_uevent(sde_kms); - /* update impacted crtc and plane property by splash */ _sde_splash_update_property(sde_kms); + /* send uevent to notify user to recycle resource */ + _sde_splash_sent_pipe_update_uevent(sde_kms); + /* set display's splash status to false after handoff is done */ _sde_splash_update_display_splash_status(sde_kms); @@ -974,8 +918,8 @@ int sde_splash_lk_stop_splash(struct msm_kms *kms, mutex_lock(&sde_splash_lock); if (_sde_splash_validate_commit(sde_kms, state) && sinfo->display_splash_enabled) { - if (_sde_splash_lk_check(sde_kms->hw_intr)) - _sde_splash_notify_lk_stop_splash(sde_kms->hw_intr); + if (_sde_splash_lk_check()) + _sde_splash_notify_lk_stop_splash(); sinfo->display_splash_enabled = false; diff --git a/drivers/gpu/drm/msm/sde/sde_splash.h b/drivers/gpu/drm/msm/sde/sde_splash.h index c4bb7b08f817..ee94c348e25b 100644 --- a/drivers/gpu/drm/msm/sde/sde_splash.h +++ b/drivers/gpu/drm/msm/sde/sde_splash.h @@ -68,12 +68,6 @@ struct sde_splash_info { /* constructed gem objects for smmu mapping */ struct drm_gem_object **obj; - /* physical address of lk pool */ - phys_addr_t lk_pool_paddr; - - /* memory size of lk pool */ - size_t lk_pool_size; - /* enabled statue of displays*/ uint32_t intf_sel_status; diff --git a/drivers/infiniband/ulp/iser/iser_verbs.c b/drivers/infiniband/ulp/iser/iser_verbs.c index 0cbc7ceb9a55..1610accfed0b 100644 --- a/drivers/infiniband/ulp/iser/iser_verbs.c +++ b/drivers/infiniband/ulp/iser/iser_verbs.c @@ -1289,7 +1289,9 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, IB_MR_CHECK_SIG_STATUS, &mr_status); if (ret) { pr_err("ib_check_mr_status failed, ret %d\n", ret); - goto err; + /* Not a lot we can do, return ambiguous guard error */ + *sector = 0; + return 0x1; } if (mr_status.fail_status & IB_MR_CHECK_SIG_STATUS) { @@ -1317,7 +1319,4 @@ u8 iser_check_task_pi_status(struct iscsi_iser_task *iser_task, } return 0; -err: - /* Not alot we can do here, return ambiguous guard error */ - return 0x1; } diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c index 2e52015634f9..f55dcdf99bc5 100644 --- a/drivers/input/joystick/xpad.c +++ b/drivers/input/joystick/xpad.c @@ -483,18 +483,18 @@ static const u8 xboxone_hori_init[] = { }; /* - * This packet is required for some of the PDP pads to start + * This packet is required for most (all?) of the PDP pads to start * sending input reports. These pads include: (0x0e6f:0x02ab), - * (0x0e6f:0x02a4). + * (0x0e6f:0x02a4), (0x0e6f:0x02a6). */ static const u8 xboxone_pdp_init1[] = { 0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14 }; /* - * This packet is required for some of the PDP pads to start + * This packet is required for most (all?) of the PDP pads to start * sending input reports. These pads include: (0x0e6f:0x02ab), - * (0x0e6f:0x02a4). + * (0x0e6f:0x02a4), (0x0e6f:0x02a6). */ static const u8 xboxone_pdp_init2[] = { 0x06, 0x20, 0x00, 0x02, 0x01, 0x00 @@ -530,12 +530,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = { XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init), XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init), XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init), - XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1), - XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2), - XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init1), - XBOXONE_INIT_PKT(0x0e6f, 0x02a4, xboxone_pdp_init2), - XBOXONE_INIT_PKT(0x0e6f, 0x02a6, xboxone_pdp_init1), - XBOXONE_INIT_PKT(0x0e6f, 0x02a6, xboxone_pdp_init2), + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init1), + XBOXONE_INIT_PKT(0x0e6f, 0x0000, xboxone_pdp_init2), XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init), XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init), XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init), diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 795fa353de7c..c64d87442a62 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -405,7 +405,7 @@ matrix_keypad_parse_dt(struct device *dev) struct matrix_keypad_platform_data *pdata; struct device_node *np = dev->of_node; unsigned int *gpios; - int i, nrow, ncol; + int ret, i, nrow, ncol; if (!np) { dev_err(dev, "device lacks DT data\n"); @@ -447,12 +447,19 @@ matrix_keypad_parse_dt(struct device *dev) return ERR_PTR(-ENOMEM); } - for (i = 0; i < pdata->num_row_gpios; i++) - gpios[i] = of_get_named_gpio(np, "row-gpios", i); + for (i = 0; i < nrow; i++) { + ret = of_get_named_gpio(np, "row-gpios", i); + if (ret < 0) + return ERR_PTR(ret); + gpios[i] = ret; + } - for (i = 0; i < pdata->num_col_gpios; i++) - gpios[pdata->num_row_gpios + i] = - of_get_named_gpio(np, "col-gpios", i); + for (i = 0; i < ncol; i++) { + ret = of_get_named_gpio(np, "col-gpios", i); + if (ret < 0) + return ERR_PTR(ret); + gpios[nrow + i] = ret; + } pdata->row_gpios = gpios; pdata->col_gpios = &gpios[pdata->num_row_gpios]; @@ -479,10 +486,8 @@ static int matrix_keypad_probe(struct platform_device *pdev) pdata = dev_get_platdata(&pdev->dev); if (!pdata) { pdata = matrix_keypad_parse_dt(&pdev->dev); - if (IS_ERR(pdata)) { - dev_err(&pdev->dev, "no platform data defined\n"); + if (IS_ERR(pdata)) return PTR_ERR(pdata); - } } else if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; diff --git a/drivers/input/mouse/elan_i2c_core.c b/drivers/input/mouse/elan_i2c_core.c index b3119589a444..471984ec2db0 100644 --- a/drivers/input/mouse/elan_i2c_core.c +++ b/drivers/input/mouse/elan_i2c_core.c @@ -1253,6 +1253,9 @@ static const struct acpi_device_id elan_acpi_id[] = { { "ELAN0618", 0 }, { "ELAN061C", 0 }, { "ELAN061D", 0 }, + { "ELAN061E", 0 }, + { "ELAN0620", 0 }, + { "ELAN0621", 0 }, { "ELAN0622", 0 }, { "ELAN1000", 0 }, { } diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 49b266433f4c..7feaa82f8c7c 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -2977,7 +2977,7 @@ static int copy_context_table(struct intel_iommu *iommu, } if (old_ce) - iounmap(old_ce); + memunmap(old_ce); ret = 0; if (devfn < 0x80) diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index 10068a481e22..cbde03e509c1 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -558,7 +558,7 @@ static irqreturn_t prq_event_thread(int irq, void *d) pr_err("%s: Page request without PASID: %08llx %08llx\n", iommu->name, ((unsigned long long *)req)[0], ((unsigned long long *)req)[1]); - goto bad_req; + goto no_pasid; } if (!svm || svm->pasid != req->pasid) { diff --git a/drivers/iommu/ipmmu-vmsa.c b/drivers/iommu/ipmmu-vmsa.c index 624e7ff76166..9101be1a6b59 100644 --- a/drivers/iommu/ipmmu-vmsa.c +++ b/drivers/iommu/ipmmu-vmsa.c @@ -372,6 +372,9 @@ static int ipmmu_domain_init_context(struct ipmmu_vmsa_domain *domain) static void ipmmu_domain_destroy_context(struct ipmmu_vmsa_domain *domain) { + if (!domain->mmu) + return; + /* * Disable the context. Flush the TLB as required when modifying the * context registers. diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index ba20b8e42fbd..cdb9018c3f02 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c @@ -265,12 +265,13 @@ void led_classdev_unregister(struct led_classdev *led_cdev) up_write(&led_cdev->trigger_lock); #endif - cancel_work_sync(&led_cdev->set_brightness_work); - /* Stop blinking */ led_stop_software_blink(led_cdev); + led_set_brightness(led_cdev, LED_OFF); + flush_work(&led_cdev->set_brightness_work); + device_unregister(led_cdev->dev); down_write(&leds_list_lock); diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c index 5db4515a4fd7..df186b38da78 100644 --- a/drivers/leds/leds-gpio.c +++ b/drivers/leds/leds-gpio.c @@ -118,8 +118,8 @@ static int create_gpio_led(const struct gpio_led *template, return ret; led_dat->gpiod = gpio_to_desc(template->gpio); - if (IS_ERR(led_dat->gpiod)) - return PTR_ERR(led_dat->gpiod); + if (!led_dat->gpiod) + return -EINVAL; } led_dat->cdev.name = template->name; diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c index 1d07e3e83d29..3149dbece146 100644 --- a/drivers/leds/leds-pwm.c +++ b/drivers/leds/leds-pwm.c @@ -132,6 +132,7 @@ static int led_pwm_add(struct device *dev, struct led_pwm_priv *priv, ret = led_classdev_register(dev, &led_data->cdev); if (ret == 0) { priv->num_leds++; + led_pwm_set(&led_data->cdev, led_data->cdev.brightness); } else { dev_err(dev, "failed to register PWM led for %s: %d\n", led->name, ret); diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c index 357be76c7a55..5502a0fb94fd 100644 --- a/drivers/media/usb/em28xx/em28xx-dvb.c +++ b/drivers/media/usb/em28xx/em28xx-dvb.c @@ -1806,6 +1806,8 @@ static int em28xx_dvb_fini(struct em28xx *dev) } } + em28xx_unregister_dvb(dvb); + /* remove I2C SEC */ client = dvb->i2c_client_sec; if (client) { @@ -1827,7 +1829,6 @@ static int em28xx_dvb_fini(struct em28xx *dev) i2c_unregister_device(client); } - em28xx_unregister_dvb(dvb); kfree(dvb); dev->dvb = NULL; kref_put(&dev->ref, em28xx_free_device); diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c index 6a451bd65bf3..8bd63128d536 100644 --- a/drivers/misc/mic/scif/scif_rma.c +++ b/drivers/misc/mic/scif/scif_rma.c @@ -414,7 +414,7 @@ static int scif_create_remote_lookup(struct scif_dev *remote_dev, if (err) goto error_window; err = scif_map_page(&window->num_pages_lookup.lookup[j], - vmalloc_dma_phys ? + vmalloc_num_pages ? vmalloc_to_page(&window->num_pages[i]) : virt_to_page(&window->num_pages[i]), remote_dev); diff --git a/drivers/net/can/rcar_can.c b/drivers/net/can/rcar_can.c index bc46be39549d..9d93492ddfcc 100644 --- a/drivers/net/can/rcar_can.c +++ b/drivers/net/can/rcar_can.c @@ -24,6 +24,9 @@ #define RCAR_CAN_DRV_NAME "rcar_can" +#define RCAR_SUPPORTED_CLOCKS (BIT(CLKR_CLKP1) | BIT(CLKR_CLKP2) | \ + BIT(CLKR_CLKEXT)) + /* Mailbox configuration: * mailbox 60 - 63 - Rx FIFO mailboxes * mailbox 56 - 59 - Tx FIFO mailboxes @@ -789,7 +792,7 @@ static int rcar_can_probe(struct platform_device *pdev) goto fail_clk; } - if (clock_select >= ARRAY_SIZE(clock_names)) { + if (!(BIT(clock_select) & RCAR_SUPPORTED_CLOCKS)) { err = -EINVAL; dev_err(&pdev->dev, "invalid CAN clock selected\n"); goto fail_clk; diff --git a/drivers/net/ethernet/amd/sunlance.c b/drivers/net/ethernet/amd/sunlance.c index 7847638bdd22..8914170fccff 100644 --- a/drivers/net/ethernet/amd/sunlance.c +++ b/drivers/net/ethernet/amd/sunlance.c @@ -1419,7 +1419,7 @@ static int sparc_lance_probe_one(struct platform_device *op, prop = of_get_property(nd, "tpe-link-test?", NULL); if (!prop) - goto no_link_test; + goto node_put; if (strcmp(prop, "true")) { printk(KERN_NOTICE "SunLance: warning: overriding option " @@ -1428,6 +1428,8 @@ static int sparc_lance_probe_one(struct platform_device *op, "to ecd@skynet.be\n"); auxio_set_lte(AUXIO_LTE_ON); } +node_put: + of_node_put(nd); no_link_test: lp->auto_select = 1; lp->tpe = 0; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 1ea068815419..2491cdc2535c 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -2291,6 +2291,13 @@ void bnx2x_igu_clear_sb_gen(struct bnx2x *bp, u8 func, u8 idu_sb_id, #define PMF_DMAE_C(bp) (BP_PORT(bp) * MAX_DMAE_C_PER_PORT + \ E1HVN_MAX) +/* Following is the DMAE channel number allocation for the clients. + * MFW: OCBB/OCSD implementations use DMAE channels 14/15 respectively. + * Driver: 0-3 and 8-11 (for PF dmae operations) + * 4 and 12 (for stats requests) + */ +#define BNX2X_FW_DMAE_C 13 /* Channel for FW DMAE operations */ + /* PCIE link and speed */ #define PCICFG_LINK_WIDTH 0x1f00000 #define PCICFG_LINK_WIDTH_SHIFT 20 diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index ff702a707a91..343e3366d751 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -5931,6 +5931,7 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, rdata->sd_vlan_tag = cpu_to_le16(start_params->sd_vlan_tag); rdata->path_id = BP_PATH(bp); rdata->network_cos_mode = start_params->network_cos_mode; + rdata->dmae_cmd_id = BNX2X_FW_DMAE_C; rdata->vxlan_dst_port = cpu_to_le16(start_params->vxlan_dst_port); rdata->geneve_dst_port = cpu_to_le16(start_params->geneve_dst_port); diff --git a/drivers/net/ethernet/faraday/ftmac100.c b/drivers/net/ethernet/faraday/ftmac100.c index dce5f7b7f772..05e1f923f49e 100644 --- a/drivers/net/ethernet/faraday/ftmac100.c +++ b/drivers/net/ethernet/faraday/ftmac100.c @@ -865,11 +865,10 @@ static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) struct net_device *netdev = dev_id; struct ftmac100 *priv = netdev_priv(netdev); - if (likely(netif_running(netdev))) { - /* Disable interrupts for polling */ - ftmac100_disable_all_int(priv); + /* Disable interrupts for polling */ + ftmac100_disable_all_int(priv); + if (likely(netif_running(netdev))) napi_schedule(&priv->napi); - } return IRQ_HANDLED; } diff --git a/drivers/net/ethernet/mellanox/mlx4/alloc.c b/drivers/net/ethernet/mellanox/mlx4/alloc.c index 0c51c69f802f..a4912b11e54f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/alloc.c +++ b/drivers/net/ethernet/mellanox/mlx4/alloc.c @@ -339,7 +339,7 @@ void mlx4_zone_allocator_destroy(struct mlx4_zone_allocator *zone_alloc) static u32 __mlx4_alloc_from_zone(struct mlx4_zone_entry *zone, int count, int align, u32 skip_mask, u32 *puid) { - u32 uid; + u32 uid = 0; u32 res; struct mlx4_zone_allocator *zone_alloc = zone->allocator; struct mlx4_zone_entry *curr_node; diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index f5fdbd53d052..db40387ffaf6 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -537,8 +537,8 @@ struct slave_list { struct resource_allocator { spinlock_t alloc_lock; /* protect quotas */ union { - int res_reserved; - int res_port_rsvd[MLX4_MAX_PORTS]; + unsigned int res_reserved; + unsigned int res_port_rsvd[MLX4_MAX_PORTS]; }; union { int res_free; diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 93195191f45b..53833c06696f 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -366,6 +366,7 @@ int mlx4_mr_hw_write_mpt(struct mlx4_dev *dev, struct mlx4_mr *mmr, container_of((void *)mpt_entry, struct mlx4_cmd_mailbox, buf); + (*mpt_entry)->lkey = 0; err = mlx4_SW2HW_MPT(dev, mailbox, key); } diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index 9cc9d62c1fec..8b15a018d625 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -177,6 +177,8 @@ static int qed_int_attentions(struct qed_hwfn *p_hwfn) */ do { index = p_sb_attn->sb_index; + /* finish reading index before the loop condition */ + dma_rmb(); attn_bits = le32_to_cpu(p_sb_attn->atten_bits); attn_acks = le32_to_cpu(p_sb_attn->atten_ack); } while (index != p_sb_attn->sb_index); diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index 35e1468d8196..b8ae6ed5c7ba 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -1124,9 +1124,9 @@ static int qed_drain(struct qed_dev *cdev) return -EBUSY; } rc = qed_mcp_drain(hwfn, ptt); + qed_ptt_release(hwfn, ptt); if (rc) return rc; - qed_ptt_release(hwfn, ptt); } return 0; diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index e7034c55e796..6ef9188384ce 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -215,9 +215,9 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) * it just report sending a packet to the target * (without actual packet transfer). */ - dev_kfree_skb_any(skb); ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; + dev_kfree_skb_any(skb); } } diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index 76465b117b72..f1f8227e7342 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -140,7 +140,6 @@ struct ipheth_device { struct usb_device *udev; struct usb_interface *intf; struct net_device *net; - struct sk_buff *tx_skb; struct urb *tx_urb; struct urb *rx_urb; unsigned char *tx_buf; @@ -229,6 +228,7 @@ static void ipheth_rcvbulk_callback(struct urb *urb) case -ENOENT: case -ECONNRESET: case -ESHUTDOWN: + case -EPROTO: return; case 0: break; @@ -280,7 +280,6 @@ static void ipheth_sndbulk_callback(struct urb *urb) dev_err(&dev->intf->dev, "%s: urb status: %d\n", __func__, status); - dev_kfree_skb_irq(dev->tx_skb); netif_wake_queue(dev->net); } @@ -410,7 +409,7 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net) if (skb->len > IPHETH_BUF_SIZE) { WARN(1, "%s: skb too large: %d bytes\n", __func__, skb->len); dev->net->stats.tx_dropped++; - dev_kfree_skb_irq(skb); + dev_kfree_skb_any(skb); return NETDEV_TX_OK; } @@ -430,12 +429,11 @@ static int ipheth_tx(struct sk_buff *skb, struct net_device *net) dev_err(&dev->intf->dev, "%s: usb_submit_urb: %d\n", __func__, retval); dev->net->stats.tx_errors++; - dev_kfree_skb_irq(skb); + dev_kfree_skb_any(skb); } else { - dev->tx_skb = skb; - dev->net->stats.tx_packets++; dev->net->stats.tx_bytes += skb->len; + dev_consume_skb_any(skb); netif_stop_queue(net); } diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 7945b1cd6244..b4c7b36117bd 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -256,6 +256,13 @@ config MAC80211_HWSIM To compile this driver as a module, choose M here: the module will be called mac80211_hwsim. If unsure, say N. +config VIRT_WIFI + tristate "Wifi wrapper for ethernet drivers" + depends on CFG80211 + ---help--- + This option adds support for ethernet connections to appear as if they + are wifi connections through a special rtnetlink device. + config MWL8K tristate "Marvell 88W8xxx PCI/PCIe Wireless support" depends on MAC80211 && PCI diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index f23a2fbc3afa..51f02058adf2 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile @@ -51,6 +51,8 @@ obj-$(CONFIG_ATH_CARDS) += ath/ obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o +obj-$(CONFIG_VIRT_WIFI) += virt_wifi.o + obj-$(CONFIG_WL_TI) += ti/ obj-$(CONFIG_MWIFIEX) += mwifiex/ diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 05413176a5d6..ab480ea6d95a 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c @@ -2515,6 +2515,10 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, if (param->no_vif) ieee80211_hw_set(hw, NO_AUTO_VIF); + tasklet_hrtimer_init(&data->beacon_timer, + mac80211_hwsim_beacon, + CLOCK_MONOTONIC, HRTIMER_MODE_ABS); + err = ieee80211_register_hw(hw); if (err < 0) { printk(KERN_DEBUG "mac80211_hwsim: ieee80211_register_hw failed (%d)\n", @@ -2539,10 +2543,6 @@ static int mac80211_hwsim_new_radio(struct genl_info *info, data->debugfs, data, &hwsim_simulate_radar); - tasklet_hrtimer_init(&data->beacon_timer, - mac80211_hwsim_beacon, - CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - spin_lock_bh(&hwsim_radio_lock); list_add_tail(&data->list, &hwsim_radios); spin_unlock_bh(&hwsim_radio_lock); diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index 15dc7a398b90..f01d24baff7c 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c @@ -35,7 +35,6 @@ #include "wl12xx_80211.h" #include "cmd.h" #include "event.h" -#include "ps.h" #include "tx.h" #include "hw_ops.h" @@ -192,10 +191,6 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl, timeout_time = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT); - ret = wl1271_ps_elp_wakeup(wl); - if (ret < 0) - return ret; - do { if (time_after(jiffies, timeout_time)) { wl1271_debug(DEBUG_CMD, "timeout waiting for event %d", @@ -227,7 +222,6 @@ int wlcore_cmd_wait_for_event_or_timeout(struct wl1271 *wl, } while (!event); out: - wl1271_ps_elp_sleep(wl); kfree(events_vector); return ret; } diff --git a/drivers/net/wireless/virt_wifi.c b/drivers/net/wireless/virt_wifi.c new file mode 100644 index 000000000000..90ecb7e8834f --- /dev/null +++ b/drivers/net/wireless/virt_wifi.c @@ -0,0 +1,629 @@ +// SPDX-License-Identifier: GPL-2.0 +/* drivers/net/wireless/virt_wifi.c + * + * A fake implementation of cfg80211_ops that can be tacked on to an ethernet + * net_device to make it appear as a wireless connection. + * + * Copyright (C) 2018 Google, Inc. + * + * Author: schuffelen@google.com + */ + +#include <net/cfg80211.h> +#include <net/rtnetlink.h> +#include <linux/etherdevice.h> +#include <linux/module.h> + +#include <net/cfg80211.h> +#include <net/rtnetlink.h> +#include <linux/etherdevice.h> +#include <linux/module.h> + +static struct wiphy *common_wiphy; + +struct virt_wifi_wiphy_priv { + struct delayed_work scan_result; + struct cfg80211_scan_request *scan_request; + bool being_deleted; +}; + +static struct ieee80211_channel channel_2ghz = { + .band = IEEE80211_BAND_2GHZ, + .center_freq = 2432, + .hw_value = 2432, + .max_power = 20, +}; + +static struct ieee80211_rate bitrates_2ghz[] = { + { .bitrate = 10 }, + { .bitrate = 20 }, + { .bitrate = 55 }, + { .bitrate = 110 }, + { .bitrate = 60 }, + { .bitrate = 120 }, + { .bitrate = 240 }, +}; + +static struct ieee80211_supported_band band_2ghz = { + .channels = &channel_2ghz, + .bitrates = bitrates_2ghz, + .band = IEEE80211_BAND_2GHZ, + .n_channels = 1, + .n_bitrates = ARRAY_SIZE(bitrates_2ghz), + .ht_cap = { + .ht_supported = true, + .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40, + .ampdu_factor = 0x3, + .ampdu_density = 0x6, + .mcs = { + .rx_mask = {0xff, 0xff}, + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, + }, +}; + +static struct ieee80211_channel channel_5ghz = { + .band = IEEE80211_BAND_5GHZ, + .center_freq = 5240, + .hw_value = 5240, + .max_power = 20, +}; + +static struct ieee80211_rate bitrates_5ghz[] = { + { .bitrate = 60 }, + { .bitrate = 120 }, + { .bitrate = 240 }, +}; + +#define RX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 14) + +#define TX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \ + IEEE80211_VHT_MCS_SUPPORT_0_9 << 14) + +static struct ieee80211_supported_band band_5ghz = { + .channels = &channel_5ghz, + .bitrates = bitrates_5ghz, + .band = IEEE80211_BAND_5GHZ, + .n_channels = 1, + .n_bitrates = ARRAY_SIZE(bitrates_5ghz), + .ht_cap = { + .ht_supported = true, + .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | + IEEE80211_HT_CAP_GRN_FLD | + IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_DSSSCCK40, + .ampdu_factor = 0x3, + .ampdu_density = 0x6, + .mcs = { + .rx_mask = {0xff, 0xff}, + .tx_params = IEEE80211_HT_MCS_TX_DEFINED, + }, + }, + .vht_cap = { + .vht_supported = true, + .cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | + IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | + IEEE80211_VHT_CAP_RXLDPC | + IEEE80211_VHT_CAP_SHORT_GI_80 | + IEEE80211_VHT_CAP_SHORT_GI_160 | + IEEE80211_VHT_CAP_TXSTBC | + IEEE80211_VHT_CAP_RXSTBC_1 | + IEEE80211_VHT_CAP_RXSTBC_2 | + IEEE80211_VHT_CAP_RXSTBC_3 | + IEEE80211_VHT_CAP_RXSTBC_4 | + IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, + .vht_mcs = { + .rx_mcs_map = cpu_to_le16(RX_MCS_MAP), + .tx_mcs_map = cpu_to_le16(TX_MCS_MAP), + } + }, +}; + +/* Assigned at module init. Guaranteed locally-administered and unicast. */ +static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; + +/* Called with the rtnl lock held. */ +static int virt_wifi_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) +{ + struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy); + + wiphy_debug(wiphy, "scan\n"); + + if (priv->scan_request || priv->being_deleted) + return -EBUSY; + + priv->scan_request = request; + schedule_delayed_work(&priv->scan_result, HZ * 2); + + return 0; +} + +/* Acquires and releases the rdev BSS lock. */ +static void virt_wifi_scan_result(struct work_struct *work) +{ + struct { + u8 tag; + u8 len; + u8 ssid[8]; + } __packed ssid = { + .tag = WLAN_EID_SSID, .len = 8, .ssid = "VirtWifi", + }; + struct cfg80211_bss *informed_bss; + struct virt_wifi_wiphy_priv *priv = + container_of(work, struct virt_wifi_wiphy_priv, + scan_result.work); + struct wiphy *wiphy = priv_to_wiphy(priv); + + informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, + CFG80211_BSS_FTYPE_PRESP, + fake_router_bssid, + ktime_get_boot_ns(), + WLAN_CAPABILITY_ESS, 0, + (void *)&ssid, sizeof(ssid), + DBM_TO_MBM(-50), GFP_KERNEL); + cfg80211_put_bss(wiphy, informed_bss); + + /* Schedules work which acquires and releases the rtnl lock. */ + cfg80211_scan_done(priv->scan_request, false); + priv->scan_request = NULL; +} + +/* May acquire and release the rdev BSS lock. */ +static void virt_wifi_cancel_scan(struct wiphy *wiphy) +{ + struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy); + + cancel_delayed_work_sync(&priv->scan_result); + /* Clean up dangling callbacks if necessary. */ + if (priv->scan_request) { + /* Schedules work which acquires and releases the rtnl lock. */ + cfg80211_scan_done(priv->scan_request, true); + priv->scan_request = NULL; + } +} + +struct virt_wifi_netdev_priv { + struct delayed_work connect; + struct net_device *lowerdev; + struct net_device *upperdev; + u32 tx_packets; + u32 tx_failed; + u8 connect_requested_bss[ETH_ALEN]; + bool is_up; + bool is_connected; + bool being_deleted; +}; + +/* Called with the rtnl lock held. */ +static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev, + struct cfg80211_connect_params *sme) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); + bool could_schedule; + + if (priv->being_deleted || !priv->is_up) + return -EBUSY; + + could_schedule = schedule_delayed_work(&priv->connect, HZ * 2); + if (!could_schedule) + return -EBUSY; + + if (sme->bssid) + ether_addr_copy(priv->connect_requested_bss, sme->bssid); + else + eth_zero_addr(priv->connect_requested_bss); + + wiphy_debug(wiphy, "connect\n"); + + return 0; +} + +/* Acquires and releases the rdev event lock. */ +static void virt_wifi_connect_complete(struct work_struct *work) +{ + struct virt_wifi_netdev_priv *priv = + container_of(work, struct virt_wifi_netdev_priv, connect.work); + u8 *requested_bss = priv->connect_requested_bss; + bool has_addr = !is_zero_ether_addr(requested_bss); + bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); + u16 status = WLAN_STATUS_SUCCESS; + + if (!priv->is_up || (has_addr && !right_addr)) + status = WLAN_STATUS_UNSPECIFIED_FAILURE; + else + priv->is_connected = true; + + /* Schedules an event that acquires the rtnl lock. */ + cfg80211_connect_result(priv->upperdev, requested_bss, NULL, 0, NULL, 0, + status, GFP_KERNEL); + netif_carrier_on(priv->upperdev); +} + +/* May acquire and release the rdev event lock. */ +static void virt_wifi_cancel_connect(struct net_device *netdev) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); + + /* If there is work pending, clean up dangling callbacks. */ + if (cancel_delayed_work_sync(&priv->connect)) { + /* Schedules an event that acquires the rtnl lock. */ + cfg80211_connect_result(priv->upperdev, + priv->connect_requested_bss, NULL, 0, + NULL, 0, + WLAN_STATUS_UNSPECIFIED_FAILURE, + GFP_KERNEL); + } +} + +/* Called with the rtnl lock held. Acquires the rdev event lock. */ +static int virt_wifi_disconnect(struct wiphy *wiphy, struct net_device *netdev, + u16 reason_code) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); + + if (priv->being_deleted) + return -EBUSY; + + wiphy_debug(wiphy, "disconnect\n"); + virt_wifi_cancel_connect(netdev); + + cfg80211_disconnected(netdev, reason_code, NULL, 0, true, GFP_KERNEL); + priv->is_connected = false; + netif_carrier_off(netdev); + + return 0; +} + +/* Called with the rtnl lock held. */ +static int virt_wifi_get_station(struct wiphy *wiphy, struct net_device *dev, + const u8 *mac, struct station_info *sinfo) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(dev); + + wiphy_debug(wiphy, "get_station\n"); + + if (!priv->is_connected || !ether_addr_equal(mac, fake_router_bssid)) + return -ENOENT; + + sinfo->filled = BIT_ULL(NL80211_STA_INFO_TX_PACKETS) | + BIT_ULL(NL80211_STA_INFO_TX_FAILED) | + BIT_ULL(NL80211_STA_INFO_SIGNAL) | + BIT_ULL(NL80211_STA_INFO_TX_BITRATE); + sinfo->tx_packets = priv->tx_packets; + sinfo->tx_failed = priv->tx_failed; + /* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ */ + sinfo->signal = -50; + sinfo->txrate = (struct rate_info) { + .legacy = 10, /* units are 100kbit/s */ + }; + return 0; +} + +/* Called with the rtnl lock held. */ +static int virt_wifi_dump_station(struct wiphy *wiphy, struct net_device *dev, + int idx, u8 *mac, struct station_info *sinfo) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(dev); + + wiphy_debug(wiphy, "dump_station\n"); + + if (idx != 0 || !priv->is_connected) + return -ENOENT; + + ether_addr_copy(mac, fake_router_bssid); + return virt_wifi_get_station(wiphy, dev, fake_router_bssid, sinfo); +} + +static const struct cfg80211_ops virt_wifi_cfg80211_ops = { + .scan = virt_wifi_scan, + + .connect = virt_wifi_connect, + .disconnect = virt_wifi_disconnect, + + .get_station = virt_wifi_get_station, + .dump_station = virt_wifi_dump_station, +}; + +/* Acquires and releases the rtnl lock. */ +static struct wiphy *virt_wifi_make_wiphy(void) +{ + struct wiphy *wiphy; + struct virt_wifi_wiphy_priv *priv; + int err; + + wiphy = wiphy_new(&virt_wifi_cfg80211_ops, sizeof(*priv)); + + if (!wiphy) + return NULL; + + wiphy->max_scan_ssids = 4; + wiphy->max_scan_ie_len = 1000; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2ghz; + wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5ghz; + wiphy->bands[IEEE80211_BAND_60GHZ] = NULL; + + wiphy->regulatory_flags = REGULATORY_WIPHY_SELF_MANAGED; + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + priv = wiphy_priv(wiphy); + priv->being_deleted = false; + priv->scan_request = NULL; + INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result); + + err = wiphy_register(wiphy); + if (err < 0) { + wiphy_free(wiphy); + return NULL; + } + + return wiphy; +} + +/* Acquires and releases the rtnl lock. */ +static void virt_wifi_destroy_wiphy(struct wiphy *wiphy) +{ + struct virt_wifi_wiphy_priv *priv; + + WARN(!wiphy, "%s called with null wiphy", __func__); + if (!wiphy) + return; + + priv = wiphy_priv(wiphy); + priv->being_deleted = true; + virt_wifi_cancel_scan(wiphy); + + if (wiphy->registered) + wiphy_unregister(wiphy); + wiphy_free(wiphy); +} + +/* Enters and exits a RCU-bh critical section. */ +static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb, + struct net_device *dev) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(dev); + + priv->tx_packets++; + if (!priv->is_connected) { + priv->tx_failed++; + return NET_XMIT_DROP; + } + + skb->dev = priv->lowerdev; + return dev_queue_xmit(skb); +} + +/* Called with rtnl lock held. */ +static int virt_wifi_net_device_open(struct net_device *dev) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(dev); + + priv->is_up = true; + return 0; +} + +/* Called with rtnl lock held. */ +static int virt_wifi_net_device_stop(struct net_device *dev) +{ + struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev); + struct virt_wifi_wiphy_priv *w_priv; + + n_priv->is_up = false; + + if (!dev->ieee80211_ptr) + return 0; + w_priv = wiphy_priv(dev->ieee80211_ptr->wiphy); + + virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); + virt_wifi_cancel_connect(dev); + netif_carrier_off(dev); + + return 0; +} + +static const struct net_device_ops virt_wifi_ops = { + .ndo_start_xmit = virt_wifi_start_xmit, + .ndo_open = virt_wifi_net_device_open, + .ndo_stop = virt_wifi_net_device_stop, +}; + +/* Invoked as part of rtnl lock release. */ +static void virt_wifi_net_device_destructor(struct net_device *dev) +{ + /* Delayed past dellink to allow nl80211 to react to the device being + * deleted. + */ + kfree(dev->ieee80211_ptr); + dev->ieee80211_ptr = NULL; + free_netdev(dev); +} + +/* No lock interaction. */ +static void virt_wifi_setup(struct net_device *dev) +{ + ether_setup(dev); + dev->netdev_ops = &virt_wifi_ops; + dev->destructor = virt_wifi_net_device_destructor; +} + +/* Called in a RCU read critical section from netif_receive_skb */ +static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb) +{ + struct sk_buff *skb = *pskb; + struct virt_wifi_netdev_priv *priv = + rcu_dereference(skb->dev->rx_handler_data); + + if (!priv->is_connected) + return RX_HANDLER_PASS; + + /* GFP_ATOMIC because this is a packet interrupt handler. */ + skb = skb_share_check(skb, GFP_ATOMIC); + if (!skb) { + dev_err(&priv->upperdev->dev, "can't skb_share_check\n"); + return RX_HANDLER_CONSUMED; + } + + *pskb = skb; + skb->dev = priv->upperdev; + skb->pkt_type = PACKET_HOST; + return RX_HANDLER_ANOTHER; +} + +/* Called with rtnl lock held. */ +static int virt_wifi_newlink(struct net *src_net, struct net_device *dev, + struct nlattr *tb[], struct nlattr *data[]) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(dev); + int err; + + if (!tb[IFLA_LINK]) + return -EINVAL; + + netif_carrier_off(dev); + + priv->upperdev = dev; + priv->lowerdev = __dev_get_by_index(src_net, + nla_get_u32(tb[IFLA_LINK])); + + if (!priv->lowerdev) + return -ENODEV; + if (!tb[IFLA_MTU]) + dev->mtu = priv->lowerdev->mtu; + else if (dev->mtu > priv->lowerdev->mtu) + return -EINVAL; + + err = netdev_rx_handler_register(priv->lowerdev, virt_wifi_rx_handler, + priv); + if (err) { + dev_err(&priv->lowerdev->dev, + "can't netdev_rx_handler_register: %d\n", err); + return err; + } + + eth_hw_addr_inherit(dev, priv->lowerdev); + netif_stacked_transfer_operstate(priv->lowerdev, dev); + + SET_NETDEV_DEV(dev, &priv->lowerdev->dev); + dev->ieee80211_ptr = kzalloc(sizeof(*dev->ieee80211_ptr), GFP_KERNEL); + + if (!dev->ieee80211_ptr) + goto remove_handler; + + dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; + dev->ieee80211_ptr->wiphy = common_wiphy; + + err = register_netdevice(dev); + if (err) { + dev_err(&priv->lowerdev->dev, "can't register_netdevice: %d\n", + err); + goto free_wireless_dev; + } + + err = netdev_upper_dev_link(priv->lowerdev, dev); + if (err) { + dev_err(&priv->lowerdev->dev, "can't netdev_upper_dev_link: %d\n", + err); + goto unregister_netdev; + } + + priv->being_deleted = false; + priv->is_connected = false; + priv->is_up = false; + INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete); + + return 0; +unregister_netdev: + unregister_netdevice(dev); +free_wireless_dev: + kfree(dev->ieee80211_ptr); + dev->ieee80211_ptr = NULL; +remove_handler: + netdev_rx_handler_unregister(priv->lowerdev); + + return err; +} + +/* Called with rtnl lock held. */ +static void virt_wifi_dellink(struct net_device *dev, + struct list_head *head) +{ + struct virt_wifi_netdev_priv *priv = netdev_priv(dev); + + if (dev->ieee80211_ptr) + virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); + + priv->being_deleted = true; + virt_wifi_cancel_connect(dev); + netif_carrier_off(dev); + + netdev_rx_handler_unregister(priv->lowerdev); + netdev_upper_dev_unlink(priv->lowerdev, dev); + + unregister_netdevice_queue(dev, head); + + /* Deleting the wiphy is handled in the module destructor. */ +} + +static struct rtnl_link_ops virt_wifi_link_ops = { + .kind = "virt_wifi", + .setup = virt_wifi_setup, + .newlink = virt_wifi_newlink, + .dellink = virt_wifi_dellink, + .priv_size = sizeof(struct virt_wifi_netdev_priv), +}; + +/* Acquires and releases the rtnl lock. */ +static int __init virt_wifi_init_module(void) +{ + int err; + + /* Guaranteed to be locallly-administered and not multicast. */ + eth_random_addr(fake_router_bssid); + + common_wiphy = virt_wifi_make_wiphy(); + if (!common_wiphy) + return -ENOMEM; + + err = rtnl_link_register(&virt_wifi_link_ops); + if (err) + virt_wifi_destroy_wiphy(common_wiphy); + + return err; +} + +/* Acquires and releases the rtnl lock. */ +static void __exit virt_wifi_cleanup_module(void) +{ + /* Will delete any devices that depend on the wiphy. */ + rtnl_link_unregister(&virt_wifi_link_ops); + virt_wifi_destroy_wiphy(common_wiphy); +} + +module_init(virt_wifi_init_module); +module_exit(virt_wifi_cleanup_module); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>"); +MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices"); +MODULE_ALIAS_RTNL_LINK("virt_wifi"); diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 09ac56317f1b..533bd2467910 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -4519,8 +4519,8 @@ static int qeth_snmp_command_cb(struct qeth_card *card, { struct qeth_ipa_cmd *cmd; struct qeth_arp_query_info *qinfo; - struct qeth_snmp_cmd *snmp; unsigned char *data; + void *snmp_data; __u16 data_len; QETH_CARD_TEXT(card, 3, "snpcmdcb"); @@ -4528,7 +4528,6 @@ static int qeth_snmp_command_cb(struct qeth_card *card, cmd = (struct qeth_ipa_cmd *) sdata; data = (unsigned char *)((char *)cmd - reply->offset); qinfo = (struct qeth_arp_query_info *) reply->param; - snmp = &cmd->data.setadapterparms.data.snmp; if (cmd->hdr.return_code) { QETH_CARD_TEXT_(card, 4, "scer1%x", cmd->hdr.return_code); @@ -4541,10 +4540,15 @@ static int qeth_snmp_command_cb(struct qeth_card *card, return 0; } data_len = *((__u16 *)QETH_IPA_PDU_LEN_PDU1(data)); - if (cmd->data.setadapterparms.hdr.seq_no == 1) - data_len -= (__u16)((char *)&snmp->data - (char *)cmd); - else - data_len -= (__u16)((char *)&snmp->request - (char *)cmd); + if (cmd->data.setadapterparms.hdr.seq_no == 1) { + snmp_data = &cmd->data.setadapterparms.data.snmp; + data_len -= offsetof(struct qeth_ipa_cmd, + data.setadapterparms.data.snmp); + } else { + snmp_data = &cmd->data.setadapterparms.data.snmp.request; + data_len -= offsetof(struct qeth_ipa_cmd, + data.setadapterparms.data.snmp.request); + } /* check if there is enough room in userspace */ if ((qinfo->udata_len - qinfo->udata_offset) < data_len) { @@ -4557,16 +4561,9 @@ static int qeth_snmp_command_cb(struct qeth_card *card, QETH_CARD_TEXT_(card, 4, "sseqn%i", cmd->data.setadapterparms.hdr.seq_no); /*copy entries to user buffer*/ - if (cmd->data.setadapterparms.hdr.seq_no == 1) { - memcpy(qinfo->udata + qinfo->udata_offset, - (char *)snmp, - data_len + offsetof(struct qeth_snmp_cmd, data)); - qinfo->udata_offset += offsetof(struct qeth_snmp_cmd, data); - } else { - memcpy(qinfo->udata + qinfo->udata_offset, - (char *)&snmp->request, data_len); - } + memcpy(qinfo->udata + qinfo->udata_offset, snmp_data, data_len); qinfo->udata_offset += data_len; + /* check if all replies received ... */ QETH_CARD_TEXT_(card, 4, "srtot%i", cmd->data.setadapterparms.hdr.used_total); diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c index 1b831598df7c..ff06bdfd2b20 100644 --- a/drivers/s390/virtio/virtio_ccw.c +++ b/drivers/s390/virtio/virtio_ccw.c @@ -59,6 +59,7 @@ struct virtio_ccw_device { unsigned int revision; /* Transport revision */ wait_queue_head_t wait_q; spinlock_t lock; + struct mutex io_lock; /* Serializes I/O requests */ struct list_head virtqueues; unsigned long indicators; unsigned long indicators2; @@ -307,6 +308,7 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev, unsigned long flags; int flag = intparm & VIRTIO_CCW_INTPARM_MASK; + mutex_lock(&vcdev->io_lock); do { spin_lock_irqsave(get_ccwdev_lock(vcdev->cdev), flags); ret = ccw_device_start(vcdev->cdev, ccw, intparm, 0, 0); @@ -319,7 +321,9 @@ static int ccw_io_helper(struct virtio_ccw_device *vcdev, cpu_relax(); } while (ret == -EBUSY); wait_event(vcdev->wait_q, doing_io(vcdev, flag) == 0); - return ret ? ret : vcdev->err; + ret = ret ? ret : vcdev->err; + mutex_unlock(&vcdev->io_lock); + return ret; } static void virtio_ccw_drop_indicator(struct virtio_ccw_device *vcdev, @@ -833,6 +837,7 @@ static void virtio_ccw_get_config(struct virtio_device *vdev, int ret; struct ccw1 *ccw; void *config_area; + unsigned long flags; ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); if (!ccw) @@ -851,11 +856,13 @@ static void virtio_ccw_get_config(struct virtio_device *vdev, if (ret) goto out_free; + spin_lock_irqsave(&vcdev->lock, flags); memcpy(vcdev->config, config_area, offset + len); - if (buf) - memcpy(buf, &vcdev->config[offset], len); if (vcdev->config_ready < offset + len) vcdev->config_ready = offset + len; + spin_unlock_irqrestore(&vcdev->lock, flags); + if (buf) + memcpy(buf, config_area + offset, len); out_free: kfree(config_area); @@ -869,6 +876,7 @@ static void virtio_ccw_set_config(struct virtio_device *vdev, struct virtio_ccw_device *vcdev = to_vc_device(vdev); struct ccw1 *ccw; void *config_area; + unsigned long flags; ccw = kzalloc(sizeof(*ccw), GFP_DMA | GFP_KERNEL); if (!ccw) @@ -881,9 +889,11 @@ static void virtio_ccw_set_config(struct virtio_device *vdev, /* Make sure we don't overwrite fields. */ if (vcdev->config_ready < offset) virtio_ccw_get_config(vdev, 0, NULL, offset); + spin_lock_irqsave(&vcdev->lock, flags); memcpy(&vcdev->config[offset], buf, len); /* Write the config area to the host. */ memcpy(config_area, vcdev->config, sizeof(vcdev->config)); + spin_unlock_irqrestore(&vcdev->lock, flags); ccw->cmd_code = CCW_CMD_WRITE_CONF; ccw->flags = 0; ccw->count = offset + len; @@ -1230,6 +1240,7 @@ static int virtio_ccw_online(struct ccw_device *cdev) init_waitqueue_head(&vcdev->wait_q); INIT_LIST_HEAD(&vcdev->virtqueues); spin_lock_init(&vcdev->lock); + mutex_init(&vcdev->io_lock); spin_lock_irqsave(get_ccwdev_lock(cdev), flags); dev_set_drvdata(&cdev->dev, vcdev); diff --git a/drivers/scsi/bfa/bfa_fcbuild.c b/drivers/scsi/bfa/bfa_fcbuild.c index dce787f6cca2..daade591409a 100644 --- a/drivers/scsi/bfa/bfa_fcbuild.c +++ b/drivers/scsi/bfa/bfa_fcbuild.c @@ -1249,8 +1249,8 @@ fc_rspnid_build(struct fchs_s *fchs, void *pyld, u32 s_id, u16 ox_id, memset(rspnid, 0, sizeof(struct fcgs_rspnid_req_s)); rspnid->dap = s_id; - rspnid->spn_len = (u8) strlen((char *)name); - strncpy((char *)rspnid->spn, (char *)name, rspnid->spn_len); + strlcpy(rspnid->spn, name, sizeof(rspnid->spn)); + rspnid->spn_len = (u8) strlen(rspnid->spn); return sizeof(struct fcgs_rspnid_req_s) + sizeof(struct ct_hdr_s); } @@ -1270,8 +1270,8 @@ fc_rsnn_nn_build(struct fchs_s *fchs, void *pyld, u32 s_id, memset(rsnn_nn, 0, sizeof(struct fcgs_rsnn_nn_req_s)); rsnn_nn->node_name = node_name; - rsnn_nn->snn_len = (u8) strlen((char *)name); - strncpy((char *)rsnn_nn->snn, (char *)name, rsnn_nn->snn_len); + strlcpy(rsnn_nn->snn, name, sizeof(rsnn_nn->snn)); + rsnn_nn->snn_len = (u8) strlen(rsnn_nn->snn); return sizeof(struct fcgs_rsnn_nn_req_s) + sizeof(struct ct_hdr_s); } diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 0f19455951ec..475470efb7c6 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -831,23 +831,23 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); /* Model name/number */ - strncpy((char *)&port_cfg->sym_name, model, - BFA_FCS_PORT_SYMBNAME_MODEL_SZ); - strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + strlcpy(port_cfg->sym_name.symname, model, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, + BFA_SYMNAME_MAXLEN); /* Driver Version */ - strncat((char *)&port_cfg->sym_name, (char *)driver_info->version, - BFA_FCS_PORT_SYMBNAME_VERSION_SZ); - strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + strlcat(port_cfg->sym_name.symname, driver_info->version, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, + BFA_SYMNAME_MAXLEN); /* Host machine name */ - strncat((char *)&port_cfg->sym_name, - (char *)driver_info->host_machine_name, - BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ); - strncat((char *)&port_cfg->sym_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + strlcat(port_cfg->sym_name.symname, + driver_info->host_machine_name, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, + BFA_SYMNAME_MAXLEN); /* * Host OS Info : @@ -855,24 +855,24 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) * OS name string and instead copy the entire OS info string (64 bytes). */ if (driver_info->host_os_patch[0] == '\0') { - strncat((char *)&port_cfg->sym_name, - (char *)driver_info->host_os_name, - BFA_FCS_OS_STR_LEN); - strncat((char *)&port_cfg->sym_name, + strlcat(port_cfg->sym_name.symname, + driver_info->host_os_name, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + BFA_SYMNAME_MAXLEN); } else { - strncat((char *)&port_cfg->sym_name, - (char *)driver_info->host_os_name, - BFA_FCS_PORT_SYMBNAME_OSINFO_SZ); - strncat((char *)&port_cfg->sym_name, + strlcat(port_cfg->sym_name.symname, + driver_info->host_os_name, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + BFA_SYMNAME_MAXLEN); /* Append host OS Patch Info */ - strncat((char *)&port_cfg->sym_name, - (char *)driver_info->host_os_patch, - BFA_FCS_PORT_SYMBNAME_OSPATCH_SZ); + strlcat(port_cfg->sym_name.symname, + driver_info->host_os_patch, + BFA_SYMNAME_MAXLEN); } /* null terminate */ @@ -892,26 +892,26 @@ bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric) bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); /* Model name/number */ - strncpy((char *)&port_cfg->node_sym_name, model, - BFA_FCS_PORT_SYMBNAME_MODEL_SZ); - strncat((char *)&port_cfg->node_sym_name, + strlcpy(port_cfg->node_sym_name.symname, model, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->node_sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + BFA_SYMNAME_MAXLEN); /* Driver Version */ - strncat((char *)&port_cfg->node_sym_name, (char *)driver_info->version, - BFA_FCS_PORT_SYMBNAME_VERSION_SZ); - strncat((char *)&port_cfg->node_sym_name, + strlcat(port_cfg->node_sym_name.symname, (char *)driver_info->version, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->node_sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + BFA_SYMNAME_MAXLEN); /* Host machine name */ - strncat((char *)&port_cfg->node_sym_name, - (char *)driver_info->host_machine_name, - BFA_FCS_PORT_SYMBNAME_MACHINENAME_SZ); - strncat((char *)&port_cfg->node_sym_name, + strlcat(port_cfg->node_sym_name.symname, + driver_info->host_machine_name, + BFA_SYMNAME_MAXLEN); + strlcat(port_cfg->node_sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); + BFA_SYMNAME_MAXLEN); /* null terminate */ port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0; diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index ff75ef891755..aa96f31ebc43 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -2630,10 +2630,10 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, bfa_ioc_get_adapter_fw_ver(&port->fcs->bfa->ioc, hba_attr->fw_version); - strncpy(hba_attr->driver_version, (char *)driver_info->version, + strlcpy(hba_attr->driver_version, (char *)driver_info->version, sizeof(hba_attr->driver_version)); - strncpy(hba_attr->os_name, driver_info->host_os_name, + strlcpy(hba_attr->os_name, driver_info->host_os_name, sizeof(hba_attr->os_name)); /* @@ -2641,23 +2641,23 @@ bfa_fcs_fdmi_get_hbaattr(struct bfa_fcs_lport_fdmi_s *fdmi, * to the os name along with a separator */ if (driver_info->host_os_patch[0] != '\0') { - strncat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - sizeof(BFA_FCS_PORT_SYMBNAME_SEPARATOR)); - strncat(hba_attr->os_name, driver_info->host_os_patch, - sizeof(driver_info->host_os_patch)); + strlcat(hba_attr->os_name, BFA_FCS_PORT_SYMBNAME_SEPARATOR, + sizeof(hba_attr->os_name)); + strlcat(hba_attr->os_name, driver_info->host_os_patch, + sizeof(hba_attr->os_name)); } /* Retrieve the max frame size from the port attr */ bfa_fcs_fdmi_get_portattr(fdmi, &fcs_port_attr); hba_attr->max_ct_pyld = fcs_port_attr.max_frm_size; - strncpy(hba_attr->node_sym_name.symname, + strlcpy(hba_attr->node_sym_name.symname, port->port_cfg.node_sym_name.symname, BFA_SYMNAME_MAXLEN); strcpy(hba_attr->vendor_info, "BROCADE"); hba_attr->num_ports = cpu_to_be32(bfa_ioc_get_nports(&port->fcs->bfa->ioc)); hba_attr->fabric_name = port->fabric->lps->pr_nwwn; - strncpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); + strlcpy(hba_attr->bios_ver, hba_attr->option_rom_ver, BFA_VERSION_LEN); } @@ -2724,20 +2724,20 @@ bfa_fcs_fdmi_get_portattr(struct bfa_fcs_lport_fdmi_s *fdmi, /* * OS device Name */ - strncpy(port_attr->os_device_name, (char *)driver_info->os_device_name, + strlcpy(port_attr->os_device_name, driver_info->os_device_name, sizeof(port_attr->os_device_name)); /* * Host name */ - strncpy(port_attr->host_name, (char *)driver_info->host_machine_name, + strlcpy(port_attr->host_name, driver_info->host_machine_name, sizeof(port_attr->host_name)); port_attr->node_name = bfa_fcs_lport_get_nwwn(port); port_attr->port_name = bfa_fcs_lport_get_pwwn(port); - strncpy(port_attr->port_sym_name.symname, - (char *)&bfa_fcs_lport_get_psym_name(port), BFA_SYMNAME_MAXLEN); + strlcpy(port_attr->port_sym_name.symname, + bfa_fcs_lport_get_psym_name(port).symname, BFA_SYMNAME_MAXLEN); bfa_fcs_lport_get_attr(port, &lport_attr); port_attr->port_type = cpu_to_be32(lport_attr.port_type); port_attr->scos = pport_attr.cos_supported; @@ -3217,7 +3217,7 @@ bfa_fcs_lport_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, rsp_str[gmal_entry->len-1] = 0; /* copy IP Address to fabric */ - strncpy(bfa_fcs_lport_get_fabric_ipaddr(port), + strlcpy(bfa_fcs_lport_get_fabric_ipaddr(port), gmal_entry->ip_addr, BFA_FCS_FABRIC_IPADDR_SZ); break; @@ -4655,21 +4655,13 @@ bfa_fcs_lport_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) * to that of the base port. */ - strncpy((char *)psymbl, - (char *) & - (bfa_fcs_lport_get_psym_name + strlcpy(symbl, + (char *)&(bfa_fcs_lport_get_psym_name (bfa_fcs_get_base_port(port->fcs))), - strlen((char *) & - bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port - (port->fcs)))); - - /* Ensure we have a null terminating string. */ - ((char *)psymbl)[strlen((char *) & - bfa_fcs_lport_get_psym_name(bfa_fcs_get_base_port - (port->fcs)))] = 0; - strncat((char *)psymbl, - (char *) &(bfa_fcs_lport_get_psym_name(port)), - strlen((char *) &bfa_fcs_lport_get_psym_name(port))); + sizeof(symbl)); + + strlcat(symbl, (char *)&(bfa_fcs_lport_get_psym_name(port)), + sizeof(symbl)); } else { psymbl = (u8 *) &(bfa_fcs_lport_get_psym_name(port)); } @@ -5161,7 +5153,6 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) struct fchs_s fchs; struct bfa_fcxp_s *fcxp; u8 symbl[256]; - u8 *psymbl = &symbl[0]; int len; /* Avoid sending RSPN in the following states. */ @@ -5191,22 +5182,17 @@ bfa_fcs_lport_ns_util_send_rspn_id(void *cbarg, struct bfa_fcxp_s *fcxp_alloced) * For Vports, we append the vport's port symbolic name * to that of the base port. */ - strncpy((char *)psymbl, (char *)&(bfa_fcs_lport_get_psym_name + strlcpy(symbl, (char *)&(bfa_fcs_lport_get_psym_name (bfa_fcs_get_base_port(port->fcs))), - strlen((char *)&bfa_fcs_lport_get_psym_name( - bfa_fcs_get_base_port(port->fcs)))); - - /* Ensure we have a null terminating string. */ - ((char *)psymbl)[strlen((char *)&bfa_fcs_lport_get_psym_name( - bfa_fcs_get_base_port(port->fcs)))] = 0; + sizeof(symbl)); - strncat((char *)psymbl, + strlcat(symbl, (char *)&(bfa_fcs_lport_get_psym_name(port)), - strlen((char *)&bfa_fcs_lport_get_psym_name(port))); + sizeof(symbl)); } len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), - bfa_fcs_lport_get_fcid(port), 0, psymbl); + bfa_fcs_lport_get_fcid(port), 0, symbl); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0); diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 98f7e8cca52d..e533474748a5 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c @@ -2802,7 +2802,7 @@ void bfa_ioc_get_adapter_manufacturer(struct bfa_ioc_s *ioc, char *manufacturer) { memset((void *)manufacturer, 0, BFA_ADAPTER_MFG_NAME_LEN); - memcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); + strlcpy(manufacturer, BFA_MFG_NAME, BFA_ADAPTER_MFG_NAME_LEN); } void diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index 625225f31081..15d02eb09476 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c @@ -365,8 +365,8 @@ bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid, lp.eid = event; lp.log_type = BFA_PL_LOG_TYPE_STRING; lp.misc = misc; - strncpy(lp.log_entry.string_log, log_str, - BFA_PL_STRING_LOG_SZ - 1); + strlcpy(lp.log_entry.string_log, log_str, + BFA_PL_STRING_LOG_SZ); lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0'; bfa_plog_add(plog, &lp); } diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index cc3b9d3d6d40..bfefa2bfde0e 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c @@ -987,20 +987,20 @@ bfad_start_ops(struct bfad_s *bfad) { /* Fill the driver_info info to fcs*/ memset(&driver_info, 0, sizeof(driver_info)); - strncpy(driver_info.version, BFAD_DRIVER_VERSION, - sizeof(driver_info.version) - 1); + strlcpy(driver_info.version, BFAD_DRIVER_VERSION, + sizeof(driver_info.version)); if (host_name) - strncpy(driver_info.host_machine_name, host_name, - sizeof(driver_info.host_machine_name) - 1); + strlcpy(driver_info.host_machine_name, host_name, + sizeof(driver_info.host_machine_name)); if (os_name) - strncpy(driver_info.host_os_name, os_name, - sizeof(driver_info.host_os_name) - 1); + strlcpy(driver_info.host_os_name, os_name, + sizeof(driver_info.host_os_name)); if (os_patch) - strncpy(driver_info.host_os_patch, os_patch, - sizeof(driver_info.host_os_patch) - 1); + strlcpy(driver_info.host_os_patch, os_patch, + sizeof(driver_info.host_os_patch)); - strncpy(driver_info.os_device_name, bfad->pci_name, - sizeof(driver_info.os_device_name) - 1); + strlcpy(driver_info.os_device_name, bfad->pci_name, + sizeof(driver_info.os_device_name)); /* FCS driver info init */ spin_lock_irqsave(&bfad->bfad_lock, flags); diff --git a/drivers/scsi/bfa/bfad_attr.c b/drivers/scsi/bfa/bfad_attr.c index 40be670a1cbc..6d21bc6a7713 100644 --- a/drivers/scsi/bfa/bfad_attr.c +++ b/drivers/scsi/bfa/bfad_attr.c @@ -842,7 +842,7 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr, char symname[BFA_SYMNAME_MAXLEN]; bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); - strncpy(symname, port_attr.port_cfg.sym_name.symname, + strlcpy(symname, port_attr.port_cfg.sym_name.symname, BFA_SYMNAME_MAXLEN); return snprintf(buf, PAGE_SIZE, "%s\n", symname); } diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 023b9d42ad9a..be2de04179d0 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -126,7 +126,7 @@ bfad_iocmd_ioc_get_attr(struct bfad_s *bfad, void *cmd) /* fill in driver attr info */ strcpy(iocmd->ioc_attr.driver_attr.driver, BFAD_DRIVER_NAME); - strncpy(iocmd->ioc_attr.driver_attr.driver_ver, + strlcpy(iocmd->ioc_attr.driver_attr.driver_ver, BFAD_DRIVER_VERSION, BFA_VERSION_LEN); strcpy(iocmd->ioc_attr.driver_attr.fw_ver, iocmd->ioc_attr.adapter_attr.fw_ver); @@ -314,9 +314,9 @@ bfad_iocmd_port_get_attr(struct bfad_s *bfad, void *cmd) iocmd->attr.port_type = port_attr.port_type; iocmd->attr.loopback = port_attr.loopback; iocmd->attr.authfail = port_attr.authfail; - strncpy(iocmd->attr.port_symname.symname, + strlcpy(iocmd->attr.port_symname.symname, port_attr.port_cfg.sym_name.symname, - sizeof(port_attr.port_cfg.sym_name.symname)); + sizeof(iocmd->attr.port_symname.symname)); iocmd->status = BFA_STATUS_OK; return 0; diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index c00b2ff72b55..be5ee2d37815 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -238,14 +238,23 @@ csio_osname(uint8_t *buf, size_t buf_len) } static inline void -csio_append_attrib(uint8_t **ptr, uint16_t type, uint8_t *val, uint16_t len) +csio_append_attrib(uint8_t **ptr, uint16_t type, void *val, size_t val_len) { + uint16_t len; struct fc_fdmi_attr_entry *ae = (struct fc_fdmi_attr_entry *)*ptr; + + if (WARN_ON(val_len > U16_MAX)) + return; + + len = val_len; + ae->type = htons(type); len += 4; /* includes attribute type and length */ len = (len + 3) & ~3; /* should be multiple of 4 bytes */ ae->len = htons(len); - memcpy(ae->value, val, len); + memcpy(ae->value, val, val_len); + if (len > val_len) + memset(ae->value + val_len, 0, len - val_len); *ptr += len; } @@ -335,7 +344,7 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) numattrs++; val = htonl(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT); csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED, - (uint8_t *)&val, + &val, FC_FDMI_PORT_ATTR_SUPPORTEDSPEED_LEN); numattrs++; @@ -346,23 +355,22 @@ csio_ln_fdmi_rhba_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) else val = htonl(CSIO_HBA_PORTSPEED_UNKNOWN); csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED, - (uint8_t *)&val, - FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN); + &val, FC_FDMI_PORT_ATTR_CURRENTPORTSPEED_LEN); numattrs++; mfs = ln->ln_sparm.csp.sp_bb_data; csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_MAXFRAMESIZE, - (uint8_t *)&mfs, FC_FDMI_PORT_ATTR_MAXFRAMESIZE_LEN); + &mfs, sizeof(mfs)); numattrs++; strcpy(buf, "csiostor"); csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_OSDEVICENAME, buf, - (uint16_t)strlen(buf)); + strlen(buf)); numattrs++; if (!csio_hostname(buf, sizeof(buf))) { csio_append_attrib(&pld, FC_FDMI_PORT_ATTR_HOSTNAME, - buf, (uint16_t)strlen(buf)); + buf, strlen(buf)); numattrs++; } attrib_blk->numattrs = htonl(numattrs); @@ -444,33 +452,32 @@ csio_ln_fdmi_dprt_cbfn(struct csio_hw *hw, struct csio_ioreq *fdmi_req) strcpy(buf, "Chelsio Communications"); csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MANUFACTURER, buf, - (uint16_t)strlen(buf)); + strlen(buf)); numattrs++; csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_SERIALNUMBER, - hw->vpd.sn, (uint16_t)sizeof(hw->vpd.sn)); + hw->vpd.sn, sizeof(hw->vpd.sn)); numattrs++; csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODEL, hw->vpd.id, - (uint16_t)sizeof(hw->vpd.id)); + sizeof(hw->vpd.id)); numattrs++; csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MODELDESCRIPTION, - hw->model_desc, (uint16_t)strlen(hw->model_desc)); + hw->model_desc, strlen(hw->model_desc)); numattrs++; csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_HARDWAREVERSION, - hw->hw_ver, (uint16_t)sizeof(hw->hw_ver)); + hw->hw_ver, sizeof(hw->hw_ver)); numattrs++; csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_FIRMWAREVERSION, - hw->fwrev_str, (uint16_t)strlen(hw->fwrev_str)); + hw->fwrev_str, strlen(hw->fwrev_str)); numattrs++; if (!csio_osname(buf, sizeof(buf))) { csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_OSNAMEVERSION, - buf, (uint16_t)strlen(buf)); + buf, strlen(buf)); numattrs++; } csio_append_attrib(&pld, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD, - (uint8_t *)&maxpayload, - FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN); + &maxpayload, FC_FDMI_HBA_ATTR_MAXCTPAYLOAD_LEN); len = (uint32_t)(pld - (uint8_t *)cmd); numattrs++; attrib_blk->numattrs = htonl(numattrs); @@ -1794,6 +1801,8 @@ csio_ln_mgmt_submit_req(struct csio_ioreq *io_req, struct csio_mgmtm *mgmtm = csio_hw_to_mgmtm(hw); int rv; + BUG_ON(pld_len > pld->len); + io_req->io_cbfn = io_cbfn; /* Upper layer callback handler */ io_req->fw_handle = (uintptr_t) (io_req); io_req->eq_idx = mgmtm->eq_idx; diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 6b61b09b3226..75f2179860a7 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -33,7 +33,6 @@ struct scsi_dev_info_list_table { }; -static const char spaces[] = " "; /* 16 of them */ static unsigned scsi_default_dev_flags; static LIST_HEAD(scsi_dev_info_list); static char scsi_dev_flags[256]; @@ -291,20 +290,13 @@ static void scsi_strcpy_devinfo(char *name, char *to, size_t to_length, size_t from_length; from_length = strlen(from); - strncpy(to, from, min(to_length, from_length)); - if (from_length < to_length) { - if (compatible) { - /* - * NUL terminate the string if it is short. - */ - to[from_length] = '\0'; - } else { - /* - * space pad the string if it is short. - */ - strncpy(&to[from_length], spaces, - to_length - from_length); - } + /* this zero-pads the destination */ + strncpy(to, from, to_length); + if (from_length < to_length && !compatible) { + /* + * space pad the string if it is short. + */ + memset(&to[from_length], ' ', to_length - from_length); } if (from_length > to_length) printk(KERN_WARNING "%s: %s string '%s' is too long\n", diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 635a93cc94de..eed7603db5ec 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -700,7 +700,7 @@ repeat_fid2path: memmove(ptr + strlen(gf->gf_path) + 1, ptr, strlen(ori_gf->gf_path)); - strncpy(ptr, gf->gf_path, strlen(gf->gf_path)); + strcpy(ptr, gf->gf_path); ptr += strlen(gf->gf_path); *ptr = '/'; } diff --git a/drivers/staging/rts5208/sd.c b/drivers/staging/rts5208/sd.c index 9a876ce92dbd..dc91cd29f1d2 100644 --- a/drivers/staging/rts5208/sd.c +++ b/drivers/staging/rts5208/sd.c @@ -4165,12 +4165,6 @@ RTY_SEND_CMD: rtsx_trace(chip); return STATUS_FAIL; } - - } else if (rsp_type == SD_RSP_TYPE_R0) { - if ((ptr[3] & 0x1E) != 0x03) { - rtsx_trace(chip); - return STATUS_FAIL; - } } } } diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c index 78883ca64ddd..035810bbcd02 100644 --- a/drivers/tty/serial/8250/8250_mtk.c +++ b/drivers/tty/serial/8250/8250_mtk.c @@ -231,17 +231,17 @@ static int mtk8250_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - pm_runtime_enable(&pdev->dev); - if (!pm_runtime_enabled(&pdev->dev)) { - err = mtk8250_runtime_resume(&pdev->dev); - if (err) - return err; - } + err = mtk8250_runtime_resume(&pdev->dev); + if (err) + return err; data->line = serial8250_register_8250_port(&uart); if (data->line < 0) return data->line; + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + return 0; } @@ -252,13 +252,11 @@ static int mtk8250_remove(struct platform_device *pdev) pm_runtime_get_sync(&pdev->dev); serial8250_unregister_port(data->line); + mtk8250_runtime_suspend(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); - if (!pm_runtime_status_suspended(&pdev->dev)) - mtk8250_runtime_suspend(&pdev->dev); - return 0; } diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c index 2db68dfe497d..f2b0d8cee8ef 100644 --- a/drivers/tty/serial/kgdboc.c +++ b/drivers/tty/serial/kgdboc.c @@ -131,24 +131,6 @@ static void kgdboc_unregister_kbd(void) #define kgdboc_restore_input() #endif /* ! CONFIG_KDB_KEYBOARD */ -static int kgdboc_option_setup(char *opt) -{ - if (!opt) { - pr_err("kgdboc: config string not provided\n"); - return -EINVAL; - } - - if (strlen(opt) >= MAX_CONFIG_LEN) { - printk(KERN_ERR "kgdboc: config string too long\n"); - return -ENOSPC; - } - strcpy(config, opt); - - return 0; -} - -__setup("kgdboc=", kgdboc_option_setup); - static void cleanup_kgdboc(void) { if (kgdb_unregister_nmi_console()) @@ -162,15 +144,13 @@ static int configure_kgdboc(void) { struct tty_driver *p; int tty_line = 0; - int err; + int err = -ENODEV; char *cptr = config; struct console *cons; - err = kgdboc_option_setup(config); - if (err || !strlen(config) || isspace(config[0])) + if (!strlen(config) || isspace(config[0])) goto noconfig; - err = -ENODEV; kgdboc_io_ops.is_console = 0; kgdb_tty_driver = NULL; @@ -252,7 +232,7 @@ static void kgdboc_put_char(u8 chr) static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) { - int len = strlen(kmessage); + size_t len = strlen(kmessage); if (len >= MAX_CONFIG_LEN) { printk(KERN_ERR "kgdboc: config string too long\n"); @@ -274,7 +254,7 @@ static int param_set_kgdboc_var(const char *kmessage, struct kernel_param *kp) strcpy(config, kmessage); /* Chop out \n char as a result of echo */ - if (config[len - 1] == '\n') + if (len && config[len - 1] == '\n') config[len - 1] = '\0'; if (configured == 1) @@ -318,6 +298,25 @@ static struct kgdb_io kgdboc_io_ops = { }; #ifdef CONFIG_KGDB_SERIAL_CONSOLE +static int kgdboc_option_setup(char *opt) +{ + if (!opt) { + pr_err("config string not provided\n"); + return -EINVAL; + } + + if (strlen(opt) >= MAX_CONFIG_LEN) { + pr_err("config string too long\n"); + return -ENOSPC; + } + strcpy(config, opt); + + return 0; +} + +__setup("kgdboc=", kgdboc_option_setup); + + /* This is only available if kgdboc is a built in for early debugging */ static int __init kgdboc_early_init(char *opt) { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index ebae7460a60e..ab58cb3a9b6a 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2222,7 +2222,7 @@ static int usb_enumerate_device_otg(struct usb_device *udev) /* descriptor may appear anywhere in config */ err = __usb_get_extra_descriptor(udev->rawdescriptors[0], le16_to_cpu(udev->config[0].desc.wTotalLength), - USB_DT_OTG, (void **) &desc); + USB_DT_OTG, (void **) &desc, sizeof(*desc)); if (err || !(desc->bmAttributes & USB_OTG_HNP)) return 0; diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 1e8f68960014..cf378b1ed373 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -64,6 +64,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Microsoft LifeCam-VX700 v2.0 */ { USB_DEVICE(0x045e, 0x0770), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Cherry Stream G230 2.0 (G85-231) and 3.0 (G85-232) */ + { USB_DEVICE(0x046a, 0x0023), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Logitech HD Pro Webcams C920, C920-C, C925e and C930e */ { USB_DEVICE(0x046d, 0x082d), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x046d, 0x0841), .driver_info = USB_QUIRK_DELAY_INIT }, @@ -185,6 +188,10 @@ static const struct usb_device_id usb_quirk_list[] = { /* Midiman M-Audio Keystation 88es */ { USB_DEVICE(0x0763, 0x0192), .driver_info = USB_QUIRK_RESET_RESUME }, + /* SanDisk Ultra Fit and Ultra Flair */ + { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM }, + { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, + /* M-Systems Flash Disk Pioneers */ { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 74087b265317..d96ed8fe6442 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -726,14 +726,14 @@ EXPORT_SYMBOL(usb_get_xfer_ring_dma_addr); */ int __usb_get_extra_descriptor(char *buffer, unsigned size, - unsigned char type, void **ptr) + unsigned char type, void **ptr, size_t minsize) { struct usb_descriptor_header *header; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; - if (header->bLength < 2) { + if (header->bLength < 2 || header->bLength > size) { printk(KERN_ERR "%s: bogus descriptor, type %d length %d\n", usbcore_name, @@ -742,7 +742,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, return -1; } - if (header->bDescriptorType == type) { + if (header->bDescriptorType == type && header->bLength >= minsize) { *ptr = header; return 0; } diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c index eb876ed96861..85f1f282c1d5 100644 --- a/drivers/usb/gadget/udc/dummy_hcd.c +++ b/drivers/usb/gadget/udc/dummy_hcd.c @@ -379,11 +379,10 @@ static void set_link_state_by_speed(struct dummy_hcd *dum_hcd) USB_PORT_STAT_CONNECTION) == 0) dum_hcd->port_status |= (USB_PORT_STAT_C_CONNECTION << 16); - if ((dum_hcd->port_status & - USB_PORT_STAT_ENABLE) == 1 && - (dum_hcd->port_status & - USB_SS_PORT_LS_U0) == 1 && - dum_hcd->rh_state != DUMMY_RH_SUSPENDED) + if ((dum_hcd->port_status & USB_PORT_STAT_ENABLE) && + (dum_hcd->port_status & + USB_PORT_STAT_LINK_STATE) == USB_SS_PORT_LS_U0 && + dum_hcd->rh_state != DUMMY_RH_SUSPENDED) dum_hcd->active = 1; } } else { diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 1db0626c8bf4..97750f162f01 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c @@ -654,7 +654,7 @@ static int hwahc_security_create(struct hwahc *hwahc) top = itr + itr_size; result = __usb_get_extra_descriptor(usb_dev->rawdescriptors[index], le16_to_cpu(usb_dev->actconfig->desc.wTotalLength), - USB_DT_SECURITY, (void **) &secd); + USB_DT_SECURITY, (void **) &secd, sizeof(*secd)); if (result == -1) { dev_warn(dev, "BUG? WUSB host has no security descriptors\n"); return 0; diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index abe6d3c17047..3e11317db602 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4442,6 +4442,14 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci, { unsigned long long timeout_ns; + /* Prevent U1 if service interval is shorter than U1 exit latency */ + if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { + if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) { + dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n"); + return USB3_LPM_DISABLED; + } + } + if (xhci->quirks & XHCI_INTEL_HOST) timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc); else @@ -4498,6 +4506,14 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci, { unsigned long long timeout_ns; + /* Prevent U2 if service interval is shorter than U2 exit latency */ + if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) { + if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) { + dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n"); + return USB3_LPM_DISABLED; + } + } + if (xhci->quirks & XHCI_INTEL_HOST) timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc); else diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index b15842c6f916..993f4da065c3 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c @@ -64,6 +64,7 @@ static const struct usb_device_id appledisplay_table[] = { { APPLEDISPLAY_DEVICE(0x921c) }, { APPLEDISPLAY_DEVICE(0x921d) }, { APPLEDISPLAY_DEVICE(0x9222) }, + { APPLEDISPLAY_DEVICE(0x9226) }, { APPLEDISPLAY_DEVICE(0x9236) }, /* Terminating entry */ diff --git a/drivers/usb/storage/unusual_realtek.h b/drivers/usb/storage/unusual_realtek.h index e41f50c95ed4..f5fc3271e19c 100644 --- a/drivers/usb/storage/unusual_realtek.h +++ b/drivers/usb/storage/unusual_realtek.h @@ -38,4 +38,14 @@ UNUSUAL_DEV(0x0bda, 0x0159, 0x0000, 0x9999, "USB Card Reader", USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0), +UNUSUAL_DEV(0x0bda, 0x0177, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", + USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0), + +UNUSUAL_DEV(0x0bda, 0x0184, 0x0000, 0x9999, + "Realtek", + "USB Card Reader", + USB_SC_DEVICE, USB_PR_DEVICE, init_realtek_cr, 0), + #endif /* defined(CONFIG_USB_STORAGE_REALTEK) || ... */ diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b0875ef48522..1f21c6c33228 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -445,9 +445,9 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, int mirror_num = 0; int failed_mirror = 0; - clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); io_tree = &BTRFS_I(root->fs_info->btree_inode)->io_tree; while (1) { + clear_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags); ret = read_extent_buffer_pages(io_tree, eb, start, WAIT_COMPLETE, btree_get_extent, mirror_num); @@ -459,14 +459,6 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root, ret = -EIO; } - /* - * This buffer's crc is fine, but its contents are corrupted, so - * there is no reason to read the other copies, they won't be - * any less wrong. - */ - if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags)) - break; - num_copies = btrfs_num_copies(root->fs_info, eb->start, eb->len); if (num_copies == 1) diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 1aa897dd9ce3..6c0161284a9e 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -2469,6 +2469,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, struct rb_node *n; int count = 0; + spin_lock(&ctl->tree_lock); for (n = rb_first(&ctl->free_space_offset); n; n = rb_next(n)) { info = rb_entry(n, struct btrfs_free_space, offset_index); if (info->bytes >= bytes && !block_group->ro) @@ -2478,6 +2479,7 @@ void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group, info->offset, info->bytes, (info->bitmap) ? "yes" : "no"); } + spin_unlock(&ctl->tree_lock); btrfs_info(block_group->fs_info, "block group has cluster?: %s", list_empty(&block_group->cluster_list) ? "no" : "yes"); btrfs_info(block_group->fs_info, diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 3bd2233737ac..0f99336c37eb 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -2104,6 +2104,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, vol = memdup_user((void __user *)arg, sizeof(*vol)); if (IS_ERR(vol)) return PTR_ERR(vol); + vol->name[BTRFS_PATH_NAME_MAX] = '\0'; switch (cmd) { case BTRFS_IOC_SCAN_DEV: diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index be8eae80ff65..098016338f98 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -1821,6 +1821,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, return ret; } + btrfs_trans_release_metadata(trans, root); + trans->block_rsv = NULL; + /* make a pass through all the delayed refs we have so far * any runnings procs may add more while we are here */ @@ -1830,9 +1833,6 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, return ret; } - btrfs_trans_release_metadata(trans, root); - trans->block_rsv = NULL; - cur_trans = trans->transaction; /* diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 76dacd5307b9..afd317eb9db9 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -163,7 +163,7 @@ cifs_bp_rename_retry: cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath); memcpy(full_path+dfsplen+1, cifs_sb->prepath, pplen-1); - full_path[dfsplen] = '\\'; + full_path[dfsplen] = dirsep; for (i = 0; i < pplen-1; i++) if (full_path[dfsplen+1+i] == '/') full_path[dfsplen+1+i] = CIFS_DIR_SEP(cifs_sb); diff --git a/fs/exec.c b/fs/exec.c index 0428c34d4773..6bbea71c6d92 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1077,15 +1077,14 @@ killed: return -EAGAIN; } -char *get_task_comm(char *buf, struct task_struct *tsk) +char *__get_task_comm(char *buf, size_t buf_size, struct task_struct *tsk) { - /* buf must be at least sizeof(tsk->comm) in size */ task_lock(tsk); - strncpy(buf, tsk->comm, sizeof(tsk->comm)); + strncpy(buf, tsk->comm, buf_size); task_unlock(tsk); return buf; } -EXPORT_SYMBOL_GPL(get_task_comm); +EXPORT_SYMBOL_GPL(__get_task_comm); /* * These functions flushes out all traces of the currently running executable diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c index 24736c8b3d51..e66047d6943f 100644 --- a/fs/ext2/xattr.c +++ b/fs/ext2/xattr.c @@ -606,9 +606,9 @@ skip_replace: } cleanup: - brelse(bh); if (!(bh && header == HDR(bh))) kfree(header); + brelse(bh); up_write(&EXT2_I(inode)->xattr_sem); return error; diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index db272528ab5b..b3b293e2c099 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c @@ -88,7 +88,7 @@ static int kernfs_get_target_path(struct kernfs_node *parent, int slen = strlen(kn->name); len -= slen; - strncpy(s + len, kn->name, slen); + memcpy(s + len, kn->name, slen); if (len) s[--len] = '/'; diff --git a/include/linux/sched.h b/include/linux/sched.h index 8f6894c6e83c..ded334b5cf8d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -3082,7 +3082,12 @@ static inline void set_task_comm(struct task_struct *tsk, const char *from) { __set_task_comm(tsk, from, false); } -extern char *get_task_comm(char *to, struct task_struct *tsk); + +extern char *__get_task_comm(char *to, size_t len, struct task_struct *tsk); +#define get_task_comm(buf, tsk) ({ \ + BUILD_BUG_ON(sizeof(buf) != TASK_COMM_LEN); \ + __get_task_comm(buf, sizeof(buf), tsk); \ +}) #ifdef CONFIG_SMP void scheduler_ipi(void); diff --git a/include/linux/usb.h b/include/linux/usb.h index d88c31c8e6a4..e27df29a298e 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -336,11 +336,11 @@ struct usb_host_bos { }; int __usb_get_extra_descriptor(char *buffer, unsigned size, - unsigned char type, void **ptr); + unsigned char type, void **ptr, size_t min); #define usb_get_extra_descriptor(ifpoint, type, ptr) \ __usb_get_extra_descriptor((ifpoint)->extra, \ (ifpoint)->extralen, \ - type, (void **)ptr) + type, (void **)ptr, sizeof(**(ptr))) /* ----------------------------------------------------------------------- */ diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index 48fe32252e8d..89e05abfd74b 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -1489,11 +1489,35 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_PRIMARY_MI2S_RX 0x1000 #define AFE_PORT_ID_PRIMARY_MI2S_TX 0x1001 #define AFE_PORT_ID_SECONDARY_MI2S_RX 0x1002 +#define AFE_PORT_ID_SECONDARY_MI2S_RX_1 0x1040 +#define AFE_PORT_ID_SECONDARY_MI2S_RX_2 0x1042 +#define AFE_PORT_ID_SECONDARY_MI2S_RX_3 0x1044 +#define AFE_PORT_ID_SECONDARY_MI2S_RX_4 0x1046 #define AFE_PORT_ID_SECONDARY_MI2S_TX 0x1003 +#define AFE_PORT_ID_SECONDARY_MI2S_TX_1 0x1041 +#define AFE_PORT_ID_SECONDARY_MI2S_TX_2 0x1043 +#define AFE_PORT_ID_SECONDARY_MI2S_TX_3 0x1045 +#define AFE_PORT_ID_SECONDARY_MI2S_TX_4 0x1047 #define AFE_PORT_ID_TERTIARY_MI2S_RX 0x1004 +#define AFE_PORT_ID_TERTIARY_MI2S_RX_1 0x1048 +#define AFE_PORT_ID_TERTIARY_MI2S_RX_2 0x104A +#define AFE_PORT_ID_TERTIARY_MI2S_RX_3 0x104C +#define AFE_PORT_ID_TERTIARY_MI2S_RX_4 0x104E #define AFE_PORT_ID_TERTIARY_MI2S_TX 0x1005 +#define AFE_PORT_ID_TERTIARY_MI2S_TX_1 0x1049 +#define AFE_PORT_ID_TERTIARY_MI2S_TX_2 0x104B +#define AFE_PORT_ID_TERTIARY_MI2S_TX_3 0x104D +#define AFE_PORT_ID_TERTIARY_MI2S_TX_4 0x104F #define AFE_PORT_ID_QUATERNARY_MI2S_RX 0x1006 +#define AFE_PORT_ID_QUATERNARY_MI2S_RX_1 0x1020 +#define AFE_PORT_ID_QUATERNARY_MI2S_RX_2 0x1022 +#define AFE_PORT_ID_QUATERNARY_MI2S_RX_3 0x1024 +#define AFE_PORT_ID_QUATERNARY_MI2S_RX_4 0x1026 #define AFE_PORT_ID_QUATERNARY_MI2S_TX 0x1007 +#define AFE_PORT_ID_QUATERNARY_MI2S_TX_1 0x1021 +#define AFE_PORT_ID_QUATERNARY_MI2S_TX_2 0x1023 +#define AFE_PORT_ID_QUATERNARY_MI2S_TX_3 0x1025 +#define AFE_PORT_ID_QUATERNARY_MI2S_TX_4 0x1027 #define AUDIO_PORT_ID_I2S_RX 0x1008 #define AFE_PORT_ID_DIGITAL_MIC_TX 0x1009 #define AFE_PORT_ID_PRIMARY_PCM_RX 0x100A @@ -10886,6 +10910,7 @@ struct afe_port_cmd_set_aanc_acdb_table { #define AFE_PARAM_ID_GROUP_DEVICE_CFG 0x00010255 #define AFE_PARAM_ID_GROUP_DEVICE_ENABLE 0x00010256 #define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX 0x1102 +#define AFE_PARAM_ID_GROUP_DEVICE_I2S_CONFIG 0x00010286 /* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_CFG * parameter, which configures max of 8 AFE ports @@ -11069,6 +11094,119 @@ struct afe_param_id_group_device_tdm_cfg { @values 1 to 2^32 -1 */ } __packed; +#define AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX \ + (AFE_PORT_ID_SECONDARY_MI2S_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX \ + (AFE_PORT_ID_TERTIARY_MI2S_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX \ + (AFE_PORT_ID_TERTIARY_MI2S_TX + 0x100) +#define AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX \ + (AFE_PORT_ID_QUATERNARY_MI2S_RX + 0x100) +#define AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX \ + (AFE_PORT_ID_QUATERNARY_MI2S_TX + 0x100) + +#define AFE_API_VERSION_GROUP_DEVICE_I2S_CONFIG 0x1 + +/* Payload of the AFE_PARAM_ID_GROUP_DEVICE_I2S_CONFIG parameter ID +* used by AFE_MODULE_GROUP_DEVICE. +*/ +struct afe_param_id_group_device_i2s_cfg_v1 { + u32 minor_version; + /**< Minor version used to track group device configuration. + * @values #AFE_API_VERSION_GROUP_DEVICE_I2S_CONFIG + */ + + u16 group_id; + /**< ID for the group device. + * @values + * - #AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX + * - #AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX + * - #AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX + * - #AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX + * - #AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX + * - #AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX + */ + + u16 channel_mode; + /**< Group line channel mode + * @values + * - #AFE_PORT_I2S_SD0 + * - #AFE_PORT_I2S_SD1 + * - #AFE_PORT_I2S_SD2 + * - #AFE_PORT_I2S_SD3 + * - #AFE_PORT_I2S_QUAD01 + * - #AFE_PORT_I2S_QUAD23 + * - #AFE_PORT_I2S_6CHS + * - #AFE_PORT_I2S_8CHS + */ + + u32 sample_rate; + /**< Sampling rate of the port. + * @values + * - #AFE_PORT_SAMPLE_RATE_8K + * - #AFE_PORT_SAMPLE_RATE_16K + * - #AFE_PORT_SAMPLE_RATE_24K + * - #AFE_PORT_SAMPLE_RATE_32K + */ + + u16 port_id[AFE_GROUP_DEVICE_NUM_PORTS]; + /**< Array of member port IDs of this group. + * @values + * - #AFE_PORT_ID_SECONDARY_MI2S_RX_1 + * - #AFE_PORT_ID_SECONDARY_MI2S_RX_2 + * - #AFE_PORT_ID_SECONDARY_MI2S_RX_3 + * - #AFE_PORT_ID_SECONDARY_MI2S_RX_4 + + * - #AFE_PORT_ID_SECONDARY_MI2S_TX_1 + * - #AFE_PORT_ID_SECONDARY_MI2S_TX_2 + * - #AFE_PORT_ID_SECONDARY_MI2S_TX_3 + * - #AFE_PORT_ID_SECONDARY_MI2S_TX_4 + + * - #AFE_PORT_ID_TERTIARY_MI2S_RX_1 + * - #AFE_PORT_ID_TERTIARY_MI2S_RX_2 + * - #AFE_PORT_ID_TERTIARY_MI2S_RX_3 + * - #AFE_PORT_ID_TERTIARY_MI2S_RX_4 + + * - #AFE_PORT_ID_TERTIARY_MI2S_TX_1 + * - #AFE_PORT_ID_TERTIARY_MI2S_TX_2 + * - #AFE_PORT_ID_TERTIARY_MI2S_TX_3 + * - #AFE_PORT_ID_TERTIARY_MI2S_TX_4 + + * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_1 + * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_2 + * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_3 + * - #AFE_PORT_ID_QUATERNARY_MI2S_RX_4 + + * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_1 + * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_2 + * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_3 + * - #AFE_PORT_ID_QUATERNARY_MI2S_TX_4 + * @tablebulletend + */ + + u16 bit_width; + /**< Bit width of the sample. + * @values 16, 24, (32) + */ + + u16 reserved; +} __packed; + +struct afe_param_id_group_device_enable { + u16 group_id; + u16 enable; +} __packed; + +union afe_port_group_mi2s_config { + struct afe_param_id_group_device_i2s_cfg_v1 i2s_cfg; + struct afe_param_id_group_device_enable group_enable; +} __packed; + +struct afe_i2s_port_config { + struct afe_param_id_i2s_cfg i2s_cfg; + struct afe_param_id_slot_mapping_cfg slot_mapping; +} __packed; + /* Payload of the #AFE_PARAM_ID_GROUP_DEVICE_ENABLE * parameter, which enables or * disables any module. diff --git a/include/sound/pcm_params.h b/include/sound/pcm_params.h index 747c94a9a3d6..91f6abfb2ce0 100644 --- a/include/sound/pcm_params.h +++ b/include/sound/pcm_params.h @@ -251,11 +251,13 @@ static inline int snd_interval_empty(const struct snd_interval *i) static inline int snd_interval_single(const struct snd_interval *i) { return (i->min == i->max || - (i->min + 1 == i->max && i->openmax)); + (i->min + 1 == i->max && (i->openmin || i->openmax))); } static inline int snd_interval_value(const struct snd_interval *i) { + if (i->openmin && !i->openmax) + return i->max; return i->min; } diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h index cdbf97023f66..a6d697d6a8f8 100644 --- a/include/sound/q6afe-v2.h +++ b/include/sound/q6afe-v2.h @@ -208,6 +208,33 @@ enum { IDX_AFE_PORT_ID_INT5_MI2S_TX, IDX_AFE_PORT_ID_INT6_MI2S_RX, IDX_AFE_PORT_ID_INT6_MI2S_TX, + /* IDX 143 -> 150 */ + IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_1, + IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_2, + IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_3, + IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_4, + IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_1, + IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_2, + IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_3, + IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_4, + /* IDX 151 -> 158 */ + IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_1, + IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_2, + IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_3, + IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_4, + IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_1, + IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_2, + IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_3, + IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_4, + /* IDX 159 -> 166 */ + IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_1, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_2, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_3, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_4, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_1, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_2, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_3, + IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_4, AFE_MAX_PORTS }; @@ -292,6 +319,44 @@ enum { IDX_GROUP_TDM_MAX, }; +enum { + IDX_SECONDARY_MI2S_RX_1, + IDX_SECONDARY_MI2S_RX_2, + IDX_SECONDARY_MI2S_RX_3, + IDX_SECONDARY_MI2S_RX_4, + IDX_SECONDARY_MI2S_TX_1, + IDX_SECONDARY_MI2S_TX_2, + IDX_SECONDARY_MI2S_TX_3, + IDX_SECONDARY_MI2S_TX_4, + IDX_TERTIARY_MI2S_RX_1, + IDX_TERTIARY_MI2S_RX_2, + IDX_TERTIARY_MI2S_RX_3, + IDX_TERTIARY_MI2S_RX_4, + IDX_TERTIARY_MI2S_TX_1, + IDX_TERTIARY_MI2S_TX_2, + IDX_TERTIARY_MI2S_TX_3, + IDX_TERTIARY_MI2S_TX_4, + IDX_QUATERNARY_MI2S_RX_1, + IDX_QUATERNARY_MI2S_RX_2, + IDX_QUATERNARY_MI2S_RX_3, + IDX_QUATERNARY_MI2S_RX_4, + IDX_QUATERNARY_MI2S_TX_1, + IDX_QUATERNARY_MI2S_TX_2, + IDX_QUATERNARY_MI2S_TX_3, + IDX_QUATERNARY_MI2S_TX_4, + IDX_GROUP_MI2S_PORT_MAX, +}; + +enum { + IDX_GROUP_SECONDARY_MI2S_RX, + IDX_GROUP_SECONDARY_MI2S_TX, + IDX_GROUP_TERTIARY_MI2S_RX, + IDX_GROUP_TERTIARY_MI2S_TX, + IDX_GROUP_QUATERNARY_MI2S_RX, + IDX_GROUP_QUATERNARY_MI2S_TX, + IDX_GROUP_MI2S_MAX, +}; + enum afe_mad_type { MAD_HW_NONE = 0x00, MAD_HW_AUDIO = 0x01, @@ -458,4 +523,9 @@ int afe_request_dma_resources(uint8_t dma_type, uint8_t num_read_dma_channels, int afe_get_dma_idx(bool **ret_rddma_idx, bool **ret_wrdma_idx); int afe_release_all_dma_resources(void); +int afe_i2s_port_start(u16 port_id, struct afe_i2s_port_config *i2s_port, + u32 rate, u16 num_groups); +int afe_port_group_mi2s_enable(u16 group_id, + union afe_port_group_mi2s_config *afe_group_config, + u16 enable); #endif /* __Q6AFE_V2_H__ */ diff --git a/kernel/debug/kdb/kdb_support.c b/kernel/debug/kdb/kdb_support.c index 2aed4a33521b..61cd704a21c8 100644 --- a/kernel/debug/kdb/kdb_support.c +++ b/kernel/debug/kdb/kdb_support.c @@ -129,13 +129,13 @@ int kdbnearsym(unsigned long addr, kdb_symtab_t *symtab) } if (i >= ARRAY_SIZE(kdb_name_table)) { debug_kfree(kdb_name_table[0]); - memcpy(kdb_name_table, kdb_name_table+1, + memmove(kdb_name_table, kdb_name_table+1, sizeof(kdb_name_table[0]) * (ARRAY_SIZE(kdb_name_table)-1)); } else { debug_kfree(knt1); knt1 = kdb_name_table[i]; - memcpy(kdb_name_table+i, kdb_name_table+i+1, + memmove(kdb_name_table+i, kdb_name_table+i+1, sizeof(kdb_name_table[0]) * (ARRAY_SIZE(kdb_name_table)-i-1)); } diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 7b1b772ab1ce..d8fc54eef51c 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c @@ -606,7 +606,7 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file, BUG_ON((uprobe->offset & ~PAGE_MASK) + UPROBE_SWBP_INSN_SIZE > PAGE_SIZE); - smp_wmb(); /* pairs with rmb() in find_active_uprobe() */ + smp_wmb(); /* pairs with the smp_rmb() in handle_swbp() */ set_bit(UPROBE_COPY_INSN, &uprobe->flags); out: @@ -1891,10 +1891,18 @@ static void handle_swbp(struct pt_regs *regs) * After we hit the bp, _unregister + _register can install the * new and not-yet-analyzed uprobe at the same address, restart. */ - smp_rmb(); /* pairs with wmb() in install_breakpoint() */ if (unlikely(!test_bit(UPROBE_COPY_INSN, &uprobe->flags))) goto out; + /* + * Pairs with the smp_wmb() in prepare_uprobe(). + * + * Guarantees that if we see the UPROBE_COPY_INSN bit set, then + * we must also see the stores to &uprobe->arch performed by the + * prepare_uprobe() call. + */ + smp_rmb(); + /* Tracing handlers use ->utask to communicate with fetch methods */ if (!get_utask()) goto out; diff --git a/lib/kobject.c b/lib/kobject.c index 895edb63fba4..35d490b02cdd 100644 --- a/lib/kobject.c +++ b/lib/kobject.c @@ -127,7 +127,7 @@ static void fill_kobj_path(struct kobject *kobj, char *path, int length) int cur = strlen(kobject_name(parent)); /* back up enough to print this name with '/' */ length -= cur; - strncpy(path + length, kobject_name(parent), cur); + memcpy(path + length, kobject_name(parent), cur); *(path + --length) = '/'; } diff --git a/mm/mlock.c b/mm/mlock.c index 206e86b98a03..966dbdcfc322 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -504,6 +504,7 @@ static int mlock_fixup(struct vm_area_struct *vma, struct vm_area_struct **prev, int nr_pages; int ret = 0; int lock = !!(newflags & VM_LOCKED); + vm_flags_t old_flags = vma->vm_flags; if (newflags == vma->vm_flags || (vma->vm_flags & VM_SPECIAL) || is_vm_hugetlb_page(vma) || vma == get_gate_vma(current->mm)) @@ -538,6 +539,8 @@ success: nr_pages = (end - start) >> PAGE_SHIFT; if (!lock) nr_pages = -nr_pages; + else if (old_flags & VM_LOCKED) + nr_pages = 0; mm->locked_vm += nr_pages; /* diff --git a/mm/truncate.c b/mm/truncate.c index 8ca20a98c327..f6fedb876604 100644 --- a/mm/truncate.c +++ b/mm/truncate.c @@ -499,9 +499,13 @@ void truncate_inode_pages_final(struct address_space *mapping) */ spin_lock_irq(&mapping->tree_lock); spin_unlock_irq(&mapping->tree_lock); - - truncate_inode_pages(mapping, 0); } + + /* + * Cleancache needs notification even if there are no pages or shadow + * entries. + */ + truncate_inode_pages(mapping, 0); } EXPORT_SYMBOL(truncate_inode_pages_final); diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index 5d2f9d4879b2..d50c3b003dc9 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c @@ -266,7 +266,7 @@ batadv_frag_merge_packets(struct hlist_head *chain) kfree(entry); packet = (struct batadv_frag_packet *)skb_out->data; - size = ntohs(packet->total_size); + size = ntohs(packet->total_size) + hdr_size; /* Make room for the rest of the fragments. */ if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 9d3176b080a4..91ae061d46ac 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c @@ -261,8 +261,8 @@ static struct net_device *__ip_tunnel_create(struct net *net, } else { if (strlen(ops->kind) > (IFNAMSIZ - 3)) goto failed; - strlcpy(name, ops->kind, IFNAMSIZ); - strncat(name, "%d", 2); + strcpy(name, ops->kind); + strcat(name, "%d"); } ASSERT_RTNL(); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 00b25114843f..3678f2d5fcfe 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -988,6 +988,8 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, if (local->open_count == 0) ieee80211_clear_tx_pending(local); + sdata->vif.bss_conf.beacon_int = 0; + /* * If the interface goes down while suspended, presumably because * the device was unplugged and that happens before our resume, diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index aef0d41e9a9c..b02fcb388640 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1110,6 +1110,7 @@ ieee80211_rx_h_check_dup(struct ieee80211_rx_data *rx) return RX_CONTINUE; if (ieee80211_is_ctl(hdr->frame_control) || + ieee80211_is_nullfunc(hdr->frame_control) || ieee80211_is_qos_nullfunc(hdr->frame_control) || is_multicast_ether_addr(hdr->addr1)) return RX_CONTINUE; diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 2731cf5bf052..d221300e59e5 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -648,6 +648,8 @@ void ieee80211_tx_status_noskb(struct ieee80211_hw *hw, /* Track when last TDLS packet was ACKed */ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) sta->status_stats.last_tdls_pkt_time = jiffies; + } else if (test_sta_flag(sta, WLAN_STA_PS_STA)) { + return; } else { ieee80211_lost_packet(sta, info); } diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index a45248a4967b..674fe547ffee 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -431,8 +431,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) if (ieee80211_hw_check(&tx->local->hw, QUEUE_CONTROL)) info->hw_queue = tx->sdata->vif.cab_queue; - /* no stations in PS mode */ - if (!atomic_read(&ps->num_sta_ps)) + /* no stations in PS mode and no buffered packets */ + if (!atomic_read(&ps->num_sta_ps) && skb_queue_empty(&ps->bc_buf)) return TX_CONTINUE; info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 1f0687d8e3d7..62fca77bf3c7 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1722,6 +1722,7 @@ priv_release_snd_buf(struct rpc_rqst *rqstp) for (i=0; i < rqstp->rq_enc_pages_num; i++) __free_page(rqstp->rq_enc_pages[i]); kfree(rqstp->rq_enc_pages); + rqstp->rq_release_snd_buf = NULL; } static int @@ -1730,6 +1731,9 @@ alloc_enc_pages(struct rpc_rqst *rqstp) struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; int first, last, i; + if (rqstp->rq_release_snd_buf) + rqstp->rq_release_snd_buf(rqstp); + if (snd_buf->page_len == 0) { rqstp->rq_enc_pages_num = 0; return 0; diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn index abe5f47b1ab0..93e23a73b232 100644 --- a/scripts/Makefile.extrawarn +++ b/scripts/Makefile.extrawarn @@ -10,6 +10,8 @@ # are not supported by all versions of the compiler # ========================================================================== +KBUILD_CFLAGS += $(call cc-disable-warning, packed-not-aligned) + ifeq ("$(origin W)", "command line") export KBUILD_ENABLE_EXTRA_GCC_CHECKS := $(W) endif @@ -25,6 +27,7 @@ warning-1 += -Wold-style-definition warning-1 += $(call cc-option, -Wmissing-include-dirs) warning-1 += $(call cc-option, -Wunused-but-set-variable) warning-1 += $(call cc-option, -Wunused-const-variable) +warning-1 += $(call cc-option, -Wpacked-not-aligned) warning-1 += $(call cc-disable-warning, missing-field-initializers) warning-2 := -Waggregate-return diff --git a/scripts/unifdef.c b/scripts/unifdef.c index 7493c0ee51cc..db00e3e30a59 100644 --- a/scripts/unifdef.c +++ b/scripts/unifdef.c @@ -395,7 +395,7 @@ usage(void) * When we have processed a group that starts off with a known-false * #if/#elif sequence (which has therefore been deleted) followed by a * #elif that we don't understand and therefore must keep, we edit the - * latter into a #if to keep the nesting correct. We use strncpy() to + * latter into a #if to keep the nesting correct. We use memcpy() to * overwrite the 4 byte token "elif" with "if " without a '\0' byte. * * When we find a true #elif in a group, the following block will @@ -450,7 +450,7 @@ static void Idrop (void) { Fdrop(); ignoreon(); } static void Itrue (void) { Ftrue(); ignoreon(); } static void Ifalse(void) { Ffalse(); ignoreon(); } /* modify this line */ -static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); } +static void Mpass (void) { memcpy(keyword, "if ", 4); Pelif(); } static void Mtrue (void) { keywordedit("else"); state(IS_TRUE_MIDDLE); } static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); } static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); } diff --git a/sound/core/control.c b/sound/core/control.c index bd01d492f46a..2be860a446a2 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -346,6 +346,40 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) return 0; } +/* add a new kcontrol object; call with card->controls_rwsem locked */ +static int __snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) +{ + struct snd_ctl_elem_id id; + unsigned int idx; + unsigned int count; + + id = kcontrol->id; + if (id.index > UINT_MAX - kcontrol->count) + return -EINVAL; + + if (snd_ctl_find_id(card, &id)) { + dev_err(card->dev, + "control %i:%i:%i:%s:%i is already present\n", + id.iface, id.device, id.subdevice, id.name, id.index); + return -EBUSY; + } + + if (snd_ctl_find_hole(card, kcontrol->count) < 0) + return -ENOMEM; + + list_add_tail(&kcontrol->list, &card->controls); + card->controls_count += kcontrol->count; + kcontrol->id.numid = card->last_numid + 1; + card->last_numid += kcontrol->count; + + id = kcontrol->id; + count = kcontrol->count; + for (idx = 0; idx < count; idx++, id.index++, id.numid++) + snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + + return 0; +} + /** * snd_ctl_add - add the control instance to the card * @card: the card instance @@ -362,45 +396,18 @@ static int snd_ctl_find_hole(struct snd_card *card, unsigned int count) */ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) { - struct snd_ctl_elem_id id; - unsigned int idx; - unsigned int count; int err = -EINVAL; if (! kcontrol) return err; if (snd_BUG_ON(!card || !kcontrol->info)) goto error; - id = kcontrol->id; - if (id.index > UINT_MAX - kcontrol->count) - goto error; down_write(&card->controls_rwsem); - if (snd_ctl_find_id(card, &id)) { - up_write(&card->controls_rwsem); - dev_err(card->dev, "control %i:%i:%i:%s:%i is already present\n", - id.iface, - id.device, - id.subdevice, - id.name, - id.index); - err = -EBUSY; - goto error; - } - if (snd_ctl_find_hole(card, kcontrol->count) < 0) { - up_write(&card->controls_rwsem); - err = -ENOMEM; - goto error; - } - list_add_tail(&kcontrol->list, &card->controls); - card->controls_count += kcontrol->count; - kcontrol->id.numid = card->last_numid + 1; - card->last_numid += kcontrol->count; - id = kcontrol->id; - count = kcontrol->count; + err = __snd_ctl_add(card, kcontrol); up_write(&card->controls_rwsem); - for (idx = 0; idx < count; idx++, id.index++, id.numid++) - snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); + if (err < 0) + goto error; return 0; error: @@ -1322,9 +1329,12 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, kctl->tlv.c = snd_ctl_elem_user_tlv; /* This function manage to free the instance on failure. */ - err = snd_ctl_add(card, kctl); - if (err < 0) - return err; + down_write(&card->controls_rwsem); + err = __snd_ctl_add(card, kctl); + if (err < 0) { + snd_ctl_free_one(kctl); + goto unlock; + } offset = snd_ctl_get_ioff(kctl, &info->id); snd_ctl_build_ioff(&info->id, kctl, offset); /* @@ -1335,10 +1345,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, * which locks the element. */ - down_write(&card->controls_rwsem); card->user_ctl_count++; - up_write(&card->controls_rwsem); + unlock: + up_write(&card->controls_rwsem); return 0; } diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 981b18bf2e63..c4b15dd51c24 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -36,6 +36,7 @@ #include <sound/timer.h> #include <sound/minors.h> #include <linux/uio.h> +#include <linux/delay.h> /* * Compatibility @@ -79,12 +80,12 @@ static DECLARE_RWSEM(snd_pcm_link_rwsem); * and this may lead to a deadlock when the code path takes read sem * twice (e.g. one in snd_pcm_action_nonatomic() and another in * snd_pcm_stream_lock()). As a (suboptimal) workaround, let writer to - * spin until it gets the lock. + * sleep until all the readers are completed without blocking by writer. */ -static inline void down_write_nonblock(struct rw_semaphore *lock) +static inline void down_write_nonfifo(struct rw_semaphore *lock) { while (!down_write_trylock(lock)) - cond_resched(); + msleep(1); } /** @@ -1851,7 +1852,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd) res = -ENOMEM; goto _nolock; } - down_write_nonblock(&snd_pcm_link_rwsem); + down_write_nonfifo(&snd_pcm_link_rwsem); write_lock_irq(&snd_pcm_link_rwlock); if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN || substream->runtime->status->state != substream1->runtime->status->state || @@ -1898,7 +1899,7 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream) struct snd_pcm_substream *s; int res = 0; - down_write_nonblock(&snd_pcm_link_rwsem); + down_write_nonfifo(&snd_pcm_link_rwsem); write_lock_irq(&snd_pcm_link_rwlock); if (!snd_pcm_stream_linked(substream)) { res = -EALREADY; @@ -2251,7 +2252,8 @@ int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream) static void pcm_release_private(struct snd_pcm_substream *substream) { - snd_pcm_unlink(substream); + if (snd_pcm_stream_linked(substream)) + snd_pcm_unlink(substream); } void snd_pcm_release_substream(struct snd_pcm_substream *substream) diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 913b731d2236..f40330ddb9b2 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c @@ -1531,7 +1531,6 @@ static int snd_wss_playback_open(struct snd_pcm_substream *substream) if (err < 0) { if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma1); - snd_free_pages(runtime->dma_area, runtime->dma_bytes); return err; } chip->playback_substream = substream; @@ -1572,7 +1571,6 @@ static int snd_wss_capture_open(struct snd_pcm_substream *substream) if (err < 0) { if (chip->release_dma) chip->release_dma(chip, chip->dma_private_data, chip->dma2); - snd_free_pages(runtime->dma_area, runtime->dma_bytes); return err; } chip->capture_substream = substream; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 82259ca61e64..c4840fda44b4 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -824,7 +824,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; - int shift = (kcontrol->private_value >> 8) & 0xff; + int shift = (kcontrol->private_value >> 8) & 0x0f; int mask = (kcontrol->private_value >> 16) & 0xff; // int invert = (kcontrol->private_value >> 24) & 0xff; unsigned short value, old, new; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index ecb07fb036af..f964743b104c 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2363,6 +2363,10 @@ static const struct pci_device_id azx_ids[] = { /* AMD Hudson */ { PCI_DEVICE(0x1022, 0x780d), .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, + /* AMD Stoney */ + { PCI_DEVICE(0x1022, 0x157a), + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB | + AZX_DCAPS_PM_RUNTIME }, /* AMD Raven */ { PCI_DEVICE(0x1022, 0x15e3), .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB | diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index cedf13b64803..2f18b1cdc2cd 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c @@ -123,7 +123,7 @@ static int snd_trident_probe(struct pci_dev *pci, } else { strcpy(card->shortname, "Trident "); } - strcat(card->shortname, card->driver); + strcat(card->shortname, str); sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d", card->shortname, trident->port, trident->irq); diff --git a/sound/soc/msm/apq8096-auto.c b/sound/soc/msm/apq8096-auto.c index e5d99f5fd7d1..69a1fbfa45aa 100644 --- a/sound/soc/msm/apq8096-auto.c +++ b/sound/soc/msm/apq8096-auto.c @@ -160,6 +160,42 @@ static int msm_tert_tdm_slot_num = 8; static int msm_quat_tdm_slot_width = 32; static int msm_quat_tdm_slot_num = 8; +/* Group_MI2S default port channels */ +static int msm_sec_group_mi2s_rx_1_ch = 2; +static int msm_sec_group_mi2s_rx_2_ch = 2; +static int msm_sec_group_mi2s_rx_3_ch = 2; +static int msm_sec_group_mi2s_rx_4_ch = 2; +static int msm_sec_group_mi2s_tx_1_ch = 2; +static int msm_sec_group_mi2s_tx_2_ch = 2; +static int msm_sec_group_mi2s_tx_3_ch = 2; +static int msm_sec_group_mi2s_tx_4_ch = 2; +static int msm_tert_group_mi2s_rx_1_ch = 2; +static int msm_tert_group_mi2s_rx_2_ch = 2; +static int msm_tert_group_mi2s_rx_3_ch = 2; +static int msm_tert_group_mi2s_rx_4_ch = 2; +static int msm_tert_group_mi2s_tx_1_ch = 2; +static int msm_tert_group_mi2s_tx_2_ch = 2; +static int msm_tert_group_mi2s_tx_3_ch = 2; +static int msm_tert_group_mi2s_tx_4_ch = 2; +static int msm_quat_group_mi2s_rx_1_ch = 2; +static int msm_quat_group_mi2s_rx_2_ch = 2; +static int msm_quat_group_mi2s_rx_3_ch = 2; +static int msm_quat_group_mi2s_rx_4_ch = 2; +static int msm_quat_group_mi2s_tx_1_ch = 2; +static int msm_quat_group_mi2s_tx_2_ch = 2; +static int msm_quat_group_mi2s_tx_3_ch = 2; +static int msm_quat_group_mi2s_tx_4_ch = 2; + +/* Group MI2S default sample rate*/ +static int msm_sec_group_mi2s_rate = SAMPLING_RATE_48KHZ; +static int msm_tert_group_mi2s_rate = SAMPLING_RATE_48KHZ; +static int msm_quat_group_mi2s_rate = SAMPLING_RATE_48KHZ; + +/* Group MI2S slot width bit format */ +static int msm_sec_group_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE; +static int msm_tert_group_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE; +static int msm_quat_group_mi2s_bit_format = SNDRV_PCM_FORMAT_S24_LE; + /* EC Reference default values are set in mixer_paths.xml */ static int msm_ec_ref_ch = 4; static int msm_ec_ref_bit_format = SNDRV_PCM_FORMAT_S16_LE; @@ -172,6 +208,41 @@ static void *adsp_state_notifier; static bool dummy_device_registered; static struct snd_soc_card *sndcard; +#define GROUP_MI2S_SLOT_OFFSET_MAX 8 +static unsigned int group_mi2s_slot_offset + [IDX_GROUP_MI2S_PORT_MAX][GROUP_MI2S_SLOT_OFFSET_MAX] = { + /* GROUP_SEC_MI2S_RX */ + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0xFFFF}, + {0xFFFF}, + /* GROUP_SEC_MI2S_TX */ + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0xFFFF}, + {0xFFFF}, + /* GROUP_TERT_MI2S_RX */ + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0xFFFF}, + {0xFFFF}, + /* GROUP_TERT_MI2S_TX */ + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0xFFFF}, + {0xFFFF}, + /* GROUP_QUAT_MI2S_RX */ + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + /* GROUP_QUAT_MI2S_TX */ + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, + {0, 4, 0xFFFF}, +}; + enum { QUATERNARY_TDM_RX_0, QUATERNARY_TDM_RX_1, @@ -3307,6 +3378,173 @@ static int msm_mi2s_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int msm_group_mi2s_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); + + switch (cpu_dai->id) { + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + channels->min = channels->max = msm_sec_group_mi2s_rx_1_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + channels->min = channels->max = msm_sec_group_mi2s_rx_2_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + channels->min = channels->max = msm_sec_group_mi2s_rx_3_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + channels->min = channels->max = msm_sec_group_mi2s_rx_4_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + channels->min = channels->max = msm_sec_group_mi2s_tx_1_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + channels->min = channels->max = msm_sec_group_mi2s_tx_2_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + channels->min = channels->max = msm_sec_group_mi2s_tx_3_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + channels->min = channels->max = msm_sec_group_mi2s_tx_4_ch; + rate->min = rate->max = msm_sec_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_sec_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + channels->min = channels->max = msm_tert_group_mi2s_rx_1_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + channels->min = channels->max = msm_tert_group_mi2s_rx_2_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + channels->min = channels->max = msm_tert_group_mi2s_rx_3_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + channels->min = channels->max = msm_tert_group_mi2s_rx_4_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + channels->min = channels->max = msm_tert_group_mi2s_tx_1_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + channels->min = channels->max = msm_tert_group_mi2s_tx_2_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + channels->min = channels->max = msm_tert_group_mi2s_tx_3_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + channels->min = channels->max = msm_tert_group_mi2s_tx_4_ch; + rate->min = rate->max = msm_tert_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_tert_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + channels->min = channels->max = msm_quat_group_mi2s_rx_1_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + channels->min = channels->max = msm_quat_group_mi2s_rx_2_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + channels->min = channels->max = msm_quat_group_mi2s_rx_3_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + channels->min = channels->max = msm_quat_group_mi2s_rx_4_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + channels->min = channels->max = msm_quat_group_mi2s_tx_1_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + channels->min = channels->max = msm_quat_group_mi2s_tx_2_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + channels->min = channels->max = msm_quat_group_mi2s_tx_3_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + channels->min = channels->max = msm_quat_group_mi2s_tx_4_ch; + rate->min = rate->max = msm_quat_group_mi2s_rate; + param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT, + msm_quat_group_mi2s_bit_format); + break; + default: + 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 msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { @@ -4085,6 +4323,142 @@ static struct snd_soc_ops apq8096_tdm_be_ops = { .hw_params = apq8096_tdm_snd_hw_params, }; +static int apq8096_group_mi2s_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, rate; + unsigned int *slot_offset; + int offset_channels = 0; + int i; + + rate = params_rate(params); + channels = params_channels(params); + + switch (cpu_dai->id) { + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_1]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_2]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_3]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_RX_4]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_1]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_2]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_3]; + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + slot_offset = group_mi2s_slot_offset[IDX_SECONDARY_MI2S_TX_4]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_1]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_2]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_3]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_RX_4]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_1]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_2]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_3]; + break; + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + slot_offset = group_mi2s_slot_offset[IDX_TERTIARY_MI2S_TX_4]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_1]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_2]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_3]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_RX_4]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_1]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_2]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_3]; + break; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + slot_offset = group_mi2s_slot_offset[IDX_QUATERNARY_MI2S_TX_4]; + break; + default: + pr_err("%s: dai id 0x%x not supported\n", + __func__, cpu_dai->id); + return -EINVAL; + } + + for (i = 0; i < GROUP_MI2S_SLOT_OFFSET_MAX; i++) { + if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID) + offset_channels++; + } + + if (offset_channels == 0) { + pr_err("%s: slot offset not supported, offset_channels %d\n", + __func__, offset_channels); + return -EINVAL; + } + + if (channels > offset_channels) { + pr_err("%s: channels %d and offset_channels %d not match\n", + __func__, channels, offset_channels); + return -EINVAL; + } + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + 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 { + ret = snd_soc_dai_set_channel_map(cpu_dai, + channels, slot_offset, + 0, NULL); + if (ret < 0) { + pr_err("%s: failed to set channel map, err:%d\n", + __func__, ret); + goto end; + } + } +end: + return ret; +} + +static struct snd_soc_ops apq8096_group_mi2s_be_ops = { + .hw_params = apq8096_group_mi2s_snd_hw_params, +}; + static const struct soc_enum msm_snd_enum[] = { SOC_ENUM_SINGLE_EXT(2, auxpcm_rate_text), SOC_ENUM_SINGLE_EXT(7, hdmi_rx_ch_text), @@ -6546,6 +6920,342 @@ static struct snd_soc_dai_link apq8096_auto_be_dai_links[] = { .be_hw_params_fixup = msm_tdm_be_hw_params_fixup, .ops = &apq8096_tdm_be_ops, .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX_1, + .stream_name = "Secondary MI2S1 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4161", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX_2, + .stream_name = "Secondary MI2S2 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4163", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX_3, + .stream_name = "Secondary MI2S3 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4165", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_TX_4, + .stream_name = "Secondary MI2S4 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4167", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX_1, + .stream_name = "Tertiary MI2S1 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4169", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX_2, + .stream_name = "Tertiary MI2S2 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4171", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX_3, + .stream_name = "Tertiary MI2S3 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4173", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_TX_4, + .stream_name = "Tertiary MI2S4 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4175", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX_1, + .stream_name = "Quaternary MI2S1 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4129", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX_2, + .stream_name = "Quaternary MI2S2 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4131", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX_3, + .stream_name = "Quaternary MI2S3 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4133", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_TX_4, + .stream_name = "Quaternary MI2S4 Capture", + .cpu_dai_name = "msm-dai-q6-mi2s.4135", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX_1, + .stream_name = "Secondary MI2S1 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4160", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX_2, + .stream_name = "Secondary MI2S2 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4162", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX_3, + .stream_name = "Secondary MI2S3 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4164", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_SEC_MI2S_RX_4, + .stream_name = "Secondary MI2S4 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4166", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX_1, + .stream_name = "Tertiary MI2S1 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4168", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX_2, + .stream_name = "Tertiary MI2S2 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4170", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX_3, + .stream_name = "Tertiary MI2S3 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4172", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_TERT_MI2S_RX_4, + .stream_name = "Tertiary MI2S4 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4174", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX_1, + .stream_name = "Quaternary MI2S1 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4128", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX_2, + .stream_name = "Quaternary MI2S2 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4130", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX_3, + .stream_name = "Quaternary MI2S3 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4132", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, + }, + { + .name = LPASS_BE_QUAT_MI2S_RX_4, + .stream_name = "Quaternary MI2S4 Playback", + .cpu_dai_name = "msm-dai-q6-mi2s.4134", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + .be_hw_params_fixup = msm_group_mi2s_be_hw_params_fixup, + .ops = &apq8096_group_mi2s_be_ops, + .ignore_suspend = 1, } }; diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c index b09f6a1378f0..0c23e1eef483 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c @@ -124,6 +124,47 @@ struct msm_dai_q6_mi2s_dai_data { struct msm_dai_q6_mi2s_dai_config rx_dai; }; +static DEFINE_MUTEX(group_mi2s_mutex); +static atomic_t group_mi2s_ref[IDX_GROUP_MI2S_MAX]; + +/* cache of mi2s group cfg per parent node */ +static struct afe_param_id_group_device_i2s_cfg_v1 group_mi2s_cfg = { + AFE_API_VERSION_GROUP_DEVICE_I2S_CONFIG, + AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX, + AFE_PORT_I2S_QUAD01, + 48000, + { + AFE_PORT_ID_INVALID, + AFE_PORT_ID_TERTIARY_MI2S_TX_1, + AFE_PORT_ID_TERTIARY_MI2S_TX_2, + AFE_PORT_ID_INVALID, + AFE_PORT_ID_INVALID, + AFE_PORT_ID_INVALID, + AFE_PORT_ID_INVALID, + AFE_PORT_ID_INVALID + }, + 32, + 0, +}; + +static struct afe_clk_set group_mi2s_bclk_set = { + AFE_API_VERSION_CLOCK_SET, + Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT, + Q6AFE_LPASS_IBIT_CLK_3_P072_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + +static struct afe_clk_set group_mi2s_mclk_set = { + AFE_API_VERSION_CLOCK_SET, + Q6AFE_LPASS_CLK_ID_MCLK_2, + Q6AFE_LPASS_OSR_CLK_3_P072_MHZ, + Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO, + Q6AFE_LPASS_CLK_ROOT_DEFAULT, + 0, +}; + struct msm_dai_q6_auxpcm_dai_data { /* BITMAP to track Rx and Tx port usage count */ DECLARE_BITMAP(auxpcm_port_status, STATUS_MAX); @@ -147,6 +188,19 @@ struct msm_dai_q6_tdm_dai_data { struct afe_tdm_port_config port_cfg; /* hold tdm config */ }; +struct msm_dai_q6_group_mi2s_dai_data { + DECLARE_BITMAP(status_mask, STATUS_MAX); + u32 rate; + u32 channels; + u32 bit_width; + u32 num_group_ports; + u32 sync_mode; + struct afe_clk_set bclk_set; + struct afe_clk_set mclk_set; + union afe_port_group_mi2s_config group_cfg; + struct afe_i2s_port_config port_cfg; +}; + /* MI2S format field for AFE_PORT_CMD_I2S_CONFIG command * 0: linear PCM * 1: non-linear PCM @@ -455,6 +509,104 @@ int msm_dai_q6_get_port_idx(u16 id) } } +static int msm_dai_q6_get_mi2s_group_idx(u16 id) +{ + switch (id) { + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + return IDX_GROUP_SECONDARY_MI2S_RX; + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + return IDX_GROUP_SECONDARY_MI2S_TX; + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX: + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + return IDX_GROUP_TERTIARY_MI2S_RX; + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX: + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + return IDX_GROUP_TERTIARY_MI2S_TX; + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + return IDX_GROUP_QUATERNARY_MI2S_RX; + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + return IDX_GROUP_QUATERNARY_MI2S_TX; + default: return -EINVAL; + } +} + +static int msm_dai_q6_get_mi2s_port_idx(u16 id) +{ + switch (id) { + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + return IDX_SECONDARY_MI2S_RX_1; + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + return IDX_SECONDARY_MI2S_RX_2; + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + return IDX_SECONDARY_MI2S_RX_3; + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + return IDX_SECONDARY_MI2S_RX_4; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + return IDX_SECONDARY_MI2S_TX_1; + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + return IDX_SECONDARY_MI2S_TX_2; + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + return IDX_SECONDARY_MI2S_TX_3; + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + return IDX_SECONDARY_MI2S_TX_4; + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + return IDX_TERTIARY_MI2S_RX_1; + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + return IDX_TERTIARY_MI2S_RX_2; + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + return IDX_TERTIARY_MI2S_RX_3; + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + return IDX_TERTIARY_MI2S_RX_4; + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + return IDX_TERTIARY_MI2S_TX_1; + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + return IDX_TERTIARY_MI2S_TX_2; + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + return IDX_TERTIARY_MI2S_TX_3; + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + return IDX_TERTIARY_MI2S_TX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + return IDX_QUATERNARY_MI2S_RX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + return IDX_QUATERNARY_MI2S_RX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + return IDX_QUATERNARY_MI2S_RX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + return IDX_QUATERNARY_MI2S_RX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + return IDX_QUATERNARY_MI2S_TX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + return IDX_QUATERNARY_MI2S_TX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + return IDX_QUATERNARY_MI2S_TX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + return IDX_QUATERNARY_MI2S_TX_4; + default: return -EINVAL; + } +} + static u16 msm_dai_q6_max_num_slot(int frame_rate) { /* Max num of slots is bits per frame divided @@ -531,7 +683,7 @@ static int msm_dai_q6_auxpcm_hw_params( int rc = 0, slot_mapping_copy_len = 0; if (params_channels(params) != 1 || (params_rate(params) != 8000 && - params_rate(params) != 16000)) { + params_rate(params) != 16000)) { dev_err(dai->dev, "%s: invalid param chan %d rate %d\n", __func__, params_channels(params), params_rate(params)); return -EINVAL; @@ -540,7 +692,7 @@ static int msm_dai_q6_auxpcm_hw_params( mutex_lock(&aux_dai_data->rlock); if (test_bit(STATUS_TX_PORT, aux_dai_data->auxpcm_port_status) || - test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) { + test_bit(STATUS_RX_PORT, aux_dai_data->auxpcm_port_status)) { /* AUXPCM DAI in use */ if (dai_data->rate != params_rate(params)) { dev_err(dai->dev, "%s: rate mismatch of running DAI\n", @@ -569,7 +721,7 @@ static int msm_dai_q6_auxpcm_hw_params( dai_data->port_config.pcm.num_channels = dai_data->channels; dai_data->port_config.pcm.bit_width = 16; if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <= - auxpcm_pdata->mode_8k.num_slots) + auxpcm_pdata->mode_8k.num_slots) slot_mapping_copy_len = ARRAY_SIZE( dai_data->port_config.pcm.slot_number_mapping) @@ -580,8 +732,8 @@ static int msm_dai_q6_auxpcm_hw_params( if (auxpcm_pdata->mode_8k.slot_mapping) { memcpy(dai_data->port_config.pcm.slot_number_mapping, - auxpcm_pdata->mode_8k.slot_mapping, - slot_mapping_copy_len); + auxpcm_pdata->mode_8k.slot_mapping, + slot_mapping_copy_len); } else { dev_err(dai->dev, "%s 8khz slot mapping is NULL\n", __func__); @@ -605,7 +757,7 @@ static int msm_dai_q6_auxpcm_hw_params( dai_data->port_config.pcm.num_channels = dai_data->channels; dai_data->port_config.pcm.bit_width = 16; if (ARRAY_SIZE(dai_data->port_config.pcm.slot_number_mapping) <= - auxpcm_pdata->mode_16k.num_slots) + auxpcm_pdata->mode_16k.num_slots) slot_mapping_copy_len = ARRAY_SIZE( dai_data->port_config.pcm.slot_number_mapping) @@ -616,8 +768,8 @@ static int msm_dai_q6_auxpcm_hw_params( if (auxpcm_pdata->mode_16k.slot_mapping) { memcpy(dai_data->port_config.pcm.slot_number_mapping, - auxpcm_pdata->mode_16k.slot_mapping, - slot_mapping_copy_len); + auxpcm_pdata->mode_16k.slot_mapping, + slot_mapping_copy_len); } else { dev_err(dai->dev, "%s 16khz slot mapping is NULL\n", __func__); @@ -4322,6 +4474,908 @@ static struct snd_soc_dai_driver msm_dai_q6_mi2s_dai[] = { }, }; +static int msm_dai_q6_group_mi2s_set_clk_param(u32 group_id, + struct afe_clk_set *mclk_set, + struct afe_clk_set *bclk_set, + u32 sync_mode) +{ + switch (group_id) { + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX: + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX: + if (sync_mode) + bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT; + else + bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT; + mclk_set->clk_id = Q6AFE_LPASS_CLK_ID_MCLK_1; + break; + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX: + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX: + if (sync_mode) + bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT; + else + bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT; + mclk_set->clk_id = Q6AFE_LPASS_CLK_ID_MCLK_2; + break; + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX: + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX: + if (sync_mode) + bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT; + else + bclk_set->clk_id = Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT; + mclk_set->clk_id = Q6AFE_LPASS_CLK_ID_MCLK_3; + break; + default: + return -EINVAL; + } + return 0; +} + +static int msm_dai_q6_group_mi2s_set_clk( + struct msm_dai_q6_group_mi2s_dai_data *dai_data, + u16 port_id, bool enable) +{ + int rc = 0; + + dai_data->bclk_set.enable = enable; + rc = afe_set_lpass_clock_v2(port_id, + &dai_data->bclk_set); + if (rc < 0) + pr_err("%s: afe lpass bclk failed, err: %d\n", + __func__, rc); + + /*non zero mclk freq value means to enable mclk for mi2s intf*/ + if (dai_data->mclk_set.clk_freq_in_hz != 0) { + dai_data->mclk_set.enable = enable; + rc = afe_set_lpass_clock_v2(port_id, + &dai_data->mclk_set); + if (rc < 0) + pr_err("%s: afe lpass mclk failed, err: %d\n", + __func__, rc); + } + return rc; +} + +static int msm_dai_q6_dai_group_mi2s_probe(struct snd_soc_dai *dai) +{ + int rc = 0; + + msm_dai_q6_set_dai_id(dai); + rc = msm_dai_q6_dai_add_route(dai); + return rc; +} + +static int msm_dai_q6_dai_group_mi2s_remove(struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_group_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 group_id = dai_data->group_cfg.i2s_cfg.group_id; + int group_idx = 0; + atomic_t *group_ref = NULL; + + dev_dbg(dai->dev, "%s rc %d", __func__, rc); + + group_idx = msm_dai_q6_get_mi2s_group_idx(dai->id); + if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) { + dev_err(dai->dev, "%s: port id 0x%x not supported\n", + __func__, dai->id); + return -EINVAL; + } + + group_ref = &group_mi2s_ref[group_idx]; + + /* if AFE port is still up, close it */ + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(dai->id); /* can block */ + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to close Group MI2S port 0x%x\n", + __func__, dai->id); + } + atomic_dec(group_ref); + clear_bit(STATUS_PORT_STARTED, dai_data->status_mask); + + if (atomic_read(group_ref) == 0) { + rc = afe_port_group_mi2s_enable(group_id, NULL, false); + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to disable Group MI2S group 0x%x\n", + __func__, group_id); + } + rc = msm_dai_q6_group_mi2s_set_clk(dai_data, + dai->id, false); + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n", + __func__, dai->id); + } + } + } + return 0; +} + +static int msm_dai_q6_group_mi2s_set_channel_map(struct snd_soc_dai *dai, + unsigned int tx_num, unsigned int *tx_slot, + unsigned int rx_num, unsigned int *rx_slot) +{ + int rc = 0; + struct msm_dai_q6_group_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + int i = 0; + + switch (dai->id) { + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + if (!rx_slot) { + dev_err(dai->dev, "%s: rx slot not found\n", + __func__); + return -EINVAL; + } + for (i = 0; i < rx_num; i++) + dai_data->port_cfg.slot_mapping.offset[i] = rx_slot[i]; + for (i = rx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) + dai_data->port_cfg.slot_mapping.offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; + dai_data->port_cfg.slot_mapping.num_channel = rx_num; + break; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + if (!tx_slot) { + dev_err(dai->dev, "%s: tx slot not found\n", + __func__); + return -EINVAL; + } + for (i = 0; i < tx_num; i++) + dai_data->port_cfg.slot_mapping.offset[i] = tx_slot[i]; + for (i = tx_num; i < AFE_PORT_MAX_AUDIO_CHAN_CNT; i++) + dai_data->port_cfg.slot_mapping.offset[i] = + AFE_SLOT_MAPPING_OFFSET_INVALID; + + dai_data->port_cfg.slot_mapping.num_channel = tx_num; + break; + default: + dev_err(dai->dev, "%s: invalid dai id 0x%x\n", + __func__, dai->id); + return -EINVAL; + } + + return rc; +} + +static int msm_dai_q6_group_mi2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct msm_dai_q6_group_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + struct afe_param_id_group_device_i2s_cfg_v1 *group_mi2s_cfg = + &dai_data->group_cfg.i2s_cfg; + struct afe_param_id_i2s_cfg *dev_i2s_cfg = + &dai_data->port_cfg.i2s_cfg; + struct afe_param_id_slot_mapping_cfg *slot_mapping = + &dai_data->port_cfg.slot_mapping; + + /* update group_mi2s group config param */ + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S24_3LE: + dai_data->bit_width = 24; + break; + default: + pr_err("%s: format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + + /* update group_mi2s config param */ + group_mi2s_cfg->sample_rate = dai_data->rate; + group_mi2s_cfg->bit_width = dai_data->bit_width; + pr_debug("%s: Group MI2S GROUP 0x%x:\n" + "channel_mode = %d sample_rate = %d bit_width = %d\n", + __func__, group_mi2s_cfg->group_id, + group_mi2s_cfg->channel_mode, + group_mi2s_cfg->sample_rate, + group_mi2s_cfg->bit_width); + pr_debug("%s: Group MI2S GROUP 0x%x:\n" + "port_id[0]=0x%x port_id[1]=0x%x port_id[2]=0x%x port_id[3]=0x%x\n" + "port_id[4]=0x%x port_id[5]=0x%x port_id[6]=0x%x port_id[7]=0x%x\n", + __func__, group_mi2s_cfg->group_id, + group_mi2s_cfg->port_id[0], + group_mi2s_cfg->port_id[1], + group_mi2s_cfg->port_id[2], + group_mi2s_cfg->port_id[3], + group_mi2s_cfg->port_id[4], + group_mi2s_cfg->port_id[5], + group_mi2s_cfg->port_id[6], + group_mi2s_cfg->port_id[7]); + /*i2s port cfg*/ + dev_i2s_cfg->i2s_cfg_minor_version = + AFE_API_VERSION_I2S_CONFIG; + dev_i2s_cfg->bit_width = group_mi2s_cfg->bit_width; + dev_i2s_cfg->mono_stereo = AFE_PORT_I2S_STEREO; + dev_i2s_cfg->sample_rate = group_mi2s_cfg->sample_rate; + dev_i2s_cfg->data_format = AFE_LINEAR_PCM_DATA; + dev_i2s_cfg->ws_src = dai_data->sync_mode; + pr_debug("%s: MI2S port:\n" + "dai id %d dai_data->channels = %d\n" + "sample_rate = %u i2s_cfg_minor_version = 0x%x\n" + "bit_width = %hu channel_mode = 0x%x mono_stereo = %#x\n" + "ws_src = 0x%x sample_rate = %u data_format = 0x%x\n" + "reserved = %u\n", __func__, dai->id, dai_data->channels, + dai_data->rate, dev_i2s_cfg->i2s_cfg_minor_version, + dev_i2s_cfg->bit_width, dev_i2s_cfg->channel_mode, + dev_i2s_cfg->mono_stereo, dev_i2s_cfg->ws_src, + dev_i2s_cfg->sample_rate, dev_i2s_cfg->data_format, + dev_i2s_cfg->reserved); + + /*slot mapping cfg*/ + slot_mapping->minor_version = + AFE_API_VERSION_SLOT_MAPPING_CONFIG; + slot_mapping->bitwidth = group_mi2s_cfg->bit_width; + slot_mapping->data_align_type = + AFE_SLOT_MAPPING_DATA_ALIGN_MSB; + pr_debug("%s: Group MI2S port 0x%x SLOT MAPPING:\n" + "num_channel=%d bitwidth=%d data_align=0x%x\n", + __func__, dai->id, + slot_mapping->num_channel, + slot_mapping->bitwidth, + slot_mapping->data_align_type); + pr_debug("%s: Group MI2S port 0x%x SLOT MAPPING:\n" + "offset[0]=0x%x offset[1]=0x%x offset[2]=0x%x offset[3]=0x%x\n" + "offset[4]=0x%x offset[5]=0x%x offset[6]=0x%x offset[7]=0x%x\n", + __func__, dai->id, + slot_mapping->offset[0], + slot_mapping->offset[1], + slot_mapping->offset[2], + slot_mapping->offset[3], + slot_mapping->offset[4], + slot_mapping->offset[5], + slot_mapping->offset[6], + slot_mapping->offset[7]); + + return 0; +} + +static int msm_dai_q6_group_mi2s_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_group_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 group_id = dai_data->group_cfg.i2s_cfg.group_id; + int group_idx = 0; + atomic_t *group_ref = NULL; + + group_idx = msm_dai_q6_get_mi2s_group_idx(dai->id); + if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) { + dev_err(dai->dev, "%s port id 0x%x not supported\n", + __func__, dai->id); + return -EINVAL; + } + + mutex_lock(&group_mi2s_mutex); + + group_ref = &group_mi2s_ref[group_idx]; + + if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + /* PORT START should be set if prepare called + * in active state. + */ + if (atomic_read(group_ref) == 0) { + /* + * TX and RX share the same clk. + * AFE clk is enabled per group to simplify the logic. + * DSP will monitor the clk count. + */ + rc = msm_dai_q6_group_mi2s_set_clk(dai_data, + dai->id, true); + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to enable AFE clk 0x%x\n", + __func__, dai->id); + goto rtn; + } + + /* + * 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_mi2s_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; + } + } + } + + rc = afe_i2s_port_start(dai->id, &dai_data->port_cfg, + dai_data->rate, dai_data->num_group_ports); + if (IS_ERR_VALUE(rc)) { + if (atomic_read(group_ref) == 0) { + afe_port_group_mi2s_enable(group_id, + NULL, false); + msm_dai_q6_group_mi2s_set_clk(dai_data, + dai->id, false); + } + dev_err(dai->dev, "%s: fail to open AFE port 0x%x\n", + __func__, dai->id); + } else { + set_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + atomic_inc(group_ref); + } + } + +rtn: + mutex_unlock(&group_mi2s_mutex); + return rc; +} + +static void msm_dai_q6_group_mi2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + int rc = 0; + struct msm_dai_q6_group_mi2s_dai_data *dai_data = + dev_get_drvdata(dai->dev); + u16 group_id = dai_data->group_cfg.i2s_cfg.group_id; + int group_idx = 0; + atomic_t *group_ref = NULL; + + group_idx = msm_dai_q6_get_mi2s_group_idx(dai->id); + if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) { + dev_err(dai->dev, "%s port id 0x%x not supported\n", + __func__, dai->id); + return; + } + + mutex_lock(&group_mi2s_mutex); + group_ref = &group_mi2s_ref[group_idx]; + + if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) { + rc = afe_close(dai->id); + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to close AFE port 0x%x\n", + __func__, dai->id); + } + atomic_dec(group_ref); + clear_bit(STATUS_PORT_STARTED, + dai_data->status_mask); + + if (atomic_read(group_ref) == 0) { + rc = afe_port_group_mi2s_enable(group_id, + NULL, false); + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to disable AFE group 0x%x\n", + __func__, group_id); + } + rc = msm_dai_q6_group_mi2s_set_clk(dai_data, + dai->id, false); + if (IS_ERR_VALUE(rc)) { + dev_err(dai->dev, "%s: fail to disable AFE clk 0x%x\n", + __func__, dai->id); + } + } + } + + mutex_unlock(&group_mi2s_mutex); +} + +static struct snd_soc_dai_ops msm_dai_q6_group_mi2s_ops = { + .prepare = msm_dai_q6_group_mi2s_prepare, + .hw_params = msm_dai_q6_group_mi2s_hw_params, + .set_channel_map = msm_dai_q6_group_mi2s_set_channel_map, + .shutdown = msm_dai_q6_group_mi2s_shutdown, +}; + +static struct snd_soc_dai_driver msm_dai_q6_group_mi2s_dai[] = { + { + .playback = { + .stream_name = "Secondary MI2S1 Playback", + .aif_name = "SEC_MI2S_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_RX_1, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Secondary MI2S2 Playback", + .aif_name = "SEC_MI2S_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_RX_2, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Secondary MI2S3 Playback", + .aif_name = "SEC_MI2S_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_RX_3, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Secondary MI2S4 Playback", + .aif_name = "SEC_MI2S_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_RX_4, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Secondary MI2S1 Capture", + .aif_name = "SEC_MI2S_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_TX_1, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Secondary MI2S2 Capture", + .aif_name = "SEC_MI2S_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_TX_2, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Secondary MI2S3 Capture", + .aif_name = "SEC_MI2S_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_TX_3, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Secondary MI2S4 Capture", + .aif_name = "SEC_MI2S_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_SECONDARY_MI2S_TX_4, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Tertiary MI2S1 Playback", + .aif_name = "TERT_MI2S_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_RX_1, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Tertiary MI2S2 Playback", + .aif_name = "TERT_MI2S_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_RX_2, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Tertiary MI2S3 Playback", + .aif_name = "TERT_MI2S_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_RX_3, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Tertiary MI2S4 Playback", + .aif_name = "TERT_MI2S_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_RX_4, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Tertiary MI2S1 Capture", + .aif_name = "TERT_MI2S_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_TX_1, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Tertiary MI2S2 Capture", + .aif_name = "TERT_MI2S_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_TX_2, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Tertiary MI2S3 Capture", + .aif_name = "TERT_MI2S_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_TX_3, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Tertiary MI2S4 Capture", + .aif_name = "TERT_MI2S_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_TERTIARY_MI2S_TX_4, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Quaternary MI2S1 Playback", + .aif_name = "QUAT_MI2S_RX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_1, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Quaternary MI2S2 Playback", + .aif_name = "QUAT_MI2S_RX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_2, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Quaternary MI2S3 Playback", + .aif_name = "QUAT_MI2S_RX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_3, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .playback = { + .stream_name = "Quaternary MI2S4 Playback", + .aif_name = "QUAT_MI2S_RX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_RX_4, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Quaternary MI2S1 Capture", + .aif_name = "QUAT_MI2S_TX_1", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_1, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Quaternary MI2S2 Capture", + .aif_name = "QUAT_MI2S_TX_2", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_2, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Quaternary MI2S3 Capture", + .aif_name = "QUAT_MI2S_TX_3", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_3, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + }, + { + .capture = { + .stream_name = "Quaternary MI2S4 Capture", + .aif_name = "QUAT_MI2S_TX_4", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S24_3LE, + .rate_min = 8000, + .rate_max = 192000, + }, + .ops = &msm_dai_q6_group_mi2s_ops, + .id = AFE_PORT_ID_QUATERNARY_MI2S_TX_4, + .probe = msm_dai_q6_dai_group_mi2s_probe, + .remove = msm_dai_q6_dai_group_mi2s_remove, + } +}; static int msm_dai_q6_mi2s_get_lineconfig(u16 sd_lines, u16 *config_ptr, unsigned int *ch_cnt) @@ -4923,6 +5977,297 @@ static struct platform_driver msm_dai_q6_mi2s_driver = { }, }; +static int msm_dai_group_mi2s_probe(struct platform_device *pdev) +{ + int rc = 0; + + /* probe child node info */ + rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev); + if (rc) { + dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n", + __func__, rc); + goto rtn; + } else + dev_dbg(&pdev->dev, "%s: added child node\n", __func__); + +rtn: + return rc; +} + +static int msm_dai_group_mi2s_remove(struct platform_device *pdev) +{ + return 0; +} + +static int msm_dai_q6_group_mi2s_dev_id_validation(u32 dev_id) +{ + switch (dev_id) { + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + return 0; + default: + return -EINVAL; + } +} + +static const struct snd_soc_component_driver msm_q6_group_mi2s_dai_component = { + .name = "msm-dai-q6-mi2s-group", +}; + +static int msm_dai_group_mi2s_dev_probe(struct platform_device *pdev) +{ + int rc = 0; + struct msm_dai_q6_group_mi2s_dai_data *dai_data = NULL; + u32 mi2s_dev_id = 0; + u32 ch_mode = 0; + int port_idx = 0; + struct device_node *mi2s_parent_node = NULL; + u32 num_group_mi2s_ports = 0; + const uint32_t *port_id_array = NULL; + u32 array_length, i = 0; + u32 group_idx = 0; + u32 sync_mode = 0; + + mi2s_parent_node = of_get_parent(pdev->dev.of_node); + /* extract mi2s group info into static */ + rc = of_property_read_u32(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-group-id", + (u32 *)&group_mi2s_cfg.group_id); + if (rc) { + dev_err(&pdev->dev, "%s: Group ID from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-group-id"); + goto rtn; + } + + rc = of_property_read_u32(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-group-num-ports", + &num_group_mi2s_ports); + if (rc) { + dev_err(&pdev->dev, "%s: ch_mode from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-group-num-ports"); + goto rtn; + } + + if (num_group_mi2s_ports > AFE_GROUP_DEVICE_NUM_PORTS) { + dev_err(&pdev->dev, "%s: Group Num Ports %d greater than Man %d\n", + __func__, num_group_mi2s_ports, + AFE_GROUP_DEVICE_NUM_PORTS); + rc = -EINVAL; + goto rtn; + } + + port_id_array = of_get_property(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-group-port-id", + &array_length); + if (port_id_array == NULL) { + dev_err(&pdev->dev, "%s: prot_id_array is not valid\n", + __func__); + rc = -EINVAL; + goto rtn; + } + if (array_length != sizeof(uint32_t) * num_group_mi2s_ports) { + dev_err(&pdev->dev, "%s array_length is %d, expected is %zd\n", + __func__, array_length, + sizeof(uint32_t) * num_group_mi2s_ports); + rc = -EINVAL; + goto rtn; + } + + for (i = 0; i < num_group_mi2s_ports; i++) + group_mi2s_cfg.port_id[i] = (u16)be32_to_cpu(port_id_array[i]); + /* Unused index should be filled with AFE_PORT_INVALID */ + for (i = num_group_mi2s_ports; i < AFE_GROUP_DEVICE_NUM_PORTS; i++) + group_mi2s_cfg.port_id[i] = AFE_PORT_INVALID; + + /*extract group_mi2s group sd line info into static */ + rc = of_property_read_u32(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-channel-mode", + &ch_mode); + if (rc) { + dev_err(&pdev->dev, "%s: ch_mode from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-channel-mode"); + goto rtn; + } + + group_mi2s_cfg.channel_mode = ch_mode; + group_mi2s_cfg.minor_version = AFE_API_VERSION_I2S_CONFIG; + group_idx = msm_dai_q6_get_mi2s_group_idx(group_mi2s_cfg.group_id); + if (group_idx < 0 || group_idx > IDX_GROUP_MI2S_MAX) { + dev_err(&pdev->dev, "%s: group id 0x%x not supported\n", + __func__, group_mi2s_cfg.group_id); + rc = -EINVAL; + goto rtn; + } + atomic_set(&group_mi2s_ref[group_idx], 0); + + rc = of_property_read_u32(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-sync-mode", + &sync_mode); + if (rc) { + dev_err(&pdev->dev, "%s: ch_mode from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-sync-mode"); + goto rtn; + } + + rc = of_property_read_u32(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-mclk", + &group_mi2s_mclk_set.clk_freq_in_hz); + if (rc) { + dev_err(&pdev->dev, "%s: mclk from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-mclk"); + goto rtn; + } + + rc = of_property_read_u32(mi2s_parent_node, + "qcom,msm-cpudai-mi2s-bclk", + &group_mi2s_bclk_set.clk_freq_in_hz); + if (rc) { + dev_err(&pdev->dev, "%s: bclk from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-bclk"); + goto rtn; + } + + /*update default group mi2s clk set for master/slave select*/ + rc = msm_dai_q6_group_mi2s_set_clk_param(group_mi2s_cfg.group_id, + &group_mi2s_mclk_set, + &group_mi2s_bclk_set, + sync_mode); + if (rc) { + dev_err(&pdev->dev, "%s: group id not supported 0x%x\n", + __func__, tdm_group_cfg.group_id); + goto rtn; + } + + /* retrieve device/afe id */ + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-mi2s-dev-id", + &mi2s_dev_id); + if (rc) { + dev_err(&pdev->dev, "%s: DeviceID missing in DT file\n", + __func__); + goto rtn; + } + rc = msm_dai_q6_group_mi2s_dev_id_validation(mi2s_dev_id); + if (rc) { + dev_err(&pdev->dev, "%s: Invalid GMI2S device ID %d in DT file\n", + __func__, mi2s_dev_id); + rc = -ENXIO; + goto rtn; + } + + pdev->id = mi2s_dev_id; + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,msm-cpudai-mi2s-dev-channel-mode", + &ch_mode); + if (rc) { + dev_err(&pdev->dev, "%s: TX line from DT file %s\n", + __func__, "qcom,msm-cpudai-mi2s-dev-channel-mode"); + goto rtn; + } + + dai_data = kzalloc(sizeof(*dai_data), + GFP_KERNEL); + if (!dai_data) { + rc = -ENOMEM; + goto rtn; + } + dev_set_drvdata(&pdev->dev, dai_data); + + dai_data->sync_mode = sync_mode; + dai_data->num_group_ports = num_group_mi2s_ports; + dai_data->port_cfg.i2s_cfg.channel_mode = ch_mode; + dai_data->bclk_set = group_mi2s_bclk_set; + dai_data->mclk_set = group_mi2s_mclk_set; + dai_data->group_cfg.i2s_cfg = group_mi2s_cfg; + + port_idx = msm_dai_q6_get_mi2s_port_idx(mi2s_dev_id); + if (port_idx < 0 || port_idx > IDX_GROUP_MI2S_PORT_MAX) { + dev_err(&pdev->dev, "%s: Port id 0x%x not supported\n", + __func__, mi2s_dev_id); + rc = -EINVAL; + goto free_dai_data; + } + + rc = snd_soc_register_component(&pdev->dev, + &msm_q6_group_mi2s_dai_component, + &msm_dai_q6_group_mi2s_dai[port_idx], 1); + if (rc) { + dev_err(&pdev->dev, + "%s: fail to register msm_q6_group_mi2s_dai_component\n", + __func__); + goto free_dai_data; + } + + return 0; + +free_dai_data: + kfree(dai_data); +rtn: + return rc; +} + +static int msm_dai_group_mi2s_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); + return 0; +} + +static const struct of_device_id msm_dai_group_mi2s_dt_match[] = { + { .compatible = "qcom,msm-dai-group-mi2s", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_group_mi2s_dt_match); + +static struct platform_driver msm_dai_group_mi2s_driver = { + .probe = msm_dai_group_mi2s_probe, + .remove = msm_dai_group_mi2s_remove, + .driver = { + .name = "msm-dai-group-mi2s", + .owner = THIS_MODULE, + .of_match_table = msm_dai_group_mi2s_dt_match, + }, +}; + +static const struct of_device_id msm_dai_group_mi2s_dev_dt_match[] = { + { .compatible = "qcom,msm-dai-group-mi2s-dev", }, + { } +}; + +MODULE_DEVICE_TABLE(of, msm_dai_group_mi2s_dev_dt_match); + +static struct platform_driver msm_dai_group_mi2s_dev_driver = { + .probe = msm_dai_group_mi2s_dev_probe, + .remove = msm_dai_group_mi2s_dev_remove, + .driver = { + .name = "msm-dai-group-mi2s-dev", + .owner = THIS_MODULE, + .of_match_table = msm_dai_group_mi2s_dev_dt_match, + }, +}; + static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev) { int rc; @@ -8344,8 +9689,27 @@ static int __init msm_dai_q6_init(void) pr_err("%s: fail to register dai TDM\n", __func__); goto dai_tdm_q6_fail; } + + rc = platform_driver_register(&msm_dai_group_mi2s_dev_driver); + if (rc) { + pr_err("%s: fail to register dai GMI2S dev drv\n", + __func__); + goto dai_q6_group_mi2s_dev_fail; + } + + rc = platform_driver_register(&msm_dai_group_mi2s_driver); + if (rc) { + pr_err("%s: fail to register dai GMI2S\n", + __func__); + goto dai_group_mi2s_fail; + } + return rc; +dai_group_mi2s_fail: + platform_driver_unregister(&msm_dai_group_mi2s_driver); +dai_q6_group_mi2s_dev_fail: + platform_driver_unregister(&msm_dai_group_mi2s_dev_driver); dai_tdm_q6_fail: platform_driver_unregister(&msm_dai_q6_tdm_driver); dai_q6_tdm_drv_fail: @@ -8371,6 +9735,8 @@ static void __exit msm_dai_q6_exit(void) platform_driver_unregister(&msm_dai_q6); platform_driver_unregister(&msm_auxpcm_dev_driver); platform_driver_unregister(&msm_dai_q6_spdif_driver); + platform_driver_unregister(&msm_dai_group_mi2s_driver); + platform_driver_unregister(&msm_dai_group_mi2s_dev_driver); } module_exit(msm_dai_q6_exit); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index b0843bca62bf..ee8c42903c99 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -546,6 +546,54 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { LPASS_BE_INT6_MI2S_RX}, { AFE_PORT_ID_INT6_MI2S_TX, 0, {0}, {0}, 0, 0, 0, 0, {0}, LPASS_BE_INT6_MI2S_TX}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_RX_1}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_RX_2}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_RX_3}, + { AFE_PORT_ID_SECONDARY_MI2S_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_RX_4}, + { AFE_PORT_ID_SECONDARY_MI2S_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_TX_1}, + { AFE_PORT_ID_SECONDARY_MI2S_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_TX_2}, + { AFE_PORT_ID_SECONDARY_MI2S_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_TX_3}, + { AFE_PORT_ID_SECONDARY_MI2S_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_SEC_MI2S_TX_4}, + { AFE_PORT_ID_TERTIARY_MI2S_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_RX_1}, + { AFE_PORT_ID_TERTIARY_MI2S_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_RX_2}, + { AFE_PORT_ID_TERTIARY_MI2S_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_RX_3}, + { AFE_PORT_ID_TERTIARY_MI2S_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_RX_4}, + { AFE_PORT_ID_TERTIARY_MI2S_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_TX_1}, + { AFE_PORT_ID_TERTIARY_MI2S_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_TX_2}, + { AFE_PORT_ID_TERTIARY_MI2S_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_TX_3}, + { AFE_PORT_ID_TERTIARY_MI2S_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_TERT_MI2S_TX_4}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_RX_1}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_RX_2}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_RX_3}, + { AFE_PORT_ID_QUATERNARY_MI2S_RX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_RX_4}, + { AFE_PORT_ID_QUATERNARY_MI2S_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_TX_1}, + { AFE_PORT_ID_QUATERNARY_MI2S_TX_2, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_TX_2}, + { AFE_PORT_ID_QUATERNARY_MI2S_TX_3, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_TX_3}, + { AFE_PORT_ID_QUATERNARY_MI2S_TX_4, 0, {0}, {0}, 0, 0, 0, 0, {0}, + LPASS_BE_QUAT_MI2S_TX_4} }; /* Track ASM playback & capture sessions of DAI @@ -4723,6 +4771,834 @@ static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new secondary_mi2s_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new secondary_mi2s_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new secondary_mi2s_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new secondary_mi2s_rx_4_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tertiary_mi2s_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tertiary_mi2s_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tertiary_mi2s_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new tertiary_mi2s_rx_4_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quaternary_mi2s_rx_1_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quaternary_mi2s_rx_2_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quaternary_mi2s_rx_3_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + +static const struct snd_kcontrol_new quaternary_mi2s_rx_4_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia17", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia18", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia26", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA26, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SECONDARY_MI2S_RX , MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -7215,6 +8091,42 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { @@ -7308,6 +8220,42 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul3_mixer_controls[] = { @@ -7398,6 +8346,42 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { @@ -7593,6 +8577,42 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -7938,6 +8958,42 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul17_mixer_controls[] = { @@ -8091,6 +9147,42 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_1", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_2", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_3", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("SEC_MI2S_TX_4", MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_1", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_2", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_3", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("TERT_MI2S_TX_4", MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_1", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_2", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_3", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("QUAT_MI2S_TX_4", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, + MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul21_mixer_controls[] = { @@ -12773,6 +13865,56 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { 0, 0, 0 , 0), SND_SOC_DAPM_AIF_IN("PCM_TX", "AFE Capture", 0, 0, 0 , 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_1", "Secondary MI2S1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_2", "Secondary MI2S2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_3", "Secondary MI2S3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("SEC_MI2S_TX_4", "Secondary MI2S4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_1", "Tertiary MI2S1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_2", "Tertiary MI2S2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_3", "Tertiary MI2S3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("TERT_MI2S_TX_4", "Tertiary MI2S4 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_1", "Quaternary MI2S1 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_2", "Quaternary MI2S2 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_3", "Quaternary MI2S3 Capture", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("QUAT_MI2S_TX_4", "Quaternary MI2S4 Capture", + 0, 0, 0, 0), + + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_1", "Secondary MI2S1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_2", "Secondary MI2S2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_3", "Secondary MI2S3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("SEC_MI2S_RX_4", "Secondary MI2S4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_1", "Tertiary MI2S1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_2", "Tertiary MI2S2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_3", "Tertiary MI2S3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("TERT_MI2S_RX_4", "Tertiary MI2S4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_1", "Quaternary MI2S1 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_2", "Quaternary MI2S2 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_3", "Quaternary MI2S3 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("QUAT_MI2S_RX_4", "Quaternary MI2S4 Playback", + 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("PRI_TDM_RX_0", "Primary TDM0 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("PRI_TDM_TX_0", "Primary TDM0 Capture", @@ -13024,6 +14166,42 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("TERT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, tertiary_mi2s_rx_mixer_controls, ARRAY_SIZE(tertiary_mi2s_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx_1_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx_2_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx_3_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("SEC_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + secondary_mi2s_rx_4_mixer_controls, + ARRAY_SIZE(secondary_mi2s_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + tertiary_mi2s_rx_1_mixer_controls, + ARRAY_SIZE(tertiary_mi2s_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + tertiary_mi2s_rx_2_mixer_controls, + ARRAY_SIZE(tertiary_mi2s_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + tertiary_mi2s_rx_3_mixer_controls, + ARRAY_SIZE(tertiary_mi2s_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("TERT_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + tertiary_mi2s_rx_4_mixer_controls, + ARRAY_SIZE(tertiary_mi2s_rx_4_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0, + quaternary_mi2s_rx_1_mixer_controls, + ARRAY_SIZE(quaternary_mi2s_rx_1_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0, + quaternary_mi2s_rx_2_mixer_controls, + ARRAY_SIZE(quaternary_mi2s_rx_2_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0, + quaternary_mi2s_rx_3_mixer_controls, + ARRAY_SIZE(quaternary_mi2s_rx_3_mixer_controls)), + SND_SOC_DAPM_MIXER("QUAT_MI2S_RX_4 Audio Mixer", SND_SOC_NOPM, 0, 0, + quaternary_mi2s_rx_4_mixer_controls, + ARRAY_SIZE(quaternary_mi2s_rx_4_mixer_controls)), SND_SOC_DAPM_MIXER("SEC_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0, secondary_mi2s_rx_mixer_controls, ARRAY_SIZE(secondary_mi2s_rx_mixer_controls)), @@ -14346,6 +15524,222 @@ static const struct snd_soc_dapm_route intercon[] = { {"QUAT_TDM_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, {"QUAT_TDM_RX_3", NULL, "QUAT_TDM_RX_3 Audio Mixer"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_MI2S_RX_1", NULL, "SEC_MI2S_RX_1 Audio Mixer"}, + + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_MI2S_RX_2", NULL, "SEC_MI2S_RX_2 Audio Mixer"}, + + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_MI2S_RX_3", NULL, "SEC_MI2S_RX_3 Audio Mixer"}, + + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"SEC_MI2S_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"SEC_MI2S_RX_4", NULL, "SEC_MI2S_RX_4 Audio Mixer"}, + + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"TERT_MI2S_RX_1", NULL, "TERT_MI2S_RX_1 Audio Mixer"}, + + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"TERT_MI2S_RX_2", NULL, "TERT_MI2S_RX_2 Audio Mixer"}, + + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"TERT_MI2S_RX_3", NULL, "TERT_MI2S_RX_3 Audio Mixer"}, + + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"TERT_MI2S_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"TERT_MI2S_RX_4", NULL, "TERT_MI2S_RX_4 Audio Mixer"}, + + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX_1 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"QUAT_MI2S_RX_1", NULL, "QUAT_MI2S_RX_1 Audio Mixer"}, + + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX_2 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"QUAT_MI2S_RX_2", NULL, "QUAT_MI2S_RX_2 Audio Mixer"}, + + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX_3 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"QUAT_MI2S_RX_3", NULL, "QUAT_MI2S_RX_3 Audio Mixer"}, + + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"QUAT_MI2S_RX_4 Audio Mixer", "MultiMedia26", "MM_DL26"}, + {"QUAT_MI2S_RX_4", NULL, "QUAT_MI2S_RX_4 Audio Mixer"}, + {"MultiMedia1 Mixer", "PRI_TX", "PRI_I2S_TX"}, {"MultiMedia1 Mixer", "MI2S_TX", "MI2S_TX"}, {"MultiMedia2 Mixer", "MI2S_TX", "MI2S_TX"}, @@ -14423,6 +15817,19 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia1 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia1 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"}, + {"MultiMedia1 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"}, + {"MultiMedia1 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"}, + {"MultiMedia1 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"}, + {"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia2 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -14439,6 +15846,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia2 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia2 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"}, + {"MultiMedia2 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"}, + {"MultiMedia2 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"}, + {"MultiMedia2 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -14456,6 +15875,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia3 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia3 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia3 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"}, + {"MultiMedia3 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"}, + {"MultiMedia3 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"}, + {"MultiMedia3 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"}, + {"MultiMedia3 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"}, + {"MultiMedia3 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"}, + {"MultiMedia3 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"}, + {"MultiMedia3 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"}, + {"MultiMedia3 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -14490,6 +15921,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia5 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia5 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia5 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"}, + {"MultiMedia5 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"}, + {"MultiMedia5 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"}, + {"MultiMedia5 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"}, + {"MultiMedia5 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"}, + {"MultiMedia5 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, @@ -14533,11 +15976,35 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"}, {"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia9 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"}, + {"MultiMedia9 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"}, + {"MultiMedia9 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"}, + {"MultiMedia9 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"}, + {"MultiMedia9 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"}, + {"MultiMedia9 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"}, + {"MultiMedia9 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"}, + {"MultiMedia9 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"}, + {"MultiMedia9 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"}, + {"MultiMedia9 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"}, + {"MultiMedia9 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"}, + {"MultiMedia9 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"}, {"MultiMedia20 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"}, {"MultiMedia20 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"}, {"MultiMedia20 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"}, {"MultiMedia20 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX_1", "SEC_MI2S_TX_1"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX_2", "SEC_MI2S_TX_2"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX_3", "SEC_MI2S_TX_3"}, + {"MultiMedia20 Mixer", "SEC_MI2S_TX_4", "SEC_MI2S_TX_4"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX_1", "TERT_MI2S_TX_1"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX_2", "TERT_MI2S_TX_2"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX_3", "TERT_MI2S_TX_3"}, + {"MultiMedia20 Mixer", "TERT_MI2S_TX_4", "TERT_MI2S_TX_4"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX_1", "QUAT_MI2S_TX_1"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX_2", "QUAT_MI2S_TX_2"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX_3", "QUAT_MI2S_TX_3"}, + {"MultiMedia20 Mixer", "QUAT_MI2S_TX_4", "QUAT_MI2S_TX_4"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"}, {"MultiMedia20 Mixer", "PRI_TDM_TX_2", "PRI_TDM_TX_2"}, @@ -16080,6 +17547,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "QUAT_TDM_RX_1"}, {"BE_OUT", NULL, "QUAT_TDM_RX_2"}, {"BE_OUT", NULL, "QUAT_TDM_RX_3"}, + {"BE_OUT", NULL, "SEC_MI2S_RX_1"}, + {"BE_OUT", NULL, "SEC_MI2S_RX_2"}, + {"BE_OUT", NULL, "SEC_MI2S_RX_3"}, + {"BE_OUT", NULL, "SEC_MI2S_RX_4"}, + {"BE_OUT", NULL, "TERT_MI2S_RX_1"}, + {"BE_OUT", NULL, "TERT_MI2S_RX_2"}, + {"BE_OUT", NULL, "TERT_MI2S_RX_3"}, + {"BE_OUT", NULL, "TERT_MI2S_RX_4"}, + {"BE_OUT", NULL, "QUAT_MI2S_RX_1"}, + {"BE_OUT", NULL, "QUAT_MI2S_RX_2"}, + {"BE_OUT", NULL, "QUAT_MI2S_RX_3"}, + {"BE_OUT", NULL, "QUAT_MI2S_RX_4"}, {"PRI_I2S_TX", NULL, "BE_IN"}, {"MI2S_TX", NULL, "BE_IN"}, @@ -16094,6 +17573,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"INT5_MI2S_TX", NULL, "BE_IN"}, {"SEC_MI2S_TX", NULL, "BE_IN"}, {"SENARY_MI2S_TX", NULL, "BE_IN" }, + {"SEC_MI2S_TX_1", NULL, "BE_IN"}, + {"SEC_MI2S_TX_2", NULL, "BE_IN"}, + {"SEC_MI2S_TX_3", NULL, "BE_IN"}, + {"SEC_MI2S_TX_4", NULL, "BE_IN"}, + {"TERT_MI2S_TX_1", NULL, "BE_IN"}, + {"TERT_MI2S_TX_2", NULL, "BE_IN"}, + {"TERT_MI2S_TX_3", NULL, "BE_IN"}, + {"TERT_MI2S_TX_4", NULL, "BE_IN"}, + {"QUAT_MI2S_TX_1", NULL, "BE_IN"}, + {"QUAT_MI2S_TX_2", NULL, "BE_IN"}, + {"QUAT_MI2S_TX_3", NULL, "BE_IN"}, + {"QUAT_MI2S_TX_4", NULL, "BE_IN"}, {"SLIMBUS_0_TX", NULL, "BE_IN" }, {"SLIMBUS_1_TX", NULL, "BE_IN" }, {"SLIMBUS_3_TX", NULL, "BE_IN" }, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index 531f83d752b0..bfeee4ad3607 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -167,6 +167,34 @@ #define LPASS_BE_INT5_MI2S_TX "INT5_MI2S_TX" #define LPASS_BE_INT6_MI2S_RX "INT6_MI2S_RX" #define LPASS_BE_INT6_MI2S_TX "INT6_MI2S_TX" + +#define LPASS_BE_SEC_MI2S_RX_1 "SEC_MI2S_RX_1" +#define LPASS_BE_SEC_MI2S_RX_2 "SEC_MI2S_RX_2" +#define LPASS_BE_SEC_MI2S_RX_3 "SEC_MI2S_RX_3" +#define LPASS_BE_SEC_MI2S_RX_4 "SEC_MI2S_RX_4" +#define LPASS_BE_SEC_MI2S_TX_1 "SEC_MI2S_TX_1" +#define LPASS_BE_SEC_MI2S_TX_2 "SEC_MI2S_TX_2" +#define LPASS_BE_SEC_MI2S_TX_3 "SEC_MI2S_TX_3" +#define LPASS_BE_SEC_MI2S_TX_4 "SEC_MI2S_TX_4" + +#define LPASS_BE_TERT_MI2S_RX_1 "TERT_MI2S_RX_1" +#define LPASS_BE_TERT_MI2S_RX_2 "TERT_MI2S_RX_2" +#define LPASS_BE_TERT_MI2S_RX_3 "TERT_MI2S_RX_3" +#define LPASS_BE_TERT_MI2S_RX_4 "TERT_MI2S_RX_4" +#define LPASS_BE_TERT_MI2S_TX_1 "TERT_MI2S_TX_1" +#define LPASS_BE_TERT_MI2S_TX_2 "TERT_MI2S_TX_2" +#define LPASS_BE_TERT_MI2S_TX_3 "TERT_MI2S_TX_3" +#define LPASS_BE_TERT_MI2S_TX_4 "TERT_MI2S_TX_4" + +#define LPASS_BE_QUAT_MI2S_RX_1 "QUAT_MI2S_RX_1" +#define LPASS_BE_QUAT_MI2S_RX_2 "QUAT_MI2S_RX_2" +#define LPASS_BE_QUAT_MI2S_RX_3 "QUAT_MI2S_RX_3" +#define LPASS_BE_QUAT_MI2S_RX_4 "QUAT_MI2S_RX_4" +#define LPASS_BE_QUAT_MI2S_TX_1 "QUAT_MI2S_TX_1" +#define LPASS_BE_QUAT_MI2S_TX_2 "QUAT_MI2S_TX_2" +#define LPASS_BE_QUAT_MI2S_TX_3 "QUAT_MI2S_TX_3" +#define LPASS_BE_QUAT_MI2S_TX_4 "QUAT_MI2S_TX_4" + /* For multimedia front-ends, asm session is allocated dynamically. * Hence, asm session/multimedia front-end mapping has to be maintained. * Due to this reason, additional multimedia front-end must be placed before @@ -373,6 +401,30 @@ enum { MSM_BACKEND_DAI_INT5_MI2S_TX, MSM_BACKEND_DAI_INT6_MI2S_RX, MSM_BACKEND_DAI_INT6_MI2S_TX, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_RX_4, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX_1, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX_2, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX_3, + MSM_BACKEND_DAI_SECONDARY_MI2S_TX_4, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_RX_4, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX_1, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX_2, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX_3, + MSM_BACKEND_DAI_TERTIARY_MI2S_TX_4, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_RX_4, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_1, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_2, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_3, + MSM_BACKEND_DAI_QUATERNARY_MI2S_TX_4, MSM_BACKEND_DAI_MAX, }; diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 0524ca21feba..c7aecd5758d4 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -785,6 +785,18 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_INT4_MI2S_RX: case AFE_PORT_ID_INT5_MI2S_RX: case AFE_PORT_ID_INT6_MI2S_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: ret = MSM_AFE_PORT_TYPE_RX; break; @@ -856,6 +868,18 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_INT4_MI2S_TX: case AFE_PORT_ID_INT5_MI2S_TX: case AFE_PORT_ID_INT6_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: ret = MSM_AFE_PORT_TYPE_TX; break; @@ -2734,6 +2758,118 @@ int afe_send_custom_tdm_header_cfg( return ret; } +int afe_i2s_port_start(u16 port_id, struct afe_i2s_port_config *i2s_port, + u32 rate, u16 num_groups) +{ + struct param_hdr_v3 param_hdr = {0}; + int index = 0; + uint16_t port_index = 0; + enum afe_mad_type mad_type = MAD_HW_NONE; + int ret = 0; + + if (!i2s_port) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: port id: 0x%x\n", __func__, port_id); + + index = q6audio_get_port_index(port_id); + if (index < 0 || index >= AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid!\n", + __func__, index); + return -EINVAL; + } + ret = q6audio_validate_port(port_id); + if (ret < 0) { + pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret); + return -EINVAL; + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if ((index >= 0) && (index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[index] = rate; + + if (this_afe.rt_cb) + this_afe.dev_acdb_id[index] = this_afe.rt_cb(port_id); + } + + /* 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) && + num_groups > 1) { + /* One time call: only for first time */ + afe_send_custom_topology(); + afe_send_port_topology_id(port_id); + afe_send_cal(port_id); + afe_send_hw_delay(port_id, rate); + } + + /* Start SW MAD module */ + mad_type = afe_port_get_mad_type(port_id); + pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id, + mad_type); + if (mad_type != MAD_HW_NONE && mad_type != MAD_SW_AUDIO) { + if (!afe_has_config(AFE_CDC_REGISTERS_CONFIG) || + !afe_has_config(AFE_SLIMBUS_SLAVE_CONFIG)) { + pr_err("%s: AFE isn't configured yet for\n" + "HW MAD try Again\n", __func__); + ret = -EAGAIN; + goto fail_cmd; + } + ret = afe_turn_onoff_hw_mad(mad_type, true); + if (ret) { + pr_err("%s: afe_turn_onoff_hw_mad failed %d\n", + __func__, ret); + goto fail_cmd; + } + } + + param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_I2S_CONFIG; + param_hdr.param_size = sizeof(struct afe_param_id_i2s_cfg); + + ret = q6afe_pack_and_set_param_in_band(port_id, + q6audio_get_port_index(port_id), + param_hdr, + (u8 *) &i2s_port->i2s_cfg); + if (ret) { + pr_err("%s: AFE enable for port 0x%x failed ret = %d\n", + __func__, port_id, ret); + goto fail_cmd; + } + + port_index = afe_get_port_index(port_id); + if ((port_index >= 0) && (port_index < AFE_MAX_PORTS)) { + this_afe.afe_sample_rates[port_index] = rate; + } else { + pr_err("%s: Invalid port index %d\n", __func__, port_index); + ret = -EINVAL; + goto fail_cmd; + } + /* slot mapping is not need if there is only one group */ + if (num_groups > 1) { + ret = afe_send_slot_mapping_cfg( + &i2s_port->slot_mapping, + port_id); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + goto fail_cmd; + } + } + + ret = afe_send_cmd_port_start(port_id); + +fail_cmd: + return ret; +} + int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port, u32 rate, u16 num_groups) { @@ -3598,6 +3734,54 @@ int afe_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_INT6_MI2S_RX; case AFE_PORT_ID_INT6_MI2S_TX: return IDX_AFE_PORT_ID_INT6_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_1; + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_2; + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_3; + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_4; + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_1; + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_2; + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_3; + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_4; + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_1; + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_2; + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_3; + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_4; + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_1; + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_2; + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_3; + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_4; default: pr_err("%s: port 0x%x\n", __func__, port_id); return -EINVAL; @@ -4022,6 +4206,154 @@ int afe_port_group_set_param(u16 group_id, return ret; } +static int afe_port_group_mi2s_set_param(u16 group_id, + struct afe_param_id_group_device_i2s_cfg_v1 *afe_group_config) +{ + struct param_hdr_v3 param_hdr = {0}; + int cfg_type; + int ret; + + if (!afe_group_config) { + pr_err("%s: Error, no configuration data\n", __func__); + return -EINVAL; + } + + pr_debug("%s: group id: 0x%x\n", __func__, group_id); + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + switch (group_id) { + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX: + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX: + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX: + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX: + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX: + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX: + cfg_type = AFE_PARAM_ID_GROUP_DEVICE_I2S_CONFIG; + break; + default: + pr_err("%s: Invalid group id 0x%x\n", __func__, group_id); + return -EINVAL; + } + + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = cfg_type; + param_hdr.param_size = + sizeof(struct afe_param_id_group_device_i2s_cfg_v1); + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) afe_group_config); + if (ret) + pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_CFG failed %d\n", + __func__, ret); + + return ret; +} + +static atomic_t mi2s_gp_en_ref[IDX_GROUP_MI2S_MAX]; +static int afe_get_mi2s_group_idx(u16 group_id) +{ + int gp_idx = -1; + + switch (group_id) { + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_RX: + gp_idx = IDX_GROUP_SECONDARY_MI2S_RX; + break; + case AFE_GROUP_DEVICE_ID_SECONDARY_MI2S_TX: + gp_idx = IDX_GROUP_SECONDARY_MI2S_TX; + break; + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_RX: + gp_idx = IDX_GROUP_TERTIARY_MI2S_RX; + break; + case AFE_GROUP_DEVICE_ID_TERTIARY_MI2S_TX: + gp_idx = IDX_GROUP_TERTIARY_MI2S_TX; + break; + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_RX: + gp_idx = IDX_GROUP_QUATERNARY_MI2S_RX; + break; + case AFE_GROUP_DEVICE_ID_QUATERNARY_MI2S_TX: + gp_idx = IDX_GROUP_QUATERNARY_MI2S_TX; + break; + default: + break; + } + + return gp_idx; +} + +int afe_port_group_mi2s_enable(u16 group_id, + union afe_port_group_mi2s_config *afe_group_config, + u16 enable) +{ + struct afe_param_id_group_device_enable group_enable = {0}; + struct param_hdr_v3 param_hdr = {0}; + int ret = 0; + int gp_idx; + + pr_debug("%s: group id: 0x%x enable: %d\n", __func__, + group_id, enable); + + gp_idx = afe_get_mi2s_group_idx(group_id); + + if ((gp_idx >= 0) && (gp_idx < IDX_GROUP_MI2S_MAX)) { + + atomic_t *gp_ref = &mi2s_gp_en_ref[gp_idx]; + + if (enable) + atomic_inc(gp_ref); + else + atomic_dec(gp_ref); + + if ((enable) && (atomic_read(gp_ref) > 1)) { + pr_err("%s: this TDM group is enabled already %d refs_cnt %d\n", + __func__, group_id, atomic_read(gp_ref)); + goto rtn; + } + + if ((!enable) && (atomic_read(gp_ref) > 0)) { + pr_err("%s: this TDM group will be disabled in last call %d refs_cnt %d\n", + __func__, group_id, atomic_read(gp_ref)); + goto rtn; + } + } + + ret = afe_q6_interface_prepare(); + if (ret != 0) { + pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret); + return ret; + } + + if (enable) { + ret = afe_port_group_mi2s_set_param( + group_id, &afe_group_config->i2s_cfg); + if (ret < 0) { + pr_err("%s: afe send failed %d\n", __func__, ret); + return ret; + } + } + + param_hdr.module_id = AFE_MODULE_GROUP_DEVICE; + param_hdr.instance_id = INSTANCE_ID_0; + param_hdr.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE; + param_hdr.param_size = sizeof(struct afe_group_device_enable); + group_enable.group_id = group_id; + group_enable.enable = enable; + + ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr, + (u8 *) &group_enable); + if (ret) + pr_err("%s: AFE_PARAM_ID_GROUP_DEVICE_ENABLE failed %d\n", + __func__, ret); + +rtn: + return ret; +} + int afe_port_group_enable(u16 group_id, union afe_port_group_config *afe_group_config, u16 enable) diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c index 0062e4cd6432..94a6b0c42dee 100644 --- a/sound/soc/msm/qdsp6v2/q6audio-v2.c +++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c @@ -95,6 +95,54 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX; case AFE_PORT_ID_TERTIARY_MI2S_TX: return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_1; + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_2; + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_3; + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_TX_4; + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_1; + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_2; + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_3; + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_TX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_TX_4; + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_1; + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_2; + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_3; + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + return IDX_AFE_PORT_ID_SECONDARY_MI2S_RX_4; + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_1; + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_2; + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_3; + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + return IDX_AFE_PORT_ID_TERTIARY_MI2S_RX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + return IDX_AFE_PORT_ID_QUATERNARY_MI2S_RX_4; case AUDIO_PORT_ID_I2S_RX: return IDX_AUDIO_PORT_ID_I2S_RX; case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: @@ -342,6 +390,54 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_TERTIARY_MI2S_RX; case AFE_PORT_ID_TERTIARY_MI2S_TX: return AFE_PORT_ID_TERTIARY_MI2S_TX; + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + return AFE_PORT_ID_SECONDARY_MI2S_TX_1; + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + return AFE_PORT_ID_SECONDARY_MI2S_TX_2; + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + return AFE_PORT_ID_SECONDARY_MI2S_TX_3; + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + return AFE_PORT_ID_SECONDARY_MI2S_TX_4; + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + return AFE_PORT_ID_TERTIARY_MI2S_TX_1; + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + return AFE_PORT_ID_TERTIARY_MI2S_TX_2; + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + return AFE_PORT_ID_TERTIARY_MI2S_TX_3; + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + return AFE_PORT_ID_TERTIARY_MI2S_TX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + return AFE_PORT_ID_QUATERNARY_MI2S_TX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + return AFE_PORT_ID_QUATERNARY_MI2S_TX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + return AFE_PORT_ID_QUATERNARY_MI2S_TX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: + return AFE_PORT_ID_QUATERNARY_MI2S_TX_4; + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + return AFE_PORT_ID_SECONDARY_MI2S_RX_1; + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + return AFE_PORT_ID_SECONDARY_MI2S_RX_2; + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + return AFE_PORT_ID_SECONDARY_MI2S_RX_3; + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + return AFE_PORT_ID_SECONDARY_MI2S_RX_4; + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + return AFE_PORT_ID_TERTIARY_MI2S_RX_1; + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + return AFE_PORT_ID_TERTIARY_MI2S_RX_2; + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + return AFE_PORT_ID_TERTIARY_MI2S_RX_3; + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + return AFE_PORT_ID_TERTIARY_MI2S_RX_4; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + return AFE_PORT_ID_QUATERNARY_MI2S_RX_1; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + return AFE_PORT_ID_QUATERNARY_MI2S_RX_2; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + return AFE_PORT_ID_QUATERNARY_MI2S_RX_3; + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + return AFE_PORT_ID_QUATERNARY_MI2S_RX_4; case AUDIO_PORT_ID_I2S_RX: return AUDIO_PORT_ID_I2S_RX; case AFE_PORT_ID_SECONDARY_MI2S_RX_SD1: @@ -642,6 +738,30 @@ int q6audio_is_digital_pcm_interface(u16 port_id) case AFE_PORT_ID_INT5_MI2S_TX: case AFE_PORT_ID_INT6_MI2S_RX: case AFE_PORT_ID_INT6_MI2S_TX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: break; default: ret = -EINVAL; @@ -795,6 +915,30 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_INT6_MI2S_RX: case AFE_PORT_ID_INT6_MI2S_TX: case AFE_PORT_ID_MULTICHAN_HDMI_RX: + case AFE_PORT_ID_SECONDARY_MI2S_RX_1: + case AFE_PORT_ID_SECONDARY_MI2S_RX_2: + case AFE_PORT_ID_SECONDARY_MI2S_RX_3: + case AFE_PORT_ID_SECONDARY_MI2S_RX_4: + case AFE_PORT_ID_SECONDARY_MI2S_TX_1: + case AFE_PORT_ID_SECONDARY_MI2S_TX_2: + case AFE_PORT_ID_SECONDARY_MI2S_TX_3: + case AFE_PORT_ID_SECONDARY_MI2S_TX_4: + case AFE_PORT_ID_TERTIARY_MI2S_RX_1: + case AFE_PORT_ID_TERTIARY_MI2S_RX_2: + case AFE_PORT_ID_TERTIARY_MI2S_RX_3: + case AFE_PORT_ID_TERTIARY_MI2S_RX_4: + case AFE_PORT_ID_TERTIARY_MI2S_TX_1: + case AFE_PORT_ID_TERTIARY_MI2S_TX_2: + case AFE_PORT_ID_TERTIARY_MI2S_TX_3: + case AFE_PORT_ID_TERTIARY_MI2S_TX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_RX_4: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_1: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_2: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_3: + case AFE_PORT_ID_QUATERNARY_MI2S_TX_4: { ret = 0; break; diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 30bdc971883b..017e241b0ec9 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c @@ -1146,10 +1146,8 @@ static int snd_cs4231_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_cs4231_playback; err = snd_cs4231_open(chip, CS4231_MODE_PLAY); - if (err < 0) { - snd_free_pages(runtime->dma_area, runtime->dma_bytes); + if (err < 0) return err; - } chip->playback_substream = substream; chip->p_periods_sent = 0; snd_pcm_set_sync(substream); @@ -1167,10 +1165,8 @@ static int snd_cs4231_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_cs4231_capture; err = snd_cs4231_open(chip, CS4231_MODE_RECORD); - if (err < 0) { - snd_free_pages(runtime->dma_area, runtime->dma_bytes); + if (err < 0) return err; - } chip->capture_substream = substream; chip->c_periods_sent = 0; snd_pcm_set_sync(substream); diff --git a/sound/usb/card.c b/sound/usb/card.c index 86096532dfba..bbbece670eaf 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c @@ -688,9 +688,12 @@ static int usb_audio_probe(struct usb_interface *intf, __error: if (chip) { + /* chip->active is inside the chip->card object, + * decrement before memory is possibly returned. + */ + atomic_dec(&chip->active); if (!chip->num_interfaces) snd_card_free(chip->card); - atomic_dec(&chip->active); } mutex_unlock(®ister_mutex); return err; |
