Merge "asoc: codecs: set boost state to MAX_STATE_2 for WSA8815"
diff --git a/Android.mk b/Android.mk
index 2fa054b..6b4894b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -3,7 +3,7 @@
UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
$(shell mkdir -p $(UAPI_OUT)/linux;)
$(shell mkdir -p $(UAPI_OUT)/sound;)
$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers)
@@ -14,6 +14,7 @@
$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers)
$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers)
+include $(MY_LOCAL_PATH)/include/uapi/Android.mk
include $(MY_LOCAL_PATH)/ipc/Android.mk
include $(MY_LOCAL_PATH)/dsp/Android.mk
include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk
@@ -23,9 +24,19 @@
include $(MY_LOCAL_PATH)/asoc/codecs/wcd934x/Android.mk
endif
+ifeq ($(call is-board-platform-in-list,sdm670 msmnile),true)
+$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers)
+include $(MY_LOCAL_PATH)/asoc/codecs/aqt1000/Android.mk
+endif
+
ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true)
$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/sdm660_cdc/Module.symvers)
$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/msm_sdw/Module.symvers)
include $(MY_LOCAL_PATH)/asoc/codecs/sdm660_cdc/Android.mk
include $(MY_LOCAL_PATH)/asoc/codecs/msm_sdw/Android.mk
endif
+
+ifeq ($(call is-board-platform-in-list,msmnile),true)
+$(shell rm -rf $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd9360/Module.symvers)
+include $(MY_LOCAL_PATH)/asoc/codecs/wcd9360/Android.mk
+endif
diff --git a/Makefile b/Makefile
index 2848799..4e123b6 100644
--- a/Makefile
+++ b/Makefile
@@ -11,6 +11,10 @@
include $(srctree)/techpack/audio/config/sdxpoorwillsauto.conf
export
endif
+ifeq ($(CONFIG_ARCH_SDM855), y)
+include $(srctree)/techpack/audio/config/sdm855auto.conf
+export
+endif
# Use USERINCLUDE when you must reference the UAPI directories only.
USERINCLUDE += \
@@ -34,6 +38,10 @@
LINUXINCLUDE += \
-include $(srctree)/techpack/audio/config/sdxpoorwillsautoconf.h
endif
+ifeq ($(CONFIG_ARCH_SDM855), y)
+LINUXINCLUDE += \
+ -include $(srctree)/techpack/audio/config/sdm855autoconf.h
+endif
obj-y += asoc/
obj-y += dsp/
diff --git a/asoc/Android.mk b/asoc/Android.mk
index 5023a09..6154917 100644
--- a/asoc/Android.mk
+++ b/asoc/Android.mk
@@ -13,9 +13,14 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+TARGET := msmnile
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/asoc/Kbuild b/asoc/Kbuild
index 91ebf8a..eec5947 100644
--- a/asoc/Kbuild
+++ b/asoc/Kbuild
@@ -30,6 +30,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
# As per target team, build is done as follows:
@@ -80,6 +85,11 @@
MACHINE_OBJS += sdm845.o
endif
+# for SDM855 sound card driver
+ifdef CONFIG_SND_SOC_SDM855
+ MACHINE_OBJS += sdm855.o
+endif
+
ifdef CONFIG_SND_SOC_CPE
CPE_LSM_OBJS += msm-cpe-lsm.o
endif
@@ -112,7 +122,7 @@
ifdef CONFIG_DOLBY_LICENSE
PLATFORM_OBJS += msm-ds2-dap-config.o
endif
-ifdef CONFIG_SND_HWDEP
+ifdef CONFIG_SND_HWDEP_ROUTING
PLATFORM_OBJS += msm-pcm-routing-devdep.o
endif
ifdef CONFIG_QTI_PP
@@ -168,6 +178,9 @@
obj-$(CONFIG_SND_SOC_MACHINE_SDM845) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
+obj-$(CONFIG_SND_SOC_SDM855) += machine_dlkm.o
+machine_dlkm-y := $(MACHINE_OBJS)
+
obj-$(CONFIG_SND_SOC_EXT_CODEC) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
diff --git a/asoc/codecs/Android.mk b/asoc/codecs/Android.mk
index 037774c..152f617 100644
--- a/asoc/codecs/Android.mk
+++ b/asoc/codecs/Android.mk
@@ -11,9 +11,13 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild
index 005a68c..01a6e2d 100644
--- a/asoc/codecs/Kbuild
+++ b/asoc/codecs/Kbuild
@@ -29,6 +29,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
# As per target team, build is done as follows:
@@ -69,6 +74,7 @@
CORE_OBJS += msm-cdc-supply.o
CORE_OBJS += wcd934x/wcd934x-regmap.o
CORE_OBJS += wcd934x/wcd934x-tables.o
+ CORE_OBJS += wcd9360/wcd9360-regmap.o
endif
ifdef CONFIG_SND_SOC_WCD9XXX_V2
diff --git a/asoc/codecs/aqt1000/Android.mk b/asoc/codecs/aqt1000/Android.mk
new file mode 100644
index 0000000..7de1a63
--- /dev/null
+++ b/asoc/codecs/aqt1000/Android.mk
@@ -0,0 +1,41 @@
+# Android makefile for audio kernel modules
+
+AUDIO_CHIPSET := audio
+# Build/Package only in case of supported target
+ifeq ($(call is-board-platform-in-list,sdm670),true)
+
+LOCAL_PATH := $(call my-dir)
+
+# This makefile is only for DLKM
+ifneq ($(findstring vendor,$(LOCAL_PATH)),)
+
+ifneq ($(findstring opensource,$(LOCAL_PATH)),)
+ AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel
+endif # opensource
+
+DLKM_DIR := $(TOP)/device/qcom/common/dlkm
+
+# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko
+###########################################################
+# This is set once per LOCAL_PATH, not per (kernel) module
+KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR)
+
+# We are actually building audio.ko here, as per the
+# requirement we are specifying <chipset>_audio.ko as LOCAL_MODULE.
+# This means we need to rename the module to <chipset>_audio.ko
+# after audio.ko is built.
+KBUILD_OPTIONS += MODNAME=aqt1000_cdc_dlkm
+KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
+KBUILD_OPTIONS += $(AUDIO_SELECT)
+
+###########################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(AUDIO_CHIPSET)_aqt1000_cdc.ko
+LOCAL_MODULE_KBUILD_NAME := aqt1000_cdc_dlkm.ko
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_DEBUG_ENABLE := true
+LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
+include $(DLKM_DIR)/AndroidKernelModule.mk
+###########################################################
+endif # DLKM check
+endif # supported target check
diff --git a/asoc/codecs/aqt1000/Kbuild b/asoc/codecs/aqt1000/Kbuild
new file mode 100644
index 0000000..f982951
--- /dev/null
+++ b/asoc/codecs/aqt1000/Kbuild
@@ -0,0 +1,114 @@
+# We can build either as part of a standalone Kernel build or as
+# an external module. Determine which mechanism is being used
+ifeq ($(MODNAME),)
+ KERNEL_BUILD := 1
+else
+ KERNEL_BUILD := 0
+endif
+
+ifeq ($(KERNEL_BUILD), 1)
+ # These are configurable via Kconfig for kernel-based builds
+ # Need to explicitly configure for Android-based builds
+ AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14
+ AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+ # These are configurable via Kconfig for kernel-based builds
+ # Need to explicitly configure for Android-based builds
+
+ ifeq ($(CONFIG_ARCH_SDM670), y)
+ include $(AUDIO_ROOT)/config/sdm670auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
+ endif
+
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
+endif
+
+# As per target team, build is done as follows:
+# Defconfig : build with default flags
+# Slub : defconfig + CONFIG_SLUB_DEBUG := y +
+# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y
+# Perf : Using appropriate msmXXXX-perf_defconfig
+#
+# Shipment builds (user variants) should not have any debug feature
+# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds
+# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since
+# there is no other way to identify defconfig builds, QTI internal
+# representation of perf builds (identified using the string 'perf'),
+# is used to identify if the build is a slub or defconfig one. This
+# way no critical debug feature will be enabled for perf and shipment
+# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT
+# config.
+
+############ UAPI ############
+UAPI_DIR := uapi
+UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR)
+
+############ COMMON ############
+COMMON_DIR := include
+COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR)
+
+# for AQT1000 Codec
+ifeq ($(CONFIG_SND_SOC_AQT1000), m)
+ AQT1000_CDC_OBJS += aqt1000-regmap.o
+ AQT1000_CDC_OBJS += aqt1000-utils.o
+ AQT1000_CDC_OBJS += aqt1000-core.o
+ AQT1000_CDC_OBJS += aqt1000-irq.o
+ AQT1000_CDC_OBJS += aqt1000-clsh.o
+ AQT1000_CDC_OBJS += aqt1000.o
+ AQT1000_CDC_OBJS += aqt1000-mbhc.o
+endif
+
+LINUX_INC += -Iinclude/linux
+
+INCS += $(COMMON_INC) \
+ $(UAPI_INC)
+
+EXTRA_CFLAGS += $(INCS)
+
+CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \
+ -DANI_LITTLE_BIT_ENDIAN \
+ -DDOT11F_LITTLE_ENDIAN_HOST \
+ -DANI_COMPILER_TYPE_GCC \
+ -DANI_OS_TYPE_ANDROID=6 \
+ -DPTT_SOCK_SVC_ENABLE \
+ -Wall\
+ -Werror\
+ -D__linux__
+
+KBUILD_CPPFLAGS += $(CDEFINES)
+
+# Currently, for versions of gcc which support it, the kernel Makefile
+# is disabling the maybe-uninitialized warning. Re-enable it for the
+# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it
+# will override the kernel settings.
+ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y)
+EXTRA_CFLAGS += -Wmaybe-uninitialized
+endif
+#EXTRA_CFLAGS += -Wmissing-prototypes
+
+ifeq ($(call cc-option-yn, -Wheader-guard),y)
+EXTRA_CFLAGS += -Wheader-guard
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/aqt1000/Module.symvers
+endif
+
+# Module information used by KBuild framework
+obj-$(CONFIG_SND_SOC_AQT1000) += aqt1000_cdc_dlkm.o
+aqt1000_cdc_dlkm-y := $(AQT1000_CDC_OBJS)
+
+# inject some build related information
+DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"
diff --git a/asoc/codecs/aqt1000/aqt1000-api.h b/asoc/codecs/aqt1000/aqt1000-api.h
new file mode 100644
index 0000000..ef2e526
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-api.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef AQT1000_API_H
+#define AQT1000_API_H
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <sound/soc.h>
+
+extern int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
+ int volt, int micb_num);
+extern int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable);
+extern int aqt_get_micb_vout_ctl_val(u32 micb_mv);
+extern int aqt_micbias_control(struct snd_soc_codec *codec, int micb_num,
+ int req, bool is_dapm);
+
+#endif /* AQT1000_API_H */
diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.c b/asoc/codecs/aqt1000/aqt1000-clsh.c
new file mode 100644
index 0000000..640795d
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-clsh.c
@@ -0,0 +1,805 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <sound/soc.h>
+#include "aqt1000-registers.h"
+#include "aqt1000-clsh.h"
+
+#define AQT_USLEEP_RANGE 50
+#define MAX_IMPED_PARAMS 6
+
+enum aqt_vref_dac_sel {
+ VREF_N1P9V = 0,
+ VREF_N1P86V,
+ VREF_N181V,
+ VREF_N1P74V,
+ VREF_N1P7V,
+ VREF_N0P9V,
+ VREF_N1P576V,
+ VREF_N1P827V,
+};
+
+enum aqt_vref_ctl {
+ CONTROLLER = 0,
+ I2C,
+};
+
+enum aqt_hd2_res_div_ctl {
+ DISCONNECT = 0,
+ P5_0P35,
+ P75_0P68,
+ P82_0P77,
+ P9_0P87,
+};
+
+enum aqt_curr_bias_err_amp {
+ I_0P25UA = 0,
+ I_0P5UA,
+ I_0P75UA,
+ I_1UA,
+ I_1P25UA,
+ I_1P5UA,
+ I_1P75UA,
+ I_2UA,
+};
+
+static const struct aqt_reg_mask_val imped_table_aqt[][MAX_IMPED_PARAMS] = {
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf2},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf2},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf2},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf2},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf4},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf4},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf4},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf4},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf7},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf7},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf7},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf7},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xf9},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xf9},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xf9},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xf9},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfa},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfa},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfa},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfa},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfb},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfb},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfb},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfb},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfc},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfc},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfc},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfc},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x00},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x00},
+ },
+ {
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x01, 0x01},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0xff, 0xfd},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x01, 0x01},
+ },
+};
+
+static const struct aqt_imped_val imped_index[] = {
+ {4, 0},
+ {5, 1},
+ {6, 2},
+ {7, 3},
+ {8, 4},
+ {9, 5},
+ {10, 6},
+ {11, 7},
+ {12, 8},
+ {13, 9},
+};
+
+static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *,
+ struct aqt_clsh_cdc_data *,
+ u8 req_state, bool en, int mode);
+
+static int get_impedance_index(int imped)
+{
+ int i = 0;
+
+ if (imped < imped_index[i].imped_val) {
+ pr_debug("%s, detected impedance is less than 4 Ohm\n",
+ __func__);
+ i = 0;
+ goto ret;
+ }
+ if (imped >= imped_index[ARRAY_SIZE(imped_index) - 1].imped_val) {
+ pr_debug("%s, detected impedance is greater than 12 Ohm\n",
+ __func__);
+ i = ARRAY_SIZE(imped_index) - 1;
+ goto ret;
+ }
+ for (i = 0; i < ARRAY_SIZE(imped_index) - 1; i++) {
+ if (imped >= imped_index[i].imped_val &&
+ imped < imped_index[i + 1].imped_val)
+ break;
+ }
+ret:
+ pr_debug("%s: selected impedance index = %d\n",
+ __func__, imped_index[i].index);
+ return imped_index[i].index;
+}
+
+/*
+ * Function: aqt_clsh_imped_config
+ * Params: codec, imped, reset
+ * Description:
+ * This function updates HPHL and HPHR gain settings
+ * according to the impedance value.
+ */
+void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped, bool reset)
+{
+ int i;
+ int index = 0;
+ int table_size;
+
+ static const struct aqt_reg_mask_val
+ (*imped_table_ptr)[MAX_IMPED_PARAMS];
+
+ table_size = ARRAY_SIZE(imped_table_aqt);
+ imped_table_ptr = imped_table_aqt;
+
+ /* reset = 1, which means request is to reset the register values */
+ if (reset) {
+ for (i = 0; i < MAX_IMPED_PARAMS; i++)
+ snd_soc_update_bits(codec,
+ imped_table_ptr[index][i].reg,
+ imped_table_ptr[index][i].mask, 0);
+ return;
+ }
+ index = get_impedance_index(imped);
+ if (index >= (ARRAY_SIZE(imped_index) - 1)) {
+ pr_debug("%s, impedance not in range = %d\n", __func__, imped);
+ return;
+ }
+ if (index >= table_size) {
+ pr_debug("%s, impedance index not in range = %d\n", __func__,
+ index);
+ return;
+ }
+ for (i = 0; i < MAX_IMPED_PARAMS; i++)
+ snd_soc_update_bits(codec,
+ imped_table_ptr[index][i].reg,
+ imped_table_ptr[index][i].mask,
+ imped_table_ptr[index][i].val);
+}
+EXPORT_SYMBOL(aqt_clsh_imped_config);
+
+static const char *mode_to_str(int mode)
+{
+ switch (mode) {
+ case CLS_H_NORMAL:
+ return "CLS_H_NORMAL";
+ case CLS_H_HIFI:
+ return "CLS_H_HIFI";
+ case CLS_H_LOHIFI:
+ return "CLS_H_LOHIFI";
+ case CLS_H_LP:
+ return "CLS_H_LP";
+ case CLS_H_ULP:
+ return "CLS_H_ULP";
+ case CLS_AB:
+ return "CLS_AB";
+ case CLS_AB_HIFI:
+ return "CLS_AB_HIFI";
+ default:
+ return "CLS_H_INVALID";
+ };
+}
+
+static const char *const state_to_str[] = {
+ [AQT_CLSH_STATE_IDLE] = "STATE_IDLE",
+ [AQT_CLSH_STATE_HPHL] = "STATE_HPH_L",
+ [AQT_CLSH_STATE_HPHR] = "STATE_HPH_R",
+ [AQT_CLSH_STATE_HPH_ST] = "STATE_HPH_ST",
+};
+
+static inline void
+aqt_enable_clsh_block(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d, bool enable)
+{
+ if ((enable && ++clsh_d->clsh_users == 1) ||
+ (!enable && --clsh_d->clsh_users == 0))
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_CRC, 0x01,
+ (u8) enable);
+ if (clsh_d->clsh_users < 0)
+ clsh_d->clsh_users = 0;
+ dev_dbg(codec->dev, "%s: clsh_users %d, enable %d", __func__,
+ clsh_d->clsh_users, enable);
+}
+
+static inline bool aqt_clsh_enable_status(struct snd_soc_codec *codec)
+{
+ return snd_soc_read(codec, AQT1000_CDC_CLSH_CRC) & 0x01;
+}
+
+static inline int aqt_clsh_get_int_mode(struct aqt_clsh_cdc_data *clsh_d,
+ int clsh_state)
+{
+ int mode;
+
+ if ((clsh_state != AQT_CLSH_STATE_HPHL) &&
+ (clsh_state != AQT_CLSH_STATE_HPHR))
+ mode = CLS_NONE;
+ else
+ mode = clsh_d->interpolator_modes[ffs(clsh_state)];
+
+ return mode;
+}
+
+static inline void aqt_clsh_set_int_mode(struct aqt_clsh_cdc_data *clsh_d,
+ int clsh_state, int mode)
+{
+ if ((clsh_state != AQT_CLSH_STATE_HPHL) &&
+ (clsh_state != AQT_CLSH_STATE_HPHR))
+ return;
+
+ clsh_d->interpolator_modes[ffs(clsh_state)] = mode;
+}
+
+static inline void aqt_clsh_set_buck_mode(struct snd_soc_codec *codec,
+ int mode)
+{
+ if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
+ mode == CLS_AB_HIFI || mode == CLS_AB)
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x08, 0x08); /* set to HIFI */
+ else
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x08, 0x00); /* set to default */
+}
+
+static inline void aqt_clsh_set_flyback_mode(struct snd_soc_codec *codec,
+ int mode)
+{
+ if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
+ mode == CLS_AB_HIFI || mode == CLS_AB)
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x04, 0x04); /* set to HIFI */
+ else
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x04, 0x00); /* set to Default */
+}
+
+static inline void aqt_clsh_gm3_boost_disable(struct snd_soc_codec *codec,
+ int mode)
+{
+ if (mode == CLS_H_HIFI || mode == CLS_H_LOHIFI ||
+ mode == CLS_AB_HIFI || mode == CLS_AB) {
+ snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL,
+ 0x80, 0x0); /* disable GM3 Boost */
+ snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4,
+ 0xF0, 0x80);
+ } else {
+ snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL,
+ 0x80, 0x80); /* set to Default */
+ snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEG_CTRL_4,
+ 0xF0, 0x70);
+ }
+}
+
+static inline void aqt_clsh_flyback_dac_ctl(struct snd_soc_codec *codec,
+ int vref)
+{
+ snd_soc_update_bits(codec, AQT1000_FLYBACK_VNEGDAC_CTRL_2,
+ 0xE0, (vref << 5));
+}
+
+static inline void aqt_clsh_mode_vref_ctl(struct snd_soc_codec *codec,
+ int vref_ctl)
+{
+ if (vref_ctl == I2C) {
+ snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x02);
+ snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x1C);
+ } else {
+ snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_2, 0xFF, 0x3A);
+ snd_soc_update_bits(codec, AQT1000_CLASSH_MODE_3, 0x02, 0x00);
+ }
+}
+
+static inline void aqt_clsh_buck_current_bias_ctl(struct snd_soc_codec *codec,
+ bool enable)
+{
+ if (enable) {
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4,
+ 0x70, (I_2UA << 4));
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4,
+ 0x07, I_0P25UA);
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2,
+ 0x3F, 0x3F);
+ } else {
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4,
+ 0x70, (I_1UA << 4));
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_IBIAS_CTL_4,
+ 0x07, I_1UA);
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_CTRL_CCL_2,
+ 0x3F, 0x20);
+ }
+}
+
+static inline void aqt_clsh_rdac_hd2_ctl(struct snd_soc_codec *codec,
+ u8 hd2_div_ctl, u8 state)
+{
+ u16 reg = 0;
+
+ if (state == AQT_CLSH_STATE_HPHL)
+ reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L;
+ else if (state == AQT_CLSH_STATE_HPHR)
+ reg = AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R;
+ else
+ dev_err(codec->dev, "%s: Invalid state: %d\n",
+ __func__, state);
+ if (!reg)
+ snd_soc_update_bits(codec, reg, 0x0F, hd2_div_ctl);
+}
+
+static inline void aqt_clsh_force_iq_ctl(struct snd_soc_codec *codec,
+ int mode)
+{
+ if (mode == CLS_H_LOHIFI || mode == CLS_AB) {
+ snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2,
+ 0x20, 0x20);
+ snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER,
+ 0xF0, 0xC0);
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1,
+ 0x0E, 0x02);
+ } else {
+
+ snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_PA_MISC2,
+ 0x20, 0x0);
+ snd_soc_update_bits(codec, AQT1000_RX_BIAS_HPH_LOWPOWER,
+ 0xF0, 0x80);
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL1,
+ 0x0E, 0x06);
+ }
+}
+
+static void aqt_clsh_buck_ctrl(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d,
+ int mode,
+ bool enable)
+{
+ /* enable/disable buck */
+ if ((enable && (++clsh_d->buck_users == 1)) ||
+ (!enable && (--clsh_d->buck_users == 0)))
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ (1 << 7), (enable << 7));
+ dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s",
+ __func__, clsh_d->buck_users, enable, mode_to_str(mode));
+ /*
+ * 500us sleep is required after buck enable/disable
+ * as per HW requirement
+ */
+ usleep_range(500, 500 + AQT_USLEEP_RANGE);
+}
+
+static void aqt_clsh_flyback_ctrl(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d,
+ int mode,
+ bool enable)
+{
+ /* enable/disable flyback */
+ if ((enable && (++clsh_d->flyback_users == 1)) ||
+ (!enable && (--clsh_d->flyback_users == 0))) {
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ (1 << 6), (enable << 6));
+ /* 100usec delay is needed as per HW requirement */
+ usleep_range(100, 110);
+ }
+ dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s",
+ __func__, clsh_d->flyback_users, enable, mode_to_str(mode));
+ /*
+ * 500us sleep is required after flyback enable/disable
+ * as per HW requirement
+ */
+ usleep_range(500, 500 + AQT_USLEEP_RANGE);
+}
+
+static void aqt_clsh_set_hph_mode(struct snd_soc_codec *codec,
+ int mode)
+{
+ u8 val = 0;
+ u8 gain = 0;
+ u8 res_val = VREF_FILT_R_0OHM;
+ u8 ipeak = DELTA_I_50MA;
+
+ switch (mode) {
+ case CLS_H_NORMAL:
+ res_val = VREF_FILT_R_50KOHM;
+ val = 0x00;
+ gain = DAC_GAIN_0DB;
+ ipeak = DELTA_I_50MA;
+ break;
+ case CLS_AB:
+ val = 0x00;
+ gain = DAC_GAIN_0DB;
+ ipeak = DELTA_I_50MA;
+ break;
+ case CLS_AB_HIFI:
+ val = 0x08;
+ break;
+ case CLS_H_HIFI:
+ val = 0x08;
+ gain = DAC_GAIN_M0P2DB;
+ ipeak = DELTA_I_50MA;
+ break;
+ case CLS_H_LOHIFI:
+ val = 0x00;
+ break;
+ case CLS_H_ULP:
+ val = 0x0C;
+ break;
+ case CLS_H_LP:
+ val = 0x04;
+ ipeak = DELTA_I_30MA;
+ break;
+ default:
+ return;
+ };
+
+ if (mode == CLS_H_LOHIFI || mode == CLS_AB)
+ val = 0x04;
+
+ snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x0C, val);
+}
+
+static void aqt_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec,
+ int mode)
+{
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x02, 0x00);
+}
+
+static void aqt_clsh_state_hph_st(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable, int mode)
+{
+ dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode),
+ is_enable ? "enable" : "disable");
+
+ if (mode == CLS_AB || mode == CLS_AB_HIFI)
+ return;
+
+ if (is_enable) {
+ if (req_state == AQT_CLSH_STATE_HPHL)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_CFG0,
+ 0x40, 0x40);
+ if (req_state == AQT_CLSH_STATE_HPHR)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_CFG0,
+ 0x40, 0x40);
+ } else {
+ if (req_state == AQT_CLSH_STATE_HPHL)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_CFG0,
+ 0x40, 0x00);
+ if (req_state == AQT_CLSH_STATE_HPHR)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_CFG0,
+ 0x40, 0x00);
+ }
+}
+
+static void aqt_clsh_state_hph_r(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable, int mode)
+{
+ dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode),
+ is_enable ? "enable" : "disable");
+
+ if (mode == CLS_H_NORMAL) {
+ dev_err(codec->dev, "%s: Normal mode not applicable for hph_r\n",
+ __func__);
+ return;
+ }
+
+ if (is_enable) {
+ if (mode != CLS_AB && mode != CLS_AB_HIFI) {
+ aqt_enable_clsh_block(codec, clsh_d, true);
+ /*
+ * These K1 values depend on the Headphone Impedance
+ * For now it is assumed to be 16 ohm
+ */
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB,
+ 0x0F, 0x00);
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB,
+ 0xFF, 0xC0);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_CFG0,
+ 0x40, 0x40);
+ }
+ aqt_clsh_set_buck_regulator_mode(codec, mode);
+ aqt_clsh_set_flyback_mode(codec, mode);
+ aqt_clsh_gm3_boost_disable(codec, mode);
+ aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V);
+ aqt_clsh_mode_vref_ctl(codec, I2C);
+ aqt_clsh_force_iq_ctl(codec, mode);
+ aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state);
+ aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true);
+ aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V);
+ aqt_clsh_set_buck_mode(codec, mode);
+ aqt_clsh_buck_ctrl(codec, clsh_d, mode, true);
+ aqt_clsh_mode_vref_ctl(codec, CONTROLLER);
+ aqt_clsh_buck_current_bias_ctl(codec, true);
+ aqt_clsh_set_hph_mode(codec, mode);
+ } else {
+ aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL);
+ aqt_clsh_buck_current_bias_ctl(codec, false);
+
+ if (mode != CLS_AB && mode != CLS_AB_HIFI) {
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_CFG0,
+ 0x40, 0x00);
+ aqt_enable_clsh_block(codec, clsh_d, false);
+ }
+ /* buck and flyback set to default mode and disable */
+ aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
+ aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
+ aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state);
+ aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL);
+ aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL);
+ aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
+ aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL);
+ aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL);
+ }
+}
+
+static void aqt_clsh_state_hph_l(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable, int mode)
+{
+ dev_dbg(codec->dev, "%s: mode: %s, %s\n", __func__, mode_to_str(mode),
+ is_enable ? "enable" : "disable");
+
+ if (mode == CLS_H_NORMAL) {
+ dev_err(codec->dev, "%s: Normal mode not applicable for hph_l\n",
+ __func__);
+ return;
+ }
+
+ if (is_enable) {
+ if (mode != CLS_AB && mode != CLS_AB_HIFI) {
+ aqt_enable_clsh_block(codec, clsh_d, true);
+ /*
+ * These K1 values depend on the Headphone Impedance
+ * For now it is assumed to be 16 ohm
+ */
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_MSB,
+ 0x0F, 0x00);
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_K1_LSB,
+ 0xFF, 0xC0);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_CFG0,
+ 0x40, 0x40);
+ }
+ aqt_clsh_set_buck_regulator_mode(codec, mode);
+ aqt_clsh_set_flyback_mode(codec, mode);
+ aqt_clsh_gm3_boost_disable(codec, mode);
+ aqt_clsh_flyback_dac_ctl(codec, VREF_N0P9V);
+ aqt_clsh_mode_vref_ctl(codec, I2C);
+ aqt_clsh_force_iq_ctl(codec, mode);
+ aqt_clsh_rdac_hd2_ctl(codec, P82_0P77, req_state);
+ aqt_clsh_flyback_ctrl(codec, clsh_d, mode, true);
+ aqt_clsh_flyback_dac_ctl(codec, VREF_N1P827V);
+ aqt_clsh_set_buck_mode(codec, mode);
+ aqt_clsh_buck_ctrl(codec, clsh_d, mode, true);
+ aqt_clsh_mode_vref_ctl(codec, CONTROLLER);
+ aqt_clsh_buck_current_bias_ctl(codec, true);
+ aqt_clsh_set_hph_mode(codec, mode);
+ } else {
+ aqt_clsh_set_hph_mode(codec, CLS_H_NORMAL);
+ aqt_clsh_buck_current_bias_ctl(codec, false);
+
+ if (mode != CLS_AB && mode != CLS_AB_HIFI) {
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_CFG0,
+ 0x40, 0x00);
+ aqt_enable_clsh_block(codec, clsh_d, false);
+ }
+ /* set buck and flyback to Default Mode */
+ aqt_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
+ aqt_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
+ aqt_clsh_rdac_hd2_ctl(codec, P5_0P35, req_state);
+ aqt_clsh_force_iq_ctl(codec, CLS_H_NORMAL);
+ aqt_clsh_gm3_boost_disable(codec, CLS_H_NORMAL);
+ aqt_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
+ aqt_clsh_set_buck_mode(codec, CLS_H_NORMAL);
+ aqt_clsh_set_buck_regulator_mode(codec, CLS_H_NORMAL);
+ }
+}
+
+static void aqt_clsh_state_err(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *clsh_d,
+ u8 req_state, bool is_enable, int mode)
+{
+ dev_err(codec->dev,
+ "%s Wrong request for class H state machine requested to %s %s",
+ __func__, is_enable ? "enable" : "disable",
+ state_to_str[req_state]);
+}
+
+/*
+ * Function: aqt_clsh_is_state_valid
+ * Params: state
+ * Description:
+ * Provides information on valid states of Class H configuration
+ */
+static bool aqt_clsh_is_state_valid(u8 state)
+{
+ switch (state) {
+ case AQT_CLSH_STATE_IDLE:
+ case AQT_CLSH_STATE_HPHL:
+ case AQT_CLSH_STATE_HPHR:
+ case AQT_CLSH_STATE_HPH_ST:
+ return true;
+ default:
+ return false;
+ };
+}
+
+/*
+ * Function: aqt_clsh_fsm
+ * Params: codec, cdc_clsh_d, req_state, req_type, clsh_event
+ * Description:
+ * This function handles PRE DAC and POST DAC conditions of different devices
+ * and updates class H configuration of different combination of devices
+ * based on validity of their states. cdc_clsh_d will contain current
+ * class h state information
+ */
+void aqt_clsh_fsm(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *cdc_clsh_d,
+ u8 clsh_event, u8 req_state,
+ int int_mode)
+{
+ u8 old_state, new_state;
+
+ switch (clsh_event) {
+ case AQT_CLSH_EVENT_PRE_DAC:
+ old_state = cdc_clsh_d->state;
+ new_state = old_state | req_state;
+
+ if (!aqt_clsh_is_state_valid(new_state)) {
+ dev_err(codec->dev,
+ "%s: Class-H not a valid new state: %s\n",
+ __func__, state_to_str[new_state]);
+ return;
+ }
+ if (new_state == old_state) {
+ dev_err(codec->dev,
+ "%s: Class-H already in requested state: %s\n",
+ __func__, state_to_str[new_state]);
+ return;
+ }
+ cdc_clsh_d->state = new_state;
+ aqt_clsh_set_int_mode(cdc_clsh_d, req_state, int_mode);
+ (*clsh_state_fp[new_state]) (codec, cdc_clsh_d, req_state,
+ CLSH_REQ_ENABLE, int_mode);
+ dev_dbg(codec->dev,
+ "%s: ClassH state transition from %s to %s\n",
+ __func__, state_to_str[old_state],
+ state_to_str[cdc_clsh_d->state]);
+ break;
+ case AQT_CLSH_EVENT_POST_PA:
+ old_state = cdc_clsh_d->state;
+ new_state = old_state & (~req_state);
+ if (new_state < NUM_CLSH_STATES) {
+ if (!aqt_clsh_is_state_valid(old_state)) {
+ dev_err(codec->dev,
+ "%s:Invalid old state:%s\n",
+ __func__, state_to_str[old_state]);
+ return;
+ }
+ if (new_state == old_state) {
+ dev_err(codec->dev,
+ "%s: Class-H already in requested state: %s\n",
+ __func__,state_to_str[new_state]);
+ return;
+ }
+ (*clsh_state_fp[old_state]) (codec, cdc_clsh_d,
+ req_state, CLSH_REQ_DISABLE,
+ int_mode);
+ cdc_clsh_d->state = new_state;
+ aqt_clsh_set_int_mode(cdc_clsh_d, req_state, CLS_NONE);
+ dev_dbg(codec->dev, "%s: ClassH state transition from %s to %s\n",
+ __func__, state_to_str[old_state],
+ state_to_str[cdc_clsh_d->state]);
+ }
+ break;
+ };
+}
+EXPORT_SYMBOL(aqt_clsh_fsm);
+
+/*
+ * Function: aqt_clsh_get_clsh_state
+ * Params: clsh
+ * Description:
+ * This function returns the state of the class H controller
+ */
+int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh)
+{
+ return clsh->state;
+}
+EXPORT_SYMBOL(aqt_clsh_get_clsh_state);
+
+/*
+ * Function: aqt_clsh_init
+ * Params: clsh
+ * Description:
+ * This function initializes the class H controller
+ */
+void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh)
+{
+ int i;
+
+ clsh->state = AQT_CLSH_STATE_IDLE;
+
+ for (i = 0; i < NUM_CLSH_STATES; i++)
+ clsh_state_fp[i] = aqt_clsh_state_err;
+
+ clsh_state_fp[AQT_CLSH_STATE_HPHL] = aqt_clsh_state_hph_l;
+ clsh_state_fp[AQT_CLSH_STATE_HPHR] = aqt_clsh_state_hph_r;
+ clsh_state_fp[AQT_CLSH_STATE_HPH_ST] = aqt_clsh_state_hph_st;
+ /* Set interpolator modes to NONE */
+ aqt_clsh_set_int_mode(clsh, AQT_CLSH_STATE_HPHL, CLS_NONE);
+ aqt_clsh_set_int_mode(clsh, AQT_CLSH_STATE_HPHR, CLS_NONE);
+ clsh->flyback_users = 0;
+ clsh->buck_users = 0;
+ clsh->clsh_users = 0;
+}
+EXPORT_SYMBOL(aqt_clsh_init);
diff --git a/asoc/codecs/aqt1000/aqt1000-clsh.h b/asoc/codecs/aqt1000/aqt1000-clsh.h
new file mode 100644
index 0000000..4a829b0
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-clsh.h
@@ -0,0 +1,115 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AQT1000_CLSH_H
+#define _AQT1000_CLSH_H
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <linux/kernel.h>
+
+#define CLSH_REQ_ENABLE true
+#define CLSH_REQ_DISABLE false
+
+#define AQT_CLSH_EVENT_PRE_DAC 0x01
+#define AQT_CLSH_EVENT_POST_PA 0x02
+/*
+ * Basic states for Class H state machine.
+ * represented as a bit mask within a u8 data type
+ * bit 0: HPH Left mode
+ * bit 1: HPH Right mode
+ */
+#define AQT_CLSH_STATE_IDLE 0x00
+#define AQT_CLSH_STATE_HPHL (0x01 << 0)
+#define AQT_CLSH_STATE_HPHR (0x01 << 1)
+
+/*
+ * Though number of CLSH states are 2, max state shoulbe be 3
+ * because state array index starts from 1.
+ */
+#define AQT_CLSH_STATE_MAX 3
+#define NUM_CLSH_STATES (0x01 << AQT_CLSH_STATE_MAX)
+
+
+/* Derived State: Bits 1 and 2 should be set for Headphone stereo */
+#define AQT_CLSH_STATE_HPH_ST (AQT_CLSH_STATE_HPHL | \
+ AQT_CLSH_STATE_HPHR)
+
+enum {
+ CLS_H_NORMAL = 0, /* Class-H Default */
+ CLS_H_HIFI, /* Class-H HiFi */
+ CLS_H_LP, /* Class-H Low Power */
+ CLS_AB, /* Class-AB Low HIFI*/
+ CLS_H_LOHIFI, /* LoHIFI */
+ CLS_H_ULP, /* Ultra Low power */
+ CLS_AB_HIFI, /* Class-AB */
+ CLS_NONE, /* None of the above modes */
+};
+
+enum {
+ DAC_GAIN_0DB = 0,
+ DAC_GAIN_0P2DB,
+ DAC_GAIN_0P4DB,
+ DAC_GAIN_0P6DB,
+ DAC_GAIN_0P8DB,
+ DAC_GAIN_M0P2DB,
+ DAC_GAIN_M0P4DB,
+ DAC_GAIN_M0P6DB,
+};
+
+enum {
+ VREF_FILT_R_0OHM = 0,
+ VREF_FILT_R_25KOHM,
+ VREF_FILT_R_50KOHM,
+ VREF_FILT_R_100KOHM,
+};
+
+enum {
+ DELTA_I_0MA,
+ DELTA_I_10MA,
+ DELTA_I_20MA,
+ DELTA_I_30MA,
+ DELTA_I_40MA,
+ DELTA_I_50MA,
+};
+
+struct aqt_imped_val {
+ u32 imped_val;
+ u8 index;
+};
+
+struct aqt_clsh_cdc_data {
+ u8 state;
+ int flyback_users;
+ int buck_users;
+ int clsh_users;
+ int interpolator_modes[AQT_CLSH_STATE_MAX];
+};
+
+struct aqt_reg_mask_val {
+ u16 reg;
+ u8 mask;
+ u8 val;
+};
+
+extern void aqt_clsh_fsm(struct snd_soc_codec *codec,
+ struct aqt_clsh_cdc_data *cdc_clsh_d,
+ u8 clsh_event, u8 req_state,
+ int int_mode);
+
+extern void aqt_clsh_init(struct aqt_clsh_cdc_data *clsh);
+extern int aqt_clsh_get_clsh_state(struct aqt_clsh_cdc_data *clsh);
+extern void aqt_clsh_imped_config(struct snd_soc_codec *codec, int imped,
+ bool reset);
+
+#endif /* _AQT1000_CLSH_H */
diff --git a/asoc/codecs/aqt1000/aqt1000-core.c b/asoc/codecs/aqt1000/aqt1000-core.c
new file mode 100644
index 0000000..e6313c1
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-core.c
@@ -0,0 +1,646 @@
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/ratelimit.h>
+#include <linux/mfd/core.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/debugfs.h>
+#include <linux/i2c.h>
+#include <linux/regmap.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/pm_runtime.h>
+#include <sound/soc.h>
+#include "../msm-cdc-pinctrl.h"
+#include "../msm-cdc-supply.h"
+#include "aqt1000-registers.h"
+#include "aqt1000-internal.h"
+#include "aqt1000.h"
+#include "aqt1000-utils.h"
+#include "aqt1000-irq.h"
+
+static int aqt1000_bringup(struct aqt1000 *aqt)
+{
+ struct aqt1000_pdata *pdata;
+ u8 clk_div = 0, mclk = 1;
+
+ if (!aqt->regmap) {
+ dev_err(aqt->dev, "%s: aqt regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Bringup register write sequence */
+ regmap_update_bits(aqt->regmap, AQT1000_BUCK_5V_CTRL_CCL_1, 0xF0, 0xF0);
+ regmap_update_bits(aqt->regmap, AQT1000_BIAS_CCOMP_FINE_ADJ,
+ 0xF0, 0x90);
+ regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x80, 0x80);
+ regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x40, 0x40);
+
+ /* Added 1msec sleep as per HW requirement */
+ usleep_range(1000, 1010);
+
+ regmap_update_bits(aqt->regmap, AQT1000_ANA_BIAS, 0x40, 0x00);
+
+ clk_div = 0x04; /* Assumption is CLK DIV 2 */
+ pdata = dev_get_platdata(aqt->dev);
+ if (pdata) {
+ if (pdata->mclk_rate == AQT1000_CLK_12P288MHZ)
+ mclk = 0;
+ clk_div = (((pdata->ext_clk_rate / pdata->mclk_rate) >> 1)
+ << 2);
+ }
+ regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CFG_MCLK,
+ 0x03, mclk);
+
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG,
+ 0x0C, clk_div);
+
+ /* Source clock enable */
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, 0x02, 0x02);
+
+ /* Ungate the source clock */
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10);
+
+ /* Set the I2S_HS_CLK reference to CLK DIV 2 */
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG,
+ 0x60, 0x20);
+
+ /* Set the PLL preset to CLK9P6M_IN_12P288M_OUT */
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_PLL_PRESET, 0x0F, 0x02);
+
+ /* Enable clock PLL */
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_PLL_ENABLES,
+ 0x01, 0x01);
+
+ /* Add 100usec delay as per HW requirement */
+ usleep_range(100, 110);
+
+ /* Set AQT to I2S Master */
+ regmap_update_bits(aqt->regmap, AQT1000_I2S_I2S_0_CTL, 0x02, 0x02);
+
+ /* Enable I2S HS clock */
+ regmap_update_bits(aqt->regmap, AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG,
+ 0x01, 0x01);
+
+ regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CFG_MCLK,
+ 0x04, 0x00);
+
+ /* Add 100usec delay as per HW requirement */
+ usleep_range(100, 110);
+ regmap_update_bits(aqt->regmap, AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x01, 0x01);
+ regmap_update_bits(aqt->regmap, AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x01, 0x01);
+ regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG,
+ 0x01, 0x01);
+
+ /* Codec digital reset */
+ regmap_update_bits(aqt->regmap, AQT1000_CHIP_CFG0_RST_CTL, 0x01, 0x01);
+ /* Add 100usec delay as per HW requirement */
+ usleep_range(100, 110);
+
+ return 0;
+}
+
+static int aqt1000_device_init(struct aqt1000 *aqt)
+{
+ int ret = 0;
+
+ mutex_init(&aqt->io_lock);
+ mutex_init(&aqt->xfer_lock);
+ mutex_init(&aqt->cdc_bg_clk_lock);
+ mutex_init(&aqt->master_bias_lock);
+
+ ret = aqt1000_bringup(aqt);
+ if (ret) {
+ ret = -EPROBE_DEFER;
+ goto done;
+ }
+
+ ret = aqt_irq_init(aqt);
+ if (ret)
+ goto done;
+
+ return ret;
+done:
+ mutex_destroy(&aqt->io_lock);
+ mutex_destroy(&aqt->xfer_lock);
+ mutex_destroy(&aqt->cdc_bg_clk_lock);
+ mutex_destroy(&aqt->master_bias_lock);
+ return ret;
+}
+
+static int aqt1000_i2c_write(struct aqt1000 *aqt1000, unsigned short reg,
+ void *val, int bytes)
+{
+ struct i2c_msg *msg;
+ int ret = 0;
+ u8 reg_addr = 0;
+ u8 data[bytes + 1];
+ struct aqt1000_i2c *aqt1000_i2c;
+ u8 *value = (u8 *)val;
+
+ aqt1000_i2c = &aqt1000->i2c_dev;
+ if (aqt1000_i2c == NULL || aqt1000_i2c->client == NULL) {
+ pr_err("%s: Failed to get device info\n", __func__);
+ return -ENODEV;
+ }
+ reg_addr = (u8)reg;
+ msg = &aqt1000_i2c->xfer_msg[0];
+ msg->addr = aqt1000_i2c->client->addr;
+ msg->len = bytes + 1;
+ msg->flags = 0;
+ data[0] = reg;
+ data[1] = *value;
+ msg->buf = data;
+ ret = i2c_transfer(aqt1000_i2c->client->adapter,
+ aqt1000_i2c->xfer_msg, 1);
+ /* Try again if the write fails */
+ if (ret != 1) {
+ ret = i2c_transfer(aqt1000_i2c->client->adapter,
+ aqt1000_i2c->xfer_msg, 1);
+ if (ret != 1) {
+ dev_err(aqt1000->dev,
+ "%s: I2C write failed, reg: 0x%x ret: %d\n",
+ __func__, reg, ret);
+ return ret;
+ }
+ }
+ dev_dbg(aqt1000->dev, "%s: write success register = %x val = %x\n",
+ __func__, reg, data[1]);
+ return 0;
+}
+
+static int aqt1000_i2c_read(struct aqt1000 *aqt1000, unsigned short reg,
+ void *dst, int bytes)
+{
+ struct i2c_msg *msg;
+ int ret = 0;
+ u8 reg_addr = 0;
+ struct aqt1000_i2c *aqt1000_i2c;
+ u8 i = 0;
+ unsigned char *dest = (unsigned char *)dst;
+
+ aqt1000_i2c = &aqt1000->i2c_dev;
+ if (aqt1000_i2c == NULL || aqt1000_i2c->client == NULL) {
+ pr_err("%s: Failed to get device info\n", __func__);
+ return -ENODEV;
+ }
+ for (i = 0; i < bytes; i++) {
+ reg_addr = (u8)reg++;
+ msg = &aqt1000_i2c->xfer_msg[0];
+ msg->addr = aqt1000_i2c->client->addr;
+ msg->len = 1;
+ msg->flags = 0;
+ msg->buf = ®_addr;
+
+ msg = &aqt1000_i2c->xfer_msg[1];
+ msg->addr = aqt1000_i2c->client->addr;
+ msg->len = 1;
+ msg->flags = I2C_M_RD;
+ msg->buf = dest++;
+ ret = i2c_transfer(aqt1000_i2c->client->adapter,
+ aqt1000_i2c->xfer_msg, 2);
+
+ /* Try again if read fails first time */
+ if (ret != 2) {
+ ret = i2c_transfer(aqt1000_i2c->client->adapter,
+ aqt1000_i2c->xfer_msg, 2);
+ if (ret != 2) {
+ dev_err(aqt1000->dev,
+ "%s: I2C read failed, reg: 0x%x\n",
+ __func__, reg);
+ return ret;
+ }
+ }
+ }
+ return 0;
+}
+
+static int aqt1000_reset(struct device *dev)
+{
+ struct aqt1000 *aqt1000;
+ int rc = 0;
+
+ if (!dev)
+ return -ENODEV;
+
+ aqt1000 = dev_get_drvdata(dev);
+ if (!aqt1000)
+ return -EINVAL;
+
+ if (!aqt1000->aqt_rst_np) {
+ dev_err(dev, "%s: reset gpio device node not specified\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (!msm_cdc_pinctrl_get_state(aqt1000->aqt_rst_np)) {
+ rc = msm_cdc_pinctrl_select_sleep_state(aqt1000->aqt_rst_np);
+ if (rc) {
+ dev_err(dev, "%s: aqt sleep state request fail!\n",
+ __func__);
+ return rc;
+ }
+
+ /* 20ms sleep required after pulling the reset gpio to LOW */
+ msleep(20);
+
+ rc = msm_cdc_pinctrl_select_active_state(aqt1000->aqt_rst_np);
+ if (rc) {
+ dev_err(dev,
+ "%s: aqt active state request fail, ret: %d\n",
+ __func__, rc);
+ return rc;
+ }
+ /* 20ms sleep required after pulling the reset gpio to HIGH */
+ msleep(20);
+ }
+
+ return rc;
+}
+
+static int aqt1000_read_of_property_u32(struct device *dev, const char *name,
+ u32 *val)
+{
+ int rc = 0;
+
+ rc = of_property_read_u32(dev->of_node, name, val);
+ if (rc)
+ dev_err(dev, "%s: Looking up %s property in node %s failed",
+ __func__, name, dev->of_node->full_name);
+
+ return rc;
+}
+
+static void aqt1000_dt_parse_micbias_info(struct device *dev,
+ struct aqt1000_micbias_setting *mb)
+{
+ u32 prop_val;
+ int rc;
+
+ if (of_find_property(dev->of_node, "qcom,cdc-micbias-ldoh-v", NULL)) {
+ rc = aqt1000_read_of_property_u32(dev,
+ "qcom,cdc-micbias-ldoh-v",
+ &prop_val);
+ if (!rc)
+ mb->ldoh_v = (u8)prop_val;
+ }
+
+ /* MB1 */
+ if (of_find_property(dev->of_node, "qcom,cdc-micbias-cfilt1-mv",
+ NULL)) {
+ rc = aqt1000_read_of_property_u32(dev,
+ "qcom,cdc-micbias-cfilt1-mv",
+ &prop_val);
+ if (!rc)
+ mb->cfilt1_mv = prop_val;
+
+ rc = aqt1000_read_of_property_u32(dev,
+ "qcom,cdc-micbias1-cfilt-sel",
+ &prop_val);
+ if (!rc)
+ mb->bias1_cfilt_sel = (u8)prop_val;
+
+ } else if (of_find_property(dev->of_node, "qcom,cdc-micbias1-mv",
+ NULL)) {
+ rc = aqt1000_read_of_property_u32(dev,
+ "qcom,cdc-micbias1-mv",
+ &prop_val);
+ if (!rc)
+ mb->micb1_mv = prop_val;
+ } else {
+ dev_info(dev, "%s: Micbias1 DT property not found\n",
+ __func__);
+ }
+
+ /* Print micbias info */
+ dev_dbg(dev, "%s: ldoh_v %u cfilt1_mv %u micb1_mv %u \n", __func__,
+ (u32)mb->ldoh_v, (u32)mb->cfilt1_mv, (u32)mb->micb1_mv);
+}
+
+static struct aqt1000_pdata *aqt1000_populate_dt_data(struct device *dev)
+{
+ struct aqt1000_pdata *pdata;
+ u32 prop_val;
+
+ if (!dev || !dev->of_node)
+ return NULL;
+
+ pdata = devm_kzalloc(dev, sizeof(struct aqt1000_pdata),
+ GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ /* Parse power supplies */
+ msm_cdc_get_power_supplies(dev, &pdata->regulator,
+ &pdata->num_supplies);
+ if (!pdata->regulator || (pdata->num_supplies <= 0)) {
+ dev_err(dev, "%s: no power supplies defined for codec\n",
+ __func__);
+ goto err_power_sup;
+ }
+
+ /* Parse micbias info */
+ aqt1000_dt_parse_micbias_info(dev, &pdata->micbias);
+
+ pdata->aqt_rst_np = of_parse_phandle(dev->of_node,
+ "qcom,aqt-rst-gpio-node", 0);
+ if (!pdata->aqt_rst_np) {
+ dev_err(dev, "%s: Looking up %s property in node %s failed\n",
+ __func__, "qcom,aqt-rst-gpio-node",
+ dev->of_node->full_name);
+ goto err_parse_dt_prop;
+ }
+
+ if (!(aqt1000_read_of_property_u32(dev, "qcom,cdc-ext-clk-rate",
+ &prop_val)))
+ pdata->ext_clk_rate = prop_val;
+ if (pdata->ext_clk_rate != AQT1000_CLK_24P576MHZ &&
+ pdata->ext_clk_rate != AQT1000_CLK_19P2MHZ &&
+ pdata->ext_clk_rate != AQT1000_CLK_12P288MHZ) {
+ /* Use the default ext_clk_rate if the DT value is wrong */
+ pdata->ext_clk_rate = AQT1000_CLK_9P6MHZ;
+ }
+
+ prop_val = 0;
+ if (!(aqt1000_read_of_property_u32(dev, "qcom,cdc-mclk-clk-rate",
+ &prop_val)))
+ pdata->mclk_rate = prop_val;
+
+ if (pdata->mclk_rate != AQT1000_CLK_9P6MHZ &&
+ pdata->mclk_rate != AQT1000_CLK_12P288MHZ) {
+ dev_err(dev, "%s: Invalid mclk_rate = %u\n", __func__,
+ pdata->mclk_rate);
+ goto err_parse_dt_prop;
+ }
+ if (pdata->ext_clk_rate % pdata->mclk_rate) {
+ dev_err(dev,
+ "%s: Invalid clock group, ext_clk = %d mclk = %d\n",
+ __func__, pdata->ext_clk_rate, pdata->mclk_rate);
+ goto err_parse_dt_prop;
+ }
+
+ pdata->irq_gpio = of_get_named_gpio(dev->of_node,
+ "qcom,gpio-connect", 0);
+ if (!gpio_is_valid(pdata->irq_gpio)) {
+ dev_err(dev, "%s: TLMM connect gpio not found\n", __func__);
+ goto err_parse_dt_prop;
+ }
+
+ return pdata;
+
+err_parse_dt_prop:
+ devm_kfree(dev, pdata->regulator);
+ pdata->regulator = NULL;
+ pdata->num_supplies = 0;
+err_power_sup:
+ devm_kfree(dev, pdata);
+ return NULL;
+}
+
+static int aqt1000_bringdown(struct device *dev)
+{
+ /* No sequence for teardown */
+
+ return 0;
+}
+
+static void aqt1000_device_exit(struct aqt1000 *aqt)
+{
+ aqt_irq_exit(aqt);
+ aqt1000_bringdown(aqt->dev);
+ mutex_destroy(&aqt->io_lock);
+ mutex_destroy(&aqt->xfer_lock);
+ mutex_destroy(&aqt->cdc_bg_clk_lock);
+ mutex_destroy(&aqt->master_bias_lock);
+}
+
+static int aqt1000_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct aqt1000 *aqt1000 = NULL;
+ struct aqt1000_pdata *pdata = NULL;
+ int ret = 0;
+
+ pdata = aqt1000_populate_dt_data(&client->dev);
+ if (!pdata) {
+ dev_err(&client->dev,
+ "%s: Fail to obtain pdata from device tree\n",
+ __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+ client->dev.platform_data = pdata;
+
+ aqt1000 = devm_kzalloc(&client->dev, sizeof(struct aqt1000),
+ GFP_KERNEL);
+ if (!aqt1000) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+
+ aqt1000->regmap = aqt1000_regmap_init(&client->dev,
+ &aqt1000_regmap_config);
+ if (IS_ERR(aqt1000->regmap)) {
+ ret = PTR_ERR(aqt1000->regmap);
+ dev_err(&client->dev,
+ "%s: Failed to init register map: %d\n",
+ __func__, ret);
+ goto fail;
+ }
+ aqt1000->aqt_rst_np = pdata->aqt_rst_np;
+ if (!aqt1000->aqt_rst_np) {
+ dev_err(&client->dev, "%s: pinctrl not used for rst_n\n",
+ __func__);
+ ret = -EINVAL;
+ goto fail;
+ }
+
+ if (i2c_check_functionality(client->adapter,
+ I2C_FUNC_I2C) == 0) {
+ dev_dbg(&client->dev, "%s: can't talk I2C?\n", __func__);
+ ret = -EIO;
+ goto fail;
+ }
+ dev_set_drvdata(&client->dev, aqt1000);
+ aqt1000->dev = &client->dev;
+ aqt1000->dev_up = true;
+ aqt1000->mclk_rate = pdata->mclk_rate;
+ aqt1000->irq = client->irq;
+
+ aqt1000->num_of_supplies = pdata->num_supplies;
+ ret = msm_cdc_init_supplies(aqt1000->dev, &aqt1000->supplies,
+ pdata->regulator,
+ pdata->num_supplies);
+ if (!aqt1000->supplies) {
+ dev_err(aqt1000->dev, "%s: Cannot init aqt supplies\n",
+ __func__);
+ goto err_codec;
+ }
+ ret = msm_cdc_enable_static_supplies(aqt1000->dev,
+ aqt1000->supplies,
+ pdata->regulator,
+ pdata->num_supplies);
+ if (ret) {
+ dev_err(aqt1000->dev, "%s: aqt static supply enable failed!\n",
+ __func__);
+ goto err_codec;
+ }
+ /* 5 usec sleep is needed as per HW requirement */
+ usleep_range(5, 10);
+
+ ret = aqt1000_reset(aqt1000->dev);
+ if (ret) {
+ dev_err(aqt1000->dev, "%s: Codec reset failed\n", __func__);
+ goto err_supplies;
+ }
+
+ aqt1000->i2c_dev.client = client;
+ aqt1000->read_dev = aqt1000_i2c_read;
+ aqt1000->write_dev = aqt1000_i2c_write;
+
+ ret = aqt1000_device_init(aqt1000);
+ if (ret) {
+ pr_err("%s: error, initializing device failed (%d)\n",
+ __func__, ret);
+ goto err_supplies;
+ }
+
+ pm_runtime_set_active(aqt1000->dev);
+ pm_runtime_enable(aqt1000->dev);
+
+ ret = aqt_register_codec(&client->dev);
+ if (ret) {
+ dev_err(aqt1000->dev, "%s: Codec registration failed\n",
+ __func__);
+ goto err_cdc_register;
+ }
+
+ return ret;
+
+err_cdc_register:
+ pm_runtime_disable(aqt1000->dev);
+ aqt1000_device_exit(aqt1000);
+err_supplies:
+ msm_cdc_release_supplies(aqt1000->dev, aqt1000->supplies,
+ pdata->regulator,
+ pdata->num_supplies);
+ pdata->regulator = NULL;
+ pdata->num_supplies = 0;
+err_codec:
+ devm_kfree(&client->dev, aqt1000);
+ dev_set_drvdata(&client->dev, NULL);
+fail:
+ return ret;
+}
+
+static int aqt1000_i2c_remove(struct i2c_client *client)
+{
+ struct aqt1000 *aqt;
+ struct aqt1000_pdata *pdata = client->dev.platform_data;
+
+ aqt = dev_get_drvdata(&client->dev);
+
+ pm_runtime_disable(aqt->dev);
+ msm_cdc_release_supplies(aqt->dev, aqt->supplies,
+ pdata->regulator,
+ pdata->num_supplies);
+ aqt1000_device_exit(aqt);
+ dev_set_drvdata(&client->dev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int aqt1000_runtime_resume(struct device *dev)
+{
+ dev_dbg(dev, "%s system resume\n", __func__);
+
+ return 0;
+}
+
+static int aqt1000_runtime_suspend(struct device *dev)
+{
+ dev_dbg(dev, "%s system suspend\n", __func__);
+
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_PM_SLEEP
+static int aqt1000_i2c_resume(struct device *dev)
+{
+ pr_debug("%s system resume\n", __func__);
+ return 0;
+}
+
+static int aqt1000_i2c_suspend(struct device *dev)
+{
+ pr_debug("%s system suspend\n", __func__);
+ return 0;
+}
+#endif
+
+static struct i2c_device_id aqt1000_id_table[] = {
+ {"aqt1000-i2c", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, aqt1000_id_table);
+
+static const struct dev_pm_ops aqt1000_i2c_pm_ops = {
+ SET_RUNTIME_PM_OPS(aqt1000_runtime_suspend,
+ aqt1000_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(aqt1000_i2c_suspend,
+ aqt1000_i2c_resume)
+};
+
+static const struct of_device_id aqt_match_table[] = {
+ {.compatible = "qcom,aqt1000-i2c-codec"},
+ {}
+};
+MODULE_DEVICE_TABLE(of, aqt_match_table);
+
+static struct i2c_driver aqt1000_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "aqt1000-i2c-codec",
+#ifdef CONFIG_PM_SLEEP
+ .pm = &aqt1000_i2c_pm_ops,
+#endif
+ .of_match_table = aqt_match_table,
+ },
+ .id_table = aqt1000_id_table,
+ .probe = aqt1000_i2c_probe,
+ .remove = aqt1000_i2c_remove,
+};
+
+static int __init aqt1000_init(void)
+{
+ return i2c_add_driver(&aqt1000_i2c_driver);
+}
+module_init(aqt1000_init);
+
+static void __exit aqt1000_exit(void)
+{
+ i2c_del_driver(&aqt1000_i2c_driver);
+}
+module_exit(aqt1000_exit);
+
+MODULE_DESCRIPTION("AQT1000 Codec driver");
+MODULE_LICENSE("GPL v2");
diff --git a/asoc/codecs/aqt1000/aqt1000-internal.h b/asoc/codecs/aqt1000/aqt1000-internal.h
new file mode 100644
index 0000000..19b4b57
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-internal.h
@@ -0,0 +1,170 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AQT1000_INTERNAL_H
+#define _AQT1000_INTERNAL_H
+
+#include <linux/types.h>
+#include <linux/regmap.h>
+#include <sound/soc.h>
+
+#define AQT1000_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
+ SNDRV_PCM_RATE_384000)
+/* Fractional Rates */
+#define AQT1000_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_176400)
+
+#define AQT1000_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+#define AQT1000_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+#define AQT1000_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE)
+
+/* Macros for packing register writes into a U32 */
+#define AQT1000_PACKED_REG_SIZE sizeof(u32)
+#define AQT1000_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \
+ do { \
+ ((reg) = ((packed >> 16) & (0xffff))); \
+ ((mask) = ((packed >> 8) & (0xff))); \
+ ((val) = ((packed) & (0xff))); \
+ } while (0)
+
+#define STRING(name) #name
+#define AQT_DAPM_ENUM(name, reg, offset, text) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+ SOC_DAPM_ENUM(STRING(name), name##_enum)
+
+#define AQT_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+ SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
+
+#define AQT_DAPM_MUX(name, shift, kctl) \
+ SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
+
+
+#define AQT1000_INTERP_MUX_NUM_INPUTS 3
+#define AQT1000_RX_PATH_CTL_OFFSET 20
+
+#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
+
+#define AQT1000_REG_BITS 8
+#define AQT1000_MAX_VALID_ADC_MUX 3
+
+#define AQT1000_AMIC_PWR_LEVEL_LP 0
+#define AQT1000_AMIC_PWR_LEVEL_DEFAULT 1
+#define AQT1000_AMIC_PWR_LEVEL_HP 2
+#define AQT1000_AMIC_PWR_LVL_MASK 0x60
+#define AQT1000_AMIC_PWR_LVL_SHIFT 0x5
+
+#define AQT1000_DEC_PWR_LVL_MASK 0x06
+#define AQT1000_DEC_PWR_LVL_DF 0x00
+#define AQT1000_DEC_PWR_LVL_LP 0x02
+#define AQT1000_DEC_PWR_LVL_HP 0x04
+#define AQT1000_STRING_LEN 100
+
+#define AQT1000_CDC_SIDETONE_IIR_COEFF_MAX 5
+
+#define AQT1000_MAX_MICBIAS 1
+#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
+
+#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
+#define CF_MIN_3DB_4HZ 0x0
+#define CF_MIN_3DB_75HZ 0x1
+#define CF_MIN_3DB_150HZ 0x2
+
+enum {
+ AUDIO_NOMINAL,
+ HPH_PA_DELAY,
+ CLSH_Z_CONFIG,
+ ANC_MIC_AMIC1,
+ ANC_MIC_AMIC2,
+ ANC_MIC_AMIC3,
+};
+
+enum {
+ INTn_1_INP_SEL_ZERO = 0,
+ INTn_1_INP_SEL_DEC0,
+ INTn_1_INP_SEL_DEC1,
+ INTn_1_INP_SEL_IIR0,
+ INTn_1_INP_SEL_IIR1,
+ INTn_1_INP_SEL_RX0,
+ INTn_1_INP_SEL_RX1,
+};
+
+enum {
+ INTn_2_INP_SEL_ZERO = 0,
+ INTn_2_INP_SEL_RX0,
+ INTn_2_INP_SEL_RX1,
+ INTn_2_INP_SEL_PROXIMITY,
+};
+
+/* Codec supports 2 IIR filters */
+enum {
+ IIR0 = 0,
+ IIR1,
+ IIR_MAX,
+};
+
+enum {
+ ASRC_IN_HPHL,
+ ASRC_IN_HPHR,
+ ASRC_INVALID,
+};
+
+enum {
+ CONV_88P2K_TO_384K,
+ CONV_96K_TO_352P8K,
+ CONV_352P8K_TO_384K,
+ CONV_384K_TO_352P8K,
+ CONV_384K_TO_384K,
+ CONV_96K_TO_384K,
+};
+
+enum aqt_notify_event {
+ AQT_EVENT_INVALID,
+ /* events for micbias ON and OFF */
+ AQT_EVENT_PRE_MICBIAS_1_OFF,
+ AQT_EVENT_POST_MICBIAS_1_OFF,
+ AQT_EVENT_PRE_MICBIAS_1_ON,
+ AQT_EVENT_POST_MICBIAS_1_ON,
+ AQT_EVENT_PRE_DAPM_MICBIAS_1_OFF,
+ AQT_EVENT_POST_DAPM_MICBIAS_1_OFF,
+ AQT_EVENT_PRE_DAPM_MICBIAS_1_ON,
+ AQT_EVENT_POST_DAPM_MICBIAS_1_ON,
+ /* events for PA ON and OFF */
+ AQT_EVENT_PRE_HPHL_PA_ON,
+ AQT_EVENT_POST_HPHL_PA_OFF,
+ AQT_EVENT_PRE_HPHR_PA_ON,
+ AQT_EVENT_POST_HPHR_PA_OFF,
+ AQT_EVENT_PRE_HPHL_PA_OFF,
+ AQT_EVENT_PRE_HPHR_PA_OFF,
+ AQT_EVENT_OCP_OFF,
+ AQT_EVENT_OCP_ON,
+ AQT_EVENT_LAST,
+};
+
+struct interp_sample_rate {
+ int sample_rate;
+ int rate_val;
+};
+
+extern struct regmap_config aqt1000_regmap_config;
+extern int aqt_register_codec(struct device *dev);
+
+#endif /* _AQT1000_INTERNAL_H */
diff --git a/asoc/codecs/aqt1000/aqt1000-irq.c b/asoc/codecs/aqt1000/aqt1000-irq.c
new file mode 100644
index 0000000..321b490
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-irq.c
@@ -0,0 +1,289 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/slab.h>
+#include <linux/ratelimit.h>
+#include <linux/irqdomain.h>
+#include <linux/regmap.h>
+#include <linux/pm_runtime.h>
+
+#include "pdata.h"
+#include "aqt1000.h"
+
+#include "aqt1000-registers.h"
+#include "aqt1000-irq.h"
+
+static const struct regmap_irq aqt1000_irqs[AQT1000_NUM_IRQS] = {
+ REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET, 0, 0x01),
+ REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_BUTTON_PRESS_DET, 0, 0x02),
+ REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_ELECT_INS_REM_DET, 0, 0x04),
+ REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET, 0, 0x08),
+ REGMAP_IRQ_REG(AQT1000_IRQ_MBHC_SW_DET, 0, 0x10),
+ REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_OCPL_FAULT, 0, 0x20),
+ REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_OCPR_FAULT, 0, 0x40),
+ REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_CNPL_COMPLETE, 0, 0x80),
+ REGMAP_IRQ_REG(AQT1000_IRQ_HPH_PA_CNPR_COMPLETE, 1, 0x01),
+ REGMAP_IRQ_REG(AQT1000_CDC_HPHL_SURGE, 1, 0x02),
+ REGMAP_IRQ_REG(AQT1000_CDC_HPHR_SURGE, 1, 0x04),
+};
+
+static const struct regmap_irq_chip aqt_regmap_irq_chip = {
+ .name = "AQT1000",
+ .irqs = aqt1000_irqs,
+ .num_irqs = ARRAY_SIZE(aqt1000_irqs),
+ .num_regs = 2,
+ .status_base = AQT1000_INTR_CTRL_INT_STATUS_2,
+ .mask_base = AQT1000_INTR_CTRL_INT_MASK_2,
+ .unmask_base = AQT1000_INTR_CTRL_INT_CLEAR_2,
+ .ack_base = AQT1000_INTR_CTRL_INT_STATUS_2,
+ .runtime_pm = true,
+};
+
+static int aqt_map_irq(struct aqt1000 *aqt, int irq)
+{
+ return regmap_irq_get_virq(aqt->irq_chip, irq);
+}
+
+/**
+ * aqt_request_irq: Request a thread handler for the given IRQ
+ * @aqt: pointer to aqt1000 structure
+ * @irq: irq number
+ * @name: name for the IRQ thread
+ * @handler: irq handler
+ * @data: data pointer
+ *
+ * Returns 0 on success or error on failure
+ */
+int aqt_request_irq(struct aqt1000 *aqt, int irq, const char *name,
+ irq_handler_t handler, void *data)
+{
+ irq = aqt_map_irq(aqt, irq);
+ if (irq < 0)
+ return irq;
+
+ return request_threaded_irq(irq, NULL, handler,
+ IRQF_ONESHOT | IRQF_TRIGGER_RISING,
+ name, data);
+}
+EXPORT_SYMBOL(aqt_request_irq);
+
+/**
+ * aqt_free_irq: Free the IRQ resources allocated during request_irq
+ * @aqt: pointer to aqt1000 structure
+ * @irq: irq number
+ * @data: data pointer
+ */
+void aqt_free_irq(struct aqt1000 *aqt, int irq, void *data)
+{
+ irq = aqt_map_irq(aqt, irq);
+ if (irq < 0)
+ return;
+
+ free_irq(irq, data);
+}
+EXPORT_SYMBOL(aqt_free_irq);
+
+/**
+ * aqt_enable_irq: Enable the given IRQ
+ * @aqt: pointer to aqt1000 structure
+ * @irq: irq number
+ */
+void aqt_enable_irq(struct aqt1000 *aqt, int irq)
+{
+ if (aqt)
+ enable_irq(aqt_map_irq(aqt, irq));
+}
+EXPORT_SYMBOL(aqt_enable_irq);
+
+/**
+ * aqt_disable_irq: Disable the given IRQ
+ * @aqt: pointer to aqt1000 structure
+ * @irq: irq number
+ */
+void aqt_disable_irq(struct aqt1000 *aqt, int irq)
+{
+ if (aqt)
+ disable_irq(aqt_map_irq(aqt, irq));
+}
+EXPORT_SYMBOL(aqt_disable_irq);
+
+static irqreturn_t aqt_irq_thread(int irq, void *data)
+{
+ int ret = 0;
+ u8 sts[2];
+ struct aqt1000 *aqt = data;
+ int num_irq_regs = aqt->num_irq_regs;
+ struct aqt1000_pdata *pdata;
+
+ pdata = dev_get_platdata(aqt->dev);
+
+ memset(sts, 0, sizeof(sts));
+ ret = regmap_bulk_read(aqt->regmap, AQT1000_INTR_CTRL_INT_STATUS_2,
+ sts, num_irq_regs);
+ if (ret < 0) {
+ dev_err(aqt->dev, "%s: Failed to read intr status: %d\n",
+ __func__, ret);
+ } else if (ret == 0) {
+ while (gpio_get_value_cansleep(pdata->irq_gpio))
+ handle_nested_irq(irq_find_mapping(aqt->virq, 0));
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void aqt_irq_disable(struct irq_data *data)
+{
+}
+
+static void aqt_irq_enable(struct irq_data *data)
+{
+}
+
+static struct irq_chip aqt_irq_chip = {
+ .name = "AQT",
+ .irq_disable = aqt_irq_disable,
+ .irq_enable = aqt_irq_enable,
+};
+
+static struct lock_class_key aqt_irq_lock_class;
+
+static int aqt_irq_map(struct irq_domain *irqd, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct aqt1000 *data = irqd->host_data;
+
+ irq_set_chip_data(virq, data);
+ irq_set_chip_and_handler(virq, &aqt_irq_chip, handle_simple_irq);
+ irq_set_lockdep_class(virq, &aqt_irq_lock_class);
+ irq_set_nested_thread(virq, 1);
+ irq_set_noprobe(virq);
+
+ return 0;
+}
+
+static const struct irq_domain_ops aqt_domain_ops = {
+ .map = aqt_irq_map,
+ .xlate = irq_domain_xlate_twocell,
+};
+
+/**
+ * aqt_irq_init: Initializes IRQ module
+ * @aqt: pointer to aqt1000 structure
+ *
+ * Returns 0 on success or error on failure
+ */
+int aqt_irq_init(struct aqt1000 *aqt)
+{
+ int i, ret;
+ unsigned int flags = IRQF_ONESHOT;
+ struct irq_data *irq_data;
+ struct aqt1000_pdata *pdata;
+
+ if (!aqt) {
+ pr_err("%s: Null pointer handle\n", __func__);
+ return -EINVAL;
+ }
+
+ pdata = dev_get_platdata(aqt->dev);
+ if (!pdata) {
+ dev_err(aqt->dev, "%s: Invalid platform data\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Select default if not defined in DT */
+ flags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
+ if (pdata->irq_flags)
+ flags = pdata->irq_flags;
+
+ if (pdata->irq_gpio) {
+ aqt->irq = gpio_to_irq(pdata->irq_gpio);
+ ret = devm_gpio_request_one(aqt->dev, pdata->irq_gpio,
+ GPIOF_IN, "AQT IRQ");
+ if (ret) {
+ dev_err(aqt->dev, "%s: Failed to request gpio %d\n",
+ __func__, ret);
+ pdata->irq_gpio = 0;
+ return ret;
+ }
+ }
+
+ irq_data = irq_get_irq_data(aqt->irq);
+ if (!irq_data) {
+ dev_err(aqt->dev, "%s: Invalid IRQ: %d\n",
+ __func__, aqt->irq);
+ return -EINVAL;
+ }
+
+ aqt->num_irq_regs = aqt_regmap_irq_chip.num_regs;
+ for (i = 0; i < aqt->num_irq_regs; i++) {
+ regmap_write(aqt->regmap,
+ (AQT1000_INTR_CTRL_INT_TYPE_2 + i), 0);
+ }
+
+ aqt->virq = irq_domain_add_linear(NULL, 1, &aqt_domain_ops, aqt);
+ if (!aqt->virq) {
+ dev_err(aqt->dev, "%s: Failed to add IRQ domain\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = regmap_add_irq_chip(aqt->regmap,
+ irq_create_mapping(aqt->virq, 0),
+ IRQF_ONESHOT, 0, &aqt_regmap_irq_chip,
+ &aqt->irq_chip);
+ if (ret) {
+ dev_err(aqt->dev, "%s: Failed to add IRQs: %d\n",
+ __func__, ret);
+ goto err;
+ }
+
+ ret = request_threaded_irq(aqt->irq, NULL, aqt_irq_thread, flags,
+ "aqt", aqt);
+ if (ret) {
+ dev_err(aqt->dev, "%s: failed to register irq: %d\n",
+ __func__, ret);
+ goto err_irq;
+ }
+
+ return 0;
+
+err_irq:
+ regmap_del_irq_chip(irq_create_mapping(aqt->virq, 1), aqt->irq_chip);
+err:
+ return ret;
+}
+EXPORT_SYMBOL(aqt_irq_init);
+
+/**
+ * aqt_irq_exit: Uninitialize regmap IRQ and free IRQ resources
+ * @aqt: pointer to aqt1000 structure
+ *
+ * Returns 0 on success or error on failure
+ */
+int aqt_irq_exit(struct aqt1000 *aqt)
+{
+ if (!aqt) {
+ pr_err("%s: Null pointer handle\n", __func__);
+ return -EINVAL;
+ }
+ regmap_del_irq_chip(irq_create_mapping(aqt->virq, 1), aqt->irq_chip);
+ free_irq(aqt->irq, aqt);
+
+ return 0;
+}
+EXPORT_SYMBOL(aqt_irq_exit);
diff --git a/asoc/codecs/aqt1000/aqt1000-irq.h b/asoc/codecs/aqt1000/aqt1000-irq.h
new file mode 100644
index 0000000..60be49c
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-irq.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __AQT1000_IRQ_H_
+#define __AQT1000_IRQ_H_
+
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+
+enum {
+ /* INTR_CTRL_INT_MASK_2 */
+ AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET = 0,
+ AQT1000_IRQ_MBHC_BUTTON_PRESS_DET,
+ AQT1000_IRQ_MBHC_ELECT_INS_REM_DET,
+ AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
+ AQT1000_IRQ_MBHC_SW_DET,
+ AQT1000_IRQ_HPH_PA_OCPL_FAULT,
+ AQT1000_IRQ_HPH_PA_OCPR_FAULT,
+ AQT1000_IRQ_HPH_PA_CNPL_COMPLETE,
+
+ /* INTR_CTRL_INT_MASK_3 */
+ AQT1000_IRQ_HPH_PA_CNPR_COMPLETE,
+ AQT1000_CDC_HPHL_SURGE,
+ AQT1000_CDC_HPHR_SURGE,
+ AQT1000_NUM_IRQS,
+};
+
+int aqt_request_irq(struct aqt1000 *aqt, int irq, const char *name,
+ irq_handler_t handler, void *data);
+void aqt_free_irq(struct aqt1000 *aqt, int irq, void *data);
+int aqt_irq_init(struct aqt1000 *aqt);
+int aqt_irq_exit(struct aqt1000 *aqt);
+void aqt_enable_irq(struct aqt1000 *aqt, int irq);
+void aqt_disable_irq(struct aqt1000 *aqt, int irq);
+
+#endif /* __AQT1000_IRQ_H_ */
diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.c b/asoc/codecs/aqt1000/aqt1000-mbhc.c
new file mode 100644
index 0000000..24f14a4
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-mbhc.c
@@ -0,0 +1,1058 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include "aqt1000.h"
+#include "aqt1000-api.h"
+#include "aqt1000-mbhc.h"
+#include "aqt1000-registers.h"
+#include "aqt1000-irq.h"
+#include "pdata.h"
+#include "../wcdcal-hwdep.h"
+#include "../wcd-mbhc-v2-api.h"
+
+#define AQT_ZDET_SUPPORTED true
+/* Z value defined in milliohm */
+#define AQT_ZDET_VAL_32 32000
+#define AQT_ZDET_VAL_400 400000
+#define AQT_ZDET_VAL_1200 1200000
+#define AQT_ZDET_VAL_100K 100000000
+/* Z floating defined in ohms */
+#define AQT_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE
+
+#define AQT_ZDET_NUM_MEASUREMENTS 900
+#define AQT_MBHC_GET_C1(c) ((c & 0xC000) >> 14)
+#define AQT_MBHC_GET_X1(x) (x & 0x3FFF)
+/* Z value compared in milliOhm */
+#define AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
+#define AQT_MBHC_ZDET_CONST (86 * 16384)
+#define AQT_MBHC_MOISTURE_RREF R_24_KOHM
+
+static struct wcd_mbhc_register
+ wcd_mbhc_registers[WCD_MBHC_REG_FUNC_MAX] = {
+ WCD_MBHC_REGISTER("WCD_MBHC_L_DET_EN",
+ AQT1000_ANA_MBHC_MECH, 0x80, 7, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_GND_DET_EN",
+ AQT1000_ANA_MBHC_MECH, 0x40, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_MECH_DETECTION_TYPE",
+ AQT1000_ANA_MBHC_MECH, 0x20, 5, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_MIC_CLAMP_CTL",
+ AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x30, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ELECT_DETECTION_TYPE",
+ AQT1000_ANA_MBHC_ELECT, 0x08, 3, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_CTRL",
+ AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, 0x1F, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL",
+ AQT1000_ANA_MBHC_MECH, 0x04, 2, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PLUG_TYPE",
+ AQT1000_ANA_MBHC_MECH, 0x10, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_GND_PLUG_TYPE",
+ AQT1000_ANA_MBHC_MECH, 0x08, 3, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_SW_HPH_LP_100K_TO_GND",
+ AQT1000_ANA_MBHC_MECH, 0x01, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ELECT_SCHMT_ISRC",
+ AQT1000_ANA_MBHC_ELECT, 0x06, 1, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_FSM_EN",
+ AQT1000_ANA_MBHC_ELECT, 0x80, 7, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_INSREM_DBNC",
+ AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x0F, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_BTN_DBNC",
+ AQT1000_MBHC_NEW_CTL_1, 0x03, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HS_VREF",
+ AQT1000_MBHC_NEW_CTL_2, 0x03, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HS_COMP_RESULT",
+ AQT1000_ANA_MBHC_RESULT_3, 0x08, 3, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_MIC_SCHMT_RESULT",
+ AQT1000_ANA_MBHC_RESULT_3, 0x20, 5, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHL_SCHMT_RESULT",
+ AQT1000_ANA_MBHC_RESULT_3, 0x80, 7, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHR_SCHMT_RESULT",
+ AQT1000_ANA_MBHC_RESULT_3, 0x40, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_OCP_FSM_EN",
+ AQT1000_HPH_OCP_CTL, 0x10, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_BTN_RESULT",
+ AQT1000_ANA_MBHC_RESULT_3, 0x07, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_BTN_ISRC_CTL",
+ AQT1000_ANA_MBHC_ELECT, 0x70, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ELECT_RESULT",
+ AQT1000_ANA_MBHC_RESULT_3, 0xFF, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_MICB_CTRL",
+ AQT1000_ANA_MICB1, 0xC0, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPH_CNP_WG_TIME",
+ AQT1000_HPH_CNP_WG_TIME, 0xFF, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHR_PA_EN",
+ AQT1000_ANA_HPH, 0x40, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHL_PA_EN",
+ AQT1000_ANA_HPH, 0x80, 7, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPH_PA_EN",
+ AQT1000_ANA_HPH, 0xC0, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
+ AQT1000_ANA_MBHC_RESULT_3, 0x10, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_PULLDOWN_CTRL",
+ 0, 0, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ANC_DET_EN",
+ AQT1000_MBHC_CTL_BCS, 0x02, 1, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_FSM_STATUS",
+ AQT1000_MBHC_NEW_FSM_STATUS, 0x01, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
+ AQT1000_MBHC_NEW_CTL_2, 0x70, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN",
+ AQT1000_HPH_L_TEST, 0x01, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN",
+ AQT1000_HPH_R_TEST, 0x01, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_STATUS",
+ AQT1000_INTR_CTRL_INT_STATUS_2, 0x20, 5, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_STATUS",
+ AQT1000_INTR_CTRL_INT_STATUS_2, 0x40, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ADC_EN",
+ AQT1000_MBHC_NEW_CTL_1, 0x08, 3, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ADC_COMPLETE", AQT1000_MBHC_NEW_FSM_STATUS,
+ 0x40, 6, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ADC_TIMEOUT", AQT1000_MBHC_NEW_FSM_STATUS,
+ 0x80, 7, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ADC_RESULT", AQT1000_MBHC_NEW_ADC_RESULT,
+ 0xFF, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_MICB2_VOUT", AQT1000_ANA_MICB1, 0x3F, 0, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ADC_MODE",
+ AQT1000_MBHC_NEW_CTL_1, 0x10, 4, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_DETECTION_DONE",
+ AQT1000_MBHC_NEW_CTL_1, 0x04, 2, 0),
+ WCD_MBHC_REGISTER("WCD_MBHC_ELECT_ISRC_EN",
+ AQT1000_ANA_MBHC_ZDET, 0x02, 1, 0),
+};
+
+static const struct wcd_mbhc_intr intr_ids = {
+ .mbhc_sw_intr = AQT1000_IRQ_MBHC_SW_DET,
+ .mbhc_btn_press_intr = AQT1000_IRQ_MBHC_BUTTON_PRESS_DET,
+ .mbhc_btn_release_intr = AQT1000_IRQ_MBHC_BUTTON_RELEASE_DET,
+ .mbhc_hs_ins_intr = AQT1000_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
+ .mbhc_hs_rem_intr = AQT1000_IRQ_MBHC_ELECT_INS_REM_DET,
+ .hph_left_ocp = AQT1000_IRQ_HPH_PA_OCPL_FAULT,
+ .hph_right_ocp = AQT1000_IRQ_HPH_PA_OCPR_FAULT,
+};
+
+struct aqt_mbhc_zdet_param {
+ u16 ldo_ctl;
+ u16 noff;
+ u16 nshift;
+ u16 btn5;
+ u16 btn6;
+ u16 btn7;
+};
+
+static int aqt_mbhc_request_irq(struct snd_soc_codec *codec,
+ int irq, irq_handler_t handler,
+ const char *name, void *data)
+{
+ struct aqt1000 *aqt = dev_get_drvdata(codec->dev);
+
+ return aqt_request_irq(aqt, irq, name, handler, data);
+}
+
+static void aqt_mbhc_irq_control(struct snd_soc_codec *codec,
+ int irq, bool enable)
+{
+ struct aqt1000 *aqt = dev_get_drvdata(codec->dev);
+
+ if (enable)
+ aqt_enable_irq(aqt, irq);
+ else
+ aqt_disable_irq(aqt, irq);
+}
+
+static int aqt_mbhc_free_irq(struct snd_soc_codec *codec,
+ int irq, void *data)
+{
+ struct aqt1000 *aqt = dev_get_drvdata(codec->dev);
+
+ aqt_free_irq(aqt, irq, data);
+
+ return 0;
+}
+
+static void aqt_mbhc_clk_setup(struct snd_soc_codec *codec,
+ bool enable)
+{
+ if (enable)
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_1,
+ 0x80, 0x80);
+ else
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_1,
+ 0x80, 0x00);
+}
+
+static int aqt_mbhc_btn_to_num(struct snd_soc_codec *codec)
+{
+ return snd_soc_read(codec, AQT1000_ANA_MBHC_RESULT_3) & 0x7;
+}
+
+static void aqt_mbhc_mbhc_bias_control(struct snd_soc_codec *codec,
+ bool enable)
+{
+ if (enable)
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_ELECT,
+ 0x01, 0x01);
+ else
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_ELECT,
+ 0x01, 0x00);
+}
+
+static void aqt_mbhc_program_btn_thr(struct snd_soc_codec *codec,
+ s16 *btn_low, s16 *btn_high,
+ int num_btn, bool is_micbias)
+{
+ int i;
+ int vth;
+
+ if (num_btn > WCD_MBHC_DEF_BUTTONS) {
+ dev_err(codec->dev, "%s: invalid number of buttons: %d\n",
+ __func__, num_btn);
+ return;
+ }
+
+ for (i = 0; i < num_btn; i++) {
+ vth = ((btn_high[i] * 2) / 25) & 0x3F;
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN0 + i,
+ 0xFC, vth << 2);
+ dev_dbg(codec->dev, "%s: btn_high[%d]: %d, vth: %d\n",
+ __func__, i, btn_high[i], vth);
+ }
+}
+
+static bool aqt_mbhc_lock_sleep(struct wcd_mbhc *mbhc, bool lock)
+{
+ struct snd_soc_codec *codec = mbhc->codec;
+ struct aqt1000 *aqt = dev_get_drvdata(codec->dev);
+ bool ret = 0;
+
+ dev_dbg(aqt->dev, "%s: lock: %d\n", __func__, lock);
+
+ return ret;
+}
+
+static int aqt_mbhc_register_notifier(struct wcd_mbhc *mbhc,
+ struct notifier_block *nblock,
+ bool enable)
+{
+ struct aqt1000_mbhc *aqt_mbhc;
+
+ aqt_mbhc = container_of(mbhc, struct aqt1000_mbhc, wcd_mbhc);
+
+ if (enable)
+ return blocking_notifier_chain_register(&aqt_mbhc->notifier,
+ nblock);
+ else
+ return blocking_notifier_chain_unregister(
+ &aqt_mbhc->notifier, nblock);
+}
+
+static bool aqt_mbhc_micb_en_status(struct wcd_mbhc *mbhc, int micb_num)
+{
+ u8 val;
+
+ if (micb_num == MIC_BIAS_1) {
+ val = ((snd_soc_read(mbhc->codec, AQT1000_ANA_MICB1) & 0xC0)
+ >> 6);
+ if (val == 0x01)
+ return true;
+ }
+ return false;
+}
+
+static bool aqt_mbhc_hph_pa_on_status(struct snd_soc_codec *codec)
+{
+ return (snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0) ? true : false;
+}
+
+static void aqt_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
+ int pull_up_cur)
+{
+ /* Default pull up current to 2uA */
+ if (pull_up_cur > HS_PULLUP_I_OFF || pull_up_cur < HS_PULLUP_I_3P0_UA ||
+ pull_up_cur == HS_PULLUP_I_DEFAULT)
+ pull_up_cur = HS_PULLUP_I_2P0_UA;
+
+ dev_dbg(codec->dev, "%s: HS pull up current:%d\n",
+ __func__, pull_up_cur);
+
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT,
+ 0x1F, pull_up_cur);
+}
+
+static int aqt_mbhc_request_micbias(struct snd_soc_codec *codec,
+ int micb_num, int req)
+{
+ int ret = 0;
+
+ /*
+ * If micbias is requested, make sure that there
+ * is vote to enable mclk
+ */
+ if (req == MICB_ENABLE)
+ aqt_cdc_mclk_enable(codec, true);
+
+ ret = aqt_micbias_control(codec, micb_num, req, false);
+
+ /*
+ * Release vote for mclk while requesting for
+ * micbias disable
+ */
+ if (req == MICB_DISABLE)
+ aqt_cdc_mclk_enable(codec, false);
+
+ return ret;
+}
+
+static void aqt_mbhc_micb_ramp_control(struct snd_soc_codec *codec,
+ bool enable)
+{
+ if (enable) {
+ snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP,
+ 0x1C, 0x0C);
+ snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP,
+ 0x80, 0x80);
+ } else {
+ snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP,
+ 0x80, 0x00);
+ snd_soc_update_bits(codec, AQT1000_ANA_MICB1_RAMP,
+ 0x1C, 0x00);
+ }
+}
+
+static struct firmware_cal *aqt_get_hwdep_fw_cal(struct wcd_mbhc *mbhc,
+ enum wcd_cal_type type)
+{
+ struct aqt1000_mbhc *aqt_mbhc;
+ struct firmware_cal *hwdep_cal;
+ struct snd_soc_codec *codec = mbhc->codec;
+
+ aqt_mbhc = container_of(mbhc, struct aqt1000_mbhc, wcd_mbhc);
+
+ if (!codec) {
+ pr_err("%s: NULL codec pointer\n", __func__);
+ return NULL;
+ }
+ hwdep_cal = wcdcal_get_fw_cal(aqt_mbhc->fw_data, type);
+ if (!hwdep_cal)
+ dev_err(codec->dev, "%s: cal not sent by %d\n",
+ __func__, type);
+
+ return hwdep_cal;
+}
+
+static int aqt_mbhc_micb_ctrl_threshold_mic(struct snd_soc_codec *codec,
+ int micb_num, bool req_en)
+{
+ struct aqt1000_pdata *pdata = dev_get_platdata(codec->dev);
+ int rc, micb_mv;
+
+ if (micb_num != MIC_BIAS_1)
+ return -EINVAL;
+
+ /*
+ * If device tree micbias level is already above the minimum
+ * voltage needed to detect threshold microphone, then do
+ * not change the micbias, just return.
+ */
+ if (pdata->micbias.micb1_mv >= WCD_MBHC_THR_HS_MICB_MV)
+ return 0;
+
+ micb_mv = req_en ? WCD_MBHC_THR_HS_MICB_MV : pdata->micbias.micb1_mv;
+
+ rc = aqt_mbhc_micb_adjust_voltage(codec, micb_mv, MIC_BIAS_1);
+
+ return rc;
+}
+
+static inline void aqt_mbhc_get_result_params(struct aqt1000 *aqt,
+ s16 *d1_a, u16 noff,
+ int32_t *zdet)
+{
+ int i;
+ int val, val1;
+ s16 c1;
+ s32 x1, d1;
+ int32_t denom;
+ int minCode_param[] = {
+ 3277, 1639, 820, 410, 205, 103, 52, 26
+ };
+
+ regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_ZDET, 0x20, 0x20);
+ for (i = 0; i < AQT_ZDET_NUM_MEASUREMENTS; i++) {
+ regmap_read(aqt->regmap, AQT1000_ANA_MBHC_RESULT_2, &val);
+ if (val & 0x80)
+ break;
+ }
+ val = val << 0x8;
+ regmap_read(aqt->regmap, AQT1000_ANA_MBHC_RESULT_1, &val1);
+ val |= val1;
+ regmap_update_bits(aqt->regmap, AQT1000_ANA_MBHC_ZDET, 0x20, 0x00);
+ x1 = AQT_MBHC_GET_X1(val);
+ c1 = AQT_MBHC_GET_C1(val);
+ /* If ramp is not complete, give additional 5ms */
+ if ((c1 < 2) && x1)
+ usleep_range(5000, 5050);
+
+ if (!c1 || !x1) {
+ dev_dbg(aqt->dev,
+ "%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
+ __func__, c1, x1);
+ goto ramp_down;
+ }
+ d1 = d1_a[c1];
+ denom = (x1 * d1) - (1 << (14 - noff));
+ if (denom > 0)
+ *zdet = (AQT_MBHC_ZDET_CONST * 1000) / denom;
+ else if (x1 < minCode_param[noff])
+ *zdet = AQT_ZDET_FLOATING_IMPEDANCE;
+
+ dev_dbg(aqt->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
+ __func__, d1, c1, x1, *zdet);
+ramp_down:
+ i = 0;
+ while (x1) {
+ regmap_bulk_read(aqt->regmap,
+ AQT1000_ANA_MBHC_RESULT_1, (u8 *)&val, 2);
+ x1 = AQT_MBHC_GET_X1(val);
+ i++;
+ if (i == AQT_ZDET_NUM_MEASUREMENTS)
+ break;
+ }
+}
+
+static void aqt_mbhc_zdet_ramp(struct snd_soc_codec *codec,
+ struct aqt_mbhc_zdet_param *zdet_param,
+ int32_t *zl, int32_t *zr, s16 *d1_a)
+{
+ struct aqt1000 *aqt = dev_get_drvdata(codec->dev);
+ int32_t zdet = 0;
+
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x70,
+ zdet_param->ldo_ctl << 4);
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN5, 0xFC,
+ zdet_param->btn5);
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN6, 0xFC,
+ zdet_param->btn6);
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_BTN7, 0xFC,
+ zdet_param->btn7);
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x0F,
+ zdet_param->noff);
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_ZDET_RAMP_CTL, 0x0F,
+ zdet_param->nshift);
+
+ if (!zl)
+ goto z_right;
+ /* Start impedance measurement for HPH_L */
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_ZDET, 0x80, 0x80);
+ dev_dbg(aqt->dev, "%s: ramp for HPH_L, noff = %d\n",
+ __func__, zdet_param->noff);
+ aqt_mbhc_get_result_params(aqt, d1_a, zdet_param->noff, &zdet);
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_ZDET, 0x80, 0x00);
+
+ *zl = zdet;
+
+z_right:
+ if (!zr)
+ return;
+ /* Start impedance measurement for HPH_R */
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_ZDET, 0x40, 0x40);
+ dev_dbg(aqt->dev, "%s: ramp for HPH_R, noff = %d\n",
+ __func__, zdet_param->noff);
+ aqt_mbhc_get_result_params(aqt, d1_a, zdet_param->noff, &zdet);
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_ZDET, 0x40, 0x00);
+
+ *zr = zdet;
+}
+
+static inline void aqt_wcd_mbhc_qfuse_cal(struct snd_soc_codec *codec,
+ int32_t *z_val, int flag_l_r)
+{
+ s16 q1;
+ int q1_cal;
+
+ if (*z_val < (AQT_ZDET_VAL_400/1000))
+ q1 = snd_soc_read(codec,
+ AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1 + (2 * flag_l_r));
+ else
+ q1 = snd_soc_read(codec,
+ AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2 + (2 * flag_l_r));
+ if (q1 & 0x80)
+ q1_cal = (10000 - ((q1 & 0x7F) * 25));
+ else
+ q1_cal = (10000 + (q1 * 25));
+ if (q1_cal > 0)
+ *z_val = ((*z_val) * 10000) / q1_cal;
+}
+
+static void aqt_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
+ uint32_t *zr)
+{
+ struct snd_soc_codec *codec = mbhc->codec;
+ struct aqt1000 *aqt = dev_get_drvdata(codec->dev);
+ s16 reg0, reg1, reg2, reg3, reg4;
+ int32_t z1L, z1R, z1Ls;
+ int zMono, z_diff1, z_diff2;
+ bool is_fsm_disable = false;
+ struct aqt_mbhc_zdet_param zdet_param[] = {
+ {4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
+ {2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
+ {1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
+ {1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
+ };
+ struct aqt_mbhc_zdet_param *zdet_param_ptr = NULL;
+ s16 d1_a[][4] = {
+ {0, 30, 90, 30},
+ {0, 30, 30, 5},
+ {0, 30, 30, 5},
+ {0, 30, 30, 5},
+ };
+ s16 *d1 = NULL;
+
+ WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
+
+ reg0 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN5);
+ reg1 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN6);
+ reg2 = snd_soc_read(codec, AQT1000_ANA_MBHC_BTN7);
+ reg3 = snd_soc_read(codec, AQT1000_MBHC_CTL_CLK);
+ reg4 = snd_soc_read(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL);
+
+ if (snd_soc_read(codec, AQT1000_ANA_MBHC_ELECT) & 0x80) {
+ is_fsm_disable = true;
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_ELECT, 0x80, 0x00);
+ }
+
+ /* For NO-jack, disable L_DET_EN before Z-det measurements */
+ if (mbhc->hphl_swh)
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_MECH, 0x80, 0x00);
+
+ /* Turn off 100k pull down on HPHL */
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_MECH, 0x01, 0x00);
+
+ /* First get impedance on Left */
+ d1 = d1_a[1];
+ zdet_param_ptr = &zdet_param[1];
+ aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
+
+ if (!AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
+ goto left_ch_impedance;
+
+ /* Second ramp for left ch */
+ if (z1L < AQT_ZDET_VAL_32) {
+ zdet_param_ptr = &zdet_param[0];
+ d1 = d1_a[0];
+ } else if ((z1L > AQT_ZDET_VAL_400) && (z1L <= AQT_ZDET_VAL_1200)) {
+ zdet_param_ptr = &zdet_param[2];
+ d1 = d1_a[2];
+ } else if (z1L > AQT_ZDET_VAL_1200) {
+ zdet_param_ptr = &zdet_param[3];
+ d1 = d1_a[3];
+ }
+ aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, &z1L, NULL, d1);
+
+left_ch_impedance:
+ if ((z1L == AQT_ZDET_FLOATING_IMPEDANCE) ||
+ (z1L > AQT_ZDET_VAL_100K)) {
+ *zl = AQT_ZDET_FLOATING_IMPEDANCE;
+ zdet_param_ptr = &zdet_param[1];
+ d1 = d1_a[1];
+ } else {
+ *zl = z1L/1000;
+ aqt_wcd_mbhc_qfuse_cal(codec, zl, 0);
+ }
+ dev_dbg(codec->dev, "%s: impedance on HPH_L = %d(ohms)\n",
+ __func__, *zl);
+
+ /* Start of right impedance ramp and calculation */
+ aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
+ if (AQT_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
+ if (((z1R > AQT_ZDET_VAL_1200) &&
+ (zdet_param_ptr->noff == 0x6)) ||
+ ((*zl) != AQT_ZDET_FLOATING_IMPEDANCE))
+ goto right_ch_impedance;
+ /* Second ramp for right ch */
+ if (z1R < AQT_ZDET_VAL_32) {
+ zdet_param_ptr = &zdet_param[0];
+ d1 = d1_a[0];
+ } else if ((z1R > AQT_ZDET_VAL_400) &&
+ (z1R <= AQT_ZDET_VAL_1200)) {
+ zdet_param_ptr = &zdet_param[2];
+ d1 = d1_a[2];
+ } else if (z1R > AQT_ZDET_VAL_1200) {
+ zdet_param_ptr = &zdet_param[3];
+ d1 = d1_a[3];
+ }
+ aqt_mbhc_zdet_ramp(codec, zdet_param_ptr, NULL, &z1R, d1);
+ }
+right_ch_impedance:
+ if ((z1R == AQT_ZDET_FLOATING_IMPEDANCE) ||
+ (z1R > AQT_ZDET_VAL_100K)) {
+ *zr = AQT_ZDET_FLOATING_IMPEDANCE;
+ } else {
+ *zr = z1R/1000;
+ aqt_wcd_mbhc_qfuse_cal(codec, zr, 1);
+ }
+ dev_dbg(codec->dev, "%s: impedance on HPH_R = %d(ohms)\n",
+ __func__, *zr);
+
+ /* Mono/stereo detection */
+ if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) &&
+ (*zr == AQT_ZDET_FLOATING_IMPEDANCE)) {
+ dev_dbg(codec->dev,
+ "%s: plug type is invalid or extension cable\n",
+ __func__);
+ goto zdet_complete;
+ }
+ if ((*zl == AQT_ZDET_FLOATING_IMPEDANCE) ||
+ (*zr == AQT_ZDET_FLOATING_IMPEDANCE) ||
+ ((*zl < WCD_MONO_HS_MIN_THR) && (*zr > WCD_MONO_HS_MIN_THR)) ||
+ ((*zl > WCD_MONO_HS_MIN_THR) && (*zr < WCD_MONO_HS_MIN_THR))) {
+ dev_dbg(codec->dev,
+ "%s: Mono plug type with one ch floating or shorted to GND\n",
+ __func__);
+ mbhc->hph_type = WCD_MBHC_HPH_MONO;
+ goto zdet_complete;
+ }
+ snd_soc_update_bits(codec, AQT1000_HPH_R_ATEST, 0x02, 0x02);
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x01);
+ if (*zl < (AQT_ZDET_VAL_32/1000))
+ aqt_mbhc_zdet_ramp(codec, &zdet_param[0], &z1Ls, NULL, d1);
+ else
+ aqt_mbhc_zdet_ramp(codec, &zdet_param[1], &z1Ls, NULL, d1);
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2, 0x40, 0x00);
+ snd_soc_update_bits(codec, AQT1000_HPH_R_ATEST, 0x02, 0x00);
+ z1Ls /= 1000;
+ aqt_wcd_mbhc_qfuse_cal(codec, &z1Ls, 0);
+ /* Parallel of left Z and 9 ohm pull down resistor */
+ zMono = ((*zl) * 9) / ((*zl) + 9);
+ z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
+ z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
+ if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
+ dev_dbg(codec->dev, "%s: stereo plug type detected\n",
+ __func__);
+ mbhc->hph_type = WCD_MBHC_HPH_STEREO;
+ } else {
+ dev_dbg(codec->dev, "%s: MONO plug type detected\n",
+ __func__);
+ mbhc->hph_type = WCD_MBHC_HPH_MONO;
+ }
+
+zdet_complete:
+ snd_soc_write(codec, AQT1000_ANA_MBHC_BTN5, reg0);
+ snd_soc_write(codec, AQT1000_ANA_MBHC_BTN6, reg1);
+ snd_soc_write(codec, AQT1000_ANA_MBHC_BTN7, reg2);
+ /* Turn on 100k pull down on HPHL */
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_MECH, 0x01, 0x01);
+
+ /* For NO-jack, re-enable L_DET_EN after Z-det measurements */
+ if (mbhc->hphl_swh)
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_MECH, 0x80, 0x80);
+
+ snd_soc_write(codec, AQT1000_MBHC_NEW_ZDET_ANA_CTL, reg4);
+ snd_soc_write(codec, AQT1000_MBHC_CTL_CLK, reg3);
+ if (is_fsm_disable)
+ regmap_update_bits(aqt->regmap,
+ AQT1000_ANA_MBHC_ELECT, 0x80, 0x80);
+}
+
+static void aqt_mbhc_gnd_det_ctrl(struct snd_soc_codec *codec, bool enable)
+{
+ if (enable) {
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH,
+ 0x02, 0x02);
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH,
+ 0x40, 0x40);
+ } else {
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH,
+ 0x40, 0x00);
+ snd_soc_update_bits(codec, AQT1000_ANA_MBHC_MECH,
+ 0x02, 0x00);
+ }
+}
+
+static void aqt_mbhc_hph_pull_down_ctrl(struct snd_soc_codec *codec,
+ bool enable)
+{
+ if (enable) {
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2,
+ 0x40, 0x40);
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2,
+ 0x10, 0x10);
+ } else {
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2,
+ 0x40, 0x00);
+ snd_soc_update_bits(codec, AQT1000_HPH_PA_CTL2,
+ 0x10, 0x00);
+ }
+}
+
+static void aqt_mbhc_moisture_config(struct wcd_mbhc *mbhc)
+{
+ struct snd_soc_codec *codec = mbhc->codec;
+
+ if ((mbhc->moist_rref == R_OFF) ||
+ (mbhc->mbhc_cfg->enable_usbc_analog)) {
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2,
+ 0x0C, R_OFF << 2);
+ return;
+ }
+
+ /* Do not enable moisture detection if jack type is NC */
+ if (!mbhc->hphl_swh) {
+ dev_dbg(codec->dev, "%s: disable moisture detection for NC\n",
+ __func__);
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2,
+ 0x0C, R_OFF << 2);
+ return;
+ }
+
+ snd_soc_update_bits(codec, AQT1000_MBHC_NEW_CTL_2,
+ 0x0C, mbhc->moist_rref << 2);
+}
+
+static void aqt_update_anc_state(struct snd_soc_codec *codec, bool enable,
+ int anc_num)
+{
+ if (enable)
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0 +
+ (20 * anc_num), 0x10, 0x10);
+ else
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CFG0 +
+ (20 * anc_num), 0x10, 0x00);
+}
+
+static bool aqt_is_anc_on(struct wcd_mbhc *mbhc)
+{
+ bool anc_on = false;
+ u16 ancl, ancr;
+
+ ancl =
+ (snd_soc_read(mbhc->codec, AQT1000_CDC_RX1_RX_PATH_CFG0)) & 0x10;
+ ancr =
+ (snd_soc_read(mbhc->codec, AQT1000_CDC_RX2_RX_PATH_CFG0)) & 0x10;
+
+ anc_on = !!(ancl | ancr);
+
+ return anc_on;
+}
+
+static const struct wcd_mbhc_cb mbhc_cb = {
+ .request_irq = aqt_mbhc_request_irq,
+ .irq_control = aqt_mbhc_irq_control,
+ .free_irq = aqt_mbhc_free_irq,
+ .clk_setup = aqt_mbhc_clk_setup,
+ .map_btn_code_to_num = aqt_mbhc_btn_to_num,
+ .mbhc_bias = aqt_mbhc_mbhc_bias_control,
+ .set_btn_thr = aqt_mbhc_program_btn_thr,
+ .lock_sleep = aqt_mbhc_lock_sleep,
+ .register_notifier = aqt_mbhc_register_notifier,
+ .micbias_enable_status = aqt_mbhc_micb_en_status,
+ .hph_pa_on_status = aqt_mbhc_hph_pa_on_status,
+ .hph_pull_up_control_v2 = aqt_mbhc_hph_l_pull_up_control,
+ .mbhc_micbias_control = aqt_mbhc_request_micbias,
+ .mbhc_micb_ramp_control = aqt_mbhc_micb_ramp_control,
+ .get_hwdep_fw_cal = aqt_get_hwdep_fw_cal,
+ .mbhc_micb_ctrl_thr_mic = aqt_mbhc_micb_ctrl_threshold_mic,
+ .compute_impedance = aqt_wcd_mbhc_calc_impedance,
+ .mbhc_gnd_det_ctrl = aqt_mbhc_gnd_det_ctrl,
+ .hph_pull_down_ctrl = aqt_mbhc_hph_pull_down_ctrl,
+ .mbhc_moisture_config = aqt_mbhc_moisture_config,
+ .update_anc_state = aqt_update_anc_state,
+ .is_anc_on = aqt_is_anc_on,
+};
+
+static int aqt_get_hph_type(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ struct aqt1000_mbhc *aqt_mbhc = aqt->mbhc;
+ struct wcd_mbhc *mbhc;
+
+ if (!aqt_mbhc) {
+ dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__);
+ return -EINVAL;
+ }
+
+ mbhc = &aqt_mbhc->wcd_mbhc;
+
+ ucontrol->value.integer.value[0] = (u32) mbhc->hph_type;
+ dev_dbg(codec->dev, "%s: hph_type = %u\n", __func__, mbhc->hph_type);
+
+ return 0;
+}
+
+static int aqt_hph_impedance_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ uint32_t zl, zr;
+ bool hphr;
+ struct soc_multi_mixer_control *mc;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ struct aqt1000_mbhc *aqt_mbhc = aqt->mbhc;
+
+ if (!aqt_mbhc) {
+ dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__);
+ return -EINVAL;
+ }
+
+ mc = (struct soc_multi_mixer_control *)(kcontrol->private_value);
+ hphr = mc->shift;
+ wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, &zl, &zr);
+ dev_dbg(codec->dev, "%s: zl=%u(ohms), zr=%u(ohms)\n", __func__, zl, zr);
+ ucontrol->value.integer.value[0] = hphr ? zr : zl;
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new hph_type_detect_controls[] = {
+ SOC_SINGLE_EXT("HPH Type", 0, 0, UINT_MAX, 0,
+ aqt_get_hph_type, NULL),
+};
+
+static const struct snd_kcontrol_new impedance_detect_controls[] = {
+ SOC_SINGLE_EXT("HPHL Impedance", 0, 0, UINT_MAX, 0,
+ aqt_hph_impedance_get, NULL),
+ SOC_SINGLE_EXT("HPHR Impedance", 0, 1, UINT_MAX, 0,
+ aqt_hph_impedance_get, NULL),
+};
+
+/*
+ * aqt_mbhc_get_impedance: get impedance of headphone left and right channels
+ * @aqt_mbhc: handle to struct aqt_mbhc *
+ * @zl: handle to left-ch impedance
+ * @zr: handle to right-ch impedance
+ * return 0 for success or error code in case of failure
+ */
+int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc,
+ uint32_t *zl, uint32_t *zr)
+{
+ if (!aqt_mbhc) {
+ pr_err("%s: mbhc not initialized!\n", __func__);
+ return -EINVAL;
+ }
+ if (!zl || !zr) {
+ pr_err("%s: zl or zr null!\n", __func__);
+ return -EINVAL;
+ }
+
+ return wcd_mbhc_get_impedance(&aqt_mbhc->wcd_mbhc, zl, zr);
+}
+EXPORT_SYMBOL(aqt_mbhc_get_impedance);
+
+/*
+ * aqt_mbhc_hs_detect: starts mbhc insertion/removal functionality
+ * @codec: handle to snd_soc_codec *
+ * @mbhc_cfg: handle to mbhc configuration structure
+ * return 0 if mbhc_start is success or error code in case of failure
+ */
+int aqt_mbhc_hs_detect(struct snd_soc_codec *codec,
+ struct wcd_mbhc_config *mbhc_cfg)
+{
+ struct aqt1000 *aqt;
+ struct aqt1000_mbhc *aqt_mbhc;
+
+ if (!codec) {
+ pr_err("%s: codec is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ aqt = snd_soc_codec_get_drvdata(codec);
+ if (!aqt) {
+ pr_err("%s: aqt is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ aqt_mbhc = aqt->mbhc;
+ if (!aqt_mbhc) {
+ dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__);
+ return -EINVAL;
+ }
+
+ return wcd_mbhc_start(&aqt_mbhc->wcd_mbhc, mbhc_cfg);
+}
+EXPORT_SYMBOL(aqt_mbhc_hs_detect);
+
+/*
+ * aqt_mbhc_hs_detect_exit: stop mbhc insertion/removal functionality
+ * @codec: handle to snd_soc_codec *
+ */
+void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
+{
+ struct aqt1000 *aqt;
+ struct aqt1000_mbhc *aqt_mbhc;
+
+ if (!codec) {
+ pr_err("%s: codec is NULL\n", __func__);
+ return;
+ }
+
+ aqt = snd_soc_codec_get_drvdata(codec);
+ if (!aqt) {
+ pr_err("%s: aqt is NULL\n", __func__);
+ return;
+ }
+
+ aqt_mbhc = aqt->mbhc;
+ if (!aqt_mbhc) {
+ dev_err(codec->dev, "%s: mbhc not initialized!\n", __func__);
+ return;
+ }
+ wcd_mbhc_stop(&aqt_mbhc->wcd_mbhc);
+}
+EXPORT_SYMBOL(aqt_mbhc_hs_detect_exit);
+
+/*
+ * aqt_mbhc_post_ssr_init: initialize mbhc for aqt post subsystem restart
+ * @mbhc: poniter to aqt_mbhc structure
+ * @codec: handle to snd_soc_codec *
+ *
+ * return 0 if mbhc_init is success or error code in case of failure
+ */
+int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc,
+ struct snd_soc_codec *codec)
+{
+ int ret;
+ struct wcd_mbhc *wcd_mbhc;
+
+ if (!mbhc || !codec)
+ return -EINVAL;
+
+ wcd_mbhc = &mbhc->wcd_mbhc;
+ if (wcd_mbhc == NULL) {
+ pr_err("%s: wcd_mbhc is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ wcd_mbhc_deinit(wcd_mbhc);
+ ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb, &intr_ids,
+ wcd_mbhc_registers, AQT_ZDET_SUPPORTED);
+ if (ret) {
+ dev_err(codec->dev, "%s: mbhc initialization failed\n",
+ __func__);
+ goto done;
+ }
+
+done:
+ return ret;
+}
+EXPORT_SYMBOL(aqt_mbhc_post_ssr_init);
+
+/*
+ * aqt_mbhc_init: initialize mbhc for aqt
+ * @mbhc: poniter to aqt_mbhc struct pointer to store the configs
+ * @codec: handle to snd_soc_codec *
+ * @fw_data: handle to firmware data
+ *
+ * return 0 if mbhc_init is success or error code in case of failure
+ */
+int aqt_mbhc_init(struct aqt1000_mbhc **mbhc, struct snd_soc_codec *codec,
+ struct fw_info *fw_data)
+{
+ struct aqt1000_mbhc *aqt_mbhc;
+ struct wcd_mbhc *wcd_mbhc;
+ int ret;
+
+ if (!codec) {
+ pr_err("%s: codec is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ aqt_mbhc = devm_kzalloc(codec->dev, sizeof(struct aqt1000_mbhc),
+ GFP_KERNEL);
+ if (!aqt_mbhc)
+ return -ENOMEM;
+
+ aqt_mbhc->aqt = dev_get_drvdata(codec->dev);
+ aqt_mbhc->fw_data = fw_data;
+ BLOCKING_INIT_NOTIFIER_HEAD(&aqt_mbhc->notifier);
+ wcd_mbhc = &aqt_mbhc->wcd_mbhc;
+ if (wcd_mbhc == NULL) {
+ pr_err("%s: wcd_mbhc is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+
+ /* Setting default mbhc detection logic to ADC */
+ wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC;
+
+ ret = wcd_mbhc_init(wcd_mbhc, codec, &mbhc_cb,
+ &intr_ids, wcd_mbhc_registers,
+ AQT_ZDET_SUPPORTED);
+ if (ret) {
+ dev_err(codec->dev, "%s: mbhc initialization failed\n",
+ __func__);
+ goto err;
+ }
+
+ (*mbhc) = aqt_mbhc;
+ snd_soc_add_codec_controls(codec, impedance_detect_controls,
+ ARRAY_SIZE(impedance_detect_controls));
+ snd_soc_add_codec_controls(codec, hph_type_detect_controls,
+ ARRAY_SIZE(hph_type_detect_controls));
+
+ return 0;
+err:
+ devm_kfree(codec->dev, aqt_mbhc);
+ return ret;
+}
+EXPORT_SYMBOL(aqt_mbhc_init);
+
+/*
+ * aqt_mbhc_deinit: deinitialize mbhc for aqt
+ * @codec: handle to snd_soc_codec *
+ */
+void aqt_mbhc_deinit(struct snd_soc_codec *codec)
+{
+ struct aqt1000 *aqt;
+ struct aqt1000_mbhc *aqt_mbhc;
+
+ if (!codec) {
+ pr_err("%s: codec is NULL\n", __func__);
+ return;
+ }
+
+ aqt = snd_soc_codec_get_drvdata(codec);
+ if (!aqt) {
+ pr_err("%s: aqt is NULL\n", __func__);
+ return;
+ }
+
+ aqt_mbhc = aqt->mbhc;
+ if (aqt_mbhc) {
+ wcd_mbhc_deinit(&aqt_mbhc->wcd_mbhc);
+ devm_kfree(codec->dev, aqt_mbhc);
+ }
+}
+EXPORT_SYMBOL(aqt_mbhc_deinit);
diff --git a/asoc/codecs/aqt1000/aqt1000-mbhc.h b/asoc/codecs/aqt1000/aqt1000-mbhc.h
new file mode 100644
index 0000000..bdf0f5a
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-mbhc.h
@@ -0,0 +1,71 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __AQT1000_MBHC_H__
+#define __AQT1000_MBHC_H__
+#include "../wcd-mbhc-v2.h"
+
+struct aqt1000_mbhc {
+ struct wcd_mbhc wcd_mbhc;
+ struct blocking_notifier_head notifier;
+ struct aqt1000 *aqt;
+ struct fw_info *fw_data;
+ bool mbhc_started;
+};
+
+#if IS_ENABLED(CONFIG_SND_SOC_AQT1000)
+extern int aqt_mbhc_init(struct aqt1000_mbhc **mbhc,
+ struct snd_soc_codec *codec,
+ struct fw_info *fw_data);
+extern void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec);
+extern int aqt_mbhc_hs_detect(struct snd_soc_codec *codec,
+ struct wcd_mbhc_config *mbhc_cfg);
+extern void aqt_mbhc_deinit(struct snd_soc_codec *codec);
+extern int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc,
+ struct snd_soc_codec *codec);
+extern int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc,
+ uint32_t *zl, uint32_t *zr);
+#else
+static inline int aqt_mbhc_init(struct aqt1000_mbhc **mbhc,
+ struct snd_soc_codec *codec,
+ struct fw_info *fw_data)
+{
+ return 0;
+}
+static inline void aqt_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
+{
+}
+static inline int aqt_mbhc_hs_detect(struct snd_soc_codec *codec,
+ struct wcd_mbhc_config *mbhc_cfg)
+{
+ return 0;
+}
+static inline void aqt_mbhc_deinit(struct snd_soc_codec *codec)
+{
+}
+static inline int aqt_mbhc_post_ssr_init(struct aqt1000_mbhc *mbhc,
+ struct snd_soc_codec *codec)
+{
+ return 0;
+}
+
+static inline int aqt_mbhc_get_impedance(struct aqt1000_mbhc *aqt_mbhc,
+ uint32_t *zl, uint32_t *zr)
+{
+ if (zl)
+ *zl = 0;
+ if (zr)
+ *zr = 0;
+ return -EINVAL;
+}
+#endif
+
+#endif /* __AQT1000_MBHC_H__ */
diff --git a/asoc/codecs/aqt1000/aqt1000-reg-defaults.h b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h
new file mode 100644
index 0000000..5a5da25
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-reg-defaults.h
@@ -0,0 +1,1616 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AQT1000_REG_DEFAULTS_H
+#define _AQT1000_REG_DEFAULTS_H
+
+#include <linux/types.h>
+#include "aqt1000-registers.h"
+
+#define AQT1000_REG(reg) ((reg) & 0xFF)
+#define AQT1000_PAGE_SIZE 256
+
+enum {
+ AQT1000_PAGE_0 = 0,
+ AQT1000_PAGE_1,
+ AQT1000_PAGE_2,
+ AQT1000_PAGE_5 = 5,
+ AQT1000_PAGE_6,
+ AQT1000_PAGE_7,
+ AQT1000_PAGE_10 = 0xA,
+ AQT1000_PAGE_11,
+ AQT1000_PAGE_12,
+ AQT1000_PAGE_13,
+ AQT1000_PAGE_15 = 0xF,
+ AQT1000_PAGE_128,
+ AQT1000_PAGE_MAX,
+};
+
+enum {
+ AQT1000_WO = 0,
+ AQT1000_RO,
+ AQT1000_RW,
+};
+
+static const struct reg_default aqt1000_defaults[] = {
+ {AQT1000_CHIP_CFG1_PWR_MEM_SD, 0x07},
+ {AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM, 0x00},
+ {AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM, 0x00},
+ {AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM, 0x00},
+ {AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM, 0x00},
+ {AQT1000_CHIP_CFG1_CLK_CFG_FLL, 0x20},
+ {AQT1000_CHIP_CFG1_CLK_CFG_SPI_M, 0x01},
+ {AQT1000_CHIP_CFG1_CLK_CFG_I2C_M, 0x01},
+ {AQT1000_CHIP_CFG1_CLK_CFG_UART, 0x01},
+ {AQT1000_CHIP_CFG1_RST_USB_SS, 0x0E},
+ {AQT1000_CHIP_CFG1_RST_BLSP, 0x0F},
+ {AQT1000_CHIP_CFG1_RST_BUS_MTRX, 0x00},
+ {AQT1000_CHIP_CFG1_RST_MISC, 0x00},
+ {AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL, 0xCC},
+ {AQT1000_PAGE1_PAGE_REGISTER, 0x00},
+ {AQT1000_FLL_USER_CTL_0, 0x71},
+ {AQT1000_FLL_USER_CTL_1, 0x34},
+ {AQT1000_FLL_USER_CTL_2, 0x0B},
+ {AQT1000_FLL_USER_CTL_3, 0x02},
+ {AQT1000_FLL_USER_CTL_4, 0x04},
+ {AQT1000_FLL_USER_CTL_5, 0x02},
+ {AQT1000_FLL_USER_CTL_6, 0x6E},
+ {AQT1000_FLL_USER_CTL_7, 0x00},
+ {AQT1000_FLL_USER_CTL_8, 0x94},
+ {AQT1000_FLL_USER_CTL_9, 0x70},
+ {AQT1000_FLL_L_VAL_CTL_0, 0x34},
+ {AQT1000_FLL_L_VAL_CTL_1, 0x00},
+ {AQT1000_FLL_DSM_FRAC_CTL_0, 0x00},
+ {AQT1000_FLL_DSM_FRAC_CTL_1, 0xFF},
+ {AQT1000_FLL_CONFIG_CTL_0, 0x6B},
+ {AQT1000_FLL_CONFIG_CTL_1, 0x05},
+ {AQT1000_FLL_CONFIG_CTL_2, 0x08},
+ {AQT1000_FLL_CONFIG_CTL_3, 0x00},
+ {AQT1000_FLL_CONFIG_CTL_4, 0x10},
+ {AQT1000_FLL_TEST_CTL_0, 0x80},
+ {AQT1000_FLL_TEST_CTL_1, 0x00},
+ {AQT1000_FLL_TEST_CTL_2, 0x00},
+ {AQT1000_FLL_TEST_CTL_3, 0x00},
+ {AQT1000_FLL_TEST_CTL_4, 0x00},
+ {AQT1000_FLL_TEST_CTL_5, 0x00},
+ {AQT1000_FLL_TEST_CTL_6, 0x04},
+ {AQT1000_FLL_TEST_CTL_7, 0x33},
+ {AQT1000_FLL_FREQ_CTL_0, 0x00},
+ {AQT1000_FLL_FREQ_CTL_1, 0x00},
+ {AQT1000_FLL_FREQ_CTL_2, 0x00},
+ {AQT1000_FLL_FREQ_CTL_3, 0x00},
+ {AQT1000_FLL_SSC_CTL_0, 0x00},
+ {AQT1000_FLL_SSC_CTL_1, 0x00},
+ {AQT1000_FLL_SSC_CTL_2, 0x00},
+ {AQT1000_FLL_SSC_CTL_3, 0x00},
+ {AQT1000_FLL_FLL_MODE, 0xA0},
+ {AQT1000_FLL_STATUS_0, 0x00},
+ {AQT1000_FLL_STATUS_1, 0x00},
+ {AQT1000_FLL_STATUS_2, 0x00},
+ {AQT1000_FLL_STATUS_3, 0x00},
+ {AQT1000_PAGE2_PAGE_REGISTER, 0x00},
+ {AQT1000_I2S_I2S_0_TX_CFG, 0x00},
+ {AQT1000_I2S_I2S_0_RX_CFG, 0x00},
+ {AQT1000_I2S_I2S_0_CTL, 0x0C},
+ {AQT1000_I2S_I2S_CLKSRC_CTL, 0x01},
+ {AQT1000_I2S_I2S_HS_CLK_CTL, 0x00},
+ {AQT1000_I2S_I2S_0_RST, 0x00},
+ {AQT1000_I2S_SHADOW_I2S_0_CTL, 0x00},
+ {AQT1000_I2S_SHADOW_I2S_0_RX_CFG, 0x09},
+ {AQT1000_PAGE5_PAGE_REGISTER, 0x00},
+ {AQT1000_INTR_CTRL_MCU_INT_POLARITY, 0x00},
+ {AQT1000_INTR_CTRL_INT_MASK_0, 0xFE},
+ {AQT1000_INTR_CTRL_INT_MASK_1, 0xFF},
+ {AQT1000_INTR_CTRL_INT_MASK_2, 0xFF},
+ {AQT1000_INTR_CTRL_INT_MASK_3, 0xEF},
+ {AQT1000_INTR_CTRL_INT_MASK_4, 0x3B},
+ {AQT1000_INTR_CTRL_INT_MASK_5, 0xFF},
+ {AQT1000_INTR_CTRL_INT_MASK_6, 0x3F},
+ {AQT1000_INTR_CTRL_INT_STATUS_0, 0x00},
+ {AQT1000_INTR_CTRL_INT_STATUS_1, 0x00},
+ {AQT1000_INTR_CTRL_INT_STATUS_2, 0x00},
+ {AQT1000_INTR_CTRL_INT_STATUS_3, 0x00},
+ {AQT1000_INTR_CTRL_INT_STATUS_4, 0x00},
+ {AQT1000_INTR_CTRL_INT_STATUS_5, 0x00},
+ {AQT1000_INTR_CTRL_INT_STATUS_6, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_0, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_1, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_2, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_3, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_4, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_5, 0x00},
+ {AQT1000_INTR_CTRL_INT_CLEAR_6, 0x00},
+ {AQT1000_INTR_CTRL_INT_TYPE_0, 0xEF},
+ {AQT1000_INTR_CTRL_INT_TYPE_1, 0x03},
+ {AQT1000_INTR_CTRL_INT_TYPE_2, 0x00},
+ {AQT1000_INTR_CTRL_INT_TYPE_3, 0x20},
+ {AQT1000_INTR_CTRL_INT_TYPE_4, 0x44},
+ {AQT1000_INTR_CTRL_INT_TYPE_5, 0x00},
+ {AQT1000_INTR_CTRL_INT_TYPE_6, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_0, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_1, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_2, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_3, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_4, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_5, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_EN_6, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_0, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_1, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_2, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_3, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_4, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_5, 0x00},
+ {AQT1000_INTR_CTRL_INT_TEST_VAL_6, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_0, 0x02},
+ {AQT1000_INTR_CTRL_INT_DEST_1, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_2, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_3, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_4, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_5, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_6, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_7, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_8, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_9, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_10, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_11, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_12, 0x00},
+ {AQT1000_INTR_CTRL_INT_DEST_13, 0x00},
+ {AQT1000_INTR_CTRL_CLR_COMMIT, 0x00},
+ {AQT1000_ANA_PAGE_REGISTER, 0x00},
+ {AQT1000_ANA_BIAS, 0x00},
+ {AQT1000_ANA_RX_SUPPLIES, 0x00},
+ {AQT1000_ANA_HPH, 0x0C},
+ {AQT1000_ANA_AMIC1, 0x20},
+ {AQT1000_ANA_AMIC2, 0x00},
+ {AQT1000_ANA_AMIC3, 0x20},
+ {AQT1000_ANA_AMIC3_HPF, 0x00},
+ {AQT1000_ANA_MBHC_MECH, 0x39},
+ {AQT1000_ANA_MBHC_ELECT, 0x08},
+ {AQT1000_ANA_MBHC_ZDET, 0x00},
+ {AQT1000_ANA_MBHC_RESULT_1, 0x00},
+ {AQT1000_ANA_MBHC_RESULT_2, 0x00},
+ {AQT1000_ANA_MBHC_RESULT_3, 0x00},
+ {AQT1000_ANA_MBHC_BTN0, 0x00},
+ {AQT1000_ANA_MBHC_BTN1, 0x10},
+ {AQT1000_ANA_MBHC_BTN2, 0x20},
+ {AQT1000_ANA_MBHC_BTN3, 0x30},
+ {AQT1000_ANA_MBHC_BTN4, 0x40},
+ {AQT1000_ANA_MBHC_BTN5, 0x50},
+ {AQT1000_ANA_MBHC_BTN6, 0x60},
+ {AQT1000_ANA_MBHC_BTN7, 0x70},
+ {AQT1000_ANA_MICB1, 0x10},
+ {AQT1000_ANA_MICB1_RAMP, 0x00},
+ {AQT1000_BIAS_CTL, 0x28},
+ {AQT1000_BIAS_CCOMP_FINE_ADJ, 0x75},
+ {AQT1000_LED_LED_MODE_SEL_R, 0x00},
+ {AQT1000_LED_LED_MISC_R, 0x00},
+ {AQT1000_LED_LED_MODE_SEL_G, 0x00},
+ {AQT1000_LED_LED_MISC_G, 0x00},
+ {AQT1000_LED_LED_MODE_SEL_B, 0x00},
+ {AQT1000_LED_LED_MISC_B, 0x00},
+ {AQT1000_LDOH_MODE, 0x1D},
+ {AQT1000_LDOH_BIAS, 0x00},
+ {AQT1000_LDOH_STB_LOADS, 0x00},
+ {AQT1000_LDOH_MISC1, 0x00},
+ {AQT1000_LDOL_VDDCX_ADJUST, 0x01},
+ {AQT1000_LDOL_DISABLE_LDOL, 0x00},
+ {AQT1000_BUCK_5V_EN_CTL, 0x03},
+ {AQT1000_BUCK_5V_VOUT_SEL, 0x03},
+ {AQT1000_BUCK_5V_CTRL_VCL_1, 0x03},
+ {AQT1000_BUCK_5V_CTRL_VCL_2, 0x21},
+ {AQT1000_BUCK_5V_CTRL_CCL_2, 0x20},
+ {AQT1000_BUCK_5V_CTRL_CCL_1, 0xA1},
+ {AQT1000_BUCK_5V_CTRL_CCL_3, 0x02},
+ {AQT1000_BUCK_5V_CTRL_CCL_4, 0x05},
+ {AQT1000_BUCK_5V_CTRL_CCL_5, 0x00},
+ {AQT1000_BUCK_5V_IBIAS_CTL_1, 0x37},
+ {AQT1000_BUCK_5V_IBIAS_CTL_2, 0x00},
+ {AQT1000_BUCK_5V_IBIAS_CTL_3, 0x33},
+ {AQT1000_BUCK_5V_IBIAS_CTL_4, 0x33},
+ {AQT1000_BUCK_5V_IBIAS_CTL_5, 0x00},
+ {AQT1000_BUCK_5V_ATEST_DTEST_CTL, 0x00},
+ {AQT1000_PON_BG_CTRL, 0x80},
+ {AQT1000_PON_TEST_CTRL, 0x00},
+ {AQT1000_MBHC_CTL_CLK, 0x30},
+ {AQT1000_MBHC_CTL_ANA, 0x00},
+ {AQT1000_MBHC_CTL_SPARE_1, 0x00},
+ {AQT1000_MBHC_CTL_SPARE_2, 0x00},
+ {AQT1000_MBHC_CTL_BCS, 0x00},
+ {AQT1000_MBHC_MOISTURE_DET_FSM_STATUS, 0x00},
+ {AQT1000_MBHC_TEST_CTL, 0x00},
+ {AQT1000_MICB1_TEST_CTL_1, 0x1A},
+ {AQT1000_MICB1_TEST_CTL_2, 0x18},
+ {AQT1000_MICB1_TEST_CTL_3, 0xA4},
+ {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x00},
+ {AQT1000_MICB1_MISC_MICB_MISC1, 0x00},
+ {AQT1000_MICB1_MISC_MICB_MISC2, 0x00},
+ {AQT1000_TX_COM_ADC_VCM, 0x39},
+ {AQT1000_TX_COM_BIAS_ATEST, 0xC0},
+ {AQT1000_TX_COM_ADC_INT1_IB, 0x6F},
+ {AQT1000_TX_COM_ADC_INT2_IB, 0x4F},
+ {AQT1000_TX_COM_TXFE_DIV_CTL, 0x2E},
+ {AQT1000_TX_COM_TXFE_DIV_START, 0x00},
+ {AQT1000_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7},
+ {AQT1000_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF},
+ {AQT1000_TX_1_2_TEST_EN, 0xCC},
+ {AQT1000_TX_1_2_ADC_IB, 0x09},
+ {AQT1000_TX_1_2_ATEST_REFCTL, 0x0A},
+ {AQT1000_TX_1_2_TEST_CTL, 0x38},
+ {AQT1000_TX_1_2_TEST_BLK_EN, 0xFF},
+ {AQT1000_TX_1_2_TXFE_CLKDIV, 0x00},
+ {AQT1000_TX_1_2_SAR1_ERR, 0x00},
+ {AQT1000_TX_1_2_SAR2_ERR, 0x00},
+ {AQT1000_TX_3_TEST_EN, 0xC0},
+ {AQT1000_TX_3_ADC_IB, 0x09},
+ {AQT1000_TX_3_ATEST_REFCTL, 0x0A},
+ {AQT1000_TX_3_TEST_CTL, 0x38},
+ {AQT1000_TX_3_TEST_BLK_EN, 0xFE},
+ {AQT1000_TX_3_TXFE_CLKDIV, 0x00},
+ {AQT1000_TX_3_SAR1_ERR, 0x00},
+ {AQT1000_TX_3_SAR2_ERR, 0x00},
+ {AQT1000_TX_ATEST1_2_SEL, 0x60},
+ {AQT1000_CLASSH_MODE_1, 0x40},
+ {AQT1000_CLASSH_MODE_2, 0x3A},
+ {AQT1000_CLASSH_MODE_3, 0x00},
+ {AQT1000_CLASSH_CTRL_VCL_1, 0x70},
+ {AQT1000_CLASSH_CTRL_VCL_2, 0x82},
+ {AQT1000_CLASSH_CTRL_CCL_1, 0x31},
+ {AQT1000_CLASSH_CTRL_CCL_2, 0x80},
+ {AQT1000_CLASSH_CTRL_CCL_3, 0x80},
+ {AQT1000_CLASSH_CTRL_CCL_4, 0x51},
+ {AQT1000_CLASSH_CTRL_CCL_5, 0x00},
+ {AQT1000_CLASSH_BUCK_TMUX_A_D, 0x00},
+ {AQT1000_CLASSH_BUCK_SW_DRV_CNTL, 0x77},
+ {AQT1000_CLASSH_SPARE, 0x00},
+ {AQT1000_FLYBACK_EN, 0x4E},
+ {AQT1000_FLYBACK_VNEG_CTRL_1, 0x0B},
+ {AQT1000_FLYBACK_VNEG_CTRL_2, 0x45},
+ {AQT1000_FLYBACK_VNEG_CTRL_3, 0x74},
+ {AQT1000_FLYBACK_VNEG_CTRL_4, 0x7F},
+ {AQT1000_FLYBACK_VNEG_CTRL_5, 0x83},
+ {AQT1000_FLYBACK_VNEG_CTRL_6, 0x98},
+ {AQT1000_FLYBACK_VNEG_CTRL_7, 0xA9},
+ {AQT1000_FLYBACK_VNEG_CTRL_8, 0x68},
+ {AQT1000_FLYBACK_VNEG_CTRL_9, 0x64},
+ {AQT1000_FLYBACK_VNEGDAC_CTRL_1, 0xED},
+ {AQT1000_FLYBACK_VNEGDAC_CTRL_2, 0xF0},
+ {AQT1000_FLYBACK_VNEGDAC_CTRL_3, 0xA6},
+ {AQT1000_FLYBACK_CTRL_1, 0x65},
+ {AQT1000_FLYBACK_TEST_CTL, 0x00},
+ {AQT1000_RX_AUX_SW_CTL, 0x00},
+ {AQT1000_RX_PA_AUX_IN_CONN, 0x00},
+ {AQT1000_RX_TIMER_DIV, 0x32},
+ {AQT1000_RX_OCP_CTL, 0x1F},
+ {AQT1000_RX_OCP_COUNT, 0x77},
+ {AQT1000_RX_BIAS_ATEST, 0x00},
+ {AQT1000_RX_BIAS_MISC1, 0xAA},
+ {AQT1000_RX_BIAS_HPH_LDO, 0xA9},
+ {AQT1000_RX_BIAS_HPH_PA, 0xAA},
+ {AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A},
+ {AQT1000_RX_BIAS_HPH_RDAC_LDO, 0x88},
+ {AQT1000_RX_BIAS_HPH_CNP1, 0x82},
+ {AQT1000_RX_BIAS_HPH_LOWPOWER, 0x82},
+ {AQT1000_RX_BIAS_MISC2, 0x80},
+ {AQT1000_RX_BIAS_MISC3, 0x88},
+ {AQT1000_RX_BIAS_MISC4, 0x88},
+ {AQT1000_RX_BIAS_MISC5, 0xA8},
+ {AQT1000_RX_BIAS_BUCK_RST, 0x08},
+ {AQT1000_RX_BIAS_BUCK_VREF_ERRAMP, 0x44},
+ {AQT1000_RX_BIAS_FLYB_ERRAMP, 0x40},
+ {AQT1000_RX_BIAS_FLYB_BUFF, 0xAA},
+ {AQT1000_RX_BIAS_FLYB_MID_RST, 0x14},
+ {AQT1000_HPH_L_STATUS, 0x04},
+ {AQT1000_HPH_R_STATUS, 0x04},
+ {AQT1000_HPH_CNP_EN, 0x80},
+ {AQT1000_HPH_CNP_WG_CTL, 0x9A},
+ {AQT1000_HPH_CNP_WG_TIME, 0x14},
+ {AQT1000_HPH_OCP_CTL, 0x28},
+ {AQT1000_HPH_AUTO_CHOP, 0x16},
+ {AQT1000_HPH_CHOP_CTL, 0x83},
+ {AQT1000_HPH_PA_CTL1, 0x46},
+ {AQT1000_HPH_PA_CTL2, 0x50},
+ {AQT1000_HPH_L_EN, 0x80},
+ {AQT1000_HPH_L_TEST, 0xE0},
+ {AQT1000_HPH_L_ATEST, 0x50},
+ {AQT1000_HPH_R_EN, 0x80},
+ {AQT1000_HPH_R_TEST, 0xE0},
+ {AQT1000_HPH_R_ATEST, 0x54},
+ {AQT1000_HPH_RDAC_CLK_CTL1, 0x99},
+ {AQT1000_HPH_RDAC_CLK_CTL2, 0x9B},
+ {AQT1000_HPH_RDAC_LDO_CTL, 0x33},
+ {AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00},
+ {AQT1000_HPH_REFBUFF_UHQA_CTL, 0xA8},
+ {AQT1000_HPH_REFBUFF_LP_CTL, 0x0E},
+ {AQT1000_HPH_L_DAC_CTL, 0x00},
+ {AQT1000_HPH_R_DAC_CTL, 0x00},
+ {AQT1000_HPHLR_SURGE_COMP_SEL, 0x55},
+ {AQT1000_HPHLR_SURGE_EN, 0x1D},
+ {AQT1000_HPHLR_SURGE_MISC1, 0xA0},
+ {AQT1000_HPHLR_SURGE_STATUS, 0x00},
+ {AQT1000_ANA_NEW_PAGE_REGISTER, 0x00},
+ {AQT1000_HPH_NEW_ANA_HPH2, 0x00},
+ {AQT1000_HPH_NEW_ANA_HPH3, 0x00},
+ {AQT1000_CLK_SYS_MCLK1_PRG, 0x09},
+ {AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG, 0x20},
+ {AQT1000_CLK_SYS_XO_CAP_XTP, 0x3F},
+ {AQT1000_CLK_SYS_XO_CAP_XTM, 0x3F},
+ {AQT1000_CLK_SYS_PLL_ENABLES, 0x00},
+ {AQT1000_CLK_SYS_PLL_PRESET, 0x00},
+ {AQT1000_CLK_SYS_PLL_STATUS, 0x00},
+ {AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00},
+ {AQT1000_MBHC_NEW_CTL_1, 0x02},
+ {AQT1000_MBHC_NEW_CTL_2, 0x05},
+ {AQT1000_MBHC_NEW_PLUG_DETECT_CTL, 0x29},
+ {AQT1000_MBHC_NEW_ZDET_ANA_CTL, 0x0F},
+ {AQT1000_MBHC_NEW_ZDET_RAMP_CTL, 0x00},
+ {AQT1000_MBHC_NEW_FSM_STATUS, 0x00},
+ {AQT1000_MBHC_NEW_ADC_RESULT, 0x00},
+ {AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40},
+ {AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81},
+ {AQT1000_HPH_NEW_INT_RDAC_VREF_CTL, 0x10},
+ {AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00},
+ {AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81},
+ {AQT1000_HPH_NEW_INT_PA_MISC1, 0x22},
+ {AQT1000_HPH_NEW_INT_PA_MISC2, 0x00},
+ {AQT1000_HPH_NEW_INT_PA_RDAC_MISC, 0x00},
+ {AQT1000_HPH_NEW_INT_HPH_TIMER1, 0xFE},
+ {AQT1000_HPH_NEW_INT_HPH_TIMER2, 0x02},
+ {AQT1000_HPH_NEW_INT_HPH_TIMER3, 0x4E},
+ {AQT1000_HPH_NEW_INT_HPH_TIMER4, 0x54},
+ {AQT1000_HPH_NEW_INT_PA_RDAC_MISC2, 0x80},
+ {AQT1000_HPH_NEW_INT_PA_RDAC_MISC3, 0x00},
+ {AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62},
+ {AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01},
+ {AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11},
+ {AQT1000_CLK_SYS_INT_CLK_TEST1, 0x00},
+ {AQT1000_CLK_SYS_INT_XO_TEST1, 0x98},
+ {AQT1000_CLK_SYS_INT_XO_TEST2, 0x00},
+ {AQT1000_CLK_SYS_INT_POST_DIV_REG0, 0x00},
+ {AQT1000_CLK_SYS_INT_POST_DIV_REG1, 0x00},
+ {AQT1000_CLK_SYS_INT_REF_DIV_REG0, 0x00},
+ {AQT1000_CLK_SYS_INT_REF_DIV_REG1, 0x00},
+ {AQT1000_CLK_SYS_INT_FILTER_REG0, 0x00},
+ {AQT1000_CLK_SYS_INT_FILTER_REG1, 0x00},
+ {AQT1000_CLK_SYS_INT_PLL_L_VAL, 0x00},
+ {AQT1000_CLK_SYS_INT_PLL_M_VAL, 0x00},
+ {AQT1000_CLK_SYS_INT_PLL_N_VAL, 0x00},
+ {AQT1000_CLK_SYS_INT_TEST_REG0, 0x00},
+ {AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00},
+ {AQT1000_CLK_SYS_INT_VCO_PROG, 0x00},
+ {AQT1000_CLK_SYS_INT_TEST_REG1, 0x00},
+ {AQT1000_CLK_SYS_INT_LDO_LOCK_CFG, 0x00},
+ {AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00},
+ {AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57},
+ {AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01},
+ {AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00},
+ {AQT1000_MBHC_NEW_INT_SPARE_2, 0x00},
+ {AQT1000_PAGE10_PAGE_REGISTER, 0x00},
+ {AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x00},
+ {AQT1000_CDC_ANC0_MODE_1_CTL, 0x00},
+ {AQT1000_CDC_ANC0_MODE_2_CTL, 0x00},
+ {AQT1000_CDC_ANC0_FF_SHIFT, 0x00},
+ {AQT1000_CDC_ANC0_FB_SHIFT, 0x00},
+ {AQT1000_CDC_ANC0_LPF_FF_A_CTL, 0x00},
+ {AQT1000_CDC_ANC0_LPF_FF_B_CTL, 0x00},
+ {AQT1000_CDC_ANC0_LPF_FB_CTL, 0x00},
+ {AQT1000_CDC_ANC0_SMLPF_CTL, 0x00},
+ {AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00},
+ {AQT1000_CDC_ANC0_IIR_ADAPT_CTL, 0x00},
+ {AQT1000_CDC_ANC0_IIR_COEFF_1_CTL, 0x00},
+ {AQT1000_CDC_ANC0_IIR_COEFF_2_CTL, 0x00},
+ {AQT1000_CDC_ANC0_FF_A_GAIN_CTL, 0x00},
+ {AQT1000_CDC_ANC0_FF_B_GAIN_CTL, 0x00},
+ {AQT1000_CDC_ANC0_FB_GAIN_CTL, 0x00},
+ {AQT1000_CDC_ANC0_RC_COMMON_CTL, 0x00},
+ {AQT1000_CDC_ANC0_FIFO_COMMON_CTL, 0x88},
+ {AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR, 0x00},
+ {AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR, 0x00},
+ {AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR, 0x00},
+ {AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR, 0x00},
+ {AQT1000_CDC_ANC0_STATUS_FIFO, 0x00},
+ {AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x00},
+ {AQT1000_CDC_ANC1_MODE_1_CTL, 0x00},
+ {AQT1000_CDC_ANC1_MODE_2_CTL, 0x00},
+ {AQT1000_CDC_ANC1_FF_SHIFT, 0x00},
+ {AQT1000_CDC_ANC1_FB_SHIFT, 0x00},
+ {AQT1000_CDC_ANC1_LPF_FF_A_CTL, 0x00},
+ {AQT1000_CDC_ANC1_LPF_FF_B_CTL, 0x00},
+ {AQT1000_CDC_ANC1_LPF_FB_CTL, 0x00},
+ {AQT1000_CDC_ANC1_SMLPF_CTL, 0x00},
+ {AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL, 0x00},
+ {AQT1000_CDC_ANC1_IIR_ADAPT_CTL, 0x00},
+ {AQT1000_CDC_ANC1_IIR_COEFF_1_CTL, 0x00},
+ {AQT1000_CDC_ANC1_IIR_COEFF_2_CTL, 0x00},
+ {AQT1000_CDC_ANC1_FF_A_GAIN_CTL, 0x00},
+ {AQT1000_CDC_ANC1_FF_B_GAIN_CTL, 0x00},
+ {AQT1000_CDC_ANC1_FB_GAIN_CTL, 0x00},
+ {AQT1000_CDC_ANC1_RC_COMMON_CTL, 0x00},
+ {AQT1000_CDC_ANC1_FIFO_COMMON_CTL, 0x88},
+ {AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR, 0x00},
+ {AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR, 0x00},
+ {AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR, 0x00},
+ {AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR, 0x00},
+ {AQT1000_CDC_ANC1_STATUS_FIFO, 0x00},
+ {AQT1000_CDC_TX0_TX_PATH_CTL, 0x04},
+ {AQT1000_CDC_TX0_TX_PATH_CFG0, 0x10},
+ {AQT1000_CDC_TX0_TX_PATH_CFG1, 0x03},
+ {AQT1000_CDC_TX0_TX_VOL_CTL, 0x00},
+ {AQT1000_CDC_TX0_TX_PATH_SEC0, 0x00},
+ {AQT1000_CDC_TX0_TX_PATH_SEC1, 0x00},
+ {AQT1000_CDC_TX0_TX_PATH_SEC2, 0x01},
+ {AQT1000_CDC_TX0_TX_PATH_SEC3, 0x3C},
+ {AQT1000_CDC_TX0_TX_PATH_SEC4, 0x20},
+ {AQT1000_CDC_TX0_TX_PATH_SEC5, 0x00},
+ {AQT1000_CDC_TX0_TX_PATH_SEC6, 0x00},
+ {AQT1000_CDC_TX1_TX_PATH_CTL, 0x04},
+ {AQT1000_CDC_TX1_TX_PATH_CFG0, 0x10},
+ {AQT1000_CDC_TX1_TX_PATH_CFG1, 0x03},
+ {AQT1000_CDC_TX1_TX_VOL_CTL, 0x00},
+ {AQT1000_CDC_TX1_TX_PATH_SEC0, 0x00},
+ {AQT1000_CDC_TX1_TX_PATH_SEC1, 0x00},
+ {AQT1000_CDC_TX1_TX_PATH_SEC2, 0x01},
+ {AQT1000_CDC_TX1_TX_PATH_SEC3, 0x3C},
+ {AQT1000_CDC_TX1_TX_PATH_SEC4, 0x20},
+ {AQT1000_CDC_TX1_TX_PATH_SEC5, 0x00},
+ {AQT1000_CDC_TX1_TX_PATH_SEC6, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_CTL, 0x04},
+ {AQT1000_CDC_TX2_TX_PATH_CFG0, 0x10},
+ {AQT1000_CDC_TX2_TX_PATH_CFG1, 0x03},
+ {AQT1000_CDC_TX2_TX_VOL_CTL, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_SEC0, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_SEC1, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_SEC2, 0x01},
+ {AQT1000_CDC_TX2_TX_PATH_SEC3, 0x3C},
+ {AQT1000_CDC_TX2_TX_PATH_SEC4, 0x20},
+ {AQT1000_CDC_TX2_TX_PATH_SEC5, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_SEC6, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_SEC7, 0x25},
+ {AQT1000_PAGE11_PAGE_REGISTER, 0x00},
+ {AQT1000_CDC_COMPANDER1_CTL0, 0x60},
+ {AQT1000_CDC_COMPANDER1_CTL1, 0xDB},
+ {AQT1000_CDC_COMPANDER1_CTL2, 0xFF},
+ {AQT1000_CDC_COMPANDER1_CTL3, 0x35},
+ {AQT1000_CDC_COMPANDER1_CTL4, 0xFF},
+ {AQT1000_CDC_COMPANDER1_CTL5, 0x00},
+ {AQT1000_CDC_COMPANDER1_CTL6, 0x01},
+ {AQT1000_CDC_COMPANDER1_CTL7, 0x26},
+ {AQT1000_CDC_COMPANDER2_CTL0, 0x60},
+ {AQT1000_CDC_COMPANDER2_CTL1, 0xDB},
+ {AQT1000_CDC_COMPANDER2_CTL2, 0xFF},
+ {AQT1000_CDC_COMPANDER2_CTL3, 0x35},
+ {AQT1000_CDC_COMPANDER2_CTL4, 0xFF},
+ {AQT1000_CDC_COMPANDER2_CTL5, 0x00},
+ {AQT1000_CDC_COMPANDER2_CTL6, 0x01},
+ {AQT1000_CDC_COMPANDER2_CTL7, 0x26},
+ {AQT1000_CDC_RX1_RX_PATH_CTL, 0x04},
+ {AQT1000_CDC_RX1_RX_PATH_CFG0, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_CFG1, 0x64},
+ {AQT1000_CDC_RX1_RX_PATH_CFG2, 0x8F},
+ {AQT1000_CDC_RX1_RX_VOL_CTL, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_MIX_CTL, 0x04},
+ {AQT1000_CDC_RX1_RX_PATH_MIX_CFG, 0x7E},
+ {AQT1000_CDC_RX1_RX_VOL_MIX_CTL, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_SEC0, 0xFC},
+ {AQT1000_CDC_RX1_RX_PATH_SEC1, 0x08},
+ {AQT1000_CDC_RX1_RX_PATH_SEC2, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_SEC3, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_SEC4, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_SEC5, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_SEC6, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_SEC7, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_MIX_SEC0, 0x08},
+ {AQT1000_CDC_RX1_RX_PATH_MIX_SEC1, 0x00},
+ {AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_CTL, 0x04},
+ {AQT1000_CDC_RX2_RX_PATH_CFG0, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_CFG1, 0x64},
+ {AQT1000_CDC_RX2_RX_PATH_CFG2, 0x8F},
+ {AQT1000_CDC_RX2_RX_VOL_CTL, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_MIX_CTL, 0x04},
+ {AQT1000_CDC_RX2_RX_PATH_MIX_CFG, 0x7E},
+ {AQT1000_CDC_RX2_RX_VOL_MIX_CTL, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_SEC0, 0xFC},
+ {AQT1000_CDC_RX2_RX_PATH_SEC1, 0x08},
+ {AQT1000_CDC_RX2_RX_PATH_SEC2, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_SEC3, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_SEC4, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_SEC5, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_SEC6, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_SEC7, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_MIX_SEC0, 0x08},
+ {AQT1000_CDC_RX2_RX_PATH_MIX_SEC1, 0x00},
+ {AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL, 0x00},
+ {AQT1000_CDC_EQ_IIR0_PATH_CTL, 0x00},
+ {AQT1000_CDC_EQ_IIR0_PATH_CFG0, 0x1F},
+ {AQT1000_CDC_EQ_IIR0_PATH_CFG1, 0x00},
+ {AQT1000_CDC_EQ_IIR0_PATH_CFG2, 0x00},
+ {AQT1000_CDC_EQ_IIR0_PATH_CFG3, 0x00},
+ {AQT1000_CDC_EQ_IIR0_COEF_CFG0, 0x00},
+ {AQT1000_CDC_EQ_IIR0_COEF_CFG1, 0x00},
+ {AQT1000_CDC_EQ_IIR1_PATH_CTL, 0x00},
+ {AQT1000_CDC_EQ_IIR1_PATH_CFG0, 0x1F},
+ {AQT1000_CDC_EQ_IIR1_PATH_CFG1, 0x00},
+ {AQT1000_CDC_EQ_IIR1_PATH_CFG2, 0x00},
+ {AQT1000_CDC_EQ_IIR1_PATH_CFG3, 0x00},
+ {AQT1000_CDC_EQ_IIR1_COEF_CFG0, 0x00},
+ {AQT1000_CDC_EQ_IIR1_COEF_CFG1, 0x00},
+ {AQT1000_PAGE12_PAGE_REGISTER, 0x00},
+ {AQT1000_CDC_CLSH_CRC, 0x00},
+ {AQT1000_CDC_CLSH_DLY_CTRL, 0x03},
+ {AQT1000_CDC_CLSH_DECAY_CTRL, 0x02},
+ {AQT1000_CDC_CLSH_HPH_V_PA, 0x1C},
+ {AQT1000_CDC_CLSH_EAR_V_PA, 0x39},
+ {AQT1000_CDC_CLSH_HPH_V_HD, 0x0C},
+ {AQT1000_CDC_CLSH_EAR_V_HD, 0x0C},
+ {AQT1000_CDC_CLSH_K1_MSB, 0x01},
+ {AQT1000_CDC_CLSH_K1_LSB, 0x00},
+ {AQT1000_CDC_CLSH_K2_MSB, 0x00},
+ {AQT1000_CDC_CLSH_K2_LSB, 0x80},
+ {AQT1000_CDC_CLSH_IDLE_CTRL, 0x00},
+ {AQT1000_CDC_CLSH_IDLE_HPH, 0x00},
+ {AQT1000_CDC_CLSH_IDLE_EAR, 0x00},
+ {AQT1000_CDC_CLSH_TEST0, 0x07},
+ {AQT1000_CDC_CLSH_TEST1, 0x00},
+ {AQT1000_CDC_CLSH_OVR_VREF, 0x00},
+ {AQT1000_MIXING_ASRC0_CLK_RST_CTL, 0x00},
+ {AQT1000_MIXING_ASRC0_CTL0, 0x00},
+ {AQT1000_MIXING_ASRC0_CTL1, 0x00},
+ {AQT1000_MIXING_ASRC0_FIFO_CTL, 0xA8},
+ {AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+ {AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+ {AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+ {AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+ {AQT1000_MIXING_ASRC0_STATUS_FIFO, 0x00},
+ {AQT1000_MIXING_ASRC1_CLK_RST_CTL, 0x00},
+ {AQT1000_MIXING_ASRC1_CTL0, 0x00},
+ {AQT1000_MIXING_ASRC1_CTL1, 0x00},
+ {AQT1000_MIXING_ASRC1_FIFO_CTL, 0xA8},
+ {AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
+ {AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
+ {AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
+ {AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
+ {AQT1000_MIXING_ASRC1_STATUS_FIFO, 0x00},
+ {AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04},
+ {AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00},
+ {AQT1000_SIDETONE_ASRC0_CLK_RST_CTL, 0x00},
+ {AQT1000_SIDETONE_ASRC0_CTL0, 0x00},
+ {AQT1000_SIDETONE_ASRC0_CTL1, 0x00},
+ {AQT1000_SIDETONE_ASRC0_FIFO_CTL, 0xA8},
+ {AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+ {AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+ {AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+ {AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+ {AQT1000_SIDETONE_ASRC0_STATUS_FIFO, 0x00},
+ {AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
+ {AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01},
+ {AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
+ {AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01},
+ {AQT1000_EC_ASRC0_CLK_RST_CTL, 0x00},
+ {AQT1000_EC_ASRC0_CTL0, 0x00},
+ {AQT1000_EC_ASRC0_CTL1, 0x00},
+ {AQT1000_EC_ASRC0_FIFO_CTL, 0xA8},
+ {AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+ {AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+ {AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+ {AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+ {AQT1000_EC_ASRC0_STATUS_FIFO, 0x00},
+ {AQT1000_EC_ASRC1_CLK_RST_CTL, 0x00},
+ {AQT1000_EC_ASRC1_CTL0, 0x00},
+ {AQT1000_EC_ASRC1_CTL1, 0x00},
+ {AQT1000_EC_ASRC1_FIFO_CTL, 0xA8},
+ {AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
+ {AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
+ {AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
+ {AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
+ {AQT1000_EC_ASRC1_STATUS_FIFO, 0x00},
+ {AQT1000_PAGE13_PAGE_REGISTER, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_DSD_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00},
+ {AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0x00},
+ {AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00},
+ {AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00},
+ {AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
+ {AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+ {AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL, 0x00},
+ {AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0F},
+ {AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL, 0x00},
+ {AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_CTL, 0x40},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00},
+ {AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00},
+ {AQT1000_CDC_TOP_TOP_CFG0, 0x00},
+ {AQT1000_CDC_TOP_HPHL_COMP_WR_LSB, 0x00},
+ {AQT1000_CDC_TOP_HPHL_COMP_WR_MSB, 0x00},
+ {AQT1000_CDC_TOP_HPHL_COMP_LUT, 0x00},
+ {AQT1000_CDC_TOP_HPHL_COMP_RD_LSB, 0x00},
+ {AQT1000_CDC_TOP_HPHL_COMP_RD_MSB, 0x00},
+ {AQT1000_CDC_TOP_HPHR_COMP_WR_LSB, 0x00},
+ {AQT1000_CDC_TOP_HPHR_COMP_WR_MSB, 0x00},
+ {AQT1000_CDC_TOP_HPHR_COMP_LUT, 0x00},
+ {AQT1000_CDC_TOP_HPHR_COMP_RD_LSB, 0x00},
+ {AQT1000_CDC_TOP_HPHR_COMP_RD_MSB, 0x00},
+ {AQT1000_CDC_DSD0_PATH_CTL, 0x00},
+ {AQT1000_CDC_DSD0_CFG0, 0x00},
+ {AQT1000_CDC_DSD0_CFG1, 0x00},
+ {AQT1000_CDC_DSD0_CFG2, 0x42},
+ {AQT1000_CDC_DSD0_CFG3, 0x00},
+ {AQT1000_CDC_DSD0_CFG4, 0x02},
+ {AQT1000_CDC_DSD0_CFG5, 0x00},
+ {AQT1000_CDC_DSD1_PATH_CTL, 0x00},
+ {AQT1000_CDC_DSD1_CFG0, 0x00},
+ {AQT1000_CDC_DSD1_CFG1, 0x00},
+ {AQT1000_CDC_DSD1_CFG2, 0x42},
+ {AQT1000_CDC_DSD1_CFG3, 0x00},
+ {AQT1000_CDC_DSD1_CFG4, 0x02},
+ {AQT1000_CDC_DSD1_CFG5, 0x00},
+ {AQT1000_CDC_RX_IDLE_DET_PATH_CTL, 0x00},
+ {AQT1000_CDC_RX_IDLE_DET_CFG0, 0x07},
+ {AQT1000_CDC_RX_IDLE_DET_CFG1, 0x3C},
+ {AQT1000_CDC_RX_IDLE_DET_CFG2, 0x00},
+ {AQT1000_CDC_RX_IDLE_DET_CFG3, 0x00},
+ {AQT1000_CDC_DOP_DET_CTL, 0x00},
+ {AQT1000_CDC_DOP_DET_CFG0, 0xFA},
+ {AQT1000_CDC_DOP_DET_CFG1, 0x05},
+ {AQT1000_CDC_DOP_DET_CFG2, 0x00},
+ {AQT1000_CDC_DOP_DET_CFG3, 0x33},
+ {AQT1000_CDC_DOP_DET_CFG4, 0x20},
+ {AQT1000_CDC_DOP_DET_STATUS0, 0x00},
+ {AQT1000_PAGE15_PAGE_REGISTER, 0x00},
+ {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0, 0x1B},
+ {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1, 0x24},
+ {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2, 0x00},
+ {AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3, 0x08},
+ {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0, 0x1B},
+ {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1, 0x24},
+ {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2, 0x00},
+ {AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3, 0x08},
+ {AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0, 0x00},
+ {AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL, 0x4C},
+ {AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL, 0x4C},
+ {AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL, 0x4C},
+ {AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL, 0x4C},
+ {AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR, 0x00},
+ {AQT1000_PAGE128_PAGE_REGISTER, 0x00},
+ {AQT1000_TLMM_SPI_CLK_PINCFG, 0x00},
+ {AQT1000_TLMM_SPI_MOSI_PINCFG, 0x00},
+ {AQT1000_TLMM_SPI_MISO_PINCFG, 0x00},
+ {AQT1000_TLMM_SPI_CS_N_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO1_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO2_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO3_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO4_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO5_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO6_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO7_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO8_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO9_PINCFG, 0x00},
+ {AQT1000_TLMM_GPIO10_PINCFG, 0x00},
+ {AQT1000_PAD_CTRL_PAD_PDN_CTRL_0, 0x00},
+ {AQT1000_PAD_CTRL_PAD_PDN_CTRL_1, 0x00},
+ {AQT1000_PAD_CTRL_PAD_PU_CTRL_0, 0x00},
+ {AQT1000_PAD_CTRL_PAD_PU_CTRL_1, 0x00},
+ {AQT1000_PAD_CTRL_GPIO_CTL_0_OE, 0x00},
+ {AQT1000_PAD_CTRL_GPIO_CTL_1_OE, 0x00},
+ {AQT1000_PAD_CTRL_GPIO_CTL_0_DATA, 0x00},
+ {AQT1000_PAD_CTRL_GPIO_CTL_1_DATA, 0x00},
+ {AQT1000_PAD_CTRL_PAD_DRVCTL, 0x00},
+ {AQT1000_PAD_CTRL_PIN_STATUS, 0x00},
+ {AQT1000_PAD_CTRL_MEM_CTRL, 0x00},
+ {AQT1000_PAD_CTRL_PAD_INP_DISABLE_0, 0x00},
+ {AQT1000_PAD_CTRL_PAD_INP_DISABLE_1, 0x00},
+ {AQT1000_PAD_CTRL_PIN_CTL_OE_0, 0x00},
+ {AQT1000_PAD_CTRL_PIN_CTL_OE_1, 0x00},
+ {AQT1000_PAD_CTRL_PIN_CTL_DATA_0, 0x00},
+ {AQT1000_PAD_CTRL_PIN_CTL_DATA_1, 0x00},
+ {AQT1000_PAD_CTRL_USB_PHY_CLK_DIV, 0x0F},
+ {AQT1000_PAD_CTRL_DEBUG_BUS_CDC, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_BUS_SEL, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_EN_1, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_EN_2, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_EN_3, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_EN_4, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_EN_5, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0, 0x00},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1, 0x01},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2, 0x02},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3, 0x03},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4, 0x04},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5, 0x05},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6, 0x06},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7, 0x07},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8, 0x08},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9, 0x09},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10, 0x0A},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11, 0x0B},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12, 0x0C},
+ {AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13, 0x0D},
+ {AQT1000_PAD_CTRL_DEBUG_READ_0, 0x0D},
+ {AQT1000_PAD_CTRL_DEBUG_READ_1, 0x0D},
+ {AQT1000_PAD_CTRL_DEBUG_READ_2, 0x0D},
+ {AQT1000_PAD_CTRL_DEBUG_READ_3, 0x0D},
+ {AQT1000_PAD_CTRL_FPGA_CTL, 0x00},
+};
+
+const u8 aqt1000_page0_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE0_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE0)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CHIP_ID_BYTE3)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_TEST0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_TEST1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT0)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT3)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT4)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT5)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT6)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT7)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT8)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT9)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT10)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT11)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT12)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT13)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT14)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_VAL_OUT15)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_NONNEGO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_SLAVE_ID_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_I2C_ACTIVE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CFG_MCLK)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CFG_MCLK2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_RST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_TEST0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_TEST1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT0)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT3)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT4)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT5)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT6)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT7)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT8)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT9)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT10)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT11)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT12)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT13)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT14)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT15)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG0_EFUSE2_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_BUS_MTRX_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_DMA_BUS_VOTE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_USB_BUS_VOTE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_BLSP_BUS_VOTE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_MEM_SD)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_FLL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_SPI_M)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_I2C_M)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_CLK_CFG_UART)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_RST_USB_SS)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_RST_BLSP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_RST_BUS_MTRX)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_RST_MISC)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL)] = AQT1000_RW,
+};
+
+const u8 aqt1000_page1_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE1_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_8)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_USER_CTL_9)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_L_VAL_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_L_VAL_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_DSM_FRAC_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_DSM_FRAC_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_CONFIG_CTL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_TEST_CTL_7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_FREQ_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_FREQ_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_FREQ_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_FREQ_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_SSC_CTL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_SSC_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_SSC_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_SSC_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_FLL_MODE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLL_STATUS_0)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_FLL_STATUS_1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_FLL_STATUS_2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_FLL_STATUS_3)] = AQT1000_RO,
+};
+
+const u8 aqt1000_page2_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE2_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_I2S_0_TX_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_I2S_0_RX_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_I2S_0_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_I2S_CLKSRC_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_I2S_HS_CLK_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_I2S_0_RST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_SHADOW_I2S_0_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_I2S_SHADOW_I2S_0_RX_CFG)] = AQT1000_RW,
+};
+
+const u8 aqt1000_page5_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE5_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_MCU_INT_POLARITY)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_MASK_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_0)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_3)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_4)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_5)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_STATUS_6)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_0)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_1)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_2)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_3)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_4)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_5)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_CLEAR_6)] = AQT1000_WO,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TYPE_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_EN_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_TEST_VAL_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_8)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_9)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_10)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_11)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_12)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_INT_DEST_13)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_INTR_CTRL_CLR_COMMIT)] = AQT1000_WO,
+};
+
+const u8 aqt1000_page6_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_ANA_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_BIAS)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_RX_SUPPLIES)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_HPH)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_AMIC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_AMIC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_AMIC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_AMIC3_HPF)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_MECH)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_ELECT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_ZDET)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_ANA_MBHC_RESULT_3)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MBHC_BTN7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MICB1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_ANA_MICB1_RAMP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BIAS_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BIAS_CCOMP_FINE_ADJ)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_R)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LED_LED_MISC_R)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_G)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LED_LED_MISC_G)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LED_LED_MODE_SEL_B)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LED_LED_MISC_B)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LDOH_MODE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LDOH_BIAS)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LDOH_STB_LOADS)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LDOH_MISC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LDOL_VDDCX_ADJUST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_LDOL_DISABLE_LDOL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_EN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_VOUT_SEL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_VCL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_VCL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_CTRL_CCL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_IBIAS_CTL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_BUCK_5V_ATEST_DTEST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PON_BG_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PON_TEST_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_CTL_CLK)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_CTL_ANA)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_CTL_SPARE_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_CTL_SPARE_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_CTL_BCS)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_MOISTURE_DET_FSM_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MBHC_TEST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MICB1_TEST_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MICB1_TEST_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MICB1_TEST_CTL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MICB1_MISC_MICB_MISC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MICB1_MISC_MICB_MISC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_ADC_VCM)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_BIAS_ATEST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_ADC_INT1_IB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_ADC_INT2_IB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_START)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_STOP_9P6M)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_COM_TXFE_DIV_STOP_12P288M)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_TEST_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_ADC_IB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_ATEST_REFCTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_TEST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_TEST_BLK_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_TXFE_CLKDIV)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_1_2_SAR1_ERR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_TX_1_2_SAR2_ERR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_TX_3_TEST_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_3_ADC_IB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_3_ATEST_REFCTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_3_TEST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_3_TEST_BLK_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_3_TXFE_CLKDIV)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TX_3_SAR1_ERR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_TX_3_SAR2_ERR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_TX_ATEST1_2_SEL)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CLASSH_MODE_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_MODE_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_MODE_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_VCL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_VCL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_CTRL_CCL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_BUCK_TMUX_A_D)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_BUCK_SW_DRV_CNTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLASSH_SPARE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_8)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEG_CTRL_9)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_VNEGDAC_CTRL_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_CTRL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_FLYBACK_TEST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_AUX_SW_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_PA_AUX_IN_CONN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_TIMER_DIV)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_OCP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_OCP_COUNT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_ATEST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_MISC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_HPH_LDO)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_HPH_PA)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_HPH_RDAC_LDO)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_HPH_CNP1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_HPH_LOWPOWER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_MISC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_MISC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_MISC4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_MISC5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_BUCK_RST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_BUCK_VREF_ERRAMP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_FLYB_ERRAMP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_FLYB_BUFF)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_BIAS_FLYB_MID_RST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_L_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_HPH_R_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_HPH_CNP_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_CNP_WG_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_CNP_WG_TIME)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_OCP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_AUTO_CHOP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_CHOP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_PA_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_PA_CTL2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_L_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_L_TEST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_L_ATEST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_R_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_R_TEST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_R_ATEST)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_RDAC_CLK_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_RDAC_CLK_CTL2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_RDAC_LDO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_REFBUFF_UHQA_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_REFBUFF_LP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_L_DAC_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_R_DAC_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPHLR_SURGE_COMP_SEL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPHLR_SURGE_EN)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPHLR_SURGE_MISC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPHLR_SURGE_STATUS)] = AQT1000_RO,
+};
+
+const u8 aqt1000_page7_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_ANA_NEW_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_ANA_HPH2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_ANA_HPH3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_MCLK1_PRG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_XO_CAP_XTP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_XO_CAP_XTM)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_PLL_ENABLES)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_PLL_PRESET)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_PLL_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_CTL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_CTL_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_PLUG_DETECT_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_ZDET_ANA_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_ZDET_RAMP_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_FSM_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MBHC_NEW_ADC_RESULT)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_VREF_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_MISC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_MISC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_HPH_TIMER4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_HPH_NEW_INT_PA_RDAC_MISC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_CLK_TEST1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_XO_TEST1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_XO_TEST2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_POST_DIV_REG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_POST_DIV_REG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_REF_DIV_REG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_REF_DIV_REG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_FILTER_REG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_FILTER_REG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_L_VAL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_M_VAL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_PLL_N_VAL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_TEST_REG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_VCO_PROG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_TEST_REG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_LDO_LOCK_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)] =
+ AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MBHC_NEW_INT_SPARE_2)] = AQT1000_RW,
+};
+
+const u8 aqt1000_page10_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE10_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_CLK_RESET_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_MODE_1_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_MODE_2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_FF_SHIFT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_FB_SHIFT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FF_A_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FF_B_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_LPF_FB_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_SMLPF_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_IIR_ADAPT_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_IIR_COEFF_1_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_IIR_COEFF_2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_FF_A_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_FF_B_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_FB_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_RC_COMMON_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_FIFO_COMMON_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC0_STATUS_FIFO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC1_CLK_RESET_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_MODE_1_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_MODE_2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_FF_SHIFT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_FB_SHIFT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FF_A_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FF_B_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_LPF_FB_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_SMLPF_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_IIR_ADAPT_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_IIR_COEFF_1_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_IIR_COEFF_2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_FF_A_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_FF_B_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_FB_GAIN_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_RC_COMMON_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_FIFO_COMMON_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_ANC1_STATUS_FIFO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_VOL_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX0_TX_PATH_SEC6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_VOL_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX1_TX_PATH_SEC6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_VOL_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX2_TX_PATH_SEC7)] = AQT1000_RW,
+};
+
+const u8 aqt1000_page11_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE11_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL6)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER1_CTL7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL6)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_COMPANDER2_CTL7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_VOL_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_VOL_MIX_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_SEC7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_MIX_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_VOL_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_CFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_VOL_MIX_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_SEC7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_SEC0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_MIX_SEC1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_PATH_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_COEF_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR0_COEF_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_PATH_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_COEF_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_EQ_IIR1_COEF_CFG1)] = AQT1000_RW,
+};
+
+const u8 aqt1000_page12_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE12_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_CRC)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_DLY_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_DECAY_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_HPH_V_PA)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_EAR_V_PA)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_HPH_V_HD)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_EAR_V_HD)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_K1_MSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_K1_LSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_K2_MSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_K2_LSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_HPH)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_IDLE_EAR)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_TEST0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_TEST1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLSH_OVR_VREF)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_CLK_RST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC0_STATUS_FIFO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_CLK_RST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_MIXING_ASRC1_STATUS_FIFO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CLK_RST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_SIDETONE_ASRC0_STATUS_FIFO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC0_CLK_RST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC0_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC0_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC0_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC0_STATUS_FIFO)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC1_CLK_RST_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC1_CTL0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC1_CTL1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC1_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_EC_ASRC1_STATUS_FIFO)] = AQT1000_RO,
+};
+
+const u8 aqt1000_page13_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE13_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_DSD_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_ANC_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] =
+ AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] =
+ AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_TOP_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_WR_LSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_WR_MSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_LUT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_RD_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHL_COMP_RD_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_WR_LSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_WR_MSB)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_LUT)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_RD_LSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_TOP_HPHR_COMP_RD_MSB)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_DSD0_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD0_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD0_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD0_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD0_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD0_CFG4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD0_CFG5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_CFG4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DSD1_CFG5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_PATH_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_RX_IDLE_DET_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_CFG4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DOP_DET_STATUS0)] = AQT1000_RO,
+};
+
+const u8 aqt1000_page15_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE15_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR)] = AQT1000_RW,
+};
+
+const u8 aqt1000_page128_reg_access[AQT1000_PAGE_SIZE] = {
+ [AQT1000_REG(AQT1000_PAGE128_PAGE_REGISTER)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_SPI_CLK_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_SPI_MOSI_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_SPI_MISO_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_SPI_CS_N_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO1_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO2_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO3_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO4_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO5_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO6_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO7_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO8_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO9_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_TLMM_GPIO10_PINCFG)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PDN_CTRL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PDN_CTRL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PU_CTRL_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_PU_CTRL_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_0_OE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_1_OE)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_0_DATA)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_GPIO_CTL_1_DATA)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_DRVCTL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PIN_STATUS)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_PAD_CTRL_MEM_CTRL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_INP_DISABLE_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PAD_INP_DISABLE_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_OE_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_OE_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_DATA_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_PIN_CTL_DATA_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_USB_PHY_CLK_DIV)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_BUS_CDC)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_BUS_SEL)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_EN_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13)] = AQT1000_RW,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_0)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_1)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_2)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_PAD_CTRL_DEBUG_READ_3)] = AQT1000_RO,
+ [AQT1000_REG(AQT1000_PAD_CTRL_FPGA_CTL)] = AQT1000_RW,
+};
+
+const u8 * const aqt1000_reg[AQT1000_PAGE_MAX] = {
+ [AQT1000_PAGE_0] = aqt1000_page0_reg_access,
+ [AQT1000_PAGE_1] = aqt1000_page1_reg_access,
+ [AQT1000_PAGE_2] = aqt1000_page2_reg_access,
+ [AQT1000_PAGE_5] = aqt1000_page5_reg_access,
+ [AQT1000_PAGE_6] = aqt1000_page6_reg_access,
+ [AQT1000_PAGE_7] = aqt1000_page7_reg_access,
+ [AQT1000_PAGE_10] = aqt1000_page10_reg_access,
+ [AQT1000_PAGE_11] = aqt1000_page11_reg_access,
+ [AQT1000_PAGE_12] = aqt1000_page12_reg_access,
+ [AQT1000_PAGE_13] = aqt1000_page13_reg_access,
+ [AQT1000_PAGE_15] = aqt1000_page15_reg_access,
+ [AQT1000_PAGE_128] = aqt1000_page128_reg_access,
+};
+
+#endif /* _AQT1000_REG_DEFAULTS_H */
diff --git a/asoc/codecs/aqt1000/aqt1000-registers.h b/asoc/codecs/aqt1000/aqt1000-registers.h
new file mode 100644
index 0000000..9033466
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-registers.h
@@ -0,0 +1,881 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AQT1000_REGISTERS_H
+#define _AQT1000_REGISTERS_H
+
+#define AQT1000_PAGE0_BASE (0x00000000)
+#define AQT1000_PAGE0_PAGE_REGISTER (0x00000000)
+#define AQT1000_CHIP_CFG0_BASE (0x00000001)
+#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE0 (0x00000001)
+#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE1 (0x00000002)
+#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE2 (0x00000003)
+#define AQT1000_CHIP_CFG0_CHIP_ID_BYTE3 (0x00000004)
+#define AQT1000_CHIP_CFG0_EFUSE_CTL (0x00000005)
+#define AQT1000_CHIP_CFG0_EFUSE_TEST0 (0x00000006)
+#define AQT1000_CHIP_CFG0_EFUSE_TEST1 (0x00000007)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT0 (0x00000009)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT1 (0x0000000A)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT2 (0x0000000B)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT3 (0x0000000C)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT4 (0x0000000D)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT5 (0x0000000E)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT6 (0x0000000F)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT7 (0x00000010)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT8 (0x00000011)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT9 (0x00000012)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT10 (0x00000013)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT11 (0x00000014)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT12 (0x00000015)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT13 (0x00000016)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT14 (0x00000017)
+#define AQT1000_CHIP_CFG0_EFUSE_VAL_OUT15 (0x00000018)
+#define AQT1000_CHIP_CFG0_EFUSE_STATUS (0x00000019)
+#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_NONNEGO (0x0000001A)
+#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_1 (0x0000001B)
+#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_2 (0x0000001C)
+#define AQT1000_CHIP_CFG0_I2C_SLAVE_ID_3 (0x0000001D)
+#define AQT1000_CHIP_CFG0_I2C_ACTIVE (0x00000020)
+#define AQT1000_CHIP_CFG0_CLK_CFG_MCLK (0x00000021)
+#define AQT1000_CHIP_CFG0_CLK_CFG_MCLK2 (0x00000022)
+#define AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG (0x00000023)
+#define AQT1000_CHIP_CFG0_RST_CTL (0x00000032)
+#define AQT1000_CHIP_CFG0_EFUSE2_CTL (0x0000003D)
+#define AQT1000_CHIP_CFG0_EFUSE2_TEST0 (0x0000003E)
+#define AQT1000_CHIP_CFG0_EFUSE2_TEST1 (0x0000003F)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT0 (0x00000040)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT1 (0x00000041)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT2 (0x00000042)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT3 (0x00000043)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT4 (0x00000044)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT5 (0x00000045)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT6 (0x00000046)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT7 (0x00000047)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT8 (0x00000048)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT9 (0x00000049)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT10 (0x0000004A)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT11 (0x0000004B)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT12 (0x0000004C)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT13 (0x0000004D)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT14 (0x0000004E)
+#define AQT1000_CHIP_CFG0_EFUSE2_VAL_OUT15 (0x0000004F)
+#define AQT1000_CHIP_CFG0_EFUSE2_STATUS (0x00000050)
+#define AQT1000_CHIP_CFG1_BASE (0x00000051)
+#define AQT1000_CHIP_CFG1_PWR_CTL (0x00000051)
+#define AQT1000_CHIP_CFG1_BUS_MTRX_CFG (0x00000052)
+#define AQT1000_CHIP_CFG1_DMA_BUS_VOTE (0x00000053)
+#define AQT1000_CHIP_CFG1_USB_BUS_VOTE (0x00000054)
+#define AQT1000_CHIP_CFG1_BLSP_BUS_VOTE (0x00000055)
+#define AQT1000_CHIP_CFG1_PWR_MEM_SD (0x00000059)
+#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_RAM (0x0000005C)
+#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_SD_ROM (0x0000005D)
+#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_RAM (0x0000005E)
+#define AQT1000_CHIP_CFG1_PWR_SYS_MEM_FORCE_DS_ROM (0x0000005F)
+#define AQT1000_CHIP_CFG1_CLK_CFG_FLL (0x00000061)
+#define AQT1000_CHIP_CFG1_CLK_CFG_SPI_M (0x00000062)
+#define AQT1000_CHIP_CFG1_CLK_CFG_I2C_M (0x00000063)
+#define AQT1000_CHIP_CFG1_CLK_CFG_UART (0x00000064)
+#define AQT1000_CHIP_CFG1_RST_USB_SS (0x00000071)
+#define AQT1000_CHIP_CFG1_RST_BLSP (0x00000072)
+#define AQT1000_CHIP_CFG1_RST_BUS_MTRX (0x00000073)
+#define AQT1000_CHIP_CFG1_RST_MISC (0x00000074)
+#define AQT1000_CHIP_CFG1_ANA_WAIT_STATE_CTL (0x00000081)
+#define AQT1000_PAGE1_BASE (0x00000100)
+#define AQT1000_PAGE1_PAGE_REGISTER (0x00000100)
+#define AQT1000_FLL_BASE (0x00000101)
+#define AQT1000_FLL_USER_CTL_0 (0x00000101)
+#define AQT1000_FLL_USER_CTL_1 (0x00000102)
+#define AQT1000_FLL_USER_CTL_2 (0x00000103)
+#define AQT1000_FLL_USER_CTL_3 (0x00000104)
+#define AQT1000_FLL_USER_CTL_4 (0x00000105)
+#define AQT1000_FLL_USER_CTL_5 (0x00000106)
+#define AQT1000_FLL_USER_CTL_6 (0x00000107)
+#define AQT1000_FLL_USER_CTL_7 (0x00000108)
+#define AQT1000_FLL_USER_CTL_8 (0x00000109)
+#define AQT1000_FLL_USER_CTL_9 (0x0000010A)
+#define AQT1000_FLL_L_VAL_CTL_0 (0x0000010B)
+#define AQT1000_FLL_L_VAL_CTL_1 (0x0000010C)
+#define AQT1000_FLL_DSM_FRAC_CTL_0 (0x0000010D)
+#define AQT1000_FLL_DSM_FRAC_CTL_1 (0x0000010E)
+#define AQT1000_FLL_CONFIG_CTL_0 (0x0000010F)
+#define AQT1000_FLL_CONFIG_CTL_1 (0x00000110)
+#define AQT1000_FLL_CONFIG_CTL_2 (0x00000111)
+#define AQT1000_FLL_CONFIG_CTL_3 (0x00000112)
+#define AQT1000_FLL_CONFIG_CTL_4 (0x00000113)
+#define AQT1000_FLL_TEST_CTL_0 (0x00000114)
+#define AQT1000_FLL_TEST_CTL_1 (0x00000115)
+#define AQT1000_FLL_TEST_CTL_2 (0x00000116)
+#define AQT1000_FLL_TEST_CTL_3 (0x00000117)
+#define AQT1000_FLL_TEST_CTL_4 (0x00000118)
+#define AQT1000_FLL_TEST_CTL_5 (0x00000119)
+#define AQT1000_FLL_TEST_CTL_6 (0x0000011A)
+#define AQT1000_FLL_TEST_CTL_7 (0x0000011B)
+#define AQT1000_FLL_FREQ_CTL_0 (0x0000011C)
+#define AQT1000_FLL_FREQ_CTL_1 (0x0000011D)
+#define AQT1000_FLL_FREQ_CTL_2 (0x0000011E)
+#define AQT1000_FLL_FREQ_CTL_3 (0x0000011F)
+#define AQT1000_FLL_SSC_CTL_0 (0x00000120)
+#define AQT1000_FLL_SSC_CTL_1 (0x00000121)
+#define AQT1000_FLL_SSC_CTL_2 (0x00000122)
+#define AQT1000_FLL_SSC_CTL_3 (0x00000123)
+#define AQT1000_FLL_FLL_MODE (0x00000124)
+#define AQT1000_FLL_STATUS_0 (0x00000125)
+#define AQT1000_FLL_STATUS_1 (0x00000126)
+#define AQT1000_FLL_STATUS_2 (0x00000127)
+#define AQT1000_FLL_STATUS_3 (0x00000128)
+#define AQT1000_PAGE2_BASE (0x00000200)
+#define AQT1000_PAGE2_PAGE_REGISTER (0x00000200)
+#define AQT1000_I2S_BASE (0x00000201)
+#define AQT1000_I2S_I2S_0_TX_CFG (0x00000201)
+#define AQT1000_I2S_I2S_0_RX_CFG (0x00000202)
+#define AQT1000_I2S_I2S_0_CTL (0x00000203)
+#define AQT1000_I2S_I2S_CLKSRC_CTL (0x00000204)
+#define AQT1000_I2S_I2S_HS_CLK_CTL (0x00000205)
+#define AQT1000_I2S_I2S_0_RST (0x00000206)
+#define AQT1000_I2S_SHADOW_I2S_0_CTL (0x00000207)
+#define AQT1000_I2S_SHADOW_I2S_0_RX_CFG (0x00000208)
+#define AQT1000_PAGE5_BASE (0x00000500)
+#define AQT1000_PAGE5_PAGE_REGISTER (0x00000500)
+#define AQT1000_INTR_CTRL_INTR_CTRL_BASE (0x00000501)
+#define AQT1000_INTR_CTRL_MCU_INT_POLARITY (0x00000501)
+#define AQT1000_INTR_CTRL_INT_MASK_0 (0x00000502)
+#define AQT1000_INTR_CTRL_INT_MASK_1 (0x00000503)
+#define AQT1000_INTR_CTRL_INT_MASK_2 (0x00000504)
+#define AQT1000_INTR_CTRL_INT_MASK_3 (0x00000505)
+#define AQT1000_INTR_CTRL_INT_MASK_4 (0x00000506)
+#define AQT1000_INTR_CTRL_INT_MASK_5 (0x00000507)
+#define AQT1000_INTR_CTRL_INT_MASK_6 (0x00000508)
+#define AQT1000_INTR_CTRL_INT_STATUS_0 (0x00000509)
+#define AQT1000_INTR_CTRL_INT_STATUS_1 (0x0000050A)
+#define AQT1000_INTR_CTRL_INT_STATUS_2 (0x0000050B)
+#define AQT1000_INTR_CTRL_INT_STATUS_3 (0x0000050C)
+#define AQT1000_INTR_CTRL_INT_STATUS_4 (0x0000050D)
+#define AQT1000_INTR_CTRL_INT_STATUS_5 (0x0000050E)
+#define AQT1000_INTR_CTRL_INT_STATUS_6 (0x0000050F)
+#define AQT1000_INTR_CTRL_INT_CLEAR_0 (0x00000510)
+#define AQT1000_INTR_CTRL_INT_CLEAR_1 (0x00000511)
+#define AQT1000_INTR_CTRL_INT_CLEAR_2 (0x00000512)
+#define AQT1000_INTR_CTRL_INT_CLEAR_3 (0x00000513)
+#define AQT1000_INTR_CTRL_INT_CLEAR_4 (0x00000514)
+#define AQT1000_INTR_CTRL_INT_CLEAR_5 (0x00000515)
+#define AQT1000_INTR_CTRL_INT_CLEAR_6 (0x00000516)
+#define AQT1000_INTR_CTRL_INT_TYPE_0 (0x00000517)
+#define AQT1000_INTR_CTRL_INT_TYPE_1 (0x00000518)
+#define AQT1000_INTR_CTRL_INT_TYPE_2 (0x00000519)
+#define AQT1000_INTR_CTRL_INT_TYPE_3 (0x0000051A)
+#define AQT1000_INTR_CTRL_INT_TYPE_4 (0x0000051B)
+#define AQT1000_INTR_CTRL_INT_TYPE_5 (0x0000051C)
+#define AQT1000_INTR_CTRL_INT_TYPE_6 (0x0000051D)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_0 (0x0000051E)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_1 (0x0000051F)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_2 (0x00000520)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_3 (0x00000521)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_4 (0x00000522)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_5 (0x00000523)
+#define AQT1000_INTR_CTRL_INT_TEST_EN_6 (0x00000524)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_0 (0x00000525)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_1 (0x00000526)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_2 (0x00000527)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_3 (0x00000528)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_4 (0x00000529)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_5 (0x0000052A)
+#define AQT1000_INTR_CTRL_INT_TEST_VAL_6 (0x0000052B)
+#define AQT1000_INTR_CTRL_INT_DEST_0 (0x0000052C)
+#define AQT1000_INTR_CTRL_INT_DEST_1 (0x0000052D)
+#define AQT1000_INTR_CTRL_INT_DEST_2 (0x0000052E)
+#define AQT1000_INTR_CTRL_INT_DEST_3 (0x0000052F)
+#define AQT1000_INTR_CTRL_INT_DEST_4 (0x00000530)
+#define AQT1000_INTR_CTRL_INT_DEST_5 (0x00000531)
+#define AQT1000_INTR_CTRL_INT_DEST_6 (0x00000532)
+#define AQT1000_INTR_CTRL_INT_DEST_7 (0x00000533)
+#define AQT1000_INTR_CTRL_INT_DEST_8 (0x00000534)
+#define AQT1000_INTR_CTRL_INT_DEST_9 (0x00000535)
+#define AQT1000_INTR_CTRL_INT_DEST_10 (0x00000536)
+#define AQT1000_INTR_CTRL_INT_DEST_11 (0x00000537)
+#define AQT1000_INTR_CTRL_INT_DEST_12 (0x00000538)
+#define AQT1000_INTR_CTRL_INT_DEST_13 (0x00000539)
+#define AQT1000_INTR_CTRL_CLR_COMMIT (0x000005E1)
+#define AQT1000_ANA_BASE (0x00000600)
+#define AQT1000_ANA_PAGE_REGISTER (0x00000600)
+#define AQT1000_ANA_BIAS (0x00000601)
+#define AQT1000_ANA_RX_SUPPLIES (0x00000608)
+#define AQT1000_ANA_HPH (0x00000609)
+#define AQT1000_ANA_AMIC1 (0x0000060E)
+#define AQT1000_ANA_AMIC2 (0x0000060F)
+#define AQT1000_ANA_AMIC3 (0x00000610)
+#define AQT1000_ANA_AMIC3_HPF (0x00000611)
+#define AQT1000_ANA_MBHC_MECH (0x00000614)
+#define AQT1000_ANA_MBHC_ELECT (0x00000615)
+#define AQT1000_ANA_MBHC_ZDET (0x00000616)
+#define AQT1000_ANA_MBHC_RESULT_1 (0x00000617)
+#define AQT1000_ANA_MBHC_RESULT_2 (0x00000618)
+#define AQT1000_ANA_MBHC_RESULT_3 (0x00000619)
+#define AQT1000_ANA_MBHC_BTN0 (0x0000061A)
+#define AQT1000_ANA_MBHC_BTN1 (0x0000061B)
+#define AQT1000_ANA_MBHC_BTN2 (0x0000061C)
+#define AQT1000_ANA_MBHC_BTN3 (0x0000061D)
+#define AQT1000_ANA_MBHC_BTN4 (0x0000061E)
+#define AQT1000_ANA_MBHC_BTN5 (0x0000061F)
+#define AQT1000_ANA_MBHC_BTN6 (0x00000620)
+#define AQT1000_ANA_MBHC_BTN7 (0x00000621)
+#define AQT1000_ANA_MICB1 (0x00000622)
+#define AQT1000_ANA_MICB1_RAMP (0x00000624)
+#define AQT1000_BIAS_BASE (0x00000628)
+#define AQT1000_BIAS_CTL (0x00000628)
+#define AQT1000_BIAS_CCOMP_FINE_ADJ (0x00000629)
+#define AQT1000_LED_BASE (0x0000062E)
+#define AQT1000_LED_LED_MODE_SEL_R (0x0000062E)
+#define AQT1000_LED_LED_MISC_R (0x0000062F)
+#define AQT1000_LED_LED_MODE_SEL_G (0x00000630)
+#define AQT1000_LED_LED_MISC_G (0x00000631)
+#define AQT1000_LED_LED_MODE_SEL_B (0x00000632)
+#define AQT1000_LED_LED_MISC_B (0x00000633)
+#define AQT1000_LDOH_BASE (0x0000063A)
+#define AQT1000_LDOH_MODE (0x0000063A)
+#define AQT1000_LDOH_BIAS (0x0000063B)
+#define AQT1000_LDOH_STB_LOADS (0x0000063C)
+#define AQT1000_LDOH_MISC1 (0x0000063D)
+#define AQT1000_LDOL_BASE (0x00000640)
+#define AQT1000_LDOL_VDDCX_ADJUST (0x00000640)
+#define AQT1000_LDOL_DISABLE_LDOL (0x00000641)
+#define AQT1000_BUCK_5V_BASE (0x00000644)
+#define AQT1000_BUCK_5V_EN_CTL (0x00000644)
+#define AQT1000_BUCK_5V_VOUT_SEL (0x00000645)
+#define AQT1000_BUCK_5V_CTRL_VCL_1 (0x00000646)
+#define AQT1000_BUCK_5V_CTRL_VCL_2 (0x00000647)
+#define AQT1000_BUCK_5V_CTRL_CCL_2 (0x00000648)
+#define AQT1000_BUCK_5V_CTRL_CCL_1 (0x00000649)
+#define AQT1000_BUCK_5V_CTRL_CCL_3 (0x0000064A)
+#define AQT1000_BUCK_5V_CTRL_CCL_4 (0x0000064B)
+#define AQT1000_BUCK_5V_CTRL_CCL_5 (0x0000064C)
+#define AQT1000_BUCK_5V_IBIAS_CTL_1 (0x0000064D)
+#define AQT1000_BUCK_5V_IBIAS_CTL_2 (0x0000064E)
+#define AQT1000_BUCK_5V_IBIAS_CTL_3 (0x0000064F)
+#define AQT1000_BUCK_5V_IBIAS_CTL_4 (0x00000650)
+#define AQT1000_BUCK_5V_IBIAS_CTL_5 (0x00000651)
+#define AQT1000_BUCK_5V_ATEST_DTEST_CTL (0x00000652)
+#define AQT1000_PON_BASE (0x00000653)
+#define AQT1000_PON_BG_CTRL (0x00000653)
+#define AQT1000_PON_TEST_CTRL (0x00000654)
+#define AQT1000_MBHC_BASE (0x00000656)
+#define AQT1000_MBHC_CTL_CLK (0x00000656)
+#define AQT1000_MBHC_CTL_ANA (0x00000657)
+#define AQT1000_MBHC_CTL_SPARE_1 (0x00000658)
+#define AQT1000_MBHC_CTL_SPARE_2 (0x00000659)
+#define AQT1000_MBHC_CTL_BCS (0x0000065A)
+#define AQT1000_MBHC_MOISTURE_DET_FSM_STATUS (0x0000065B)
+#define AQT1000_MBHC_TEST_CTL (0x0000065C)
+#define AQT1000_MICB1_BASE (0x0000066B)
+#define AQT1000_MICB1_TEST_CTL_1 (0x0000066B)
+#define AQT1000_MICB1_TEST_CTL_2 (0x0000066C)
+#define AQT1000_MICB1_TEST_CTL_3 (0x0000066D)
+#define AQT1000_MICB1_MISC_BASE (0x0000066E)
+#define AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS (0x0000066E)
+#define AQT1000_MICB1_MISC_MICB_MISC1 (0x0000066F)
+#define AQT1000_MICB1_MISC_MICB_MISC2 (0x00000670)
+#define AQT1000_TX_COM_BASE (0x00000677)
+#define AQT1000_TX_COM_ADC_VCM (0x00000677)
+#define AQT1000_TX_COM_BIAS_ATEST (0x00000678)
+#define AQT1000_TX_COM_ADC_INT1_IB (0x00000679)
+#define AQT1000_TX_COM_ADC_INT2_IB (0x0000067A)
+#define AQT1000_TX_COM_TXFE_DIV_CTL (0x0000067B)
+#define AQT1000_TX_COM_TXFE_DIV_START (0x0000067C)
+#define AQT1000_TX_COM_TXFE_DIV_STOP_9P6M (0x0000067D)
+#define AQT1000_TX_COM_TXFE_DIV_STOP_12P288M (0x0000067E)
+#define AQT1000_TX_1_2_BASE (0x0000067F)
+#define AQT1000_TX_1_2_TEST_EN (0x0000067F)
+#define AQT1000_TX_1_2_ADC_IB (0x00000680)
+#define AQT1000_TX_1_2_ATEST_REFCTL (0x00000681)
+#define AQT1000_TX_1_2_TEST_CTL (0x00000682)
+#define AQT1000_TX_1_2_TEST_BLK_EN (0x00000683)
+#define AQT1000_TX_1_2_TXFE_CLKDIV (0x00000684)
+#define AQT1000_TX_1_2_SAR1_ERR (0x00000685)
+#define AQT1000_TX_1_2_SAR2_ERR (0x00000686)
+#define AQT1000_TX_3_BASE (0x00000687)
+#define AQT1000_TX_3_TEST_EN (0x00000687)
+#define AQT1000_TX_3_ADC_IB (0x00000688)
+#define AQT1000_TX_3_ATEST_REFCTL (0x00000689)
+#define AQT1000_TX_3_TEST_CTL (0x0000068A)
+#define AQT1000_TX_3_TEST_BLK_EN (0x0000068B)
+#define AQT1000_TX_3_TXFE_CLKDIV (0x0000068C)
+#define AQT1000_TX_3_SAR1_ERR (0x0000068D)
+#define AQT1000_TX_3_SAR2_ERR (0x0000068E)
+#define AQT1000_TX_BASE (0x0000068F)
+#define AQT1000_TX_ATEST1_2_SEL (0x0000068F)
+#define AQT1000_CLASSH_BASE (0x00000697)
+#define AQT1000_CLASSH_MODE_1 (0x00000697)
+#define AQT1000_CLASSH_MODE_2 (0x00000698)
+#define AQT1000_CLASSH_MODE_3 (0x00000699)
+#define AQT1000_CLASSH_CTRL_VCL_1 (0x0000069A)
+#define AQT1000_CLASSH_CTRL_VCL_2 (0x0000069B)
+#define AQT1000_CLASSH_CTRL_CCL_1 (0x0000069C)
+#define AQT1000_CLASSH_CTRL_CCL_2 (0x0000069D)
+#define AQT1000_CLASSH_CTRL_CCL_3 (0x0000069E)
+#define AQT1000_CLASSH_CTRL_CCL_4 (0x0000069F)
+#define AQT1000_CLASSH_CTRL_CCL_5 (0x000006A0)
+#define AQT1000_CLASSH_BUCK_TMUX_A_D (0x000006A1)
+#define AQT1000_CLASSH_BUCK_SW_DRV_CNTL (0x000006A2)
+#define AQT1000_CLASSH_SPARE (0x000006A3)
+#define AQT1000_FLYBACK_BASE (0x000006A4)
+#define AQT1000_FLYBACK_EN (0x000006A4)
+#define AQT1000_FLYBACK_VNEG_CTRL_1 (0x000006A5)
+#define AQT1000_FLYBACK_VNEG_CTRL_2 (0x000006A6)
+#define AQT1000_FLYBACK_VNEG_CTRL_3 (0x000006A7)
+#define AQT1000_FLYBACK_VNEG_CTRL_4 (0x000006A8)
+#define AQT1000_FLYBACK_VNEG_CTRL_5 (0x000006A9)
+#define AQT1000_FLYBACK_VNEG_CTRL_6 (0x000006AA)
+#define AQT1000_FLYBACK_VNEG_CTRL_7 (0x000006AB)
+#define AQT1000_FLYBACK_VNEG_CTRL_8 (0x000006AC)
+#define AQT1000_FLYBACK_VNEG_CTRL_9 (0x000006AD)
+#define AQT1000_FLYBACK_VNEGDAC_CTRL_1 (0x000006AE)
+#define AQT1000_FLYBACK_VNEGDAC_CTRL_2 (0x000006AF)
+#define AQT1000_FLYBACK_VNEGDAC_CTRL_3 (0x000006B0)
+#define AQT1000_FLYBACK_CTRL_1 (0x000006B1)
+#define AQT1000_FLYBACK_TEST_CTL (0x000006B2)
+#define AQT1000_RX_BASE (0x000006B3)
+#define AQT1000_RX_AUX_SW_CTL (0x000006B3)
+#define AQT1000_RX_PA_AUX_IN_CONN (0x000006B4)
+#define AQT1000_RX_TIMER_DIV (0x000006B5)
+#define AQT1000_RX_OCP_CTL (0x000006B6)
+#define AQT1000_RX_OCP_COUNT (0x000006B7)
+#define AQT1000_RX_BIAS_ATEST (0x000006B8)
+#define AQT1000_RX_BIAS_MISC1 (0x000006B9)
+#define AQT1000_RX_BIAS_HPH_LDO (0x000006BA)
+#define AQT1000_RX_BIAS_HPH_PA (0x000006BB)
+#define AQT1000_RX_BIAS_HPH_RDACBUFF_CNP2 (0x000006BC)
+#define AQT1000_RX_BIAS_HPH_RDAC_LDO (0x000006BD)
+#define AQT1000_RX_BIAS_HPH_CNP1 (0x000006BE)
+#define AQT1000_RX_BIAS_HPH_LOWPOWER (0x000006BF)
+#define AQT1000_RX_BIAS_MISC2 (0x000006C0)
+#define AQT1000_RX_BIAS_MISC3 (0x000006C1)
+#define AQT1000_RX_BIAS_MISC4 (0x000006C2)
+#define AQT1000_RX_BIAS_MISC5 (0x000006C3)
+#define AQT1000_RX_BIAS_BUCK_RST (0x000006C4)
+#define AQT1000_RX_BIAS_BUCK_VREF_ERRAMP (0x000006C5)
+#define AQT1000_RX_BIAS_FLYB_ERRAMP (0x000006C6)
+#define AQT1000_RX_BIAS_FLYB_BUFF (0x000006C7)
+#define AQT1000_RX_BIAS_FLYB_MID_RST (0x000006C8)
+#define AQT1000_HPH_BASE (0x000006C9)
+#define AQT1000_HPH_L_STATUS (0x000006C9)
+#define AQT1000_HPH_R_STATUS (0x000006CA)
+#define AQT1000_HPH_CNP_EN (0x000006CB)
+#define AQT1000_HPH_CNP_WG_CTL (0x000006CC)
+#define AQT1000_HPH_CNP_WG_TIME (0x000006CD)
+#define AQT1000_HPH_OCP_CTL (0x000006CE)
+#define AQT1000_HPH_AUTO_CHOP (0x000006CF)
+#define AQT1000_HPH_CHOP_CTL (0x000006D0)
+#define AQT1000_HPH_PA_CTL1 (0x000006D1)
+#define AQT1000_HPH_PA_CTL2 (0x000006D2)
+#define AQT1000_HPH_L_EN (0x000006D3)
+#define AQT1000_HPH_L_TEST (0x000006D4)
+#define AQT1000_HPH_L_ATEST (0x000006D5)
+#define AQT1000_HPH_R_EN (0x000006D6)
+#define AQT1000_HPH_R_TEST (0x000006D7)
+#define AQT1000_HPH_R_ATEST (0x000006D8)
+#define AQT1000_HPH_RDAC_CLK_CTL1 (0x000006D9)
+#define AQT1000_HPH_RDAC_CLK_CTL2 (0x000006DA)
+#define AQT1000_HPH_RDAC_LDO_CTL (0x000006DB)
+#define AQT1000_HPH_RDAC_CHOP_CLK_LP_CTL (0x000006DC)
+#define AQT1000_HPH_REFBUFF_UHQA_CTL (0x000006DD)
+#define AQT1000_HPH_REFBUFF_LP_CTL (0x000006DE)
+#define AQT1000_HPH_L_DAC_CTL (0x000006DF)
+#define AQT1000_HPH_R_DAC_CTL (0x000006E0)
+#define AQT1000_HPHLR_BASE (0x000006E1)
+#define AQT1000_HPHLR_SURGE_COMP_SEL (0x000006E1)
+#define AQT1000_HPHLR_SURGE_EN (0x000006E2)
+#define AQT1000_HPHLR_SURGE_MISC1 (0x000006E3)
+#define AQT1000_HPHLR_SURGE_STATUS (0x000006E4)
+#define AQT1000_ANA_NEW_BASE (0x00000700)
+#define AQT1000_ANA_NEW_PAGE_REGISTER (0x00000700)
+#define AQT1000_HPH_NEW_BASE (0x00000701)
+#define AQT1000_HPH_NEW_ANA_HPH2 (0x00000701)
+#define AQT1000_HPH_NEW_ANA_HPH3 (0x00000702)
+#define AQT1000_CLK_SYS_BASE (0x0000070E)
+#define AQT1000_CLK_SYS_MCLK1_PRG (0x0000070E)
+#define AQT1000_CLK_SYS_MCLK2_I2S_HS_CLK_PRG (0x0000070F)
+#define AQT1000_CLK_SYS_XO_CAP_XTP (0x00000710)
+#define AQT1000_CLK_SYS_XO_CAP_XTM (0x00000711)
+#define AQT1000_CLK_SYS_PLL_ENABLES (0x00000712)
+#define AQT1000_CLK_SYS_PLL_PRESET (0x00000713)
+#define AQT1000_CLK_SYS_PLL_STATUS (0x00000714)
+#define AQT1000_MBHC_NEW_BASE (0x0000071F)
+#define AQT1000_MBHC_NEW_ELECT_REM_CLAMP_CTL (0x0000071F)
+#define AQT1000_MBHC_NEW_CTL_1 (0x00000720)
+#define AQT1000_MBHC_NEW_CTL_2 (0x00000721)
+#define AQT1000_MBHC_NEW_PLUG_DETECT_CTL (0x00000722)
+#define AQT1000_MBHC_NEW_ZDET_ANA_CTL (0x00000723)
+#define AQT1000_MBHC_NEW_ZDET_RAMP_CTL (0x00000724)
+#define AQT1000_MBHC_NEW_FSM_STATUS (0x00000725)
+#define AQT1000_MBHC_NEW_ADC_RESULT (0x00000726)
+#define AQT1000_HPH_NEW_INT_BASE (0x00000732)
+#define AQT1000_HPH_NEW_INT_RDAC_GAIN_CTL (0x00000732)
+#define AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_L (0x00000733)
+#define AQT1000_HPH_NEW_INT_RDAC_VREF_CTL (0x00000734)
+#define AQT1000_HPH_NEW_INT_RDAC_OVERRIDE_CTL (0x00000735)
+#define AQT1000_HPH_NEW_INT_RDAC_HD2_CTL_R (0x00000736)
+#define AQT1000_HPH_NEW_INT_PA_MISC1 (0x00000737)
+#define AQT1000_HPH_NEW_INT_PA_MISC2 (0x00000738)
+#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC (0x00000739)
+#define AQT1000_HPH_NEW_INT_HPH_TIMER1 (0x0000073A)
+#define AQT1000_HPH_NEW_INT_HPH_TIMER2 (0x0000073B)
+#define AQT1000_HPH_NEW_INT_HPH_TIMER3 (0x0000073C)
+#define AQT1000_HPH_NEW_INT_HPH_TIMER4 (0x0000073D)
+#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC2 (0x0000073E)
+#define AQT1000_HPH_NEW_INT_PA_RDAC_MISC3 (0x0000073F)
+#define AQT1000_RX_NEW_INT_BASE (0x00000745)
+#define AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (0x00000745)
+#define AQT1000_RX_NEW_INT_HPH_RDAC_BIAS_ULP (0x00000746)
+#define AQT1000_RX_NEW_INT_HPH_RDAC_LDO_LP (0x00000747)
+#define AQT1000_CLK_SYS_INT_BASE (0x0000076C)
+#define AQT1000_CLK_SYS_INT_CLK_TEST1 (0x0000076C)
+#define AQT1000_CLK_SYS_INT_XO_TEST1 (0x0000076D)
+#define AQT1000_CLK_SYS_INT_XO_TEST2 (0x0000076E)
+#define AQT1000_CLK_SYS_INT_POST_DIV_REG0 (0x0000076F)
+#define AQT1000_CLK_SYS_INT_POST_DIV_REG1 (0x00000770)
+#define AQT1000_CLK_SYS_INT_REF_DIV_REG0 (0x00000771)
+#define AQT1000_CLK_SYS_INT_REF_DIV_REG1 (0x00000772)
+#define AQT1000_CLK_SYS_INT_FILTER_REG0 (0x00000773)
+#define AQT1000_CLK_SYS_INT_FILTER_REG1 (0x00000774)
+#define AQT1000_CLK_SYS_INT_PLL_L_VAL (0x00000775)
+#define AQT1000_CLK_SYS_INT_PLL_M_VAL (0x00000776)
+#define AQT1000_CLK_SYS_INT_PLL_N_VAL (0x00000777)
+#define AQT1000_CLK_SYS_INT_TEST_REG0 (0x00000778)
+#define AQT1000_CLK_SYS_INT_PFD_CP_DSM_PROG (0x00000779)
+#define AQT1000_CLK_SYS_INT_VCO_PROG (0x0000077A)
+#define AQT1000_CLK_SYS_INT_TEST_REG1 (0x0000077B)
+#define AQT1000_CLK_SYS_INT_LDO_LOCK_CFG (0x0000077C)
+#define AQT1000_CLK_SYS_INT_DIG_LOCK_DET_CFG (0x0000077D)
+#define AQT1000_MBHC_NEW_INT_BASE (0x000007AF)
+#define AQT1000_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (0x000007AF)
+#define AQT1000_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL (0x000007B0)
+#define AQT1000_MBHC_NEW_INT_MECH_DET_CURRENT (0x000007B1)
+#define AQT1000_MBHC_NEW_INT_SPARE_2 (0x000007B2)
+#define AQT1000_PAGE10_BASE (0x00000A00)
+#define AQT1000_PAGE10_PAGE_REGISTER (0x00000A00)
+#define AQT1000_CDC_ANC0_BASE (0x00000A01)
+#define AQT1000_CDC_ANC0_CLK_RESET_CTL (0x00000A01)
+#define AQT1000_CDC_ANC0_MODE_1_CTL (0x00000A02)
+#define AQT1000_CDC_ANC0_MODE_2_CTL (0x00000A03)
+#define AQT1000_CDC_ANC0_FF_SHIFT (0x00000A04)
+#define AQT1000_CDC_ANC0_FB_SHIFT (0x00000A05)
+#define AQT1000_CDC_ANC0_LPF_FF_A_CTL (0x00000A06)
+#define AQT1000_CDC_ANC0_LPF_FF_B_CTL (0x00000A07)
+#define AQT1000_CDC_ANC0_LPF_FB_CTL (0x00000A08)
+#define AQT1000_CDC_ANC0_SMLPF_CTL (0x00000A09)
+#define AQT1000_CDC_ANC0_DCFLT_SHIFT_CTL (0x00000A0A)
+#define AQT1000_CDC_ANC0_IIR_ADAPT_CTL (0x00000A0B)
+#define AQT1000_CDC_ANC0_IIR_COEFF_1_CTL (0x00000A0C)
+#define AQT1000_CDC_ANC0_IIR_COEFF_2_CTL (0x00000A0D)
+#define AQT1000_CDC_ANC0_FF_A_GAIN_CTL (0x00000A0E)
+#define AQT1000_CDC_ANC0_FF_B_GAIN_CTL (0x00000A0F)
+#define AQT1000_CDC_ANC0_FB_GAIN_CTL (0x00000A10)
+#define AQT1000_CDC_ANC0_RC_COMMON_CTL (0x00000A11)
+#define AQT1000_CDC_ANC0_FIFO_COMMON_CTL (0x00000A13)
+#define AQT1000_CDC_ANC0_RC0_STATUS_FMIN_CNTR (0x00000A14)
+#define AQT1000_CDC_ANC0_RC1_STATUS_FMIN_CNTR (0x00000A15)
+#define AQT1000_CDC_ANC0_RC0_STATUS_FMAX_CNTR (0x00000A16)
+#define AQT1000_CDC_ANC0_RC1_STATUS_FMAX_CNTR (0x00000A17)
+#define AQT1000_CDC_ANC0_STATUS_FIFO (0x00000A18)
+#define AQT1000_CDC_ANC1_BASE (0x00000A19)
+#define AQT1000_CDC_ANC1_CLK_RESET_CTL (0x00000A19)
+#define AQT1000_CDC_ANC1_MODE_1_CTL (0x00000A1A)
+#define AQT1000_CDC_ANC1_MODE_2_CTL (0x00000A1B)
+#define AQT1000_CDC_ANC1_FF_SHIFT (0x00000A1C)
+#define AQT1000_CDC_ANC1_FB_SHIFT (0x00000A1D)
+#define AQT1000_CDC_ANC1_LPF_FF_A_CTL (0x00000A1E)
+#define AQT1000_CDC_ANC1_LPF_FF_B_CTL (0x00000A1F)
+#define AQT1000_CDC_ANC1_LPF_FB_CTL (0x00000A20)
+#define AQT1000_CDC_ANC1_SMLPF_CTL (0x00000A21)
+#define AQT1000_CDC_ANC1_DCFLT_SHIFT_CTL (0x00000A22)
+#define AQT1000_CDC_ANC1_IIR_ADAPT_CTL (0x00000A23)
+#define AQT1000_CDC_ANC1_IIR_COEFF_1_CTL (0x00000A24)
+#define AQT1000_CDC_ANC1_IIR_COEFF_2_CTL (0x00000A25)
+#define AQT1000_CDC_ANC1_FF_A_GAIN_CTL (0x00000A26)
+#define AQT1000_CDC_ANC1_FF_B_GAIN_CTL (0x00000A27)
+#define AQT1000_CDC_ANC1_FB_GAIN_CTL (0x00000A28)
+#define AQT1000_CDC_ANC1_RC_COMMON_CTL (0x00000A29)
+#define AQT1000_CDC_ANC1_FIFO_COMMON_CTL (0x00000A2B)
+#define AQT1000_CDC_ANC1_RC0_STATUS_FMIN_CNTR (0x00000A2C)
+#define AQT1000_CDC_ANC1_RC1_STATUS_FMIN_CNTR (0x00000A2D)
+#define AQT1000_CDC_ANC1_RC0_STATUS_FMAX_CNTR (0x00000A2E)
+#define AQT1000_CDC_ANC1_RC1_STATUS_FMAX_CNTR (0x00000A2F)
+#define AQT1000_CDC_ANC1_STATUS_FIFO (0x00000A30)
+#define AQT1000_CDC_TX0_BASE (0x00000A31)
+#define AQT1000_CDC_TX0_TX_PATH_CTL (0x00000A31)
+#define AQT1000_CDC_TX0_TX_PATH_CFG0 (0x00000A32)
+#define AQT1000_CDC_TX0_TX_PATH_CFG1 (0x00000A33)
+#define AQT1000_CDC_TX0_TX_VOL_CTL (0x00000A34)
+#define AQT1000_CDC_TX0_TX_PATH_SEC0 (0x00000A37)
+#define AQT1000_CDC_TX0_TX_PATH_SEC1 (0x00000A38)
+#define AQT1000_CDC_TX0_TX_PATH_SEC2 (0x00000A39)
+#define AQT1000_CDC_TX0_TX_PATH_SEC3 (0x00000A3A)
+#define AQT1000_CDC_TX0_TX_PATH_SEC4 (0x00000A3B)
+#define AQT1000_CDC_TX0_TX_PATH_SEC5 (0x00000A3C)
+#define AQT1000_CDC_TX0_TX_PATH_SEC6 (0x00000A3D)
+#define AQT1000_CDC_TX1_BASE (0x00000A41)
+#define AQT1000_CDC_TX1_TX_PATH_CTL (0x00000A41)
+#define AQT1000_CDC_TX1_TX_PATH_CFG0 (0x00000A42)
+#define AQT1000_CDC_TX1_TX_PATH_CFG1 (0x00000A43)
+#define AQT1000_CDC_TX1_TX_VOL_CTL (0x00000A44)
+#define AQT1000_CDC_TX1_TX_PATH_SEC0 (0x00000A47)
+#define AQT1000_CDC_TX1_TX_PATH_SEC1 (0x00000A48)
+#define AQT1000_CDC_TX1_TX_PATH_SEC2 (0x00000A49)
+#define AQT1000_CDC_TX1_TX_PATH_SEC3 (0x00000A4A)
+#define AQT1000_CDC_TX1_TX_PATH_SEC4 (0x00000A4B)
+#define AQT1000_CDC_TX1_TX_PATH_SEC5 (0x00000A4C)
+#define AQT1000_CDC_TX1_TX_PATH_SEC6 (0x00000A4D)
+#define AQT1000_CDC_TX2_BASE (0x00000A51)
+#define AQT1000_CDC_TX2_TX_PATH_CTL (0x00000A51)
+#define AQT1000_CDC_TX2_TX_PATH_CFG0 (0x00000A52)
+#define AQT1000_CDC_TX2_TX_PATH_CFG1 (0x00000A53)
+#define AQT1000_CDC_TX2_TX_VOL_CTL (0x00000A54)
+#define AQT1000_CDC_TX2_TX_PATH_SEC0 (0x00000A57)
+#define AQT1000_CDC_TX2_TX_PATH_SEC1 (0x00000A58)
+#define AQT1000_CDC_TX2_TX_PATH_SEC2 (0x00000A59)
+#define AQT1000_CDC_TX2_TX_PATH_SEC3 (0x00000A5A)
+#define AQT1000_CDC_TX2_TX_PATH_SEC4 (0x00000A5B)
+#define AQT1000_CDC_TX2_TX_PATH_SEC5 (0x00000A5C)
+#define AQT1000_CDC_TX2_TX_PATH_SEC6 (0x00000A5D)
+#define AQT1000_CDC_TX2_TX_PATH_SEC7 (0x00000A5E)
+#define AQT1000_PAGE11_BASE (0x00000B00)
+#define AQT1000_PAGE11_PAGE_REGISTER (0x00000B00)
+#define AQT1000_CDC_COMPANDER1_BASE (0x00000B01)
+#define AQT1000_CDC_COMPANDER1_CTL0 (0x00000B01)
+#define AQT1000_CDC_COMPANDER1_CTL1 (0x00000B02)
+#define AQT1000_CDC_COMPANDER1_CTL2 (0x00000B03)
+#define AQT1000_CDC_COMPANDER1_CTL3 (0x00000B04)
+#define AQT1000_CDC_COMPANDER1_CTL4 (0x00000B05)
+#define AQT1000_CDC_COMPANDER1_CTL5 (0x00000B06)
+#define AQT1000_CDC_COMPANDER1_CTL6 (0x00000B07)
+#define AQT1000_CDC_COMPANDER1_CTL7 (0x00000B08)
+#define AQT1000_CDC_COMPANDER2_BASE (0x00000B09)
+#define AQT1000_CDC_COMPANDER2_CTL0 (0x00000B09)
+#define AQT1000_CDC_COMPANDER2_CTL1 (0x00000B0A)
+#define AQT1000_CDC_COMPANDER2_CTL2 (0x00000B0B)
+#define AQT1000_CDC_COMPANDER2_CTL3 (0x00000B0C)
+#define AQT1000_CDC_COMPANDER2_CTL4 (0x00000B0D)
+#define AQT1000_CDC_COMPANDER2_CTL5 (0x00000B0E)
+#define AQT1000_CDC_COMPANDER2_CTL6 (0x00000B0F)
+#define AQT1000_CDC_COMPANDER2_CTL7 (0x00000B10)
+#define AQT1000_CDC_RX1_BASE (0x00000B55)
+#define AQT1000_CDC_RX1_RX_PATH_CTL (0x00000B55)
+#define AQT1000_CDC_RX1_RX_PATH_CFG0 (0x00000B56)
+#define AQT1000_CDC_RX1_RX_PATH_CFG1 (0x00000B57)
+#define AQT1000_CDC_RX1_RX_PATH_CFG2 (0x00000B58)
+#define AQT1000_CDC_RX1_RX_VOL_CTL (0x00000B59)
+#define AQT1000_CDC_RX1_RX_PATH_MIX_CTL (0x00000B5A)
+#define AQT1000_CDC_RX1_RX_PATH_MIX_CFG (0x00000B5B)
+#define AQT1000_CDC_RX1_RX_VOL_MIX_CTL (0x00000B5C)
+#define AQT1000_CDC_RX1_RX_PATH_SEC0 (0x00000B5D)
+#define AQT1000_CDC_RX1_RX_PATH_SEC1 (0x00000B5E)
+#define AQT1000_CDC_RX1_RX_PATH_SEC2 (0x00000B5F)
+#define AQT1000_CDC_RX1_RX_PATH_SEC3 (0x00000B60)
+#define AQT1000_CDC_RX1_RX_PATH_SEC4 (0x00000B61)
+#define AQT1000_CDC_RX1_RX_PATH_SEC5 (0x00000B62)
+#define AQT1000_CDC_RX1_RX_PATH_SEC6 (0x00000B63)
+#define AQT1000_CDC_RX1_RX_PATH_SEC7 (0x00000B64)
+#define AQT1000_CDC_RX1_RX_PATH_MIX_SEC0 (0x00000B65)
+#define AQT1000_CDC_RX1_RX_PATH_MIX_SEC1 (0x00000B66)
+#define AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL (0x00000B67)
+#define AQT1000_CDC_RX2_BASE (0x00000B69)
+#define AQT1000_CDC_RX2_RX_PATH_CTL (0x00000B69)
+#define AQT1000_CDC_RX2_RX_PATH_CFG0 (0x00000B6A)
+#define AQT1000_CDC_RX2_RX_PATH_CFG1 (0x00000B6B)
+#define AQT1000_CDC_RX2_RX_PATH_CFG2 (0x00000B6C)
+#define AQT1000_CDC_RX2_RX_VOL_CTL (0x00000B6D)
+#define AQT1000_CDC_RX2_RX_PATH_MIX_CTL (0x00000B6E)
+#define AQT1000_CDC_RX2_RX_PATH_MIX_CFG (0x00000B6F)
+#define AQT1000_CDC_RX2_RX_VOL_MIX_CTL (0x00000B70)
+#define AQT1000_CDC_RX2_RX_PATH_SEC0 (0x00000B71)
+#define AQT1000_CDC_RX2_RX_PATH_SEC1 (0x00000B72)
+#define AQT1000_CDC_RX2_RX_PATH_SEC2 (0x00000B73)
+#define AQT1000_CDC_RX2_RX_PATH_SEC3 (0x00000B74)
+#define AQT1000_CDC_RX2_RX_PATH_SEC4 (0x00000B75)
+#define AQT1000_CDC_RX2_RX_PATH_SEC5 (0x00000B76)
+#define AQT1000_CDC_RX2_RX_PATH_SEC6 (0x00000B77)
+#define AQT1000_CDC_RX2_RX_PATH_SEC7 (0x00000B78)
+#define AQT1000_CDC_RX2_RX_PATH_MIX_SEC0 (0x00000B79)
+#define AQT1000_CDC_RX2_RX_PATH_MIX_SEC1 (0x00000B7A)
+#define AQT1000_CDC_RX2_RX_PATH_DSMDEM_CTL (0x00000B7B)
+#define AQT1000_CDC_EQ_IIR0_BASE (0x00000BD1)
+#define AQT1000_CDC_EQ_IIR0_PATH_CTL (0x00000BD1)
+#define AQT1000_CDC_EQ_IIR0_PATH_CFG0 (0x00000BD2)
+#define AQT1000_CDC_EQ_IIR0_PATH_CFG1 (0x00000BD3)
+#define AQT1000_CDC_EQ_IIR0_PATH_CFG2 (0x00000BD4)
+#define AQT1000_CDC_EQ_IIR0_PATH_CFG3 (0x00000BD5)
+#define AQT1000_CDC_EQ_IIR0_COEF_CFG0 (0x00000BD6)
+#define AQT1000_CDC_EQ_IIR0_COEF_CFG1 (0x00000BD7)
+#define AQT1000_CDC_EQ_IIR1_BASE (0x00000BE1)
+#define AQT1000_CDC_EQ_IIR1_PATH_CTL (0x00000BE1)
+#define AQT1000_CDC_EQ_IIR1_PATH_CFG0 (0x00000BE2)
+#define AQT1000_CDC_EQ_IIR1_PATH_CFG1 (0x00000BE3)
+#define AQT1000_CDC_EQ_IIR1_PATH_CFG2 (0x00000BE4)
+#define AQT1000_CDC_EQ_IIR1_PATH_CFG3 (0x00000BE5)
+#define AQT1000_CDC_EQ_IIR1_COEF_CFG0 (0x00000BE6)
+#define AQT1000_CDC_EQ_IIR1_COEF_CFG1 (0x00000BE7)
+#define AQT1000_PAGE12_BASE (0x00000C00)
+#define AQT1000_PAGE12_PAGE_REGISTER (0x00000C00)
+#define AQT1000_CDC_CLSH_CDC_CLSH_BASE (0x00000C01)
+#define AQT1000_CDC_CLSH_CRC (0x00000C01)
+#define AQT1000_CDC_CLSH_DLY_CTRL (0x00000C02)
+#define AQT1000_CDC_CLSH_DECAY_CTRL (0x00000C03)
+#define AQT1000_CDC_CLSH_HPH_V_PA (0x00000C04)
+#define AQT1000_CDC_CLSH_EAR_V_PA (0x00000C05)
+#define AQT1000_CDC_CLSH_HPH_V_HD (0x00000C06)
+#define AQT1000_CDC_CLSH_EAR_V_HD (0x00000C07)
+#define AQT1000_CDC_CLSH_K1_MSB (0x00000C08)
+#define AQT1000_CDC_CLSH_K1_LSB (0x00000C09)
+#define AQT1000_CDC_CLSH_K2_MSB (0x00000C0A)
+#define AQT1000_CDC_CLSH_K2_LSB (0x00000C0B)
+#define AQT1000_CDC_CLSH_IDLE_CTRL (0x00000C0C)
+#define AQT1000_CDC_CLSH_IDLE_HPH (0x00000C0D)
+#define AQT1000_CDC_CLSH_IDLE_EAR (0x00000C0E)
+#define AQT1000_CDC_CLSH_TEST0 (0x00000C0F)
+#define AQT1000_CDC_CLSH_TEST1 (0x00000C10)
+#define AQT1000_CDC_CLSH_OVR_VREF (0x00000C11)
+#define AQT1000_MIXING_ASRC0_BASE (0x00000C55)
+#define AQT1000_MIXING_ASRC0_CLK_RST_CTL (0x00000C55)
+#define AQT1000_MIXING_ASRC0_CTL0 (0x00000C56)
+#define AQT1000_MIXING_ASRC0_CTL1 (0x00000C57)
+#define AQT1000_MIXING_ASRC0_FIFO_CTL (0x00000C58)
+#define AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000C59)
+#define AQT1000_MIXING_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000C5A)
+#define AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000C5B)
+#define AQT1000_MIXING_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000C5C)
+#define AQT1000_MIXING_ASRC0_STATUS_FIFO (0x00000C5D)
+#define AQT1000_MIXING_ASRC1_BASE (0x00000C61)
+#define AQT1000_MIXING_ASRC1_CLK_RST_CTL (0x00000C61)
+#define AQT1000_MIXING_ASRC1_CTL0 (0x00000C62)
+#define AQT1000_MIXING_ASRC1_CTL1 (0x00000C63)
+#define AQT1000_MIXING_ASRC1_FIFO_CTL (0x00000C64)
+#define AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000C65)
+#define AQT1000_MIXING_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000C66)
+#define AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000C67)
+#define AQT1000_MIXING_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000C68)
+#define AQT1000_MIXING_ASRC1_STATUS_FIFO (0x00000C69)
+#define AQT1000_CDC_SIDETONE_SRC0_BASE (0x00000CB5)
+#define AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x00000CB5)
+#define AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x00000CB6)
+#define AQT1000_SIDETONE_ASRC0_BASE (0x00000CBD)
+#define AQT1000_SIDETONE_ASRC0_CLK_RST_CTL (0x00000CBD)
+#define AQT1000_SIDETONE_ASRC0_CTL0 (0x00000CBE)
+#define AQT1000_SIDETONE_ASRC0_CTL1 (0x00000CBF)
+#define AQT1000_SIDETONE_ASRC0_FIFO_CTL (0x00000CC0)
+#define AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CC1)
+#define AQT1000_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CC2)
+#define AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CC3)
+#define AQT1000_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CC4)
+#define AQT1000_SIDETONE_ASRC0_STATUS_FIFO (0x00000CC5)
+#define AQT1000_EC_REF_HQ0_BASE (0x00000CD5)
+#define AQT1000_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x00000CD5)
+#define AQT1000_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x00000CD6)
+#define AQT1000_EC_REF_HQ1_BASE (0x00000CDD)
+#define AQT1000_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x00000CDD)
+#define AQT1000_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x00000CDE)
+#define AQT1000_EC_ASRC0_BASE (0x00000CE5)
+#define AQT1000_EC_ASRC0_CLK_RST_CTL (0x00000CE5)
+#define AQT1000_EC_ASRC0_CTL0 (0x00000CE6)
+#define AQT1000_EC_ASRC0_CTL1 (0x00000CE7)
+#define AQT1000_EC_ASRC0_FIFO_CTL (0x00000CE8)
+#define AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CE9)
+#define AQT1000_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CEA)
+#define AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CEB)
+#define AQT1000_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CEC)
+#define AQT1000_EC_ASRC0_STATUS_FIFO (0x00000CED)
+#define AQT1000_EC_ASRC1_BASE (0x00000CF1)
+#define AQT1000_EC_ASRC1_CLK_RST_CTL (0x00000CF1)
+#define AQT1000_EC_ASRC1_CTL0 (0x00000CF2)
+#define AQT1000_EC_ASRC1_CTL1 (0x00000CF3)
+#define AQT1000_EC_ASRC1_FIFO_CTL (0x00000CF4)
+#define AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000CF5)
+#define AQT1000_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000CF6)
+#define AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000CF7)
+#define AQT1000_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000CF8)
+#define AQT1000_EC_ASRC1_STATUS_FIFO (0x00000CF9)
+#define AQT1000_PAGE13_BASE (0x00000D00)
+#define AQT1000_PAGE13_PAGE_REGISTER (0x00000D00)
+#define AQT1000_CDC_RX_INP_MUX_CDC_RX_INP_MUX_BASE (0x00000D01)
+#define AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0 (0x00000D03)
+#define AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1 (0x00000D04)
+#define AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0 (0x00000D05)
+#define AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1 (0x00000D06)
+#define AQT1000_CDC_RX_INP_MUX_EQ_IIR_CFG0 (0x00000D11)
+#define AQT1000_CDC_RX_INP_MUX_DSD_CFG0 (0x00000D12)
+#define AQT1000_CDC_RX_INP_MUX_RX_MIX_CFG0 (0x00000D13)
+#define AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x00000D18)
+#define AQT1000_CDC_RX_INP_MUX_ANC_CFG0 (0x00000D1A)
+#define AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 (0x00000D1B)
+#define AQT1000_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 (0x00000D1C)
+#define AQT1000_CDC_TX_INP_MUX_CDC_TX_INP_MUX_BASE (0x00000D1D)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x00000D1D)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x00000D1E)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x00000D1F)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x00000D20)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x00000D21)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x00000D22)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0 (0x00000D29)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG1 (0x00000D2A)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0 (0x00000D2B)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG1 (0x00000D2C)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0 (0x00000D2D)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG1 (0x00000D2E)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0 (0x00000D2F)
+#define AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG1 (0x00000D30)
+#define AQT1000_CDC_SIDETONE_IIR_INP_MUX_CDC_SIDETONE_IIR_INP_MUX_BASE (0xD31)
+#define AQT1000_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 (0x00000D31)
+#define AQT1000_CDC_IF_ROUTER_CDC_IF_ROUTER_BASE (0x00000D3D)
+#define AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0 (0x00000D3D)
+#define AQT1000_CDC_CLK_RST_CTRL_CDC_CLK_RST_CTRL_BASE (0x00000D41)
+#define AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL (0x00000D41)
+#define AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL (0x00000D42)
+#define AQT1000_CDC_CLK_RST_CTRL_DSD_CONTROL (0x00000D44)
+#define AQT1000_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x00000D45)
+#define AQT1000_CDC_CLK_RST_CTRL_GFM_CONTROL (0x00000D46)
+#define AQT1000_CDC_CLK_RST_CTRL_I2S_CONTROL (0x00000D47)
+#define AQT1000_CDC_SIDETONE_IIR0_BASE (0x00000D55)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL (0x00000D55)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x00000D56)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x00000D57)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x00000D58)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x00000D59)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x00000D5A)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x00000D5B)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x00000D5C)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x00000D5D)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_CTL (0x00000D5E)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x00000D5F)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x00000D60)
+#define AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x00000D61)
+#define AQT1000_CDC_TOP_CDC_TOP_BASE (0x00000D81)
+#define AQT1000_CDC_TOP_TOP_CFG0 (0x00000D81)
+#define AQT1000_CDC_TOP_HPHL_COMP_WR_LSB (0x00000D89)
+#define AQT1000_CDC_TOP_HPHL_COMP_WR_MSB (0x00000D8A)
+#define AQT1000_CDC_TOP_HPHL_COMP_LUT (0x00000D8B)
+#define AQT1000_CDC_TOP_HPHL_COMP_RD_LSB (0x00000D8C)
+#define AQT1000_CDC_TOP_HPHL_COMP_RD_MSB (0x00000D8D)
+#define AQT1000_CDC_TOP_HPHR_COMP_WR_LSB (0x00000D8E)
+#define AQT1000_CDC_TOP_HPHR_COMP_WR_MSB (0x00000D8F)
+#define AQT1000_CDC_TOP_HPHR_COMP_LUT (0x00000D90)
+#define AQT1000_CDC_TOP_HPHR_COMP_RD_LSB (0x00000D91)
+#define AQT1000_CDC_TOP_HPHR_COMP_RD_MSB (0x00000D92)
+#define AQT1000_CDC_DSD0_BASE (0x00000DB1)
+#define AQT1000_CDC_DSD0_PATH_CTL (0x00000DB1)
+#define AQT1000_CDC_DSD0_CFG0 (0x00000DB2)
+#define AQT1000_CDC_DSD0_CFG1 (0x00000DB3)
+#define AQT1000_CDC_DSD0_CFG2 (0x00000DB4)
+#define AQT1000_CDC_DSD0_CFG3 (0x00000DB5)
+#define AQT1000_CDC_DSD0_CFG4 (0x00000DB6)
+#define AQT1000_CDC_DSD0_CFG5 (0x00000DB7)
+#define AQT1000_CDC_DSD1_BASE (0x00000DC1)
+#define AQT1000_CDC_DSD1_PATH_CTL (0x00000DC1)
+#define AQT1000_CDC_DSD1_CFG0 (0x00000DC2)
+#define AQT1000_CDC_DSD1_CFG1 (0x00000DC3)
+#define AQT1000_CDC_DSD1_CFG2 (0x00000DC4)
+#define AQT1000_CDC_DSD1_CFG3 (0x00000DC5)
+#define AQT1000_CDC_DSD1_CFG4 (0x00000DC6)
+#define AQT1000_CDC_DSD1_CFG5 (0x00000DC7)
+#define AQT1000_CDC_RX_IDLE_DET_CDC_RX_IDLE_DET_BASE (0x00000DD1)
+#define AQT1000_CDC_RX_IDLE_DET_PATH_CTL (0x00000DD1)
+#define AQT1000_CDC_RX_IDLE_DET_CFG0 (0x00000DD2)
+#define AQT1000_CDC_RX_IDLE_DET_CFG1 (0x00000DD3)
+#define AQT1000_CDC_RX_IDLE_DET_CFG2 (0x00000DD4)
+#define AQT1000_CDC_RX_IDLE_DET_CFG3 (0x00000DD5)
+#define AQT1000_CDC_DOP_DET_CDC_DOP_DET_BASE (0x00000DD9)
+#define AQT1000_CDC_DOP_DET_CTL (0x00000DD9)
+#define AQT1000_CDC_DOP_DET_CFG0 (0x00000DDA)
+#define AQT1000_CDC_DOP_DET_CFG1 (0x00000DDB)
+#define AQT1000_CDC_DOP_DET_CFG2 (0x00000DDC)
+#define AQT1000_CDC_DOP_DET_CFG3 (0x00000DDD)
+#define AQT1000_CDC_DOP_DET_CFG4 (0x00000DDE)
+#define AQT1000_CDC_DOP_DET_STATUS0 (0x00000DE1)
+#define AQT1000_PAGE15_BASE (0x00000F00)
+#define AQT1000_PAGE15_PAGE_REGISTER (0x00000F00)
+#define AQT1000_CDC_DEBUG_CDC_DEBUG_BASE (0x00000FA1)
+#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG0 (0x00000FA1)
+#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG1 (0x00000FA2)
+#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG2 (0x00000FA3)
+#define AQT1000_CDC_DEBUG_DSD0_DEBUG_CFG3 (0x00000FA4)
+#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG0 (0x00000FA5)
+#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG1 (0x00000FA6)
+#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG2 (0x00000FA7)
+#define AQT1000_CDC_DEBUG_DSD1_DEBUG_CFG3 (0x00000FA8)
+#define AQT1000_CDC_DEBUG_RC_RE_ASRC_DEBUG_CFG0 (0x00000FAB)
+#define AQT1000_CDC_DEBUG_ANC0_RC0_FIFO_CTL (0x00000FAC)
+#define AQT1000_CDC_DEBUG_ANC0_RC1_FIFO_CTL (0x00000FAD)
+#define AQT1000_CDC_DEBUG_ANC1_RC0_FIFO_CTL (0x00000FAE)
+#define AQT1000_CDC_DEBUG_ANC1_RC1_FIFO_CTL (0x00000FAF)
+#define AQT1000_CDC_DEBUG_ANC_RC_RST_DBG_CNTR (0x00000FB0)
+#define AQT1000_PAGE128_BASE (0x00008000)
+#define AQT1000_PAGE128_PAGE_REGISTER (0x00008000)
+#define AQT1000_TLMM_TLMM_BASE (0x00008001)
+#define AQT1000_TLMM_SPI_CLK_PINCFG (0x00008001)
+#define AQT1000_TLMM_SPI_MOSI_PINCFG (0x00008002)
+#define AQT1000_TLMM_SPI_MISO_PINCFG (0x00008003)
+#define AQT1000_TLMM_SPI_CS_N_PINCFG (0x00008004)
+#define AQT1000_TLMM_GPIO1_PINCFG (0x00008005)
+#define AQT1000_TLMM_GPIO2_PINCFG (0x00008006)
+#define AQT1000_TLMM_GPIO3_PINCFG (0x00008007)
+#define AQT1000_TLMM_GPIO4_PINCFG (0x00008008)
+#define AQT1000_TLMM_GPIO5_PINCFG (0x00008009)
+#define AQT1000_TLMM_GPIO6_PINCFG (0x0000800A)
+#define AQT1000_TLMM_GPIO7_PINCFG (0x0000800B)
+#define AQT1000_TLMM_GPIO8_PINCFG (0x0000800C)
+#define AQT1000_TLMM_GPIO9_PINCFG (0x0000800D)
+#define AQT1000_TLMM_GPIO10_PINCFG (0x0000800E)
+#define AQT1000_PAD_CTRL_PAD_CTRL_BASE (0x00008031)
+#define AQT1000_PAD_CTRL_PAD_PDN_CTRL_0 (0x00008031)
+#define AQT1000_PAD_CTRL_PAD_PDN_CTRL_1 (0x00008032)
+#define AQT1000_PAD_CTRL_PAD_PU_CTRL_0 (0x00008033)
+#define AQT1000_PAD_CTRL_PAD_PU_CTRL_1 (0x00008034)
+#define AQT1000_PAD_CTRL_GPIO_CTL_0_OE (0x00008036)
+#define AQT1000_PAD_CTRL_GPIO_CTL_1_OE (0x00008037)
+#define AQT1000_PAD_CTRL_GPIO_CTL_0_DATA (0x00008038)
+#define AQT1000_PAD_CTRL_GPIO_CTL_1_DATA (0x00008039)
+#define AQT1000_PAD_CTRL_PAD_DRVCTL (0x0000803A)
+#define AQT1000_PAD_CTRL_PIN_STATUS (0x0000803B)
+#define AQT1000_PAD_CTRL_MEM_CTRL (0x0000803C)
+#define AQT1000_PAD_CTRL_PAD_INP_DISABLE_0 (0x0000803E)
+#define AQT1000_PAD_CTRL_PAD_INP_DISABLE_1 (0x0000803F)
+#define AQT1000_PAD_CTRL_PIN_CTL_OE_0 (0x00008040)
+#define AQT1000_PAD_CTRL_PIN_CTL_OE_1 (0x00008041)
+#define AQT1000_PAD_CTRL_PIN_CTL_DATA_0 (0x00008042)
+#define AQT1000_PAD_CTRL_PIN_CTL_DATA_1 (0x00008043)
+#define AQT1000_PAD_CTRL_USB_PHY_CLK_DIV (0x00008044)
+#define AQT1000_PAD_CTRL_DEBUG_BUS_CDC (0x00008045)
+#define AQT1000_PAD_CTRL_DEBUG_BUS_SEL (0x00008046)
+#define AQT1000_PAD_CTRL_DEBUG_EN_1 (0x00008047)
+#define AQT1000_PAD_CTRL_DEBUG_EN_2 (0x00008048)
+#define AQT1000_PAD_CTRL_DEBUG_EN_3 (0x00008049)
+#define AQT1000_PAD_CTRL_DEBUG_EN_4 (0x0000804A)
+#define AQT1000_PAD_CTRL_DEBUG_EN_5 (0x0000804B)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_0 (0x0000804C)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_1 (0x0000804D)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_2 (0x0000804E)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_3 (0x0000804F)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_4 (0x00008050)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_5 (0x00008051)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_6 (0x00008052)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_7 (0x00008053)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_8 (0x00008054)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_9 (0x00008055)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_10 (0x00008056)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_11 (0x00008057)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_12 (0x00008058)
+#define AQT1000_PAD_CTRL_DEBUG_MUX_BIT_13 (0x00008059)
+#define AQT1000_PAD_CTRL_DEBUG_READ_0 (0x0000805A)
+#define AQT1000_PAD_CTRL_DEBUG_READ_1 (0x0000805B)
+#define AQT1000_PAD_CTRL_DEBUG_READ_2 (0x0000805C)
+#define AQT1000_PAD_CTRL_DEBUG_READ_3 (0x0000805D)
+#define AQT1000_PAD_CTRL_FPGA_CTL (0x00008061)
+#define AQT1000_MAX_REGISTER (0x000080FF)
+
+#endif /*_AQT_REGISTERS_H*/
diff --git a/asoc/codecs/aqt1000/aqt1000-regmap.c b/asoc/codecs/aqt1000/aqt1000-regmap.c
new file mode 100644
index 0000000..e38c327
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-regmap.c
@@ -0,0 +1,110 @@
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include "aqt1000-registers.h"
+#include "aqt1000-reg-defaults.h"
+#include "aqt1000-internal.h"
+
+static bool aqt1000_is_readable_register(struct device *dev, unsigned int reg)
+{
+ u8 pg_num, reg_offset;
+ const u8 *reg_tbl = NULL;
+
+ /*
+ * Get the page number from MSB of codec register. If its 0x80, assign
+ * the corresponding page index PAGE_0x80.
+ */
+ pg_num = reg >> 0x8;
+ if (pg_num == 0x80)
+ pg_num = AQT1000_PAGE_128;
+ else if (pg_num > 15)
+ return false;
+
+ reg_tbl = aqt1000_reg[pg_num];
+ reg_offset = reg & 0xFF;
+
+ if (reg_tbl && reg_tbl[reg_offset])
+ return true;
+ else
+ return false;
+}
+
+static bool aqt1000_is_volatile_register(struct device *dev, unsigned int reg)
+{
+ u8 pg_num, reg_offset;
+ const u8 *reg_tbl = NULL;
+
+ pg_num = reg >> 0x8;
+ if (pg_num == 0x80)
+ pg_num = AQT1000_PAGE_128;
+ else if (pg_num > 15)
+ return false;
+
+ reg_tbl = aqt1000_reg[pg_num];
+ reg_offset = reg & 0xFF;
+
+ if (reg_tbl && reg_tbl[reg_offset] == AQT1000_RO)
+ return true;
+
+ /* IIR Coeff registers are not cacheable */
+ if ((reg >= AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL) &&
+ (reg <= AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL))
+ return true;
+
+ if ((reg >= AQT1000_CDC_ANC0_IIR_COEFF_1_CTL) &&
+ (reg <= AQT1000_CDC_ANC0_FB_GAIN_CTL))
+ return true;
+
+ if ((reg >= AQT1000_CDC_ANC1_IIR_COEFF_1_CTL) &&
+ (reg <= AQT1000_CDC_ANC1_FB_GAIN_CTL))
+ return true;
+
+ /*
+ * Need to mark volatile for registers that are writable but
+ * only few bits are read-only
+ */
+ switch (reg) {
+ case AQT1000_BUCK_5V_CTRL_CCL_1:
+ case AQT1000_BIAS_CCOMP_FINE_ADJ:
+ case AQT1000_ANA_BIAS:
+ case AQT1000_BUCK_5V_IBIAS_CTL_4:
+ case AQT1000_BUCK_5V_CTRL_CCL_2:
+ case AQT1000_CHIP_CFG0_RST_CTL:
+ case AQT1000_CHIP_CFG0_CLK_CTL_CDC_DIG:
+ case AQT1000_CHIP_CFG0_CLK_CFG_MCLK:
+ case AQT1000_CHIP_CFG0_EFUSE_CTL:
+ case AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL:
+ case AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL:
+ case AQT1000_ANA_RX_SUPPLIES:
+ case AQT1000_ANA_MBHC_MECH:
+ case AQT1000_ANA_MBHC_ELECT:
+ case AQT1000_ANA_MBHC_ZDET:
+ case AQT1000_ANA_MICB1:
+ case AQT1000_BUCK_5V_EN_CTL:
+ return true;
+ }
+
+ return false;
+}
+
+struct regmap_config aqt1000_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = aqt1000_defaults,
+ .num_reg_defaults = ARRAY_SIZE(aqt1000_defaults),
+ .max_register = AQT1000_MAX_REGISTER,
+ .volatile_reg = aqt1000_is_volatile_register,
+ .readable_reg = aqt1000_is_readable_register,
+};
diff --git a/asoc/codecs/aqt1000/aqt1000-routing.h b/asoc/codecs/aqt1000/aqt1000-routing.h
new file mode 100644
index 0000000..7ae3276
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-routing.h
@@ -0,0 +1,174 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef AQT1000_ROUTING_H
+#define AQT1000_ROUTING_H
+
+#include <sound/soc-dapm.h>
+
+const struct snd_soc_dapm_route aqt_audio_map[] = {
+
+ /* CDC Tx interface */
+
+ {"AQT AIF1 CAP", NULL, "AQT AIF1 CAP Mixer"},
+ {"AQT AIF1 CAP Mixer", "TX0", "AQT TX0_MUX"},
+ {"AQT AIF1 CAP Mixer", "TX1", "AQT TX1_MUX"},
+
+ {"AQT TX0_MUX", "DEC_L", "AQT ADC0 MUX"},
+ {"AQT TX0_MUX", "DEC_R", "AQT ADC1 MUX"},
+ {"AQT TX0_MUX", "DEC_V", "AQT ADC2 MUX"},
+
+ {"AQT TX1_MUX", "DEC_L", "AQT ADC0 MUX"},
+ {"AQT TX1_MUX", "DEC_R", "AQT ADC1 MUX"},
+ {"AQT TX1_MUX", "DEC_V", "AQT ADC2 MUX"},
+
+ {"AQT ADC0 MUX", "AMIC", "AQT AMIC0_MUX"},
+ {"AQT ADC0 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"},
+ {"AQT ADC0 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"},
+
+ {"AQT ADC1 MUX", "AMIC", "AQT AMIC1_MUX"},
+ {"AQT ADC1 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"},
+ {"AQT ADC1 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"},
+
+ {"AQT ADC2 MUX", "AMIC", "AQT AMIC2_MUX"},
+ {"AQT ADC2 MUX", "ANC_FB0", "AQT ANC_FB_TUNE0"},
+ {"AQT ADC2 MUX", "ANC_FB1", "AQT ANC_FB_TUNE1"},
+
+ {"AQT AMIC0_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC0_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC0_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT AMIC1_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC1_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC1_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT AMIC2_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC2_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC2_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT ADC_L", NULL, "AQT AMIC1"},
+ {"AQT ADC_R", NULL, "AQT AMIC2"},
+ {"AQT ADC_V", NULL, "AQT AMIC3"},
+
+ {"AQT AMIC10_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC10_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC10_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT AMIC11_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC11_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC11_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT AMIC12_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC12_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC12_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT AMIC13_MUX", "ADC_L", "AQT ADC_L"},
+ {"AQT AMIC13_MUX", "ADC_R", "AQT ADC_R"},
+ {"AQT AMIC13_MUX", "ADC_V", "AQT ADC_V"},
+
+ {"AQT ANC OUT HPHL Enable", "Switch", "AQT AMIC10_MUX"},
+ {"AQT ANC OUT HPHL Enable", "Switch", "AQT AMIC11_MUX"},
+ {"AQT ANC OUT HPHR Enable", "Switch", "AQT AMIC12_MUX"},
+ {"AQT ANC OUT HPHR Enable", "Switch", "AQT AMIC13_MUX"},
+
+ {"AQT RX INT1 MIX2", NULL, "AQT ANC OUT HPHL Enable"},
+ {"AQT RX INT2 MIX2", NULL, "AQT ANC OUT HPHR Enable"},
+
+ {"AQT ANC0 FB MUX", "ANC_IN_HPHL", "AQT RX INT1 MIX2"},
+ {"AQT ANC1 FB MUX", "ANC_IN_HPHR", "AQT RX INT2 MIX2"},
+
+ {"AQT I2S_L RX", NULL, "AQT AIF1 PB"},
+ {"AQT I2S_R RX", NULL, "AQT AIF1 PB"},
+
+ {"AQT RX INT1_1 MUX", "I2S0_L", "AQT I2S_L RX"},
+ {"AQT RX INT1_1 MUX", "I2S0_R", "AQT I2S_R RX"},
+ {"AQT RX INT1_1 MUX", "DEC_L", "AQT ADC0 MUX"},
+ {"AQT RX INT1_1 MUX", "DEC_R", "AQT ADC1 MUX"},
+ {"AQT RX INT1_1 MUX", "DEC_V", "AQT ADC2 MUX"},
+
+ {"AQT RX INT2_1 MUX", "I2S0_L", "AQT I2S_L RX"},
+ {"AQT RX INT2_1 MUX", "I2S0_R", "AQT I2S_R RX"},
+ {"AQT RX INT2_1 MUX", "DEC_L", "AQT ADC0 MUX"},
+ {"AQT RX INT2_1 MUX", "DEC_R", "AQT ADC1 MUX"},
+ {"AQT RX INT2_1 MUX", "DEC_V", "AQT ADC2 MUX"},
+
+ {"AQT RX INT1_2 MUX", "I2S0_L", "AQT I2S_L RX"},
+ {"AQT RX INT1_2 MUX", "I2S0_R", "AQT I2S_R RX"},
+ {"AQT RX INT1_2 MUX", "DEC_L", "AQT ADC0 MUX"},
+ {"AQT RX INT1_2 MUX", "DEC_R", "AQT ADC1 MUX"},
+ {"AQT RX INT1_2 MUX", "DEC_V", "AQT ADC2 MUX"},
+ {"AQT RX INT1_2 MUX", "IIR0", "AQT IIR0"},
+
+ {"AQT RX INT2_2 MUX", "I2S0_L", "AQT I2S_L RX"},
+ {"AQT RX INT2_2 MUX", "I2S0_R", "AQT I2S_R RX"},
+ {"AQT RX INT2_2 MUX", "DEC_L", "AQT ADC0 MUX"},
+ {"AQT RX INT2_2 MUX", "DEC_R", "AQT ADC1 MUX"},
+ {"AQT RX INT2_2 MUX", "DEC_V", "AQT ADC2 MUX"},
+ {"AQT RX INT2_2 MUX", "IIR0", "AQT IIR0"},
+
+ {"AQT RX INT1_1 INTERP", NULL, "AQT RX INT1_1 MUX"},
+ {"AQT RX INT1 MIX1", NULL, "AQT RX INT1_1 INTERP"},
+ {"AQT RX INT1 MIX2", NULL, "AQT RX INT1 MIX1"},
+
+ {"AQT RX INT1_2 INTERP", NULL, "AQT RX INT1_2 MUX"},
+ {"AQT RX INT1 MIX1", NULL, "AQT RX INT1_2 INTERP"},
+
+ {"AQT ASRC0 MUX", "ASRC_IN_HPHL", "AQT RX INT1_2 INTERP"},
+ {"AQT RX INT1 MIX1", "HPHL Switch", "AQT ASRC0 MUX"},
+
+ {"AQT RX INT2_1 INTERP", NULL, "AQT RX INT2_1 MUX"},
+ {"AQT RX INT2 MIX1", NULL, "AQT RX INT2_1 INTERP"},
+ {"AQT RX INT2 MIX2", NULL, "AQT RX INT2 MIX1"},
+
+ {"AQT RX INT2_2 INTERP", NULL, "AQT RX INT2_2 MUX"},
+ {"AQT RX INT2 MIX1", NULL, "AQT RX INT2_2 INTERP"},
+
+ {"AQT ASRC1 MUX", "ASRC_IN_HPHR", "AQT RX INT2_2 INTERP"},
+ {"AQT RX INT2 MIX1", "HPHR Switch", "AQT ASRC1 MUX"},
+
+ {"AQT RX INT1 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT1 MIX2"},
+ {"AQT RX INT1 DAC", NULL, "AQT RX INT1 DEM MUX"},
+ {"AQT RX INT1 DAC", NULL, "AQT RX_BIAS"},
+ {"AQT RX_BIAS", NULL, "AQT MCLK"},
+ {"AQT MIC BIAS1", NULL, "AQT MCLK"},
+ {"AQT HPHL PA", NULL, "AQT RX INT1 DAC"},
+ {"AQT HPHL", NULL, "AQT HPHL PA"},
+
+ {"AQT RX INT2 DEM MUX", "CLSH_DSM_OUT", "AQT RX INT2 MIX2"},
+ {"AQT RX INT2 DAC", NULL, "AQT RX INT2 DEM MUX"},
+ {"AQT RX INT2 DAC", NULL, "AQT RX_BIAS"},
+ {"AQT HPHR PA", NULL, "AQT RX INT2 DAC"},
+ {"AQT HPHR", NULL, "AQT HPHR PA"},
+
+ {"AQT ANC HPHL PA", NULL, "AQT RX INT1 DAC"},
+ {"AQT ANC HPHL", NULL, "AQT ANC HPHL PA"},
+
+ {"AQT ANC HPHR PA", NULL, "AQT RX INT2 DAC"},
+ {"AQT ANC HPHR", NULL, "AQT ANC HPHR PA"},
+
+ {"AQT IIR0", NULL, "AQT ADC2 MUX"},
+ {"AQT SRC0", NULL, "AQT IIR0"},
+ {"AQT RX ST MUX", "SRC0", "AQT SRC0"},
+
+ {"AQT RX INT1 MIX2", NULL, "AQT RX ST MUX"},
+ {"AQT RX INT2 MIX2", NULL, "AQT RX ST MUX"},
+
+ /* Native clk main path routing */
+ {"AQT RX INT1_1 NATIVE MUX", "ON", "AQT RX INT1_1 MUX"},
+ {"AQT RX INT1_1 INTERP", NULL, "AQT RX INT1_1 NATIVE MUX"},
+ {"AQT RX INT1_1 NATIVE MUX", NULL, "AQT RX INT1 NATIVE SUPPLY"},
+
+ {"AQT RX INT2_1 NATIVE MUX", "ON", "AQT RX INT2_1 MUX"},
+ {"AQT RX INT2_1 INTERP", NULL, "AQT RX INT2_1 NATIVE MUX"},
+ {"AQT RX INT2_1 NATIVE MUX", NULL, "AQT RX INT2 NATIVE SUPPLY"},
+};
+
+#endif
diff --git a/asoc/codecs/aqt1000/aqt1000-utils.c b/asoc/codecs/aqt1000/aqt1000-utils.c
new file mode 100644
index 0000000..f1c16de
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-utils.c
@@ -0,0 +1,199 @@
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/regmap.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include "aqt1000.h"
+#include "aqt1000-utils.h"
+
+#define REG_BYTES 2
+#define VAL_BYTES 1
+/*
+ * Page Register Address that APP Proc uses to
+ * access codec registers is identified as 0x00
+ */
+#define PAGE_REG_ADDR 0x00
+
+static int aqt_page_write(struct aqt1000 *aqt, unsigned short *reg)
+{
+ int ret = 0;
+ unsigned short c_reg, reg_addr;
+ u8 pg_num, prev_pg_num;
+
+ c_reg = *reg;
+ pg_num = c_reg >> 8;
+ reg_addr = c_reg & 0xff;
+ if (aqt->prev_pg_valid) {
+ prev_pg_num = aqt->prev_pg;
+ if (prev_pg_num != pg_num) {
+ ret = aqt->write_dev(
+ aqt, PAGE_REG_ADDR,
+ (void *) &pg_num, 1);
+ if (ret < 0)
+ dev_err(aqt->dev,
+ "%s: page write error, pg_num: 0x%x\n",
+ __func__, pg_num);
+ else {
+ aqt->prev_pg = pg_num;
+ dev_dbg(aqt->dev, "%s: Page 0x%x Write to 0x00\n",
+ __func__, pg_num);
+ }
+ }
+ } else {
+ ret = aqt->write_dev(
+ aqt, PAGE_REG_ADDR, (void *) &pg_num, 1);
+ if (ret < 0)
+ dev_err(aqt->dev,
+ "%s: page write error, pg_num: 0x%x\n",
+ __func__, pg_num);
+ else {
+ aqt->prev_pg = pg_num;
+ aqt->prev_pg_valid = true;
+ dev_dbg(aqt->dev, "%s: Page 0x%x Write to 0x00\n",
+ __func__, pg_num);
+ }
+ }
+ *reg = reg_addr;
+ return ret;
+}
+
+static int regmap_bus_read(void *context, const void *reg, size_t reg_size,
+ void *val, size_t val_size)
+{
+ struct device *dev = context;
+ struct aqt1000 *aqt = dev_get_drvdata(dev);
+ unsigned short c_reg, rreg;
+ int ret, i;
+
+ if (!aqt) {
+ dev_err(dev, "%s: aqt is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (!reg || !val) {
+ dev_err(dev, "%s: reg or val is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if (reg_size != REG_BYTES) {
+ dev_err(dev, "%s: register size %zd bytes, not supported\n",
+ __func__, reg_size);
+ return -EINVAL;
+ }
+
+ mutex_lock(&aqt->io_lock);
+ c_reg = *(u16 *)reg;
+ rreg = c_reg;
+
+ ret = aqt_page_write(aqt, &c_reg);
+ if (ret)
+ goto err;
+ ret = aqt->read_dev(aqt, c_reg, val, val_size);
+ if (ret < 0)
+ dev_err(dev, "%s: Codec read failed (%d), reg: 0x%x, size:%zd\n",
+ __func__, ret, rreg, val_size);
+ else {
+ for (i = 0; i < val_size; i++)
+ dev_dbg(dev, "%s: Read 0x%02x from 0x%x\n",
+ __func__, ((u8 *)val)[i], rreg + i);
+ }
+err:
+ mutex_unlock(&aqt->io_lock);
+ return ret;
+}
+
+static int regmap_bus_gather_write(void *context,
+ const void *reg, size_t reg_size,
+ const void *val, size_t val_size)
+{
+ struct device *dev = context;
+ struct aqt1000 *aqt = dev_get_drvdata(dev);
+ unsigned short c_reg, rreg;
+ int ret, i;
+
+ if (!aqt) {
+ dev_err(dev, "%s: aqt is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (!reg || !val) {
+ dev_err(dev, "%s: reg or val is NULL\n", __func__);
+ return -EINVAL;
+ }
+ if (reg_size != REG_BYTES) {
+ dev_err(dev, "%s: register size %zd bytes, not supported\n",
+ __func__, reg_size);
+ return -EINVAL;
+ }
+ mutex_lock(&aqt->io_lock);
+ c_reg = *(u16 *)reg;
+ rreg = c_reg;
+
+ ret = aqt_page_write(aqt, &c_reg);
+ if (ret)
+ goto err;
+
+ for (i = 0; i < val_size; i++)
+ dev_dbg(dev, "Write %02x to 0x%x\n", ((u8 *)val)[i],
+ rreg + i);
+
+ ret = aqt->write_dev(aqt, c_reg, (void *) val, val_size);
+ if (ret < 0)
+ dev_err(dev, "%s: Codec write failed (%d), reg:0x%x, size:%zd\n",
+ __func__, ret, rreg, val_size);
+
+err:
+ mutex_unlock(&aqt->io_lock);
+ return ret;
+}
+
+static int regmap_bus_write(void *context, const void *data, size_t count)
+{
+ struct device *dev = context;
+ struct aqt1000 *aqt = dev_get_drvdata(dev);
+
+ if (!aqt)
+ return -EINVAL;
+
+ WARN_ON(count < REG_BYTES);
+
+ return regmap_bus_gather_write(context, data, REG_BYTES,
+ data + REG_BYTES,
+ count - REG_BYTES);
+}
+
+static struct regmap_bus regmap_bus_config = {
+ .write = regmap_bus_write,
+ .gather_write = regmap_bus_gather_write,
+ .read = regmap_bus_read,
+ .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
+ .val_format_endian_default = REGMAP_ENDIAN_NATIVE,
+};
+
+/*
+ * aqt1000_regmap_init:
+ * Initialize aqt1000 register map
+ *
+ * @dev: pointer to wcd device
+ * @config: pointer to register map config
+ *
+ * Returns pointer to regmap structure for success
+ * or NULL in case of failure.
+ */
+struct regmap *aqt1000_regmap_init(struct device *dev,
+ const struct regmap_config *config)
+{
+ return devm_regmap_init(dev, ®map_bus_config, dev, config);
+}
+EXPORT_SYMBOL(aqt1000_regmap_init);
diff --git a/asoc/codecs/aqt1000/aqt1000-utils.h b/asoc/codecs/aqt1000/aqt1000-utils.h
new file mode 100644
index 0000000..9f68cf1
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000-utils.h
@@ -0,0 +1,22 @@
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __WCD9XXX_UTILS_H__
+#define __WCD9XXX_UTILS_H__
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/regmap.h>
+
+struct regmap *aqt1000_regmap_init(struct device *dev,
+ const struct regmap_config *config);
+#endif
diff --git a/asoc/codecs/aqt1000/aqt1000.c b/asoc/codecs/aqt1000/aqt1000.c
new file mode 100644
index 0000000..8463d82
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000.c
@@ -0,0 +1,3470 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/debugfs.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <sound/info.h>
+#include "aqt1000-registers.h"
+#include "aqt1000.h"
+#include "aqt1000-api.h"
+#include "aqt1000-mbhc.h"
+#include "aqt1000-routing.h"
+#include "../wcdcal-hwdep.h"
+#include "aqt1000-internal.h"
+
+#define AQT1000_TX_UNMUTE_DELAY_MS 40
+#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
+#define CF_MIN_3DB_4HZ 0x0
+#define CF_MIN_3DB_75HZ 0x1
+#define CF_MIN_3DB_150HZ 0x2
+
+#define AQT_VERSION_ENTRY_SIZE 17
+#define AQT_VOUT_CTL_TO_MICB(x) (1000 + x *50)
+
+static struct interp_sample_rate sr_val_tbl[] = {
+ {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
+ {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA},
+ {176400, 0xB}, {352800, 0xC},
+};
+
+static int tx_unmute_delay = AQT1000_TX_UNMUTE_DELAY_MS;
+module_param(tx_unmute_delay, int, 0664);
+MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
+
+static void aqt_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
+
+/* Cutoff frequency for high pass filter */
+static const char * const cf_text[] = {
+ "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
+};
+
+static const char * const rx_cf_text[] = {
+ "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
+ "CF_NEG_3DB_0P48HZ"
+};
+
+struct aqt1000_anc_header {
+ u32 reserved[3];
+ u32 num_anc_slots;
+};
+
+static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, AQT1000_CDC_TX0_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, AQT1000_CDC_TX1_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, AQT1000_CDC_TX2_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int1_1_enum, AQT1000_CDC_RX1_RX_PATH_CFG2, 0,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int1_2_enum, AQT1000_CDC_RX1_RX_PATH_MIX_CFG, 2,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int2_1_enum, AQT1000_CDC_RX2_RX_PATH_CFG2, 0,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int2_2_enum, AQT1000_CDC_RX2_RX_PATH_MIX_CFG, 2,
+ rx_cf_text);
+
+static const DECLARE_TLV_DB_SCALE(hph_gain, -3000, 150, 0);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 150, 0);
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+
+static int aqt_get_anc_slot(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = aqt->anc_slot;
+ return 0;
+}
+
+static int aqt_put_anc_slot(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ aqt->anc_slot = ucontrol->value.integer.value[0];
+ return 0;
+}
+
+static int aqt_get_anc_func(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = (aqt->anc_func == true ? 1 : 0);
+ return 0;
+}
+
+static int aqt_put_anc_func(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+
+ mutex_lock(&aqt->codec_mutex);
+ aqt->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
+ dev_dbg(codec->dev, "%s: anc_func %x", __func__, aqt->anc_func);
+
+ if (aqt->anc_func == true) {
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHL PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHR PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_enable_pin(dapm, "ANC HPHR");
+ snd_soc_dapm_disable_pin(dapm, "HPHL PA");
+ snd_soc_dapm_disable_pin(dapm, "HPHR PA");
+ snd_soc_dapm_disable_pin(dapm, "HPHL");
+ snd_soc_dapm_disable_pin(dapm, "HPHR");
+ } else {
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHL");
+ snd_soc_dapm_disable_pin(dapm, "ANC HPHR");
+ snd_soc_dapm_enable_pin(dapm, "HPHL");
+ snd_soc_dapm_enable_pin(dapm, "HPHR");
+ snd_soc_dapm_enable_pin(dapm, "HPHL PA");
+ snd_soc_dapm_enable_pin(dapm, "HPHR PA");
+ }
+ mutex_unlock(&aqt->codec_mutex);
+
+ snd_soc_dapm_sync(dapm);
+ return 0;
+}
+
+static const char *const aqt_anc_func_text[] = {"OFF", "ON"};
+static const struct soc_enum aqt_anc_func_enum =
+ SOC_ENUM_SINGLE_EXT(2, aqt_anc_func_text);
+
+static int aqt_rx_hph_mode_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = aqt->hph_mode;
+ return 0;
+}
+
+static int aqt_rx_hph_mode_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ u32 mode_val;
+
+ mode_val = ucontrol->value.enumerated.item[0];
+
+ dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val);
+
+ if (mode_val == 0) {
+ dev_warn(codec->dev, "%s:Invalid HPH Mode, default to Cls-H LOHiFi\n",
+ __func__);
+ mode_val = CLS_H_LOHIFI;
+ }
+ aqt->hph_mode = mode_val;
+ return 0;
+}
+
+static const char * const rx_hph_mode_mux_text[] = {
+ "CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI",
+ "CLS_H_ULP", "CLS_AB_HIFI",
+};
+
+static const struct soc_enum rx_hph_mode_mux_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_hph_mode_mux_text),
+ rx_hph_mode_mux_text);
+
+static int aqt_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ ucontrol->value.integer.value[0] = (snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) &
+ (1 << band_idx)) != 0;
+
+ dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__,
+ band_idx, (uint32_t)ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int aqt_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ bool iir_band_en_status;
+ int value = ucontrol->value.integer.value[0];
+
+ /* Mask first 5 bits, 6-8 are reserved */
+ snd_soc_update_bits(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_CTL,
+ (1 << band_idx), (value << band_idx));
+
+ iir_band_en_status = ((snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_CTL) &
+ (1 << band_idx)) != 0);
+ dev_dbg(codec->dev, "%s: IIR0 band #%d enable %d\n", __func__,
+ band_idx, iir_band_en_status);
+
+ return 0;
+}
+
+static uint32_t aqt_get_iir_band_coeff(struct snd_soc_codec *codec,
+ int band_idx, int coeff_idx)
+{
+ uint32_t value = 0;
+
+ /* Address does not automatically update if reading */
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL,
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t)) & 0x7F);
+
+ value |= snd_soc_read(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL);
+
+ snd_soc_write(codec, AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL,
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 1) & 0x7F);
+
+ value |= (snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 8);
+
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL,
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 2) & 0x7F);
+
+ value |= (snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL) << 16);
+
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL,
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 3) & 0x7F);
+
+ /* Mask bits top 2 bits since they are reserved */
+ value |= ((snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)
+ & 0x3F) << 24);
+
+ return value;
+}
+
+static int aqt_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ ucontrol->value.integer.value[0] =
+ aqt_get_iir_band_coeff(codec, band_idx, 0);
+ ucontrol->value.integer.value[1] =
+ aqt_get_iir_band_coeff(codec, band_idx, 1);
+ ucontrol->value.integer.value[2] =
+ aqt_get_iir_band_coeff(codec, band_idx, 2);
+ ucontrol->value.integer.value[3] =
+ aqt_get_iir_band_coeff(codec, band_idx, 3);
+ ucontrol->value.integer.value[4] =
+ aqt_get_iir_band_coeff(codec, band_idx, 4);
+
+ dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n"
+ "%s: IIR band #%d b1 = 0x%x\n"
+ "%s: IIR band #%d b2 = 0x%x\n"
+ "%s: IIR band #%d a1 = 0x%x\n"
+ "%s: IIR band #%d a2 = 0x%x\n",
+ __func__, band_idx,
+ (uint32_t)ucontrol->value.integer.value[0],
+ __func__, band_idx,
+ (uint32_t)ucontrol->value.integer.value[1],
+ __func__, band_idx,
+ (uint32_t)ucontrol->value.integer.value[2],
+ __func__, band_idx,
+ (uint32_t)ucontrol->value.integer.value[3],
+ __func__, band_idx,
+ (uint32_t)ucontrol->value.integer.value[4]);
+
+ return 0;
+}
+
+static void aqt_set_iir_band_coeff(struct snd_soc_codec *codec,
+ int band_idx, uint32_t value)
+{
+ snd_soc_write(codec,
+ (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL),
+ (value & 0xFF));
+
+ snd_soc_write(codec,
+ (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL),
+ (value >> 8) & 0xFF);
+
+ snd_soc_write(codec,
+ (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL),
+ (value >> 16) & 0xFF);
+
+ /* Mask top 2 bits, 7-8 are reserved */
+ snd_soc_write(codec,
+ (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL),
+ (value >> 24) & 0x3F);
+}
+
+static int aqt_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ int coeff_idx;
+
+ /*
+ * Mask top bit it is reserved
+ * Updates addr automatically for each B2 write
+ */
+ snd_soc_write(codec,
+ (AQT1000_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+ for (coeff_idx = 0; coeff_idx < AQT1000_CDC_SIDETONE_IIR_COEFF_MAX;
+ coeff_idx++) {
+ aqt_set_iir_band_coeff(codec, band_idx,
+ ucontrol->value.integer.value[coeff_idx]);
+ }
+
+ dev_dbg(codec->dev, "%s: IIR band #%d b0 = 0x%x\n"
+ "%s: IIR band #%d b1 = 0x%x\n"
+ "%s: IIR band #%d b2 = 0x%x\n"
+ "%s: IIR band #%d a1 = 0x%x\n"
+ "%s: IIR band #%d a2 = 0x%x\n",
+ __func__, band_idx,
+ aqt_get_iir_band_coeff(codec, band_idx, 0),
+ __func__, band_idx,
+ aqt_get_iir_band_coeff(codec, band_idx, 1),
+ __func__, band_idx,
+ aqt_get_iir_band_coeff(codec, band_idx, 2),
+ __func__, band_idx,
+ aqt_get_iir_band_coeff(codec, band_idx, 3),
+ __func__, band_idx,
+ aqt_get_iir_band_coeff(codec, band_idx, 4));
+
+ return 0;
+}
+
+static int aqt_compander_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = aqt->comp_enabled[comp];
+ return 0;
+}
+
+static int aqt_compander_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ int value = ucontrol->value.integer.value[0];
+
+ dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n",
+ __func__, comp + 1, aqt->comp_enabled[comp], value);
+ aqt->comp_enabled[comp] = value;
+
+ /* Any specific register configuration for compander */
+ switch (comp) {
+ case COMPANDER_1:
+ /* Set Gain Source Select based on compander enable/disable */
+ snd_soc_update_bits(codec, AQT1000_HPH_L_EN, 0x20,
+ (value ? 0x00:0x20));
+ break;
+ case COMPANDER_2:
+ snd_soc_update_bits(codec, AQT1000_HPH_R_EN, 0x20,
+ (value ? 0x00:0x20));
+ break;
+ default:
+ /*
+ * if compander is not enabled for any interpolator,
+ * it does not cause any audio failure, so do not
+ * return error in this case, but just print a log
+ */
+ dev_warn(codec->dev, "%s: unknown compander: %d\n",
+ __func__, comp);
+ };
+ return 0;
+}
+
+static int aqt_hph_asrc_mode_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int index = -EINVAL;
+
+ if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode"))
+ index = ASRC0;
+ if (!strcmp(kcontrol->id.name, "AQT ASRC1 Output Mode"))
+ index = ASRC1;
+
+ if (aqt && (index >= 0) && (index < ASRC_MAX))
+ aqt->asrc_output_mode[index] =
+ ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static int aqt_hph_asrc_mode_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int val = 0;
+ int index = -EINVAL;
+
+ if (!strcmp(kcontrol->id.name, "AQT ASRC0 Output Mode"))
+ index = ASRC0;
+ if (!strcmp(kcontrol->id.name, "AQT ASRC1 Output Mode"))
+ index = ASRC1;
+
+ if (aqt && (index >= 0) && (index < ASRC_MAX))
+ val = aqt->asrc_output_mode[index];
+
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static const char * const asrc_mode_text[] = {
+ "INT", "FRAC"
+};
+static SOC_ENUM_SINGLE_EXT_DECL(asrc_mode_enum, asrc_mode_text);
+
+static int aqt_hph_idle_detect_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int val = 0;
+
+ if (aqt)
+ val = aqt->idle_det_cfg.hph_idle_detect_en;
+
+ ucontrol->value.integer.value[0] = val;
+
+ return 0;
+}
+
+static int aqt_hph_idle_detect_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ if (aqt)
+ aqt->idle_det_cfg.hph_idle_detect_en =
+ ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
+static const char * const hph_idle_detect_text[] = {
+ "OFF", "ON"
+};
+
+static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text);
+
+static int aqt_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u16 amic_reg = 0;
+
+ if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE"))
+ amic_reg = AQT1000_ANA_AMIC1;
+ if (!strcmp(kcontrol->id.name, "AQT AMIC_3 PWR MODE"))
+ amic_reg = AQT1000_ANA_AMIC3;
+
+ if (amic_reg)
+ ucontrol->value.integer.value[0] =
+ (snd_soc_read(codec, amic_reg) &
+ AQT1000_AMIC_PWR_LVL_MASK) >>
+ AQT1000_AMIC_PWR_LVL_SHIFT;
+ return 0;
+}
+
+static int aqt_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u32 mode_val;
+ u16 amic_reg = 0;
+
+ mode_val = ucontrol->value.enumerated.item[0];
+
+ dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val);
+
+ if (!strcmp(kcontrol->id.name, "AQT AMIC_1_2 PWR MODE"))
+ amic_reg = AQT1000_ANA_AMIC1;
+ if (!strcmp(kcontrol->id.name, "AQT AMIC_3 PWR MODE"))
+ amic_reg = AQT1000_ANA_AMIC3;
+
+ if (amic_reg)
+ snd_soc_update_bits(codec, amic_reg, AQT1000_AMIC_PWR_LVL_MASK,
+ mode_val << AQT1000_AMIC_PWR_LVL_SHIFT);
+ return 0;
+}
+
+static const char * const amic_pwr_lvl_text[] = {
+ "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID"
+};
+
+static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text);
+
+static const struct snd_kcontrol_new aqt_snd_controls[] = {
+ SOC_SINGLE_TLV("AQT HPHL Volume", AQT1000_HPH_L_EN, 0, 24, 1, hph_gain),
+ SOC_SINGLE_TLV("AQT HPHR Volume", AQT1000_HPH_R_EN, 0, 24, 1, hph_gain),
+ SOC_SINGLE_TLV("AQT ADC1 Volume", AQT1000_ANA_AMIC1, 0, 20, 0,
+ analog_gain),
+ SOC_SINGLE_TLV("AQT ADC2 Volume", AQT1000_ANA_AMIC2, 0, 20, 0,
+ analog_gain),
+ SOC_SINGLE_TLV("AQT ADC3 Volume", AQT1000_ANA_AMIC3, 0, 20, 0,
+ analog_gain),
+
+ SOC_SINGLE_SX_TLV("AQT RX1 Digital Volume", AQT1000_CDC_RX1_RX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("AQT RX2 Digital Volume", AQT1000_CDC_RX2_RX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("AQT DEC0 Volume", AQT1000_CDC_TX0_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("AQT DEC1 Volume", AQT1000_CDC_TX1_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("AQT DEC2 Volume", AQT1000_CDC_TX2_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("AQT IIR0 INP0 Volume",
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_SX_TLV("AQT IIR0 INP1 Volume",
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_SX_TLV("AQT IIR0 INP2 Volume",
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_SX_TLV("AQT IIR0 INP3 Volume",
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_EXT("AQT ANC Slot", SND_SOC_NOPM, 0, 100, 0,
+ aqt_get_anc_slot, aqt_put_anc_slot),
+ SOC_ENUM_EXT("AQT ANC Function", aqt_anc_func_enum, aqt_get_anc_func,
+ aqt_put_anc_func),
+
+ SOC_ENUM("AQT TX0 HPF cut off", cf_dec0_enum),
+ SOC_ENUM("AQT TX1 HPF cut off", cf_dec1_enum),
+ SOC_ENUM("AQT TX2 HPF cut off", cf_dec2_enum),
+
+ SOC_ENUM("AQT RX INT1_1 HPF cut off", cf_int1_1_enum),
+ SOC_ENUM("AQT RX INT1_2 HPF cut off", cf_int1_2_enum),
+ SOC_ENUM("AQT RX INT2_1 HPF cut off", cf_int2_1_enum),
+ SOC_ENUM("AQT RX INT2_2 HPF cut off", cf_int2_2_enum),
+
+ SOC_ENUM_EXT("AQT RX HPH Mode", rx_hph_mode_mux_enum,
+ aqt_rx_hph_mode_get, aqt_rx_hph_mode_put),
+
+ SOC_SINGLE_EXT("AQT IIR0 Enable Band1", IIR0, BAND1, 1, 0,
+ aqt_iir_enable_audio_mixer_get,
+ aqt_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("AQT IIR0 Enable Band2", IIR0, BAND2, 1, 0,
+ aqt_iir_enable_audio_mixer_get,
+ aqt_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("AQT IIR0 Enable Band3", IIR0, BAND3, 1, 0,
+ aqt_iir_enable_audio_mixer_get,
+ aqt_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("AQT IIR0 Enable Band4", IIR0, BAND4, 1, 0,
+ aqt_iir_enable_audio_mixer_get,
+ aqt_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("AQT IIR0 Enable Band5", IIR0, BAND5, 1, 0,
+ aqt_iir_enable_audio_mixer_get,
+ aqt_iir_enable_audio_mixer_put),
+
+ SOC_SINGLE_MULTI_EXT("AQT IIR0 Band1", IIR0, BAND1, 255, 0, 5,
+ aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("AQT IIR0 Band2", IIR0, BAND2, 255, 0, 5,
+ aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("AQT IIR0 Band3", IIR0, BAND3, 255, 0, 5,
+ aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("AQT IIR0 Band4", IIR0, BAND4, 255, 0, 5,
+ aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("AQT IIR0 Band5", IIR0, BAND5, 255, 0, 5,
+ aqt_iir_band_audio_mixer_get, aqt_iir_band_audio_mixer_put),
+
+ SOC_SINGLE_EXT("AQT COMP1 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
+ aqt_compander_get, aqt_compander_put),
+ SOC_SINGLE_EXT("AQT COMP2 Switch", SND_SOC_NOPM, COMPANDER_2, 1, 0,
+ aqt_compander_get, aqt_compander_put),
+
+ SOC_ENUM_EXT("AQT ASRC0 Output Mode", asrc_mode_enum,
+ aqt_hph_asrc_mode_get, aqt_hph_asrc_mode_put),
+ SOC_ENUM_EXT("AQT ASRC1 Output Mode", asrc_mode_enum,
+ aqt_hph_asrc_mode_get, aqt_hph_asrc_mode_put),
+
+ SOC_ENUM_EXT("AQT HPH Idle Detect", hph_idle_detect_enum,
+ aqt_hph_idle_detect_get, aqt_hph_idle_detect_put),
+
+ SOC_ENUM_EXT("AQT AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
+ aqt_amic_pwr_lvl_get, aqt_amic_pwr_lvl_put),
+ SOC_ENUM_EXT("AQT AMIC_3 PWR MODE", amic_pwr_lvl_enum,
+ aqt_amic_pwr_lvl_get, aqt_amic_pwr_lvl_put),
+};
+
+static int aqt_codec_enable_rx_bias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ aqt->rx_bias_count++;
+ if (aqt->rx_bias_count == 1) {
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x01, 0x01);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ aqt->rx_bias_count--;
+ if (!aqt->rx_bias_count)
+ snd_soc_update_bits(codec, AQT1000_ANA_RX_SUPPLIES,
+ 0x01, 0x00);
+ break;
+ };
+ dev_dbg(codec->dev, "%s: Current RX BIAS user count: %d\n", __func__,
+ aqt->rx_bias_count);
+
+ return 0;
+}
+
+/*
+ * aqt_mbhc_micb_adjust_voltage: adjust specific micbias voltage
+ * @codec: handle to snd_soc_codec *
+ * @req_volt: micbias voltage to be set
+ * @micb_num: micbias to be set, e.g. micbias1 or micbias2
+ *
+ * return 0 if adjustment is success or error code in case of failure
+ */
+int aqt_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
+ int req_volt, int micb_num)
+{
+ struct aqt1000 *aqt;
+ int cur_vout_ctl, req_vout_ctl;
+ int micb_reg, micb_val, micb_en;
+ int ret = 0;
+
+ if (!codec) {
+ pr_err("%s: Invalid codec pointer\n", __func__);
+ return -EINVAL;
+ }
+
+ if (micb_num != MIC_BIAS_1)
+ return -EINVAL;
+ else
+ micb_reg = AQT1000_ANA_MICB1;
+
+ aqt = snd_soc_codec_get_drvdata(codec);
+ mutex_lock(&aqt->micb_lock);
+
+ /*
+ * If requested micbias voltage is same as current micbias
+ * voltage, then just return. Otherwise, adjust voltage as
+ * per requested value. If micbias is already enabled, then
+ * to avoid slow micbias ramp-up or down enable pull-up
+ * momentarily, change the micbias value and then re-enable
+ * micbias.
+ */
+ micb_val = snd_soc_read(codec, micb_reg);
+ micb_en = (micb_val & 0xC0) >> 6;
+ cur_vout_ctl = micb_val & 0x3F;
+
+ req_vout_ctl = aqt_get_micb_vout_ctl_val(req_volt);
+ if (req_vout_ctl < 0) {
+ ret = -EINVAL;
+ goto exit;
+ }
+ if (cur_vout_ctl == req_vout_ctl) {
+ ret = 0;
+ goto exit;
+ }
+
+ dev_dbg(codec->dev, "%s: micb_num: %d, cur_mv: %d, req_mv: %d, micb_en: %d\n",
+ __func__, micb_num, AQT_VOUT_CTL_TO_MICB(cur_vout_ctl),
+ req_volt, micb_en);
+
+ if (micb_en == 0x1)
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
+
+ snd_soc_update_bits(codec, micb_reg, 0x3F, req_vout_ctl);
+
+ if (micb_en == 0x1) {
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
+ /*
+ * Add 2ms delay as per HW requirement after enabling
+ * micbias
+ */
+ usleep_range(2000, 2100);
+ }
+exit:
+ mutex_unlock(&aqt->micb_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(aqt_mbhc_micb_adjust_voltage);
+
+/*
+ * aqt_micbias_control: enable/disable micbias
+ * @codec: handle to snd_soc_codec *
+ * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2
+ * @req: control requested, enable/disable or pullup enable/disable
+ * @is_dapm: triggered by dapm or not
+ *
+ * return 0 if control is success or error code in case of failure
+ */
+int aqt_micbias_control(struct snd_soc_codec *codec,
+ int micb_num, int req, bool is_dapm)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ u16 micb_reg;
+ int pre_off_event = 0, post_off_event = 0;
+ int post_on_event = 0, post_dapm_off = 0;
+ int post_dapm_on = 0;
+ int ret = 0;
+
+ switch (micb_num) {
+ case MIC_BIAS_1:
+ micb_reg = AQT1000_ANA_MICB1;
+ pre_off_event = AQT_EVENT_PRE_MICBIAS_1_OFF;
+ post_off_event = AQT_EVENT_POST_MICBIAS_1_OFF;
+ post_on_event = AQT_EVENT_POST_MICBIAS_1_ON;
+ post_dapm_on = AQT_EVENT_POST_DAPM_MICBIAS_1_ON;
+ post_dapm_off = AQT_EVENT_POST_DAPM_MICBIAS_1_OFF;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid micbias number: %d\n",
+ __func__, micb_num);
+ return -EINVAL;
+ }
+ mutex_lock(&aqt->micb_lock);
+
+ switch (req) {
+ case MICB_PULLUP_ENABLE:
+ aqt->pullup_ref++;
+ if ((aqt->pullup_ref == 1) &&
+ (aqt->micb_ref == 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
+ break;
+ case MICB_PULLUP_DISABLE:
+ if (aqt->pullup_ref > 0)
+ aqt->pullup_ref--;
+ if ((aqt->pullup_ref == 0) &&
+ (aqt->micb_ref == 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
+ break;
+ case MICB_ENABLE:
+ aqt->micb_ref++;
+ if (aqt->micb_ref == 1) {
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
+ if (post_on_event && aqt->mbhc)
+ blocking_notifier_call_chain(
+ &aqt->mbhc->notifier,
+ post_on_event,
+ &aqt->mbhc->wcd_mbhc);
+ }
+ if (is_dapm && post_dapm_on && aqt->mbhc)
+ blocking_notifier_call_chain(&aqt->mbhc->notifier,
+ post_dapm_on, &aqt->mbhc->wcd_mbhc);
+ break;
+ case MICB_DISABLE:
+ if (aqt->micb_ref > 0)
+ aqt->micb_ref--;
+ if ((aqt->micb_ref == 0) &&
+ (aqt->pullup_ref > 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
+ else if ((aqt->micb_ref == 0) &&
+ (aqt->pullup_ref == 0)) {
+ if (pre_off_event && aqt->mbhc)
+ blocking_notifier_call_chain(
+ &aqt->mbhc->notifier,
+ pre_off_event,
+ &aqt->mbhc->wcd_mbhc);
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
+ if (post_off_event && aqt->mbhc)
+ blocking_notifier_call_chain(
+ &aqt->mbhc->notifier,
+ post_off_event,
+ &aqt->mbhc->wcd_mbhc);
+ }
+ if (is_dapm && post_dapm_off && aqt->mbhc)
+ blocking_notifier_call_chain(&aqt->mbhc->notifier,
+ post_dapm_off, &aqt->mbhc->wcd_mbhc);
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid micbias request: %d\n",
+ __func__, req);
+ ret = -EINVAL;
+ break;
+ };
+
+ if (!ret)
+ dev_dbg(codec->dev,
+ "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n",
+ __func__, micb_num, aqt->micb_ref, aqt->pullup_ref);
+
+ mutex_unlock(&aqt->micb_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(aqt_micbias_control);
+
+static int __aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int micb_num;
+
+ dev_dbg(codec->dev, "%s: wname: %s, event: %d\n",
+ __func__, w->name, event);
+
+ if (strnstr(w->name, "AQT MIC BIAS1", sizeof("AQT MIC BIAS1")))
+ micb_num = MIC_BIAS_1;
+ else
+ return -EINVAL;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /*
+ * MIC BIAS can also be requested by MBHC,
+ * so use ref count to handle micbias pullup
+ * and enable requests
+ */
+ aqt_micbias_control(codec, micb_num, MICB_ENABLE, true);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* wait for cnp time */
+ usleep_range(1000, 1100);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ aqt_micbias_control(codec, micb_num, MICB_DISABLE, true);
+ break;
+ };
+
+ return 0;
+}
+
+static int aqt_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ return __aqt_codec_enable_micbias(w, event);
+}
+
+static int aqt_codec_enable_i2s_block(struct snd_soc_codec *codec)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&aqt->i2s_lock);
+ if (++aqt->i2s_users == 1)
+ snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x01);
+ mutex_unlock(&aqt->i2s_lock);
+
+ return 0;
+}
+
+static int aqt_codec_disable_i2s_block(struct snd_soc_codec *codec)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ mutex_lock(&aqt->i2s_lock);
+ if (--aqt->i2s_users == 0)
+ snd_soc_update_bits(codec, AQT1000_I2S_I2S_0_CTL, 0x01, 0x00);
+
+ if (aqt->i2s_users < 0)
+ dev_warn(codec->dev, "%s: i2s_users count (%d) < 0\n",
+ __func__, aqt->i2s_users);
+ mutex_unlock(&aqt->i2s_lock);
+
+ return 0;
+}
+
+static int aqt_codec_enable_i2s_tx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ aqt_codec_enable_i2s_block(codec);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ aqt_codec_disable_i2s_block(codec);
+ break;
+ }
+ dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
+
+ return 0;
+}
+
+static int aqt_codec_enable_i2s_rx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ aqt_codec_enable_i2s_block(codec);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ aqt_codec_disable_i2s_block(codec);
+ break;
+ }
+ dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
+
+ return 0;
+}
+
+static const char * const tx_mux_text[] = {
+ "ZERO", "DEC_L", "DEC_R", "DEC_V",
+};
+AQT_DAPM_ENUM(tx0, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 0, tx_mux_text);
+AQT_DAPM_ENUM(tx1, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0, 2, tx_mux_text);
+
+static const char * const tx_adc_mux_text[] = {
+ "AMIC", "ANC_FB0", "ANC_FB1",
+};
+AQT_DAPM_ENUM(tx_adc0, AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0,
+ tx_adc_mux_text);
+AQT_DAPM_ENUM(tx_adc1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0,
+ tx_adc_mux_text);
+AQT_DAPM_ENUM(tx_adc2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0,
+ tx_adc_mux_text);
+
+static int aqt_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n)
+{
+ u8 mask;
+ u16 adc_mux_in_reg = 0, amic_mux_sel_reg = 0;
+ bool is_amic;
+
+ if (adc_mux_n > 2)
+ return 0;
+
+ if (adc_mux_n < 3) {
+ adc_mux_in_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+ adc_mux_n;
+ mask = 0x03;
+ amic_mux_sel_reg = AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+ 2 * adc_mux_n;
+ }
+ is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask)) == 0);
+ if (!is_amic)
+ return 0;
+
+ return snd_soc_read(codec, amic_mux_sel_reg) & 0x07;
+}
+
+static u16 aqt_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic)
+{
+ u16 pwr_level_reg = 0;
+
+ switch (amic) {
+ case 1:
+ case 2:
+ pwr_level_reg = AQT1000_ANA_AMIC1;
+ break;
+ case 3:
+ pwr_level_reg = AQT1000_ANA_AMIC3;
+ break;
+ default:
+ dev_dbg(codec->dev, "%s: invalid amic: %d\n",
+ __func__, amic);
+ break;
+ }
+
+ return pwr_level_reg;
+}
+
+static void aqt_tx_hpf_corner_freq_callback(struct work_struct *work)
+{
+ struct delayed_work *hpf_delayed_work;
+ struct hpf_work *hpf_work;
+ struct aqt1000 *aqt;
+ struct snd_soc_codec *codec;
+ u16 dec_cfg_reg, amic_reg, go_bit_reg;
+ u8 hpf_cut_off_freq;
+ int amic_n;
+
+ hpf_delayed_work = to_delayed_work(work);
+ hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
+ aqt = hpf_work->aqt;
+ codec = aqt->codec;
+ hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
+
+ dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator;
+ go_bit_reg = dec_cfg_reg + 7;
+
+ dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
+ __func__, hpf_work->decimator, hpf_cut_off_freq);
+
+ amic_n = aqt_find_amic_input(codec, hpf_work->decimator);
+ if (amic_n) {
+ amic_reg = AQT1000_ANA_AMIC1 + amic_n - 1;
+ aqt_codec_set_tx_hold(codec, amic_reg, false);
+ }
+ snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
+ hpf_cut_off_freq << 5);
+ snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02);
+ /* Minimum 1 clk cycle delay is required as per HW spec */
+ usleep_range(1000, 1010);
+ snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00);
+}
+
+static void aqt_tx_mute_update_callback(struct work_struct *work)
+{
+ struct tx_mute_work *tx_mute_dwork;
+ struct aqt1000 *aqt;
+ struct delayed_work *delayed_work;
+ struct snd_soc_codec *codec;
+ u16 tx_vol_ctl_reg, hpf_gate_reg;
+
+ delayed_work = to_delayed_work(work);
+ tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
+ aqt = tx_mute_dwork->aqt;
+ codec = aqt->codec;
+
+ tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL +
+ 16 * tx_mute_dwork->decimator;
+ hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 +
+ 16 * tx_mute_dwork->decimator;
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
+}
+
+static int aqt_codec_enable_dec(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ char *widget_name = NULL;
+ char *dec = NULL;
+ unsigned int decimator = 0;
+ u8 amic_n = 0;
+ u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
+ u16 tx_gain_ctl_reg;
+ int ret = 0;
+ u8 hpf_cut_off_freq;
+
+ dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
+ widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+ if (!widget_name)
+ return -ENOMEM;
+
+ dec = strpbrk(widget_name, "012");
+ if (!dec) {
+ dev_err(codec->dev, "%s: decimator index not found\n",
+ __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = kstrtouint(dec, 10, &decimator);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+ __func__, widget_name);
+ ret = -EINVAL;
+ goto out;
+ }
+ dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__,
+ w->name, decimator);
+
+ tx_vol_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL + 16 * decimator;
+ hpf_gate_reg = AQT1000_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
+ dec_cfg_reg = AQT1000_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
+ tx_gain_ctl_reg = AQT1000_CDC_TX0_TX_VOL_CTL + 16 * decimator;
+
+ amic_n = aqt_find_amic_input(codec, decimator);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (amic_n)
+ pwr_level_reg = aqt_codec_get_amic_pwlvl_reg(codec,
+ amic_n);
+ if (pwr_level_reg) {
+ switch ((snd_soc_read(codec, pwr_level_reg) &
+ AQT1000_AMIC_PWR_LVL_MASK) >>
+ AQT1000_AMIC_PWR_LVL_SHIFT) {
+ case AQT1000_AMIC_PWR_LEVEL_LP:
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ AQT1000_DEC_PWR_LVL_MASK,
+ AQT1000_DEC_PWR_LVL_LP);
+ break;
+
+ case AQT1000_AMIC_PWR_LEVEL_HP:
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ AQT1000_DEC_PWR_LVL_MASK,
+ AQT1000_DEC_PWR_LVL_HP);
+ break;
+ case AQT1000_AMIC_PWR_LEVEL_DEFAULT:
+ default:
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ AQT1000_DEC_PWR_LVL_MASK,
+ AQT1000_DEC_PWR_LVL_DF);
+ break;
+ }
+ }
+ /* Enable TX PGA Mute */
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) &
+ TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
+
+ aqt->tx_hpf_work[decimator].hpf_cut_off_freq =
+ hpf_cut_off_freq;
+ if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ TX_HPF_CUT_OFF_FREQ_MASK,
+ CF_MIN_3DB_150HZ << 5);
+ snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02);
+ /*
+ * Minimum 1 clk cycle delay is required as per
+ * HW spec.
+ */
+ usleep_range(1000, 1010);
+ snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00);
+ }
+ /* schedule work queue to Remove Mute */
+ schedule_delayed_work(&aqt->tx_mute_dwork[decimator].dwork,
+ msecs_to_jiffies(tx_unmute_delay));
+ if (aqt->tx_hpf_work[decimator].hpf_cut_off_freq !=
+ CF_MIN_3DB_150HZ)
+ schedule_delayed_work(
+ &aqt->tx_hpf_work[decimator].dwork,
+ msecs_to_jiffies(300));
+ /* apply gain after decimator is enabled */
+ snd_soc_write(codec, tx_gain_ctl_reg,
+ snd_soc_read(codec, tx_gain_ctl_reg));
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ hpf_cut_off_freq =
+ aqt->tx_hpf_work[decimator].hpf_cut_off_freq;
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
+ if (cancel_delayed_work_sync(
+ &aqt->tx_hpf_work[decimator].dwork)) {
+ if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ TX_HPF_CUT_OFF_FREQ_MASK,
+ hpf_cut_off_freq << 5);
+ snd_soc_update_bits(codec, hpf_gate_reg,
+ 0x02, 0x02);
+ /*
+ * Minimum 1 clk cycle delay is required as per
+ * HW spec.
+ */
+ usleep_range(1000, 1010);
+ snd_soc_update_bits(codec, hpf_gate_reg,
+ 0x02, 0x00);
+ }
+ }
+ cancel_delayed_work_sync(
+ &aqt->tx_mute_dwork[decimator].dwork);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ AQT1000_DEC_PWR_LVL_MASK,
+ AQT1000_DEC_PWR_LVL_DF);
+ break;
+ }
+
+out:
+ kfree(widget_name);
+ return ret;
+}
+
+static const char * const tx_amic_text[] = {
+ "ZERO", "ADC_L", "ADC_R", "ADC_V",
+};
+AQT_DAPM_ENUM(tx_amic0, AQT1000_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0, tx_amic_text);
+AQT_DAPM_ENUM(tx_amic1, AQT1000_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0, tx_amic_text);
+AQT_DAPM_ENUM(tx_amic2, AQT1000_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0, tx_amic_text);
+
+AQT_DAPM_ENUM(tx_amic10, AQT1000_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0,
+ tx_amic_text);
+AQT_DAPM_ENUM(tx_amic11, AQT1000_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0,
+ tx_amic_text);
+AQT_DAPM_ENUM(tx_amic12, AQT1000_CDC_TX_INP_MUX_ADC_MUX12_CFG0, 0,
+ tx_amic_text);
+AQT_DAPM_ENUM(tx_amic13, AQT1000_CDC_TX_INP_MUX_ADC_MUX13_CFG0, 0,
+ tx_amic_text);
+
+static int aqt_codec_enable_adc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ aqt_codec_set_tx_hold(codec, w->reg, true);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new anc_hphl_pa_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new anc_hphr_pa_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static int aqt_config_compander(struct snd_soc_codec *codec, int interp_n,
+ int event)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int comp;
+ u16 comp_ctl0_reg, rx_path_cfg0_reg;
+
+ comp = interp_n;
+ dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
+ __func__, event, comp, aqt->comp_enabled[comp]);
+
+ if (!aqt->comp_enabled[comp])
+ return 0;
+
+ comp_ctl0_reg = AQT1000_CDC_COMPANDER1_CTL0 + (comp * 8);
+ rx_path_cfg0_reg = AQT1000_CDC_RX1_RX_PATH_CFG0 + (comp * 20);
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ /* Enable Compander Clock */
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
+ snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
+ }
+
+ return 0;
+}
+
+static void aqt_codec_idle_detect_control(struct snd_soc_codec *codec,
+ int interp, int event)
+{
+ int reg = 0, mask, val;
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ if (!aqt->idle_det_cfg.hph_idle_detect_en)
+ return;
+
+ if (interp == INTERP_HPHL) {
+ reg = AQT1000_CDC_RX_IDLE_DET_PATH_CTL;
+ mask = 0x01;
+ val = 0x01;
+ }
+ if (interp == INTERP_HPHR) {
+ reg = AQT1000_CDC_RX_IDLE_DET_PATH_CTL;
+ mask = 0x02;
+ val = 0x02;
+ }
+
+ if (reg && SND_SOC_DAPM_EVENT_ON(event))
+ snd_soc_update_bits(codec, reg, mask, val);
+
+ if (reg && SND_SOC_DAPM_EVENT_OFF(event)) {
+ snd_soc_update_bits(codec, reg, mask, 0x00);
+ aqt->idle_det_cfg.hph_idle_thr = 0;
+ snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, 0x0);
+ }
+}
+
+static void aqt_codec_hphdelay_lutbypass(struct snd_soc_codec *codec,
+ u16 interp_idx, int event)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ u8 hph_dly_mask;
+ u16 hph_lut_bypass_reg = 0;
+ u16 hph_comp_ctrl7 = 0;
+
+
+ switch (interp_idx) {
+ case INTERP_HPHL:
+ hph_dly_mask = 1;
+ hph_lut_bypass_reg = AQT1000_CDC_TOP_HPHL_COMP_LUT;
+ hph_comp_ctrl7 = AQT1000_CDC_COMPANDER1_CTL7;
+ break;
+ case INTERP_HPHR:
+ hph_dly_mask = 2;
+ hph_lut_bypass_reg = AQT1000_CDC_TOP_HPHR_COMP_LUT;
+ hph_comp_ctrl7 = AQT1000_CDC_COMPANDER2_CTL7;
+ break;
+ default:
+ break;
+ }
+
+ if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_ON(event)) {
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0,
+ hph_dly_mask, 0x0);
+ snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x80);
+ if (aqt->hph_mode == CLS_H_ULP)
+ snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x20);
+ }
+
+ if (hph_lut_bypass_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
+ snd_soc_update_bits(codec, AQT1000_CDC_CLSH_TEST0,
+ hph_dly_mask, hph_dly_mask);
+ snd_soc_update_bits(codec, hph_lut_bypass_reg, 0x80, 0x00);
+ snd_soc_update_bits(codec, hph_comp_ctrl7, 0x20, 0x0);
+ }
+}
+
+static int aqt_codec_enable_interp_clk(struct snd_soc_codec *codec,
+ int event, int interp_idx)
+{
+ struct aqt1000 *aqt;
+ u16 main_reg, dsm_reg;
+
+ if (!codec) {
+ pr_err("%s: codec is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ aqt = snd_soc_codec_get_drvdata(codec);
+ main_reg = AQT1000_CDC_RX1_RX_PATH_CTL + (interp_idx * 20);
+ dsm_reg = AQT1000_CDC_RX1_RX_PATH_DSMDEM_CTL + (interp_idx * 20);
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ if (aqt->main_clk_users[interp_idx] == 0) {
+ /* Main path PGA mute enable */
+ snd_soc_update_bits(codec, main_reg, 0x10, 0x10);
+ /* Clk enable */
+ snd_soc_update_bits(codec, dsm_reg, 0x01, 0x01);
+ snd_soc_update_bits(codec, main_reg, 0x20, 0x20);
+ aqt_codec_idle_detect_control(codec, interp_idx,
+ event);
+ aqt_codec_hphdelay_lutbypass(codec, interp_idx,
+ event);
+ aqt_config_compander(codec, interp_idx, event);
+ }
+ aqt->main_clk_users[interp_idx]++;
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ aqt->main_clk_users[interp_idx]--;
+ if (aqt->main_clk_users[interp_idx] <= 0) {
+ aqt->main_clk_users[interp_idx] = 0;
+ aqt_config_compander(codec, interp_idx, event);
+ aqt_codec_hphdelay_lutbypass(codec, interp_idx,
+ event);
+ aqt_codec_idle_detect_control(codec, interp_idx,
+ event);
+ /* Clk Disable */
+ snd_soc_update_bits(codec, main_reg, 0x20, 0x00);
+ snd_soc_update_bits(codec, dsm_reg, 0x01, 0x00);
+ /* Reset enable and disable */
+ snd_soc_update_bits(codec, main_reg, 0x40, 0x40);
+ snd_soc_update_bits(codec, main_reg, 0x40, 0x00);
+ /* Reset rate to 48K*/
+ snd_soc_update_bits(codec, main_reg, 0x0F, 0x04);
+ }
+ }
+
+ dev_dbg(codec->dev, "%s event %d main_clk_users %d\n",
+ __func__, event, aqt->main_clk_users[interp_idx]);
+
+ return aqt->main_clk_users[interp_idx];
+}
+
+static int aqt_anc_out_switch_cb(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ aqt_codec_enable_interp_clk(codec, event, w->shift);
+
+ return 0;
+}
+
+static const char * const anc0_fb_mux_text[] = {
+ "ZERO", "ANC_IN_HPHL",
+};
+
+static const char * const anc1_fb_mux_text[] = {
+ "ZERO", "ANC_IN_HPHR",
+};
+
+AQT_DAPM_ENUM(anc0_fb, AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text);
+AQT_DAPM_ENUM(anc1_fb, AQT1000_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text);
+
+static const char *const rx_int1_1_mux_text[] = {
+ "ZERO", "MAIN_DMA_L", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V",
+ "SHADOW_I2S0_L", "MAIN_DMA_R"
+};
+
+static const char *const rx_int1_2_mux_text[] = {
+ "ZERO", "MIX_DMA_L", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V",
+ "IIR0", "MIX_DMA_R"
+};
+
+static const char *const rx_int2_1_mux_text[] = {
+ "ZERO", "MAIN_DMA_R", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V",
+ "SHADOW_I2S0_R", "MAIN_DMA_L"
+};
+
+static const char *const rx_int2_2_mux_text[] = {
+ "ZERO", "MIX_DMA_R", "I2S0_L", "I2S0_R", "DEC_L", "DEC_R", "DEC_V",
+ "IIR0", "MIX_DMA_L"
+};
+
+AQT_DAPM_ENUM(rx_int1_1, AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0, 0,
+ rx_int1_1_mux_text);
+AQT_DAPM_ENUM(rx_int1_2, AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
+ rx_int1_2_mux_text);
+AQT_DAPM_ENUM(rx_int2_1, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0, 0,
+ rx_int2_1_mux_text);
+AQT_DAPM_ENUM(rx_int2_2, AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1, 0,
+ rx_int2_2_mux_text);
+
+static int aqt_codec_set_idle_detect_thr(struct snd_soc_codec *codec,
+ int interp, int path_type)
+{
+ int port_id[4] = { 0, 0, 0, 0 };
+ int *port_ptr, num_ports;
+ int bit_width = 0;
+ int mux_reg = 0, mux_reg_val = 0;
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int idle_thr;
+
+ if ((interp != INTERP_HPHL) && (interp != INTERP_HPHR))
+ return 0;
+
+ if (!aqt->idle_det_cfg.hph_idle_detect_en)
+ return 0;
+
+ port_ptr = &port_id[0];
+ num_ports = 0;
+
+ if (path_type == INTERP_MIX_PATH) {
+ if (interp == INTERP_HPHL)
+ mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG1;
+ else
+ mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG1;
+ }
+
+ if (path_type == INTERP_MAIN_PATH) {
+ if (interp == INTERP_HPHL)
+ mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT1_CFG0;
+ else
+ mux_reg = AQT1000_CDC_RX_INP_MUX_RX_INT2_CFG0;
+ }
+ mux_reg_val = snd_soc_read(codec, mux_reg);
+
+ /* Read bit width from I2S reg if mux is set to I2S0_L or I2S0_R */
+ if (mux_reg_val == 0x02 || mux_reg_val == 0x03)
+ bit_width = ((snd_soc_read(codec, AQT1000_I2S_I2S_0_CTL) &
+ 0x40) >> 6);
+
+ switch (bit_width) {
+ case 1: /* 16 bit */
+ idle_thr = 0xff; /* F16 */
+ break;
+ case 0: /* 32 bit */
+ default:
+ idle_thr = 0x03; /* F22 */
+ break;
+ }
+
+ dev_dbg(codec->dev, "%s: (new) idle_thr: %d, (cur) idle_thr: %d\n",
+ __func__, idle_thr, aqt->idle_det_cfg.hph_idle_thr);
+
+ if ((aqt->idle_det_cfg.hph_idle_thr == 0) ||
+ (idle_thr < aqt->idle_det_cfg.hph_idle_thr)) {
+ snd_soc_write(codec, AQT1000_CDC_RX_IDLE_DET_CFG3, idle_thr);
+ aqt->idle_det_cfg.hph_idle_thr = idle_thr;
+ }
+
+ return 0;
+}
+
+static int aqt_codec_enable_main_path(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ u16 gain_reg = 0;
+ int val = 0;
+
+ dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+ if (w->shift >= AQT1000_NUM_INTERPOLATORS) {
+ dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n",
+ __func__, w->shift, w->name);
+ return -EINVAL;
+ };
+
+ gain_reg = AQT1000_CDC_RX1_RX_VOL_CTL + (w->shift *
+ AQT1000_RX_PATH_CTL_OFFSET);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ aqt_codec_enable_interp_clk(codec, event, w->shift);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ aqt_codec_set_idle_detect_thr(codec, w->shift,
+ INTERP_MAIN_PATH);
+ /* apply gain after int clk is enabled */
+ val = snd_soc_read(codec, gain_reg);
+ snd_soc_write(codec, gain_reg, val);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ aqt_codec_enable_interp_clk(codec, event, w->shift);
+ break;
+ };
+
+ return 0;
+}
+
+static int aqt_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ u16 gain_reg = 0;
+ u16 mix_reg = 0;
+
+ if (w->shift >= AQT1000_NUM_INTERPOLATORS) {
+ dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n",
+ __func__, w->shift, w->name);
+ return -EINVAL;
+ };
+ gain_reg = AQT1000_CDC_RX1_RX_VOL_MIX_CTL +
+ (w->shift * AQT1000_RX_PATH_CTL_OFFSET);
+ mix_reg = AQT1000_CDC_RX1_RX_PATH_MIX_CTL +
+ (w->shift * AQT1000_RX_PATH_CTL_OFFSET);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ aqt_codec_enable_interp_clk(codec, event, w->shift);
+ /* Clk enable */
+ snd_soc_update_bits(codec, mix_reg, 0x20, 0x20);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ aqt_codec_set_idle_detect_thr(codec, w->shift,
+ INTERP_MIX_PATH);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* Clk Disable */
+ snd_soc_update_bits(codec, mix_reg, 0x20, 0x00);
+ aqt_codec_enable_interp_clk(codec, event, w->shift);
+ /* Reset enable and disable */
+ snd_soc_update_bits(codec, mix_reg, 0x40, 0x40);
+ snd_soc_update_bits(codec, mix_reg, 0x40, 0x00);
+
+ break;
+ };
+ dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name);
+
+ return 0;
+}
+
+static const char * const rx_int1_1_interp_mux_text[] = {
+ "ZERO", "RX INT1_1 MUX",
+};
+
+static const char * const rx_int2_1_interp_mux_text[] = {
+ "ZERO", "RX INT2_1 MUX",
+};
+
+static const char * const rx_int1_2_interp_mux_text[] = {
+ "ZERO", "RX INT1_2 MUX",
+};
+
+static const char * const rx_int2_2_interp_mux_text[] = {
+ "ZERO", "RX INT2_2 MUX",
+};
+
+AQT_DAPM_ENUM(rx_int1_1_interp, SND_SOC_NOPM, 0, rx_int1_1_interp_mux_text);
+AQT_DAPM_ENUM(rx_int2_1_interp, SND_SOC_NOPM, 0, rx_int2_1_interp_mux_text);
+
+AQT_DAPM_ENUM(rx_int1_2_interp, SND_SOC_NOPM, 0, rx_int1_2_interp_mux_text);
+AQT_DAPM_ENUM(rx_int2_2_interp, SND_SOC_NOPM, 0, rx_int2_2_interp_mux_text);
+
+static const char * const asrc0_mux_text[] = {
+ "ZERO", "ASRC_IN_HPHL",
+};
+
+static const char * const asrc1_mux_text[] = {
+ "ZERO", "ASRC_IN_HPHR",
+};
+
+AQT_DAPM_ENUM(asrc0, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0,
+ asrc0_mux_text);
+AQT_DAPM_ENUM(asrc1, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 2,
+ asrc1_mux_text);
+
+static int aqt_get_asrc_mode(struct aqt1000 *aqt, int asrc,
+ u8 main_sr, u8 mix_sr)
+{
+ u8 asrc_output_mode;
+ int asrc_mode = CONV_88P2K_TO_384K;
+
+ if ((asrc < 0) || (asrc >= ASRC_MAX))
+ return 0;
+
+ asrc_output_mode = aqt->asrc_output_mode[asrc];
+
+ if (asrc_output_mode) {
+ /*
+ * If Mix sample rate is < 96KHz, use 96K to 352.8K
+ * conversion, or else use 384K to 352.8K conversion
+ */
+ if (mix_sr < 5)
+ asrc_mode = CONV_96K_TO_352P8K;
+ else
+ asrc_mode = CONV_384K_TO_352P8K;
+ } else {
+ /* Integer main and Fractional mix path */
+ if (main_sr < 8 && mix_sr > 9) {
+ asrc_mode = CONV_352P8K_TO_384K;
+ } else if (main_sr > 8 && mix_sr < 8) {
+ /* Fractional main and Integer mix path */
+ if (mix_sr < 5)
+ asrc_mode = CONV_96K_TO_352P8K;
+ else
+ asrc_mode = CONV_384K_TO_352P8K;
+ } else if (main_sr < 8 && mix_sr < 8) {
+ /* Integer main and Integer mix path */
+ asrc_mode = CONV_96K_TO_384K;
+ }
+ }
+
+ return asrc_mode;
+}
+
+static int aqt_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int asrc = 0, ret = 0;
+ u8 cfg;
+ u16 cfg_reg = 0;
+ u16 ctl_reg = 0;
+ u16 clk_reg = 0;
+ u16 asrc_ctl = 0;
+ u16 mix_ctl_reg = 0;
+ u16 paired_reg = 0;
+ u8 main_sr, mix_sr, asrc_mode = 0;
+
+ cfg = snd_soc_read(codec, AQT1000_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0);
+ if (!(cfg & 0xFF)) {
+ dev_err(codec->dev, "%s: ASRC%u input not selected\n",
+ __func__, w->shift);
+ return -EINVAL;
+ }
+
+ switch (w->shift) {
+ case ASRC0:
+ if ((cfg & 0x03) == 0x01) {
+ cfg_reg = AQT1000_CDC_RX1_RX_PATH_CFG0;
+ ctl_reg = AQT1000_CDC_RX1_RX_PATH_CTL;
+ clk_reg = AQT1000_MIXING_ASRC0_CLK_RST_CTL;
+ paired_reg = AQT1000_MIXING_ASRC1_CLK_RST_CTL;
+ asrc_ctl = AQT1000_MIXING_ASRC0_CTL1;
+ }
+ break;
+ case ASRC1:
+ if ((cfg & 0x0C) == 0x4) {
+ cfg_reg = AQT1000_CDC_RX2_RX_PATH_CFG0;
+ ctl_reg = AQT1000_CDC_RX2_RX_PATH_CTL;
+ clk_reg = AQT1000_MIXING_ASRC1_CLK_RST_CTL;
+ paired_reg = AQT1000_MIXING_ASRC0_CLK_RST_CTL;
+ asrc_ctl = AQT1000_MIXING_ASRC1_CTL1;
+ }
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__,
+ w->shift);
+ ret = -EINVAL;
+ break;
+ };
+
+ if ((cfg_reg == 0) || (ctl_reg == 0) || (clk_reg == 0) ||
+ (asrc_ctl == 0) || ret)
+ goto done;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if ((snd_soc_read(codec, clk_reg) & 0x02) ||
+ (snd_soc_read(codec, paired_reg) & 0x02)) {
+ snd_soc_update_bits(codec, clk_reg, 0x02, 0x00);
+ snd_soc_update_bits(codec, paired_reg, 0x02, 0x00);
+ }
+ snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80);
+ snd_soc_update_bits(codec, clk_reg, 0x01, 0x01);
+ main_sr = snd_soc_read(codec, ctl_reg) & 0x0F;
+ mix_ctl_reg = ctl_reg + 5;
+ mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F;
+ asrc_mode = aqt_get_asrc_mode(aqt, asrc,
+ main_sr, mix_sr);
+ dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n",
+ __func__, main_sr, mix_sr, asrc_mode);
+ snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00);
+ snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00);
+ snd_soc_update_bits(codec, clk_reg, 0x03, 0x02);
+ break;
+ };
+
+done:
+ return ret;
+}
+
+static int aqt_codec_enable_anc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ const char *filename;
+ const struct firmware *fw;
+ int i;
+ int ret = 0;
+ int num_anc_slots;
+ struct aqt1000_anc_header *anc_head;
+ struct firmware_cal *hwdep_cal = NULL;
+ u32 anc_writes_size = 0;
+ u32 anc_cal_size = 0;
+ int anc_size_remaining;
+ u32 *anc_ptr;
+ u16 reg;
+ u8 mask, val;
+ size_t cal_size;
+ const void *data;
+
+ if (!aqt->anc_func)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ hwdep_cal = wcdcal_get_fw_cal(aqt->fw_data, WCD9XXX_ANC_CAL);
+ if (hwdep_cal) {
+ data = hwdep_cal->data;
+ cal_size = hwdep_cal->size;
+ dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd",
+ __func__, cal_size);
+ } else {
+ filename = "AQT1000/AQT1000_anc.bin";
+ ret = request_firmware(&fw, filename, codec->dev);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ if (!fw) {
+ dev_err(codec->dev, "%s: Failed to get anc fw\n",
+ __func__);
+ return -ENODEV;
+ }
+ data = fw->data;
+ cal_size = fw->size;
+ dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
+ __func__);
+ }
+ if (cal_size < sizeof(struct aqt1000_anc_header)) {
+ dev_err(codec->dev, "%s: Invalid cal_size %zd\n",
+ __func__, cal_size);
+ ret = -EINVAL;
+ goto err;
+ }
+ /* First number is the number of register writes */
+ anc_head = (struct aqt1000_anc_header *)(data);
+ anc_ptr = (u32 *)(data + sizeof(struct aqt1000_anc_header));
+ anc_size_remaining = cal_size -
+ sizeof(struct aqt1000_anc_header);
+ num_anc_slots = anc_head->num_anc_slots;
+
+ if (aqt->anc_slot >= num_anc_slots) {
+ dev_err(codec->dev, "%s: Invalid ANC slot selected\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ for (i = 0; i < num_anc_slots; i++) {
+ if (anc_size_remaining < AQT1000_PACKED_REG_SIZE) {
+ dev_err(codec->dev, "%s: Invalid register format\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ anc_writes_size = (u32)(*anc_ptr);
+ anc_size_remaining -= sizeof(u32);
+ anc_ptr += 1;
+
+ if ((anc_writes_size * AQT1000_PACKED_REG_SIZE) >
+ anc_size_remaining) {
+ dev_err(codec->dev, "%s: Invalid register format\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (aqt->anc_slot == i)
+ break;
+
+ anc_size_remaining -= (anc_writes_size *
+ AQT1000_PACKED_REG_SIZE);
+ anc_ptr += anc_writes_size;
+ }
+ if (i == num_anc_slots) {
+ dev_err(codec->dev, "%s: Selected ANC slot not present\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ i = 0;
+ anc_cal_size = anc_writes_size;
+ /* Rate converter clk enable and set bypass mode */
+ if (!strcmp(w->name, "AQT RX INT1 DAC")) {
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_RC_COMMON_CTL,
+ 0x05, 0x05);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_FIFO_COMMON_CTL,
+ 0x66, 0x66);
+ anc_writes_size = anc_cal_size / 2;
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x39, 0x39);
+ } else if (!strcmp(w->name, "AQT RX INT2 DAC")) {
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_RC_COMMON_CTL,
+ 0x05, 0x05);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_FIFO_COMMON_CTL,
+ 0x66, 0x66);
+ i = anc_cal_size / 2;
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x39, 0x39);
+ }
+
+ for (; i < anc_writes_size; i++) {
+ AQT1000_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
+ snd_soc_write(codec, reg, (val & mask));
+ }
+ if (!strcmp(w->name, "AQT RX INT1 DAC"))
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_CLK_RESET_CTL, 0x08, 0x08);
+ else if (!strcmp(w->name, "AQT RX INT2 DAC"))
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_CLK_RESET_CTL, 0x08, 0x08);
+
+ if (!hwdep_cal)
+ release_firmware(fw);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ /* Remove ANC Rx from reset */
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_CLK_RESET_CTL,
+ 0x08, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_CLK_RESET_CTL,
+ 0x08, 0x00);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, AQT1000_CDC_ANC0_RC_COMMON_CTL,
+ 0x05, 0x00);
+ if (!strcmp(w->name, "AQT ANC HPHL PA")) {
+ snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL,
+ 0x30, 0x00);
+ /* 50 msec sleep is needed to avoid click and pop as
+ * per HW requirement
+ */
+ msleep(50);
+ snd_soc_update_bits(codec, AQT1000_CDC_ANC0_MODE_1_CTL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_CLK_RESET_CTL,
+ 0x38, 0x38);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_CLK_RESET_CTL,
+ 0x07, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC0_CLK_RESET_CTL,
+ 0x38, 0x00);
+ } else if (!strcmp(w->name, "AQT ANC HPHR PA")) {
+ snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL,
+ 0x30, 0x00);
+ /* 50 msec sleep is needed to avoid click and pop as
+ * per HW requirement
+ */
+ msleep(50);
+ snd_soc_update_bits(codec, AQT1000_CDC_ANC1_MODE_1_CTL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_CLK_RESET_CTL,
+ 0x38, 0x38);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_CLK_RESET_CTL,
+ 0x07, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_ANC1_CLK_RESET_CTL,
+ 0x38, 0x00);
+ }
+ break;
+ }
+
+ return 0;
+err:
+ if (!hwdep_cal)
+ release_firmware(fw);
+ return ret;
+}
+
+static void aqt_codec_override(struct snd_soc_codec *codec, int mode,
+ int event)
+{
+ if (mode == CLS_AB || mode == CLS_AB_HIFI) {
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ case SND_SOC_DAPM_POST_PMU:
+ snd_soc_update_bits(codec,
+ AQT1000_ANA_RX_SUPPLIES, 0x02, 0x02);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec,
+ AQT1000_ANA_RX_SUPPLIES, 0x02, 0x00);
+ break;
+ }
+ }
+}
+
+static void aqt_codec_set_tx_hold(struct snd_soc_codec *codec,
+ u16 amic_reg, bool set)
+{
+ u8 mask = 0x20;
+ u8 val;
+
+ if (amic_reg == AQT1000_ANA_AMIC1 ||
+ amic_reg == AQT1000_ANA_AMIC3)
+ mask = 0x40;
+
+ val = set ? mask : 0x00;
+
+ switch (amic_reg) {
+ case AQT1000_ANA_AMIC1:
+ case AQT1000_ANA_AMIC2:
+ snd_soc_update_bits(codec, AQT1000_ANA_AMIC2, mask, val);
+ break;
+ case AQT1000_ANA_AMIC3:
+ snd_soc_update_bits(codec, AQT1000_ANA_AMIC3_HPF, mask, val);
+ break;
+ default:
+ dev_dbg(codec->dev, "%s: invalid amic: %d\n",
+ __func__, amic_reg);
+ break;
+ }
+}
+
+static void aqt_codec_clear_anc_tx_hold(struct aqt1000 *aqt)
+{
+ if (test_and_clear_bit(ANC_MIC_AMIC1, &aqt->status_mask))
+ aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC1, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC2, &aqt->status_mask))
+ aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC2, false);
+ if (test_and_clear_bit(ANC_MIC_AMIC3, &aqt->status_mask))
+ aqt_codec_set_tx_hold(aqt->codec, AQT1000_ANA_AMIC3, false);
+}
+
+static const char * const rx_int_dem_inp_mux_text[] = {
+ "NORMAL_DSM_OUT", "CLSH_DSM_OUT",
+};
+
+static int aqt_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int val;
+ unsigned short look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0;
+
+ val = ucontrol->value.enumerated.item[0];
+ if (val >= e->items)
+ return -EINVAL;
+
+ dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
+ widget->name, val);
+
+ if (e->reg == AQT1000_CDC_RX1_RX_PATH_SEC0)
+ look_ahead_dly_reg = AQT1000_CDC_RX1_RX_PATH_CFG0;
+ else if (e->reg == AQT1000_CDC_RX2_RX_PATH_SEC0)
+ look_ahead_dly_reg = AQT1000_CDC_RX2_RX_PATH_CFG0;
+
+ /* Set Look Ahead Delay */
+ snd_soc_update_bits(codec, look_ahead_dly_reg,
+ 0x08, (val ? 0x08 : 0x00));
+ /* Set DEM INP Select */
+ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+}
+
+AQT_DAPM_ENUM_EXT(rx_int1_dem, AQT1000_CDC_RX1_RX_PATH_SEC0, 0,
+ rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
+ aqt_int_dem_inp_mux_put);
+AQT_DAPM_ENUM_EXT(rx_int2_dem, AQT1000_CDC_RX2_RX_PATH_SEC0, 0,
+ rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
+ aqt_int_dem_inp_mux_put);
+
+static int aqt_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int hph_mode = aqt->hph_mode;
+ u8 dem_inp;
+ int ret = 0;
+ uint32_t impedl = 0;
+ uint32_t impedr = 0;
+
+ dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
+ w->name, event, hph_mode);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (aqt->anc_func) {
+ ret = aqt_codec_enable_anc(w, kcontrol, event);
+ /* 40 msec delay is needed to avoid click and pop */
+ msleep(40);
+ }
+ /* Read DEM INP Select */
+ dem_inp = snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_SEC0) &
+ 0x03;
+ if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
+ (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
+ dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
+ __func__, hph_mode);
+ return -EINVAL;
+ }
+ /* Disable AutoChop timer during power up */
+ snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1,
+ 0x02, 0x00);
+
+ aqt_clsh_fsm(codec, &aqt->clsh_d,
+ AQT_CLSH_EVENT_PRE_DAC,
+ AQT_CLSH_STATE_HPHL,
+ hph_mode);
+
+ if (aqt->anc_func)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_CFG0,
+ 0x10, 0x10);
+
+ ret = aqt_mbhc_get_impedance(aqt->mbhc,
+ &impedl, &impedr);
+ if (!ret) {
+ aqt_clsh_imped_config(codec, impedl, false);
+ set_bit(CLSH_Z_CONFIG, &aqt->status_mask);
+ } else {
+ dev_dbg(codec->dev, "%s: Failed to get mbhc impedance %d\n",
+ __func__, ret);
+ ret = 0;
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* 1000us required as per HW requirement */
+ usleep_range(1000, 1100);
+ aqt_clsh_fsm(codec, &aqt->clsh_d,
+ AQT_CLSH_EVENT_POST_PA,
+ AQT_CLSH_STATE_HPHL,
+ hph_mode);
+ if (test_bit(CLSH_Z_CONFIG, &aqt->status_mask)) {
+ aqt_clsh_imped_config(codec, impedl, true);
+ clear_bit(CLSH_Z_CONFIG, &aqt->status_mask);
+ }
+ break;
+ default:
+ break;
+ };
+
+ return ret;
+}
+
+static int aqt_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int hph_mode = aqt->hph_mode;
+ u8 dem_inp;
+ int ret = 0;
+
+ dev_dbg(codec->dev, "%s wname: %s event: %d hph_mode: %d\n", __func__,
+ w->name, event, hph_mode);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (aqt->anc_func) {
+ ret = aqt_codec_enable_anc(w, kcontrol, event);
+ /* 40 msec delay is needed to avoid click and pop */
+ msleep(40);
+ }
+ /* Read DEM INP Select */
+ dem_inp = snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_SEC0) &
+ 0x03;
+ if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
+ (hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
+ dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
+ __func__, hph_mode);
+ return -EINVAL;
+ }
+ /* Disable AutoChop timer during power up */
+ snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1,
+ 0x02, 0x00);
+ aqt_clsh_fsm(codec, &aqt->clsh_d,
+ AQT_CLSH_EVENT_PRE_DAC,
+ AQT_CLSH_STATE_HPHR,
+ hph_mode);
+ if (aqt->anc_func)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_CFG0,
+ 0x10, 0x10);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* 1000us required as per HW requirement */
+ usleep_range(1000, 1100);
+ aqt_clsh_fsm(codec, &aqt->clsh_d,
+ AQT_CLSH_EVENT_POST_PA,
+ AQT_CLSH_STATE_HPHR,
+ hph_mode);
+ break;
+ default:
+ break;
+ };
+
+ return 0;
+}
+
+static int aqt_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if ((!(strcmp(w->name, "AQT ANC HPHR PA"))) &&
+ (test_bit(HPH_PA_DELAY, &aqt->status_mask)))
+ snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0xC0, 0xC0);
+
+ set_bit(HPH_PA_DELAY, &aqt->status_mask);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if ((!(strcmp(w->name, "AQT ANC HPHR PA")))) {
+ if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0)
+ != 0xC0)
+ /*
+ * If PA_EN is not set (potentially in ANC case)
+ * then do nothing for POST_PMU and let left
+ * channel handle everything.
+ */
+ break;
+ }
+ /*
+ * 7ms sleep is required after PA is enabled as per
+ * HW requirement. If compander is disabled, then
+ * 20ms delay is needed.
+ */
+ if (test_bit(HPH_PA_DELAY, &aqt->status_mask)) {
+ if (!aqt->comp_enabled[COMPANDER_2])
+ usleep_range(20000, 20100);
+ else
+ usleep_range(7000, 7100);
+ clear_bit(HPH_PA_DELAY, &aqt->status_mask);
+ }
+ if (aqt->anc_func) {
+ /* Clear Tx FE HOLD if both PAs are enabled */
+ if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) &
+ 0xC0) == 0xC0)
+ aqt_codec_clear_anc_tx_hold(aqt);
+ }
+
+ snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x01);
+
+ /* Remove mute */
+ snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL,
+ 0x10, 0x00);
+ /* Enable GM3 boost */
+ snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL,
+ 0x80, 0x80);
+ /* Enable AutoChop timer at the end of power up */
+ snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1,
+ 0x02, 0x02);
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ if (!(strcmp(w->name, "AQT ANC HPHR PA"))) {
+ dev_dbg(codec->dev,
+ "%s:Do everything needed for left channel\n",
+ __func__);
+ /* Do everything needed for left channel */
+ snd_soc_update_bits(codec, AQT1000_HPH_L_TEST,
+ 0x01, 0x01);
+
+ /* Remove mute */
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL,
+ 0x10, 0x00);
+
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec,
+ AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+
+ /* Remove ANC Rx from reset */
+ ret = aqt_codec_enable_anc(w, kcontrol, event);
+ }
+ aqt_codec_override(codec, aqt->hph_mode, event);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ blocking_notifier_call_chain(&aqt->mbhc->notifier,
+ AQT_EVENT_PRE_HPHR_PA_OFF,
+ &aqt->mbhc->wcd_mbhc);
+ snd_soc_update_bits(codec, AQT1000_HPH_R_TEST, 0x01, 0x00);
+ snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL,
+ 0x10, 0x10);
+ snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL,
+ 0x10, 0x10);
+ if (!(strcmp(w->name, "AQT ANC HPHR PA")))
+ snd_soc_update_bits(codec, AQT1000_ANA_HPH, 0x40, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /*
+ * 5ms sleep is required after PA disable. If compander is
+ * disabled, then 20ms delay is needed after PA disable.
+ */
+ if (!aqt->comp_enabled[COMPANDER_2])
+ usleep_range(20000, 20100);
+ else
+ usleep_range(5000, 5100);
+ aqt_codec_override(codec, aqt->hph_mode, event);
+ blocking_notifier_call_chain(&aqt->mbhc->notifier,
+ AQT_EVENT_POST_HPHR_PA_OFF,
+ &aqt->mbhc->wcd_mbhc);
+ if (!(strcmp(w->name, "AQT ANC HPHR PA"))) {
+ ret = aqt_codec_enable_anc(w, kcontrol, event);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_CFG0,
+ 0x10, 0x00);
+ }
+ break;
+ };
+
+ return ret;
+}
+
+static int aqt_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if ((!(strcmp(w->name, "AQT ANC HPHL PA"))) &&
+ (test_bit(HPH_PA_DELAY, &aqt->status_mask)))
+ snd_soc_update_bits(codec, AQT1000_ANA_HPH,
+ 0xC0, 0xC0);
+ set_bit(HPH_PA_DELAY, &aqt->status_mask);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if (!(strcmp(w->name, "AQT ANC HPHL PA"))) {
+ if ((snd_soc_read(codec, AQT1000_ANA_HPH) & 0xC0)
+ != 0xC0)
+ /*
+ * If PA_EN is not set (potentially in ANC
+ * case) then do nothing for POST_PMU and
+ * let right channel handle everything.
+ */
+ break;
+ }
+ /*
+ * 7ms sleep is required after PA is enabled as per
+ * HW requirement. If compander is disabled, then
+ * 20ms delay is needed.
+ */
+ if (test_bit(HPH_PA_DELAY, &aqt->status_mask)) {
+ if (!aqt->comp_enabled[COMPANDER_1])
+ usleep_range(20000, 20100);
+ else
+ usleep_range(7000, 7100);
+ clear_bit(HPH_PA_DELAY, &aqt->status_mask);
+ }
+ if (aqt->anc_func) {
+ /* Clear Tx FE HOLD if both PAs are enabled */
+ if ((snd_soc_read(aqt->codec, AQT1000_ANA_HPH) &
+ 0xC0) == 0xC0)
+ aqt_codec_clear_anc_tx_hold(aqt);
+ }
+
+ snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x01);
+ /* Remove Mute on primary path */
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL,
+ 0x10, 0x00);
+ /* Enable GM3 boost */
+ snd_soc_update_bits(codec, AQT1000_HPH_CNP_WG_CTL,
+ 0x80, 0x80);
+ /* Enable AutoChop timer at the end of power up */
+ snd_soc_update_bits(codec, AQT1000_HPH_NEW_INT_HPH_TIMER1,
+ 0x02, 0x02);
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ if (!(strcmp(w->name, "AQT ANC HPHL PA"))) {
+ dev_dbg(codec->dev,
+ "%s:Do everything needed for right channel\n",
+ __func__);
+
+ /* Do everything needed for right channel */
+ snd_soc_update_bits(codec, AQT1000_HPH_R_TEST,
+ 0x01, 0x01);
+
+ /* Remove mute */
+ snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL,
+ 0x10, 0x00);
+
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec,
+ AQT1000_CDC_RX2_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX2_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ /* Remove ANC Rx from reset */
+ ret = aqt_codec_enable_anc(w, kcontrol, event);
+ }
+ aqt_codec_override(codec, aqt->hph_mode, event);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ blocking_notifier_call_chain(&aqt->mbhc->notifier,
+ AQT_EVENT_PRE_HPHL_PA_OFF,
+ &aqt->mbhc->wcd_mbhc);
+ snd_soc_update_bits(codec, AQT1000_HPH_L_TEST, 0x01, 0x00);
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL,
+ 0x10, 0x10);
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL,
+ 0x10, 0x10);
+ if (!(strcmp(w->name, "AQT ANC HPHL PA")))
+ snd_soc_update_bits(codec, AQT1000_ANA_HPH,
+ 0x80, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /*
+ * 5ms sleep is required after PA disable. If compander is
+ * disabled, then 20ms delay is needed after PA disable.
+ */
+ if (!aqt->comp_enabled[COMPANDER_1])
+ usleep_range(20000, 20100);
+ else
+ usleep_range(5000, 5100);
+ aqt_codec_override(codec, aqt->hph_mode, event);
+ blocking_notifier_call_chain(&aqt->mbhc->notifier,
+ AQT_EVENT_POST_HPHL_PA_OFF,
+ &aqt->mbhc->wcd_mbhc);
+ if (!(strcmp(w->name, "AQT ANC HPHL PA"))) {
+ ret = aqt_codec_enable_anc(w, kcontrol, event);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
+ }
+ break;
+ };
+
+ return ret;
+}
+
+static int aqt_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU: /* fall through */
+ case SND_SOC_DAPM_PRE_PMD:
+ if (strnstr(w->name, "AQT IIR0", sizeof("AQT IIR0"))) {
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
+ snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
+ snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
+ snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
+ snd_soc_write(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
+ snd_soc_read(codec,
+ AQT1000_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
+ }
+ break;
+ }
+ return 0;
+}
+
+static int aqt_enable_native_supply(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (++aqt->native_clk_users == 1) {
+ snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES,
+ 0x01, 0x01);
+ /* 100usec is needed as per HW requirement */
+ usleep_range(100, 120);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x02, 0x02);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x10, 0x10);
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ if (aqt->native_clk_users &&
+ (--aqt->native_clk_users == 0)) {
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x10, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec, AQT1000_CLK_SYS_PLL_ENABLES,
+ 0x01, 0x00);
+ }
+ break;
+ }
+
+ dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n",
+ __func__, aqt->native_clk_users, event);
+
+ return 0;
+}
+
+static const char * const native_mux_text[] = {
+ "OFF", "ON",
+};
+
+AQT_DAPM_ENUM(int1_1_native, SND_SOC_NOPM, 0, native_mux_text);
+AQT_DAPM_ENUM(int2_1_native, SND_SOC_NOPM, 0, native_mux_text);
+
+static int aqt_mclk_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int ret = 0;
+
+ dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = aqt_cdc_mclk_enable(codec, true);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = aqt_cdc_mclk_enable(codec, false);
+ break;
+ }
+
+ return ret;
+}
+
+static int aif_cap_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static int aif_cap_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ return 0;
+}
+
+static const struct snd_kcontrol_new aif1_cap_mixer[] = {
+ SOC_SINGLE_EXT("TX0", SND_SOC_NOPM, AQT_TX0, 1, 0,
+ aif_cap_mixer_get, aif_cap_mixer_put),
+ SOC_SINGLE_EXT("TX1", SND_SOC_NOPM, AQT_TX1, 1, 0,
+ aif_cap_mixer_get, aif_cap_mixer_put),
+};
+
+static const char * const rx_inp_st_mux_text[] = {
+ "ZERO", "SRC0",
+};
+AQT_DAPM_ENUM(rx_inp_st, AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 4,
+ rx_inp_st_mux_text);
+
+static const struct snd_soc_dapm_widget aqt_dapm_widgets[] = {
+
+ SND_SOC_DAPM_SUPPLY("AQT MCLK", SND_SOC_NOPM, 0, 0, aqt_mclk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_OUT_E("AQT AIF1 CAP", "AQT AIF1 Capture", 0,
+ SND_SOC_NOPM, AIF1_CAP, 0, aqt_codec_enable_i2s_tx,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("AQT AIF1 CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+ aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
+
+ AQT_DAPM_MUX("AQT TX0_MUX", 0, tx0),
+ AQT_DAPM_MUX("AQT TX1_MUX", 0, tx1),
+
+ SND_SOC_DAPM_MUX_E("AQT ADC0 MUX", AQT1000_CDC_TX0_TX_PATH_CTL, 5, 0,
+ &tx_adc0_mux, aqt_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("AQT ADC1 MUX", AQT1000_CDC_TX1_TX_PATH_CTL, 5, 0,
+ &tx_adc1_mux, aqt_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("AQT ADC2 MUX", AQT1000_CDC_TX2_TX_PATH_CTL, 5, 0,
+ &tx_adc2_mux, aqt_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ AQT_DAPM_MUX("AQT AMIC0_MUX", 0, tx_amic0),
+ AQT_DAPM_MUX("AQT AMIC1_MUX", 0, tx_amic1),
+ AQT_DAPM_MUX("AQT AMIC2_MUX", 0, tx_amic2),
+
+ SND_SOC_DAPM_ADC_E("AQT ADC_L", NULL, AQT1000_ANA_AMIC1, 7, 0,
+ aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_ADC_E("AQT ADC_R", NULL, AQT1000_ANA_AMIC2, 7, 0,
+ aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_ADC_E("AQT ADC_V", NULL, AQT1000_ANA_AMIC3, 7, 0,
+ aqt_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+
+ AQT_DAPM_MUX("AQT AMIC10_MUX", 0, tx_amic10),
+ AQT_DAPM_MUX("AQT AMIC11_MUX", 0, tx_amic11),
+ AQT_DAPM_MUX("AQT AMIC12_MUX", 0, tx_amic12),
+ AQT_DAPM_MUX("AQT AMIC13_MUX", 0, tx_amic13),
+
+ SND_SOC_DAPM_SWITCH_E("AQT ANC OUT HPHL Enable", SND_SOC_NOPM,
+ INTERP_HPHL, 0, &anc_hphl_pa_switch, aqt_anc_out_switch_cb,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SWITCH_E("AQT ANC OUT HPHR Enable", SND_SOC_NOPM,
+ INTERP_HPHR, 0, &anc_hphr_pa_switch, aqt_anc_out_switch_cb,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_MIXER("AQT RX INT1 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AQT RX INT2 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ AQT_DAPM_MUX("AQT ANC0 FB MUX", 0, anc0_fb),
+ AQT_DAPM_MUX("AQT ANC1 FB MUX", 0, anc1_fb),
+
+ SND_SOC_DAPM_INPUT("AQT AMIC1"),
+ SND_SOC_DAPM_INPUT("AQT AMIC2"),
+ SND_SOC_DAPM_INPUT("AQT AMIC3"),
+
+ SND_SOC_DAPM_MIXER("AQT I2S_L RX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AQT I2S_R RX", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_IN_E("AQT AIF1 PB", "AQT AIF1 Playback", 0,
+ SND_SOC_NOPM, AIF1_PB, 0, aqt_codec_enable_i2s_rx,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("AQT RX INT1_1 MUX", SND_SOC_NOPM, INTERP_HPHL, 0,
+ &rx_int1_1_mux, aqt_codec_enable_main_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("AQT RX INT2_1 MUX", SND_SOC_NOPM, INTERP_HPHR, 0,
+ &rx_int2_1_mux, aqt_codec_enable_main_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("AQT RX INT1_2 MUX", SND_SOC_NOPM, INTERP_HPHL, 0,
+ &rx_int1_2_mux, aqt_codec_enable_mix_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("AQT RX INT2_2 MUX", SND_SOC_NOPM, INTERP_HPHR, 0,
+ &rx_int2_2_mux, aqt_codec_enable_mix_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ AQT_DAPM_MUX("AQT RX INT1_1 INTERP", 0, rx_int1_1_interp),
+ AQT_DAPM_MUX("AQT RX INT1_2 INTERP", 0, rx_int1_2_interp),
+ AQT_DAPM_MUX("AQT RX INT2_1 INTERP", 0, rx_int2_1_interp),
+ AQT_DAPM_MUX("AQT RX INT2_2 INTERP", 0, rx_int2_2_interp),
+
+ SND_SOC_DAPM_MIXER("AQT RX INT1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AQT RX INT2 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX_E("AQT ASRC0 MUX", SND_SOC_NOPM, ASRC0, 0,
+ &asrc0_mux, aqt_codec_enable_asrc_resampler,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("AQT ASRC1 MUX", SND_SOC_NOPM, ASRC1, 0,
+ &asrc1_mux, aqt_codec_enable_asrc_resampler,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ AQT_DAPM_MUX("AQT RX INT1 DEM MUX", 0, rx_int1_dem),
+ AQT_DAPM_MUX("AQT RX INT2 DEM MUX", 0, rx_int2_dem),
+
+ SND_SOC_DAPM_DAC_E("AQT RX INT1 DAC", NULL, AQT1000_ANA_HPH,
+ 5, 0, aqt_codec_hphl_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_DAC_E("AQT RX INT2 DAC", NULL, AQT1000_ANA_HPH,
+ 4, 0, aqt_codec_hphr_dac_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_PGA_E("AQT HPHL PA", AQT1000_ANA_HPH, 7, 0, NULL, 0,
+ aqt_codec_enable_hphl_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("AQT HPHR PA", AQT1000_ANA_HPH, 6, 0, NULL, 0,
+ aqt_codec_enable_hphr_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("AQT ANC HPHL PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ aqt_codec_enable_hphl_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("AQT ANC HPHR PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ aqt_codec_enable_hphr_pa,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_OUTPUT("AQT HPHL"),
+ SND_SOC_DAPM_OUTPUT("AQT HPHR"),
+ SND_SOC_DAPM_OUTPUT("AQT ANC HPHL"),
+ SND_SOC_DAPM_OUTPUT("AQT ANC HPHR"),
+
+ SND_SOC_DAPM_MIXER_E("AQT IIR0", AQT1000_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
+ 4, 0, NULL, 0, aqt_codec_set_iir_gain,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_MIXER("AQT SRC0",
+ AQT1000_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
+ 4, 0, NULL, 0),
+
+ SND_SOC_DAPM_MICBIAS_E("AQT MIC BIAS1", SND_SOC_NOPM, 0, 0,
+ aqt_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("AQT RX_BIAS", SND_SOC_NOPM, 0, 0,
+ aqt_codec_enable_rx_bias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("AQT RX INT1 NATIVE SUPPLY", SND_SOC_NOPM,
+ INTERP_HPHL, 0, aqt_enable_native_supply,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SUPPLY("AQT RX INT2 NATIVE SUPPLY", SND_SOC_NOPM,
+ INTERP_HPHR, 0, aqt_enable_native_supply,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ AQT_DAPM_MUX("AQT RX INT1_1 NATIVE MUX", 0, int1_1_native),
+ AQT_DAPM_MUX("AQT RX INT2_1 NATIVE MUX", 0, int2_1_native),
+
+ SND_SOC_DAPM_MUX("AQT RX ST MUX",
+ AQT1000_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 2, 0,
+ &rx_inp_st_mux),
+};
+
+static int aqt_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ return 0;
+}
+
+static void aqt_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+}
+
+static int aqt_set_decimator_rate(struct snd_soc_dai *dai,
+ u32 sample_rate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ u8 tx_fs_rate = 0;
+ u8 tx_mux_sel = 0, tx0_mux_sel = 0, tx1_mux_sel = 0;
+ u16 tx_path_ctl_reg = 0;
+
+ switch (sample_rate) {
+ case 8000:
+ tx_fs_rate = 0;
+ break;
+ case 16000:
+ tx_fs_rate = 1;
+ break;
+ case 32000:
+ tx_fs_rate = 3;
+ break;
+ case 48000:
+ tx_fs_rate = 4;
+ break;
+ case 96000:
+ tx_fs_rate = 5;
+ break;
+ case 192000:
+ tx_fs_rate = 6;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid TX sample rate: %d\n",
+ __func__, sample_rate);
+ return -EINVAL;
+
+ };
+
+ /* Find which decimator path is enabled */
+ tx_mux_sel = snd_soc_read(codec, AQT1000_CDC_IF_ROUTER_TX_MUX_CFG0);
+ tx0_mux_sel = (tx_mux_sel & 0x03);
+ tx1_mux_sel = (tx_mux_sel & 0xC0);
+
+ if (tx0_mux_sel) {
+ tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL +
+ ((tx0_mux_sel - 1) * 16);
+ snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate);
+ }
+
+ if (tx1_mux_sel) {
+ tx_path_ctl_reg = AQT1000_CDC_TX0_TX_PATH_CTL +
+ ((tx1_mux_sel - 1) * 16);
+ snd_soc_update_bits(codec, tx_path_ctl_reg, 0x0F, tx_fs_rate);
+ }
+
+ return 0;
+}
+
+static int aqt_set_interpolator_rate(struct snd_soc_dai *dai,
+ u32 sample_rate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int rate_val = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
+ if (sample_rate == sr_val_tbl[i].sample_rate) {
+ rate_val = sr_val_tbl[i].rate_val;
+ break;
+ }
+ }
+ if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
+ dev_err(codec->dev, "%s: Unsupported sample rate: %d\n",
+ __func__, sample_rate);
+ return -EINVAL;
+ }
+
+ /* TODO - Set the rate only to enabled path */
+ /* Set Primary interpolator rate */
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_CTL,
+ 0x0F, (u8)rate_val);
+ snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_CTL,
+ 0x0F, (u8)rate_val);
+
+ /* Set mixing path interpolator rate */
+ snd_soc_update_bits(codec, AQT1000_CDC_RX1_RX_PATH_MIX_CTL,
+ 0x0F, (u8)rate_val);
+ snd_soc_update_bits(codec, AQT1000_CDC_RX2_RX_PATH_MIX_CTL,
+ 0x0F, (u8)rate_val);
+
+ return 0;
+}
+
+static int aqt_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ return 0;
+}
+
+static int aqt_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(dai->codec);
+ int ret = 0;
+
+ dev_dbg(aqt->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n",
+ __func__, dai->name, dai->id, params_rate(params),
+ params_channels(params));
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ ret = aqt_set_interpolator_rate(dai, params_rate(params));
+ if (ret) {
+ dev_err(aqt->dev, "%s: cannot set sample rate: %u\n",
+ __func__, params_rate(params));
+ return ret;
+ }
+ switch (params_width(params)) {
+ case 16:
+ aqt->dai[dai->id].bit_width = 16;
+ break;
+ case 24:
+ aqt->dai[dai->id].bit_width = 24;
+ break;
+ case 32:
+ aqt->dai[dai->id].bit_width = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ aqt->dai[dai->id].rate = params_rate(params);
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ ret = aqt_set_decimator_rate(dai, params_rate(params));
+ if (ret) {
+ dev_err(aqt->dev,
+ "%s: cannot set TX Decimator rate: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ switch (params_width(params)) {
+ case 16:
+ aqt->dai[dai->id].bit_width = 16;
+ break;
+ case 24:
+ aqt->dai[dai->id].bit_width = 24;
+ break;
+ default:
+ dev_err(aqt->dev, "%s: Invalid format 0x%x\n",
+ __func__, params_width(params));
+ return -EINVAL;
+ };
+ aqt->dai[dai->id].rate = params_rate(params);
+ break;
+ default:
+ dev_err(aqt->dev, "%s: Invalid stream type %d\n", __func__,
+ substream->stream);
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops aqt_dai_ops = {
+ .startup = aqt_startup,
+ .shutdown = aqt_shutdown,
+ .hw_params = aqt_hw_params,
+ .prepare = aqt_prepare,
+};
+
+struct snd_soc_dai_driver aqt_dai[] = {
+ {
+ .name = "aqt_rx1",
+ .id = AIF1_PB,
+ .playback = {
+ .stream_name = "AQT AIF1 Playback",
+ .rates = AQT1000_RATES_MASK | AQT1000_FRAC_RATES_MASK,
+ .formats = AQT1000_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &aqt_dai_ops,
+ },
+ {
+ .name = "aqt_tx1",
+ .id = AIF1_CAP,
+ .capture = {
+ .stream_name = "AQT AIF1 Capture",
+ .rates = AQT1000_RATES_MASK,
+ .formats = AQT1000_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &aqt_dai_ops,
+ },
+};
+
+static int aqt_enable_mclk(struct aqt1000 *aqt)
+{
+ struct snd_soc_codec *codec = aqt->codec;
+
+ /* Enable mclk requires master bias to be enabled first */
+ if (aqt->master_bias_users <= 0) {
+ dev_err(aqt->dev,
+ "%s: Cannot turn on MCLK, BG is not enabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (++aqt->mclk_users == 1) {
+ /* Set clock div 2 */
+ snd_soc_update_bits(codec,
+ AQT1000_CLK_SYS_MCLK1_PRG, 0x0C, 0x04);
+ snd_soc_update_bits(codec,
+ AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x10);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x01, 0x01);
+ /*
+ * 10us sleep is required after clock is enabled
+ * as per HW requirement
+ */
+ usleep_range(10, 15);
+ }
+
+ dev_dbg(aqt->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users);
+
+ return 0;
+}
+
+static int aqt_disable_mclk(struct aqt1000 *aqt)
+{
+ struct snd_soc_codec *codec = aqt->codec;
+
+ if (aqt->mclk_users <= 0) {
+ dev_err(aqt->dev, "%s: No mclk users, cannot disable mclk\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (--aqt->mclk_users == 0) {
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ AQT1000_CLK_SYS_MCLK1_PRG, 0x10, 0x00);
+ }
+
+ dev_dbg(codec->dev, "%s: mclk_users: %d\n", __func__, aqt->mclk_users);
+
+ return 0;
+}
+
+static int aqt_enable_master_bias(struct aqt1000 *aqt)
+{
+ struct snd_soc_codec *codec = aqt->codec;
+
+ mutex_lock(&aqt->master_bias_lock);
+
+ aqt->master_bias_users++;
+ if (aqt->master_bias_users == 1) {
+ snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x80);
+ snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x40);
+ /*
+ * 1ms delay is required after pre-charge is enabled
+ * as per HW requirement
+ */
+ usleep_range(1000, 1100);
+ snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x40, 0x00);
+ }
+
+ mutex_unlock(&aqt->master_bias_lock);
+
+ return 0;
+}
+
+static int aqt_disable_master_bias(struct aqt1000 *aqt)
+{
+ struct snd_soc_codec *codec = aqt->codec;
+
+ mutex_lock(&aqt->master_bias_lock);
+ if (aqt->master_bias_users <= 0) {
+ mutex_unlock(&aqt->master_bias_lock);
+ return -EINVAL;
+ }
+
+ aqt->master_bias_users--;
+ if (aqt->master_bias_users == 0)
+ snd_soc_update_bits(codec, AQT1000_ANA_BIAS, 0x80, 0x00);
+ mutex_unlock(&aqt->master_bias_lock);
+
+ return 0;
+}
+
+static int aqt_cdc_req_mclk_enable(struct aqt1000 *aqt,
+ bool enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = clk_prepare_enable(aqt->ext_clk);
+ if (ret) {
+ dev_err(aqt->dev, "%s: ext clk enable failed\n",
+ __func__);
+ goto done;
+ }
+ /* Get BG */
+ aqt_enable_master_bias(aqt);
+ /* Get MCLK */
+ aqt_enable_mclk(aqt);
+ } else {
+ /* put MCLK */
+ aqt_disable_mclk(aqt);
+ /* put BG */
+ if (aqt_disable_master_bias(aqt))
+ dev_err(aqt->dev, "%s: master bias disable failed\n",
+ __func__);
+ clk_disable_unprepare(aqt->ext_clk);
+ }
+
+done:
+ return ret;
+}
+
+static int __aqt_cdc_mclk_enable_locked(struct aqt1000 *aqt,
+ bool enable)
+{
+ int ret = 0;
+
+ dev_dbg(aqt->dev, "%s: mclk_enable = %u\n", __func__, enable);
+
+ if (enable)
+ ret = aqt_cdc_req_mclk_enable(aqt, true);
+ else
+ aqt_cdc_req_mclk_enable(aqt, false);
+
+ return ret;
+}
+
+static int __aqt_cdc_mclk_enable(struct aqt1000 *aqt,
+ bool enable)
+{
+ int ret;
+
+ mutex_lock(&aqt->cdc_bg_clk_lock);
+ ret = __aqt_cdc_mclk_enable_locked(aqt, enable);
+ mutex_unlock(&aqt->cdc_bg_clk_lock);
+
+ return ret;
+}
+
+/**
+ * aqt_cdc_mclk_enable - Enable/disable codec mclk
+ *
+ * @codec: codec instance
+ * @enable: Indicates clk enable or disable
+ *
+ * Returns 0 on Success and error on failure
+ */
+int aqt_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ return __aqt_cdc_mclk_enable(aqt, enable);
+}
+EXPORT_SYMBOL(aqt_cdc_mclk_enable);
+
+/*
+ * aqt_get_micb_vout_ctl_val: converts micbias from volts to register value
+ * @micb_mv: micbias in mv
+ *
+ * return register value converted
+ */
+int aqt_get_micb_vout_ctl_val(u32 micb_mv)
+{
+ /* min micbias voltage is 1V and maximum is 2.85V */
+ if (micb_mv < 1000 || micb_mv > 2850) {
+ pr_err("%s: unsupported micbias voltage\n", __func__);
+ return -EINVAL;
+ }
+
+ return (micb_mv - 1000) / 50;
+}
+EXPORT_SYMBOL(aqt_get_micb_vout_ctl_val);
+
+static int aqt_set_micbias(struct aqt1000 *aqt,
+ struct aqt1000_pdata *pdata)
+{
+ struct snd_soc_codec *codec = aqt->codec;
+ int vout_ctl_1;
+
+ if (!pdata) {
+ dev_err(codec->dev, "%s: NULL pdata\n", __func__);
+ return -ENODEV;
+ }
+
+ /* set micbias voltage */
+ vout_ctl_1 = aqt_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
+ if (vout_ctl_1 < 0)
+ return -EINVAL;
+
+ snd_soc_update_bits(codec, AQT1000_ANA_MICB1, 0x3F, vout_ctl_1);
+
+ return 0;
+}
+
+static ssize_t aqt_codec_version_read(struct snd_info_entry *entry,
+ void *file_private_data,
+ struct file *file,
+ char __user *buf, size_t count,
+ loff_t pos)
+{
+ char buffer[AQT_VERSION_ENTRY_SIZE];
+ int len = 0;
+
+ len = snprintf(buffer, sizeof(buffer), "AQT1000_1_0\n");
+
+ return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static struct snd_info_entry_ops aqt_codec_info_ops = {
+ .read = aqt_codec_version_read,
+};
+
+/*
+ * aqt_codec_info_create_codec_entry - creates aqt1000 module
+ * @codec_root: The parent directory
+ * @codec: Codec instance
+ *
+ * Creates aqt1000 module and version entry under the given
+ * parent directory.
+ *
+ * Return: 0 on success or negative error code on failure.
+ */
+int aqt_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
+ struct snd_soc_codec *codec)
+{
+ struct snd_info_entry *version_entry;
+ struct aqt1000 *aqt;
+ struct snd_soc_card *card;
+
+ if (!codec_root || !codec)
+ return -EINVAL;
+
+ aqt = snd_soc_codec_get_drvdata(codec);
+ if (!aqt) {
+ dev_dbg(codec->dev, "%s: aqt is NULL\n", __func__);
+ return -EINVAL;
+ }
+ card = codec->component.card;
+ aqt->entry = snd_info_create_subdir(codec_root->module,
+ "aqt1000", codec_root);
+ if (!aqt->entry) {
+ dev_dbg(codec->dev, "%s: failed to create aqt1000 entry\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ version_entry = snd_info_create_card_entry(card->snd_card,
+ "version",
+ aqt->entry);
+ if (!version_entry) {
+ dev_dbg(codec->dev, "%s: failed to create aqt1000 version entry\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ version_entry->private_data = aqt;
+ version_entry->size = AQT_VERSION_ENTRY_SIZE;
+ version_entry->content = SNDRV_INFO_CONTENT_DATA;
+ version_entry->c.ops = &aqt_codec_info_ops;
+
+ if (snd_info_register(version_entry) < 0) {
+ snd_info_free_entry(version_entry);
+ return -ENOMEM;
+ }
+ aqt->version_entry = version_entry;
+
+ return 0;
+}
+EXPORT_SYMBOL(aqt_codec_info_create_codec_entry);
+
+static const struct aqt_reg_mask_val aqt_codec_reg_init[] = {
+ {AQT1000_CHIP_CFG0_EFUSE_CTL, 0x01, 0x01},
+};
+
+static const struct aqt_reg_mask_val aqt_codec_reg_update[] = {
+ {AQT1000_LDOH_MODE, 0x1F, 0x0B},
+ {AQT1000_MICB1_TEST_CTL_2, 0x07, 0x01},
+ {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x03, 0x02},
+ {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x0C, 0x08},
+ {AQT1000_MICB1_MISC_MICB1_INM_RES_BIAS, 0x30, 0x20},
+ {AQT1000_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00},
+ {AQT1000_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00},
+ {AQT1000_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00},
+};
+
+static void aqt_codec_init_reg(struct aqt1000 *priv)
+{
+ struct snd_soc_codec *codec = priv->codec;
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_init); i++)
+ snd_soc_update_bits(codec,
+ aqt_codec_reg_init[i].reg,
+ aqt_codec_reg_init[i].mask,
+ aqt_codec_reg_init[i].val);
+}
+
+static void aqt_codec_update_reg(struct aqt1000 *priv)
+{
+ struct snd_soc_codec *codec = priv->codec;
+ u32 i;
+
+ for (i = 0; i < ARRAY_SIZE(aqt_codec_reg_update); i++)
+ snd_soc_update_bits(codec,
+ aqt_codec_reg_update[i].reg,
+ aqt_codec_reg_update[i].mask,
+ aqt_codec_reg_update[i].val);
+
+}
+
+static int aqt_soc_codec_probe(struct snd_soc_codec *codec)
+{
+ struct aqt1000 *aqt;
+ struct aqt1000_pdata *pdata;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ int i, ret = 0;
+
+ dev_dbg(codec->dev, "%s()\n", __func__);
+ aqt = snd_soc_codec_get_drvdata(codec);
+
+ mutex_init(&aqt->codec_mutex);
+ mutex_init(&aqt->i2s_lock);
+ /* Class-H Init */
+ aqt_clsh_init(&aqt->clsh_d);
+ /* Default HPH Mode to Class-H Low HiFi */
+ aqt->hph_mode = CLS_H_LOHIFI;
+
+ aqt->fw_data = devm_kzalloc(codec->dev, sizeof(*(aqt->fw_data)),
+ GFP_KERNEL);
+ if (!aqt->fw_data)
+ goto err;
+
+ set_bit(WCD9XXX_ANC_CAL, aqt->fw_data->cal_bit);
+ set_bit(WCD9XXX_MBHC_CAL, aqt->fw_data->cal_bit);
+
+ /* Register for Clock */
+ aqt->ext_clk = clk_get(aqt->dev, "aqt_clk");
+ if (IS_ERR(aqt->ext_clk)) {
+ dev_err(aqt->dev, "%s: clk get %s failed\n",
+ __func__, "aqt_ext_clk");
+ goto err_clk;
+ }
+
+ ret = wcd_cal_create_hwdep(aqt->fw_data,
+ AQT1000_CODEC_HWDEP_NODE, codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
+ goto err_hwdep;
+ }
+
+ /* Initialize MBHC module */
+ ret = aqt_mbhc_init(&aqt->mbhc, codec, aqt->fw_data);
+ if (ret) {
+ pr_err("%s: mbhc initialization failed\n", __func__);
+ goto err_hwdep;
+ }
+ aqt->codec = codec;
+ for (i = 0; i < COMPANDER_MAX; i++)
+ aqt->comp_enabled[i] = 0;
+
+ aqt_cdc_mclk_enable(codec, true);
+ aqt_codec_init_reg(aqt);
+ aqt_cdc_mclk_enable(codec, false);
+
+ /* Add 100usec delay as per HW requirement */
+ usleep_range(100, 110);
+
+ aqt_codec_update_reg(aqt);
+
+ pdata = dev_get_platdata(codec->dev);
+
+ /* If 1.8v is supplied externally, then disable internal 1.8v supply */
+ for (i = 0; i < pdata->num_supplies; i++) {
+ if (!strcmp(pdata->regulator->name, "aqt_vdd1p8")) {
+ snd_soc_update_bits(codec, AQT1000_BUCK_5V_EN_CTL,
+ 0x03, 0x00);
+ dev_dbg(codec->dev, "%s: Disabled internal supply\n",
+ __func__);
+ break;
+ }
+ }
+
+ aqt_set_micbias(aqt, pdata);
+
+ snd_soc_dapm_add_routes(dapm, aqt_audio_map,
+ ARRAY_SIZE(aqt_audio_map));
+
+ for (i = 0; i < NUM_CODEC_DAIS; i++) {
+ INIT_LIST_HEAD(&aqt->dai[i].ch_list);
+ init_waitqueue_head(&aqt->dai[i].dai_wait);
+ }
+
+ for (i = 0; i < AQT1000_NUM_DECIMATORS; i++) {
+ aqt->tx_hpf_work[i].aqt = aqt;
+ aqt->tx_hpf_work[i].decimator = i;
+ INIT_DELAYED_WORK(&aqt->tx_hpf_work[i].dwork,
+ aqt_tx_hpf_corner_freq_callback);
+
+ aqt->tx_mute_dwork[i].aqt = aqt;
+ aqt->tx_mute_dwork[i].decimator = i;
+ INIT_DELAYED_WORK(&aqt->tx_mute_dwork[i].dwork,
+ aqt_tx_mute_update_callback);
+ }
+
+ mutex_lock(&aqt->codec_mutex);
+ snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHL PA");
+ snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHR PA");
+ snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHL");
+ snd_soc_dapm_disable_pin(dapm, "AQT ANC HPHR");
+ mutex_unlock(&aqt->codec_mutex);
+
+ snd_soc_dapm_ignore_suspend(dapm, "AQT AIF1 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "AQT AIF1 Capture");
+
+ snd_soc_dapm_sync(dapm);
+
+ return ret;
+
+err_hwdep:
+ clk_put(aqt->ext_clk);
+err_clk:
+ devm_kfree(codec->dev, aqt->fw_data);
+ aqt->fw_data = NULL;
+err:
+ mutex_destroy(&aqt->i2s_lock);
+ mutex_destroy(&aqt->codec_mutex);
+ return ret;
+}
+
+static int aqt_soc_codec_remove(struct snd_soc_codec *codec)
+{
+ struct aqt1000 *aqt = snd_soc_codec_get_drvdata(codec);
+
+ /* Deinitialize MBHC module */
+ aqt_mbhc_deinit(codec);
+ aqt->mbhc = NULL;
+ mutex_destroy(&aqt->i2s_lock);
+ mutex_destroy(&aqt->codec_mutex);
+ clk_put(aqt->ext_clk);
+
+ return 0;
+}
+
+static struct regmap *aqt_get_regmap(struct device *dev)
+{
+ struct aqt1000 *control = dev_get_drvdata(dev);
+
+ return control->regmap;
+}
+
+struct snd_soc_codec_driver snd_cdc_dev_aqt = {
+ .probe = aqt_soc_codec_probe,
+ .remove = aqt_soc_codec_remove,
+ .get_regmap = aqt_get_regmap,
+ .component_driver = {
+ .controls = aqt_snd_controls,
+ .num_controls = ARRAY_SIZE(aqt_snd_controls),
+ .dapm_widgets = aqt_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(aqt_dapm_widgets),
+ .dapm_routes = aqt_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(aqt_audio_map),
+ },
+};
+
+/*
+ * aqt_register_codec: Register the device to ASoC
+ * @dev: device
+ *
+ * return 0 success or error code in case of failure
+ */
+int aqt_register_codec(struct device *dev)
+{
+ return snd_soc_register_codec(dev, &snd_cdc_dev_aqt, aqt_dai,
+ ARRAY_SIZE(aqt_dai));
+}
+EXPORT_SYMBOL(aqt_register_codec);
diff --git a/asoc/codecs/aqt1000/aqt1000.h b/asoc/codecs/aqt1000/aqt1000.h
new file mode 100644
index 0000000..7b870db
--- /dev/null
+++ b/asoc/codecs/aqt1000/aqt1000.h
@@ -0,0 +1,229 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef AQT1000_H
+#define AQT1000_H
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/i2c.h>
+#include "pdata.h"
+#include "aqt1000-clsh.h"
+
+#define AQT1000_MAX_MICBIAS 1
+#define AQT1000_NUM_INTERPOLATORS 2
+#define AQT1000_NUM_DECIMATORS 3
+#define AQT1000_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
+#define AQT1000_RX_PATH_CTL_OFFSET 20
+
+#define AQT1000_CLK_24P576MHZ 24576000
+#define AQT1000_CLK_19P2MHZ 19200000
+#define AQT1000_CLK_12P288MHZ 12288000
+#define AQT1000_CLK_9P6MHZ 9600000
+
+#define AQT1000_ST_IIR_COEFF_MAX 5
+
+enum {
+ AQT1000_RX0 = 0,
+ AQT1000_RX1,
+ AQT1000_RX_MAX,
+};
+
+enum {
+ AQT_NONE,
+ AQT_MCLK,
+ AQT_RCO,
+};
+
+enum {
+ AQT_TX0 = 0,
+ AQT_TX1,
+};
+
+enum {
+ ASRC0,
+ ASRC1,
+ ASRC_MAX,
+};
+
+/* Each IIR has 5 Filter Stages */
+enum {
+ BAND1 = 0,
+ BAND2,
+ BAND3,
+ BAND4,
+ BAND5,
+ BAND_MAX,
+};
+
+enum {
+ AQT1000_TX0 = 0,
+ AQT1000_TX1,
+ AQT1000_TX2,
+ AQT1000_TX_MAX,
+};
+
+enum {
+ INTERP_HPHL,
+ INTERP_HPHR,
+ INTERP_MAX,
+};
+
+enum {
+ INTERP_MAIN_PATH,
+ INTERP_MIX_PATH,
+};
+
+enum {
+ COMPANDER_1, /* HPH_L */
+ COMPANDER_2, /* HPH_R */
+ COMPANDER_MAX,
+};
+
+enum {
+ AIF1_PB = 0,
+ AIF1_CAP,
+ NUM_CODEC_DAIS,
+};
+
+struct aqt_codec_dai_data {
+ u32 rate;
+ u32 *ch_num;
+ u32 ch_act;
+ u32 ch_tot;
+};
+
+struct aqt_idle_detect_config {
+ u8 hph_idle_thr;
+ u8 hph_idle_detect_en;
+};
+
+struct aqt1000_i2c {
+ struct i2c_client *client;
+ struct i2c_msg xfer_msg[2];
+ struct mutex xfer_lock;
+ int mod_id;
+};
+
+struct aqt1000_cdc_dai_data {
+ u32 rate; /* sample rate */
+ u32 bit_width; /* sit width 16,24,32 */
+ struct list_head ch_list;
+ wait_queue_head_t dai_wait;
+};
+
+struct tx_mute_work {
+ struct aqt1000 *aqt;
+ u8 decimator;
+ struct delayed_work dwork;
+};
+
+struct hpf_work {
+ struct aqt1000 *aqt;
+ u8 decimator;
+ u8 hpf_cut_off_freq;
+ struct delayed_work dwork;
+};
+
+struct aqt1000 {
+ struct device *dev;
+ struct mutex io_lock;
+ struct mutex xfer_lock;
+ struct mutex reset_lock;
+
+ struct device_node *aqt_rst_np;
+
+ int (*read_dev)(struct aqt1000 *aqt, unsigned short reg,
+ void *dest, int bytes);
+ int (*write_dev)(struct aqt1000 *aqt, unsigned short reg,
+ void *src, int bytes);
+
+ u32 num_of_supplies;
+ struct regulator_bulk_data *supplies;
+
+ u32 mclk_rate;
+ struct regmap *regmap;
+ struct snd_soc_codec *codec;
+ bool dev_up;
+ bool prev_pg_valid;
+ u8 prev_pg;
+
+ struct aqt1000_i2c i2c_dev;
+
+ /* Codec params */
+
+ /* ANC related */
+ u32 anc_slot;
+ bool anc_func;
+
+ /* compander */
+ int comp_enabled[COMPANDER_MAX];
+
+ /* class h specific data */
+ struct aqt_clsh_cdc_data clsh_d;
+
+ /* Interpolator Mode Select for HPH_L and HPH_R */
+ u32 hph_mode;
+
+ unsigned long status_mask;
+
+ struct aqt1000_cdc_dai_data dai[NUM_CODEC_DAIS];
+
+ struct mutex micb_lock;
+
+ struct clk *ext_clk;
+
+ /* mbhc module */
+ struct aqt1000_mbhc *mbhc;
+
+ struct mutex codec_mutex;
+
+ /* cal info for codec */
+ struct fw_info *fw_data;
+
+ int native_clk_users;
+ /* ASRC users count */
+ int asrc_users[ASRC_MAX];
+ int asrc_output_mode[ASRC_MAX];
+ /* Main path clock users count */
+ int main_clk_users[AQT1000_NUM_INTERPOLATORS];
+
+ struct aqt_idle_detect_config idle_det_cfg;
+ u32 rx_bias_count;
+
+ s32 micb_ref;
+ s32 pullup_ref;
+ int master_bias_users;
+ int mclk_users;
+ int i2s_users;
+
+ struct hpf_work tx_hpf_work[AQT1000_NUM_DECIMATORS];
+ struct tx_mute_work tx_mute_dwork[AQT1000_NUM_DECIMATORS];
+
+ struct mutex master_bias_lock;
+ struct mutex cdc_bg_clk_lock;
+ struct mutex i2s_lock;
+
+ /* Interrupt */
+ struct regmap_irq_chip_data *irq_chip;
+ int num_irq_regs;
+ struct irq_domain *virq;
+ int irq;
+ int irq_base;
+
+ /* Entry for version info */
+ struct snd_info_entry *entry;
+ struct snd_info_entry *version_entry;
+};
+
+#endif /* AQT1000_H */
diff --git a/asoc/codecs/aqt1000/pdata.h b/asoc/codecs/aqt1000/pdata.h
new file mode 100644
index 0000000..2c29848
--- /dev/null
+++ b/asoc/codecs/aqt1000/pdata.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _AQT1000_PDATA_H_
+#define _AQT1000_PDATA_H_
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include "../msm-cdc-supply.h"
+
+struct aqt1000_micbias_setting {
+ u8 ldoh_v;
+ u32 cfilt1_mv;
+ u32 micb1_mv;
+ u8 bias1_cfilt_sel;
+};
+
+struct aqt1000_pdata {
+ unsigned int irq_gpio;
+ unsigned int irq_flags;
+ struct cdc_regulator *regulator;
+ int num_supplies;
+ struct aqt1000_micbias_setting micbias;
+ struct device_node *aqt_rst_np;
+ u32 mclk_rate;
+ u32 ext_clk_rate;
+ u32 ext_1p8v_supply;
+};
+
+#endif /* _AQT1000_PDATA_H_ */
diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c
index 50a8ed6..d20aab2 100644
--- a/asoc/codecs/audio-ext-clk-up.c
+++ b/asoc/codecs/audio-ext-clk-up.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,16 +19,15 @@
#include <linux/clk-provider.h>
#include "../../../drivers/clk/qcom/common.h"
#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
#include <dt-bindings/clock/qcom,audio-ext-clk.h>
#include <dsp/q6afe-v2.h>
#include "audio-ext-clk-up.h"
-enum audio_clk_mux {
- AP_CLK2,
- LPASS_MCLK,
- LPASS_MCLK2,
+enum {
+ AUDIO_EXT_CLK_PMI,
+ AUDIO_EXT_CLK_LNBB2,
+ AUDIO_EXT_CLK_LPASS,
+ AUDIO_EXT_CLK_MAX,
};
struct pinctrl_info {
@@ -38,152 +37,37 @@
char __iomem *base;
};
-struct audio_ext_ap_clk {
- bool enabled;
- int gpio;
- struct clk_fixed_factor fact;
-};
-
-struct audio_ext_pmi_clk {
- int gpio;
- struct clk_fixed_factor fact;
-};
-
-struct audio_ext_ap_clk2 {
- bool enabled;
+struct audio_ext_clk {
struct pinctrl_info pnctrl_info;
struct clk_fixed_factor fact;
};
-struct audio_ext_lpass_mclk {
- struct pinctrl_info pnctrl_info;
- struct clk_fixed_factor fact;
+struct audio_ext_clk_priv {
+ struct device *dev;
+ int clk_src;
+ struct afe_clk_set clk_cfg;
+ struct audio_ext_clk audio_clk;
};
-static struct afe_clk_set clk2_config = {
- Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
- Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR,
- Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ,
- Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
- Q6AFE_LPASS_CLK_ROOT_DEFAULT,
- 0,
-};
-
-static struct afe_clk_set lpass_default = {
- Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
- Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR,
- Q6AFE_LPASS_IBIT_CLK_11_P2896_MHZ,
- Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
- Q6AFE_LPASS_CLK_ROOT_DEFAULT,
- 0,
-};
-
-static struct afe_clk_set lpass_mclk = {
- Q6AFE_LPASS_CLK_CONFIG_API_VERSION,
- Q6AFE_LPASS_CLK_ID_MCLK_1,
- Q6AFE_LPASS_OSR_CLK_11_P2896_MHZ,
- Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
- Q6AFE_LPASS_CLK_ROOT_DEFAULT,
- 0,
-};
-
-static inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk_hw *hw)
+static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *hw)
{
- return container_of(hw, struct audio_ext_ap_clk, fact.hw);
+ return container_of(hw, struct audio_ext_clk_priv, audio_clk.fact.hw);
}
static int audio_ext_clk_prepare(struct clk_hw *hw)
{
- struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(hw);
-
- pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio);
- if (gpio_is_valid(audio_clk->gpio))
- return gpio_direction_output(audio_clk->gpio, 1);
- return 0;
-}
-
-static void audio_ext_clk_unprepare(struct clk_hw *hw)
-{
- struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(hw);
-
- pr_debug("%s: gpio: %d\n", __func__, audio_clk->gpio);
- if (gpio_is_valid(audio_clk->gpio))
- gpio_direction_output(audio_clk->gpio, 0);
-}
-
-static inline struct audio_ext_ap_clk2 *to_audio_ap_clk2(struct clk_hw *hw)
-{
- return container_of(hw, struct audio_ext_ap_clk2, fact.hw);
-}
-
-static int audio_ext_clk2_prepare(struct clk_hw *hw)
-{
- struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(hw);
- struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info;
+ struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
+ struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
int ret;
-
- if (!pnctrl_info->pinctrl || !pnctrl_info->active)
- return 0;
-
- ret = pinctrl_select_state(pnctrl_info->pinctrl,
- pnctrl_info->active);
- if (ret) {
- pr_err("%s: active state select failed with %d\n",
- __func__, ret);
- return -EIO;
- }
-
- clk2_config.enable = 1;
- ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config);
- if (ret < 0) {
- pr_err("%s: failed to set clock, ret = %d\n", __func__, ret);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void audio_ext_clk2_unprepare(struct clk_hw *hw)
-{
- struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(hw);
- struct pinctrl_info *pnctrl_info = &audio_clk2->pnctrl_info;
- int ret;
-
- if (!pnctrl_info->pinctrl || !pnctrl_info->sleep)
- return;
-
- ret = pinctrl_select_state(pnctrl_info->pinctrl,
- pnctrl_info->sleep);
- if (ret)
- pr_err("%s: sleep state select failed with %d\n",
- __func__, ret);
-
- clk2_config.enable = 0;
- ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk2_config);
- if (ret < 0)
- pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret);
-}
-
-static inline struct audio_ext_lpass_mclk *to_audio_lpass_mclk(
- struct clk_hw *hw)
-{
- return container_of(hw, struct audio_ext_lpass_mclk, fact.hw);
-}
-
-static int audio_ext_lpass_mclk_prepare(struct clk_hw *hw)
-{
- struct audio_ext_lpass_mclk *audio_lpass_mclk = to_audio_lpass_mclk(hw);
- struct pinctrl_info *pnctrl_info = &audio_lpass_mclk->pnctrl_info;
- int ret;
-
- lpass_mclk.enable = 1;
- ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX,
- &lpass_mclk);
- if (ret < 0) {
- pr_err("%s afe_set_digital_codec_core_clock failed\n",
- __func__);
- return ret;
+ if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS) {
+ clk_priv->clk_cfg.enable = 1;
+ ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
+ if (ret < 0) {
+ pr_err("%s afe_set_digital_codec_core_clock failed\n",
+ __func__);
+ return ret;
+ }
}
if (pnctrl_info->pinctrl) {
@@ -201,10 +85,10 @@
return 0;
}
-static void audio_ext_lpass_mclk_unprepare(struct clk_hw *hw)
+static void audio_ext_clk_unprepare(struct clk_hw *hw)
{
- struct audio_ext_lpass_mclk *audio_lpass_mclk = to_audio_lpass_mclk(hw);
- struct pinctrl_info *pnctrl_info = &audio_lpass_mclk->pnctrl_info;
+ struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
+ struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
int ret;
if (pnctrl_info->pinctrl) {
@@ -217,207 +101,90 @@
}
}
- lpass_mclk.enable = 0;
- ret = afe_set_lpass_clock_v2(AFE_PORT_ID_PRIMARY_MI2S_RX,
- &lpass_mclk);
- if (ret < 0)
- pr_err("%s: afe_set_digital_codec_core_clock failed, ret = %d\n",
- __func__, ret);
+ if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS) {
+ clk_priv->clk_cfg.enable = 0;
+ ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
+ if (ret < 0)
+ pr_err("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
+ __func__, ret);
+ }
+
if (pnctrl_info->base)
iowrite32(0, pnctrl_info->base);
}
-static int audio_ext_lpass_mclk2_prepare(struct clk_hw *hw)
-{
- struct audio_ext_lpass_mclk *audio_lpass_mclk2 =
- to_audio_lpass_mclk(hw);
- struct pinctrl_info *pnctrl_info = &audio_lpass_mclk2->pnctrl_info;
- int ret;
-
- if (pnctrl_info->pinctrl) {
- ret = pinctrl_select_state(pnctrl_info->pinctrl,
- pnctrl_info->active);
- if (ret) {
- pr_err("%s: active state select failed with %d\n",
- __func__, ret);
- return -EIO;
- }
- }
-
- lpass_default.enable = 1;
- ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default);
- if (ret < 0) {
- pr_err("%s: failed to set clock, ret = %d\n", __func__, ret);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void audio_ext_lpass_mclk2_unprepare(struct clk_hw *hw)
-{
- struct audio_ext_lpass_mclk *audio_lpass_mclk2 =
- to_audio_lpass_mclk(hw);
- struct pinctrl_info *pnctrl_info = &audio_lpass_mclk2->pnctrl_info;
- int ret;
-
- if (pnctrl_info->pinctrl) {
- ret = pinctrl_select_state(pnctrl_info->pinctrl,
- pnctrl_info->sleep);
- if (ret)
- pr_err("%s: sleep state select failed with %d\n",
- __func__, ret);
- }
-
- lpass_default.enable = 0;
- ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &lpass_default);
- if (ret < 0)
- pr_err("%s: failed to reset clock, ret = %d\n", __func__, ret);
-}
-
-static const struct clk_ops audio_ext_ap_clk_ops = {
+static const struct clk_ops audio_ext_clk_ops = {
.prepare = audio_ext_clk_prepare,
.unprepare = audio_ext_clk_unprepare,
};
-static const struct clk_ops audio_ext_ap_clk2_ops = {
- .prepare = audio_ext_clk2_prepare,
- .unprepare = audio_ext_clk2_unprepare,
-};
-
-static const struct clk_ops audio_ext_lpass_mclk_ops = {
- .prepare = audio_ext_lpass_mclk_prepare,
- .unprepare = audio_ext_lpass_mclk_unprepare,
-};
-
-static const struct clk_ops audio_ext_lpass_mclk2_ops = {
- .prepare = audio_ext_lpass_mclk2_prepare,
- .unprepare = audio_ext_lpass_mclk2_unprepare,
-};
-
-static struct audio_ext_pmi_clk audio_pmi_clk = {
- .gpio = -EINVAL,
- .fact = {
- .mult = 1,
- .div = 1,
- .hw.init = &(struct clk_init_data){
- .name = "audio_ext_pmi_clk",
- .parent_names = (const char *[]){ "div_clk1" },
- .num_parents = 1,
- .ops = &clk_dummy_ops,
+static struct audio_ext_clk audio_clk_array[] = {
+ {
+ .pnctrl_info = {NULL},
+ .fact = {
+ .mult = 1,
+ .div = 1,
+ .hw.init = &(struct clk_init_data){
+ .name = "audio_ext_pmi_clk",
+ .parent_names = (const char *[])
+ { "qpnp_clkdiv_1" },
+ .num_parents = 1,
+ .ops = &audio_ext_clk_ops,
+ },
+ },
+ },
+ {
+ .pnctrl_info = {NULL},
+ .fact = {
+ .mult = 1,
+ .div = 1,
+ .hw.init = &(struct clk_init_data){
+ .name = "audio_ext_pmi_lnbb_clk",
+ .parent_names = (const char *[])
+ { "ln_bb_clk2" },
+ .num_parents = 1,
+ .ops = &clk_dummy_ops,
+ },
+ },
+ },
+ {
+ .pnctrl_info = {NULL},
+ .fact = {
+ .mult = 1,
+ .div = 1,
+ .hw.init = &(struct clk_init_data){
+ .name = "audio_lpass_mclk",
+ .ops = &audio_ext_clk_ops,
+ },
},
},
};
-static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = {
- .gpio = -EINVAL,
- .fact = {
- .mult = 1,
- .div = 1,
- .hw.init = &(struct clk_init_data){
- .name = "audio_ext_pmi_lnbb_clk",
- .parent_names = (const char *[]){ "ln_bb_clk2" },
- .num_parents = 1,
- .ops = &clk_dummy_ops,
- },
- },
-};
-
-static struct audio_ext_ap_clk audio_ap_clk = {
- .gpio = -EINVAL,
- .fact = {
- .mult = 1,
- .div = 1,
- .hw.init = &(struct clk_init_data){
- .name = "audio_ap_clk",
- .ops = &audio_ext_ap_clk_ops,
- },
- },
-};
-
-static struct audio_ext_ap_clk2 audio_ap_clk2 = {
- .enabled = false,
- .pnctrl_info = {NULL},
- .fact = {
- .mult = 1,
- .div = 1,
- .hw.init = &(struct clk_init_data){
- .name = "audio_ap_clk2",
- .ops = &audio_ext_ap_clk2_ops,
- },
- },
-};
-
-static struct audio_ext_lpass_mclk audio_lpass_mclk = {
- .pnctrl_info = {NULL},
- .fact = {
- .mult = 1,
- .div = 1,
- .hw.init = &(struct clk_init_data){
- .name = "audio_lpass_mclk",
- .ops = &audio_ext_lpass_mclk_ops,
- },
- },
-};
-
-static struct audio_ext_lpass_mclk audio_lpass_mclk2 = {
- .pnctrl_info = {NULL},
- .fact = {
- .mult = 1,
- .div = 1,
- .hw.init = &(struct clk_init_data){
- .name = "audio_lpass_mclk2",
- .ops = &audio_ext_lpass_mclk2_ops,
- },
- },
-};
-
-static struct clk_hw *audio_msm_hws[] = {
- &audio_pmi_clk.fact.hw,
- &audio_ap_clk.fact.hw,
- &audio_ap_clk2.fact.hw,
- &audio_lpass_mclk.fact.hw,
- &audio_lpass_mclk2.fact.hw,
-};
-
-static struct clk_hw *audio_msm_hws1[] = {
- &audio_pmi_lnbb_clk.fact.hw,
-};
-
-static int audio_get_pinctrl(struct platform_device *pdev,
- enum audio_clk_mux mux)
+static int audio_get_pinctrl(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev);
struct pinctrl_info *pnctrl_info;
struct pinctrl *pinctrl;
int ret;
u32 reg;
- switch (mux) {
- case AP_CLK2:
- pnctrl_info = &audio_ap_clk2.pnctrl_info;
- break;
- case LPASS_MCLK:
- pnctrl_info = &audio_lpass_mclk.pnctrl_info;
- break;
- case LPASS_MCLK2:
- pnctrl_info = &audio_lpass_mclk2.pnctrl_info;
- break;
- default:
- dev_err(dev, "%s Not a valid MUX ID: %d\n",
- __func__, mux);
- return -EINVAL;
+ if (clk_priv->clk_src == AUDIO_EXT_CLK_LNBB2) {
+ dev_dbg(dev, "%s no pinctrl for clk_src = %d\n",
+ __func__, clk_priv->clk_src);
+ return 0;
}
+ pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
if (pnctrl_info->pinctrl) {
- dev_dbg(dev, "%s: already requested before\n",
+ dev_err(dev, "%s: already requested before\n",
__func__);
return -EINVAL;
}
pinctrl = devm_pinctrl_get(dev);
if (IS_ERR_OR_NULL(pinctrl)) {
- dev_dbg(dev, "%s: Unable to get pinctrl handle\n",
+ dev_err(dev, "%s: Unable to get pinctrl handle\n",
__func__);
return -EINVAL;
}
@@ -462,136 +229,134 @@
return -EINVAL;
}
-static int audio_ref_clk_probe(struct platform_device *pdev)
+static int audio_put_pinctrl(struct platform_device *pdev)
{
- int clk_gpio;
- int ret;
- u32 mclk_freq;
- struct clk *audio_clk;
- struct device *dev = &pdev->dev;
- int i;
- struct clk_onecell_data *clk_data;
+ struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev);
+ struct pinctrl_info *pnctrl_info = NULL;
- ret = of_property_read_u32(pdev->dev.of_node,
- "qcom,codec-mclk-clk-freq",
- &mclk_freq);
- if (!ret) {
- lpass_mclk.clk_freq_in_hz = mclk_freq;
-
- ret = audio_get_pinctrl(pdev, LPASS_MCLK);
- if (ret)
- dev_err(&pdev->dev, "%s: Parsing pinctrl %s failed\n",
- __func__, "LPASS_MCLK");
- ret = audio_get_pinctrl(pdev, LPASS_MCLK2);
- if (ret)
- dev_dbg(&pdev->dev, "%s: Parsing pinctrl %s failed\n",
- __func__, "LPASS_MCLK2");
- }
-
- clk_gpio = of_get_named_gpio(pdev->dev.of_node,
- "qcom,audio-ref-clk-gpio", 0);
- if (clk_gpio > 0) {
- ret = gpio_request(clk_gpio, "EXT_CLK");
- if (ret) {
- dev_err(&pdev->dev,
- "Request ext clk gpio failed %d, err:%d\n",
- clk_gpio, ret);
- goto err;
- }
- if (of_property_read_bool(pdev->dev.of_node,
- "qcom,node_has_rpm_clock")) {
- audio_pmi_clk.gpio = clk_gpio;
- } else
- audio_ap_clk.gpio = clk_gpio;
-
- }
-
- ret = audio_get_pinctrl(pdev, AP_CLK2);
- if (ret)
- dev_dbg(&pdev->dev, "%s: Parsing pinctrl failed\n",
- __func__);
-
- clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL);
- if (!clk_data)
- goto err_gpio;
-
-
- clk_gpio = of_get_named_gpio(pdev->dev.of_node,
- "qcom,audio-ref-clk-gpio", 0);
- if (clk_gpio > 0) {
- clk_data->clk_num = ARRAY_SIZE(audio_msm_hws);
- clk_data->clks = devm_kzalloc(&pdev->dev,
- clk_data->clk_num *
- sizeof(struct clk *),
- GFP_KERNEL);
- if (!clk_data->clks)
- goto err_clk;
-
- for (i = 0; i < ARRAY_SIZE(audio_msm_hws); i++) {
- audio_clk = devm_clk_register(dev, audio_msm_hws[i]);
- if (IS_ERR(audio_clk)) {
- dev_err(&pdev->dev,
- "%s: ref clock: %d register failed\n",
- __func__, i);
- return PTR_ERR(audio_clk);
- }
- clk_data->clks[i] = audio_clk;
- }
- } else {
- clk_data->clk_num = ARRAY_SIZE(audio_msm_hws1);
- clk_data->clks = devm_kzalloc(&pdev->dev,
- clk_data->clk_num *
- sizeof(struct clk *),
- GFP_KERNEL);
- if (!clk_data->clks)
- goto err_clk;
-
- for (i = 0; i < ARRAY_SIZE(audio_msm_hws1); i++) {
- audio_clk = devm_clk_register(dev, audio_msm_hws1[i]);
- if (IS_ERR(audio_clk)) {
- dev_err(&pdev->dev,
- "%s: ref clock: %d register failed\n",
- __func__, i);
- return PTR_ERR(audio_clk);
- }
- clk_data->clks[i] = audio_clk;
- }
- }
-
- ret = of_clk_add_provider(pdev->dev.of_node,
- of_clk_src_onecell_get, clk_data);
- if (ret) {
- dev_err(&pdev->dev, "%s: audio ref clock register failed\n",
- __func__);
- goto err_gpio;
+ pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
+ if (pnctrl_info && pnctrl_info->pinctrl) {
+ devm_pinctrl_put(pnctrl_info->pinctrl);
+ pnctrl_info->pinctrl = NULL;
}
return 0;
+}
-err_clk:
- if (clk_data)
- devm_kfree(&pdev->dev, clk_data->clks);
- devm_kfree(&pdev->dev, clk_data);
-err_gpio:
- gpio_free(clk_gpio);
+static int audio_get_clk_data(struct platform_device *pdev)
+{
+ int ret;
+ struct clk *audio_clk;
+ struct clk_hw *clkhw;
+ struct clk_onecell_data *clk_data;
+ struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev);
-err:
+ clk_data = devm_kzalloc(&pdev->dev, sizeof(*clk_data), GFP_KERNEL);
+ if (!clk_data)
+ return -ENOMEM;
+
+ clk_data->clk_num = 1;
+ clk_data->clks = devm_kzalloc(&pdev->dev,
+ sizeof(struct clk *),
+ GFP_KERNEL);
+ if (!clk_data->clks)
+ return -ENOMEM;
+
+ clkhw = &clk_priv->audio_clk.fact.hw;
+ audio_clk = devm_clk_register(&pdev->dev, clkhw);
+ if (IS_ERR(audio_clk)) {
+ dev_err(&pdev->dev,
+ "%s: clock register failed for clk_src = %d\\n",
+ __func__, clk_priv->clk_src);
+ ret = PTR_ERR(audio_clk);
+ return ret;
+ }
+ clk_data->clks[0] = audio_clk;
+
+ ret = of_clk_add_provider(pdev->dev.of_node,
+ of_clk_src_onecell_get, clk_data);
+ if (ret)
+ dev_err(&pdev->dev, "%s: clock add failed for clk_src = %d\n",
+ __func__, clk_priv->clk_src);
+
return ret;
}
+static int audio_ref_clk_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct audio_ext_clk_priv *clk_priv;
+ u32 clk_freq = 0, clk_id = 0, clk_src = 0;
+
+
+ clk_priv = devm_kzalloc(&pdev->dev, sizeof(*clk_priv), GFP_KERNEL);
+ if (!clk_priv)
+ return -ENOMEM;
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,codec-ext-clk-src",
+ &clk_src);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: could not get clk source, ret = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (clk_src >= AUDIO_EXT_CLK_MAX) {
+ dev_err(&pdev->dev, "%s: Invalid clk source = %d\n",
+ __func__, clk_src);
+ return -EINVAL;
+ }
+
+ clk_priv->clk_src = clk_src;
+ memcpy(&clk_priv->audio_clk, &audio_clk_array[clk_src],
+ sizeof(struct audio_ext_clk));
+
+ /* Init lpass clk default values */
+ clk_priv->clk_cfg.clk_set_minor_version =
+ Q6AFE_LPASS_CLK_CONFIG_API_VERSION;
+ clk_priv->clk_cfg.clk_id = Q6AFE_LPASS_CLK_ID_SPEAKER_I2S_OSR;
+ clk_priv->clk_cfg.clk_freq_in_hz = Q6AFE_LPASS_OSR_CLK_9_P600_MHZ;
+ clk_priv->clk_cfg.clk_attri = Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO;
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,codec-lpass-ext-clk-freq",
+ &clk_freq);
+ if (!ret)
+ clk_priv->clk_cfg.clk_freq_in_hz = clk_freq;
+
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,codec-lpass-clk-id",
+ &clk_id);
+ if (!ret)
+ clk_priv->clk_cfg.clk_id = clk_id;
+
+ dev_dbg(&pdev->dev, "%s: ext-clk freq: %d, lpass clk_id: %d, clk_src: %d\n",
+ __func__, clk_priv->clk_cfg.clk_freq_in_hz,
+ clk_priv->clk_cfg.clk_id, clk_priv->clk_src);
+ platform_set_drvdata(pdev, clk_priv);
+
+ ret = audio_get_pinctrl(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Parsing PMI pinctrl failed\n",
+ __func__);
+ return ret;
+ }
+
+ ret = audio_get_clk_data(pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: clk_init is failed\n",
+ __func__);
+ audio_put_pinctrl(pdev);
+ return ret;
+ }
+
+ return 0;
+}
+
static int audio_ref_clk_remove(struct platform_device *pdev)
{
- struct pinctrl_info *pnctrl_info = &audio_ap_clk2.pnctrl_info;
-
- if (audio_pmi_clk.gpio > 0)
- gpio_free(audio_pmi_clk.gpio);
- else if (audio_ap_clk.gpio > 0)
- gpio_free(audio_ap_clk.gpio);
-
- if (pnctrl_info->pinctrl) {
- devm_pinctrl_put(pnctrl_info->pinctrl);
- pnctrl_info->pinctrl = NULL;
- }
+ audio_put_pinctrl(pdev);
return 0;
}
diff --git a/asoc/codecs/core.h b/asoc/codecs/core.h
index b4c1be4..7d9fcd2 100644
--- a/asoc/codecs/core.h
+++ b/asoc/codecs/core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -105,6 +105,8 @@
#define IS_CODEC_VERSION(wcd, wcdversion) \
((wcd->version == wcdversion) ? true : false)
+#define PAHU_VERSION_1_0 0
+
enum {
CDC_V_1_0,
CDC_V_1_1,
@@ -117,6 +119,7 @@
WCD9335,
WCD9326,
WCD934X,
+ WCD9360,
};
enum wcd9xxx_slim_slave_addr_type {
@@ -295,6 +298,7 @@
TASHA_MAJOR = cpu_to_le16(0x0),
TASHA2P0_MAJOR = cpu_to_le16(0x107),
TAVIL_MAJOR = cpu_to_le16(0x108),
+ PAHU_MAJOR = cpu_to_le16(0x109),
};
enum codec_power_states {
diff --git a/asoc/codecs/msm-cdc-pinctrl.h b/asoc/codecs/msm-cdc-pinctrl.h
index 7eabefb..4286fff 100644
--- a/asoc/codecs/msm-cdc-pinctrl.h
+++ b/asoc/codecs/msm-cdc-pinctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -44,6 +44,10 @@
void msm_cdc_pinctrl_drv_exit(void)
{
}
+bool msm_cdc_pinctrl_get_state(struct device_node *np)
+{
+ return true;
+}
#endif
#endif
diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c
index e36baa8..1b3c5f9 100644
--- a/asoc/codecs/msm-cdc-supply.c
+++ b/asoc/codecs/msm-cdc-supply.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -127,6 +127,106 @@
}
/*
+ * msm_cdc_disable_ondemand_supply:
+ * Disable codec ondemand supply
+ *
+ * @dev: pointer to codec device
+ * @supplies: pointer to regulator bulk data
+ * @cdc_vreg: pointer to platform regulator data
+ * @num_supplies: number of supplies
+ * @supply_name: Ondemand supply name to be enabled
+ *
+ * Return error code if supply disable is failed
+ */
+int msm_cdc_disable_ondemand_supply(struct device *dev,
+ struct regulator_bulk_data *supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies,
+ char *supply_name)
+{
+ int rc, i;
+
+ if ((!supply_name) || (!supplies)) {
+ pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ /* input parameter validation */
+ rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
+ if (rc)
+ return rc;
+
+ for (i = 0; i < num_supplies; i++) {
+ if (cdc_vreg[i].ondemand &&
+ !strcmp(cdc_vreg[i].name, supply_name)) {
+ rc = regulator_disable(supplies[i].consumer);
+ if (rc)
+ dev_err(dev, "%s: failed to disable supply %s, err:%d\n",
+ __func__, supplies[i].supply, rc);
+ break;
+ }
+ }
+ if (i == num_supplies) {
+ dev_err(dev, "%s: not able to find supply %s\n",
+ __func__, supply_name);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(msm_cdc_disable_ondemand_supply);
+
+/*
+ * msm_cdc_enable_ondemand_supply:
+ * Enable codec ondemand supply
+ *
+ * @dev: pointer to codec device
+ * @supplies: pointer to regulator bulk data
+ * @cdc_vreg: pointer to platform regulator data
+ * @num_supplies: number of supplies
+ * @supply_name: Ondemand supply name to be enabled
+ *
+ * Return error code if supply enable is failed
+ */
+int msm_cdc_enable_ondemand_supply(struct device *dev,
+ struct regulator_bulk_data *supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies,
+ char *supply_name)
+{
+ int rc, i;
+
+ if ((!supply_name) || (!supplies)) {
+ pr_err("%s: either dev or supplies or cdc_vreg is NULL\n",
+ __func__);
+ return -EINVAL;
+ }
+ /* input parameter validation */
+ rc = msm_cdc_check_supply_param(dev, cdc_vreg, num_supplies);
+ if (rc)
+ return rc;
+
+ for (i = 0; i < num_supplies; i++) {
+ if (cdc_vreg[i].ondemand &&
+ !strcmp(cdc_vreg[i].name, supply_name)) {
+ rc = regulator_enable(supplies[i].consumer);
+ if (rc)
+ dev_err(dev, "%s: failed to enable supply %s, rc: %d\n",
+ __func__, supplies[i].supply, rc);
+ break;
+ }
+ }
+ if (i == num_supplies) {
+ dev_err(dev, "%s: not able to find supply %s\n",
+ __func__, supply_name);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+EXPORT_SYMBOL(msm_cdc_enable_ondemand_supply);
+
+/*
* msm_cdc_disable_static_supplies:
* Disable codec static supplies
*
@@ -209,10 +309,7 @@
regulator_set_voltage(supplies[i].consumer, 0,
cdc_vreg[i].max_uV);
regulator_set_load(supplies[i].consumer, 0);
- devm_regulator_put(supplies[i].consumer);
- supplies[i].consumer = NULL;
}
- devm_kfree(dev, supplies);
return rc;
}
@@ -330,14 +427,14 @@
if (rc) {
dev_err(dev, "%s: set regulator voltage failed for %s, err:%d\n",
__func__, vsup[i].supply, rc);
- goto err_set_supply;
+ goto err_supply;
}
rc = regulator_set_load(vsup[i].consumer,
cdc_vreg[i].optimum_uA);
if (rc < 0) {
dev_err(dev, "%s: set regulator optimum mode failed for %s, err:%d\n",
__func__, vsup[i].supply, rc);
- goto err_set_supply;
+ goto err_supply;
}
}
@@ -345,11 +442,7 @@
return 0;
-err_set_supply:
- for (i = 0; i < num_supplies; i++)
- devm_regulator_put(vsup[i].consumer);
err_supply:
- devm_kfree(dev, vsup);
return rc;
}
EXPORT_SYMBOL(msm_cdc_init_supplies);
@@ -448,7 +541,6 @@
return 0;
err_sup:
- devm_kfree(dev, cdc_reg);
err_supply_cnt:
err_mem_alloc:
return rc;
diff --git a/asoc/codecs/msm-cdc-supply.h b/asoc/codecs/msm-cdc-supply.h
index b40f44b..b6516fa 100644
--- a/asoc/codecs/msm-cdc-supply.h
+++ b/asoc/codecs/msm-cdc-supply.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,14 @@
extern int msm_cdc_get_power_supplies(struct device *dev,
struct cdc_regulator **cdc_vreg,
int *total_num_supplies);
+extern int msm_cdc_disable_ondemand_supply(struct device *dev,
+ struct regulator_bulk_data *supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies, char *supply_name);
+extern int msm_cdc_enable_ondemand_supply(struct device *dev,
+ struct regulator_bulk_data *supplies,
+ struct cdc_regulator *cdc_vreg,
+ int num_supplies, char *supply_name);
extern int msm_cdc_disable_static_supplies(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
diff --git a/asoc/codecs/msm_sdw/msm_sdw.h b/asoc/codecs/msm_sdw/msm_sdw.h
index d4ac433..3c7a07d 100644
--- a/asoc/codecs/msm_sdw/msm_sdw.h
+++ b/asoc/codecs/msm_sdw/msm_sdw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@
#include "msm_sdw_registers.h"
#define MSM_SDW_MAX_REGISTER 0x400
+#define MSM_SDW_CHILD_DEVICES_MAX 1
extern const struct regmap_config msm_sdw_regmap_config;
extern const u8 msm_sdw_page_map[MSM_SDW_MAX_REGISTER];
@@ -154,6 +155,9 @@
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
+ struct platform_device *pdev_child_devices
+ [MSM_SDW_CHILD_DEVICES_MAX];
+ int child_count;
};
#if IS_ENABLED(CONFIG_SND_SOC_MSM_SDW)
diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c
index 95250e4..15c9b4e 100644
--- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c
+++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c
@@ -1251,7 +1251,13 @@
static int msm_sdw_swrm_clock(void *handle, bool enable)
{
- struct msm_sdw_priv *msm_sdw = (struct msm_sdw_priv *) handle;
+ struct msm_sdw_priv *msm_sdw;
+
+ if (!handle) {
+ pr_err("%s: NULL handle\n", __func__);
+ return -EINVAL;
+ }
+ msm_sdw = (struct msm_sdw_priv *)handle;
mutex_lock(&msm_sdw->sdw_clk_lock);
@@ -1934,6 +1940,7 @@
msm_sdw->nr = ctrl_num;
msm_sdw->sdw_ctrl_data = sdw_ctrl_data;
}
+ msm_sdw->pdev_child_devices[msm_sdw->child_count++] = pdev;
}
return;
@@ -2050,15 +2057,21 @@
static int msm_sdw_remove(struct platform_device *pdev)
{
struct msm_sdw_priv *msm_sdw;
+ int count;
msm_sdw = dev_get_drvdata(&pdev->dev);
+ for (count = 0; count < msm_sdw->child_count &&
+ count < MSM_SDW_CHILD_DEVICES_MAX; count++)
+ platform_device_unregister(msm_sdw->pdev_child_devices[count]);
+
mutex_destroy(&msm_sdw->io_lock);
mutex_destroy(&msm_sdw->sdw_read_lock);
mutex_destroy(&msm_sdw->sdw_write_lock);
mutex_destroy(&msm_sdw->sdw_clk_lock);
mutex_destroy(&msm_sdw->codec_mutex);
mutex_destroy(&msm_sdw->cdc_int_mclk1_mutex);
+
devm_kfree(&pdev->dev, msm_sdw);
snd_soc_unregister_codec(&pdev->dev);
return 0;
diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c
index 9121baf..64b9956 100644
--- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c
+++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -4396,7 +4396,7 @@
return ret;
err_supplies:
- kfree(sdm660_cdc->supplies);
+ devm_kfree(sdm660_cdc->dev, sdm660_cdc->supplies);
err:
return ret;
}
@@ -4442,9 +4442,6 @@
pdata->regulator[i].max_uv);
regulator_set_load(sdm660_cdc->supplies[i].consumer, 0);
}
- regulator_bulk_free(sdm660_cdc->num_of_supplies,
- sdm660_cdc->supplies);
- kfree(sdm660_cdc->supplies);
}
static const struct of_device_id sdm660_codec_of_match[] = {
@@ -4531,6 +4528,7 @@
__func__);
pdata->dig_ctrl_data = dig_ctrl_data;
}
+ pdata->pdev_child_devices[pdata->child_count++] = pdev;
}
return;
@@ -4639,9 +4637,16 @@
{
struct sdm660_cdc_priv *sdm660_cdc = dev_get_drvdata(&pdev->dev);
struct sdm660_cdc_pdata *pdata = sdm660_cdc->dev->platform_data;
+ int count;
+ for (count = 0; count < sdm660_cdc->child_count &&
+ count < ANLG_CDC_CHILD_DEVICES_MAX; count++)
+ platform_device_unregister(
+ sdm660_cdc->pdev_child_devices[count]);
snd_soc_unregister_codec(&pdev->dev);
msm_anlg_cdc_disable_supplies(sdm660_cdc, pdata);
+ wcd9xxx_spmi_irq_exit();
+ devm_kfree(&pdev->dev, sdm660_cdc);
return 0;
}
diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h
index 3ee3dee..71d555f 100644
--- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h
+++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
#define MICBIAS_EXT_BYP_CAP 0x00
#define MICBIAS_NO_EXT_BYP_CAP 0x01
+#define ANLG_CDC_CHILD_DEVICES_MAX 1
#define MSM89XX_NUM_IRQ_REGS 2
#define MAX_REGULATOR 7
@@ -215,6 +216,9 @@
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
+ struct platform_device *pdev_child_devices
+ [ANLG_CDC_CHILD_DEVICES_MAX];
+ int child_count;
};
struct sdm660_cdc_pdata {
diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c
index ee4ec34..673b738 100644
--- a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c
+++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -409,5 +409,10 @@
return 0;
}
+void wcd9xxx_spmi_irq_exit(void)
+{
+ pm_qos_remove_request(&map.pm_qos_req);
+ mutex_destroy(&map.pm_lock);
+}
MODULE_DESCRIPTION("MSM8x16 SPMI IRQ driver");
MODULE_LICENSE("GPL v2");
diff --git a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h
index d0f48d0..0b9b56e 100644
--- a/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h
+++ b/asoc/codecs/sdm660_cdc/sdm660-cdc-irq.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -26,6 +26,7 @@
extern void wcd9xxx_spmi_set_codec(struct snd_soc_codec *codec);
extern void wcd9xxx_spmi_set_dev(struct platform_device *spmi, int i);
extern int wcd9xxx_spmi_irq_init(void);
+extern void wcd9xxx_spmi_irq_exit(void);
extern int wcd9xxx_spmi_suspend(pm_message_t pmesg);
extern int wcd9xxx_spmi_resume(void);
bool wcd9xxx_spmi_lock_sleep(void);
diff --git a/asoc/codecs/wcd-dsp-utils.c b/asoc/codecs/wcd-dsp-utils.c
index 4eafd55..1c95d48 100644
--- a/asoc/codecs/wcd-dsp-utils.c
+++ b/asoc/codecs/wcd-dsp-utils.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -82,6 +82,15 @@
goto bad_seg;
}
+ if (phdr->p_filesz != seg->split_fw->size) {
+ dev_err(dev,
+ "%s: %s size mismatch, phdr_size: 0x%x fw_size: 0x%zx",
+ __func__, seg->split_fname, phdr->p_filesz,
+ seg->split_fw->size);
+ ret = -EINVAL;
+ goto bad_elf;
+ }
+
seg->load_addr = phdr->p_paddr;
seg->size = phdr->p_filesz;
seg->data = (u8 *) seg->split_fw->data;
@@ -89,6 +98,8 @@
list_add_tail(&seg->list, seg_list);
done:
return ret;
+bad_elf:
+ release_firmware(seg->split_fw);
bad_seg:
kfree(seg);
return ret;
diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c
index 920796f..893df9a 100644
--- a/asoc/codecs/wcd-mbhc-adc.c
+++ b/asoc/codecs/wcd-mbhc-adc.c
@@ -996,6 +996,7 @@
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
wcd_mbhc_elec_hs_report_unplug(mbhc);
+ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0);
if (hphpa_on) {
hphpa_on = false;
diff --git a/asoc/codecs/wcd-mbhc-legacy.c b/asoc/codecs/wcd-mbhc-legacy.c
index d03d834..9ebdeca 100644
--- a/asoc/codecs/wcd-mbhc-legacy.c
+++ b/asoc/codecs/wcd-mbhc-legacy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -533,7 +533,8 @@
mbhc->hs_detect_work_stop);
wcd_enable_curr_micbias(mbhc,
WCD_MBHC_EN_NONE);
- if (mbhc->micbias_enable) {
+ if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic &&
+ mbhc->micbias_enable) {
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec, MIC_BIAS_2, false);
if (mbhc->mbhc_cb->set_micbias_value)
@@ -558,7 +559,8 @@
mbhc->hs_detect_work_stop);
wcd_enable_curr_micbias(mbhc,
WCD_MBHC_EN_NONE);
- if (mbhc->micbias_enable) {
+ if (mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic &&
+ mbhc->micbias_enable) {
mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic(
mbhc->codec, MIC_BIAS_2, false);
if (mbhc->mbhc_cb->set_micbias_value)
diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c
index 0b6e355..97989de 100644
--- a/asoc/codecs/wcd-mbhc-v2.c
+++ b/asoc/codecs/wcd-mbhc-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,7 @@
#include <linux/input.h>
#include <linux/firmware.h>
#include <linux/completion.h>
+#include <linux/soc/qcom/fsa4480-i2c.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include "msm-cdc-pinctrl.h"
@@ -958,6 +959,9 @@
mbhc->extn_cable_hph_rem = false;
wcd_mbhc_report_plug(mbhc, 0, jack_type);
+ if (mbhc->mbhc_cfg->enable_usbc_analog)
+ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0);
+
} else if (!detection_type) {
/* Disable external voltage source to micbias if present */
if (mbhc->mbhc_cb->enable_mb_source)
@@ -1274,7 +1278,10 @@
WCD_MBHC_RSC_LOCK(mbhc);
/* enable HS detection */
- if (mbhc->mbhc_cb->hph_pull_up_control)
+ if (mbhc->mbhc_cb->hph_pull_up_control_v2)
+ mbhc->mbhc_cb->hph_pull_up_control_v2(codec,
+ HS_PULLUP_I_DEFAULT);
+ else if (mbhc->mbhc_cb->hph_pull_up_control)
mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT);
else
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3);
@@ -1288,10 +1295,13 @@
* by an external source
*/
if (mbhc->mbhc_cfg->enable_usbc_analog) {
- mbhc->hphl_swh = 1;
- mbhc->gnd_swh = 1;
+ mbhc->hphl_swh = 0;
+ mbhc->gnd_swh = 0;
- if (mbhc->mbhc_cb->hph_pull_up_control)
+ if (mbhc->mbhc_cb->hph_pull_up_control_v2)
+ mbhc->mbhc_cb->hph_pull_up_control_v2(codec,
+ HS_PULLUP_I_OFF);
+ else if (mbhc->mbhc_cb->hph_pull_up_control)
mbhc->mbhc_cb->hph_pull_up_control(codec, I_OFF);
else
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL,
@@ -1304,7 +1314,16 @@
if (mbhc->mbhc_cfg->gnd_det_en && mbhc->mbhc_cb->mbhc_gnd_det_ctrl)
mbhc->mbhc_cb->mbhc_gnd_det_ctrl(codec, true);
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_COMP_CTRL, 1);
- WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
+
+ /*
+ * Disable L_DET for USB-C analog audio to avoid spurious interrupts
+ * when a non-audio accessory is inserted. L_DET_EN sets to 1 when FSA
+ * I2C driver notifies that ANALOG_AUDIO_ADAPTER is inserted
+ */
+ if (mbhc->mbhc_cfg->enable_usbc_analog)
+ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0);
+ else
+ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
if (mbhc->mbhc_cfg->enable_usbc_analog) {
/* Insertion debounce set to 48ms */
@@ -1475,207 +1494,26 @@
return result;
}
-static int wcd_mbhc_usb_c_analog_setup_gpios(struct wcd_mbhc *mbhc,
- bool active)
+static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
+ unsigned long mode, void *ptr)
{
- int rc = 0;
- struct usbc_ana_audio_config *config =
- &mbhc->mbhc_cfg->usbc_analog_cfg;
- union power_supply_propval pval;
+ struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb);
- dev_dbg(mbhc->codec->dev, "%s: setting GPIOs active = %d\n",
- __func__, active);
+ if (!mbhc)
+ return -EINVAL;
- memset(&pval, 0, sizeof(pval));
+ dev_dbg(mbhc->codec->dev, "%s: mode = %lu\n", __func__, mode);
- if (active) {
- pval.intval = POWER_SUPPLY_TYPEC_PR_SOURCE;
- if (power_supply_set_property(mbhc->usb_psy,
- POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval))
- dev_info(mbhc->codec->dev, "%s: force PR_SOURCE mode unsuccessful\n",
- __func__);
- else
- mbhc->usbc_force_pr_mode = true;
-
- if (config->usbc_en1_gpio_p)
- rc = msm_cdc_pinctrl_select_active_state(
- config->usbc_en1_gpio_p);
- if (rc == 0 && config->usbc_force_gpio_p)
- rc = msm_cdc_pinctrl_select_active_state(
- config->usbc_force_gpio_p);
- mbhc->usbc_mode = POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER;
- } else {
- /* no delay is required when disabling GPIOs */
- if (config->usbc_en1_gpio_p)
- msm_cdc_pinctrl_select_sleep_state(
- config->usbc_en1_gpio_p);
- if (config->usbc_force_gpio_p)
- msm_cdc_pinctrl_select_sleep_state(
- config->usbc_force_gpio_p);
-
- if (mbhc->usbc_force_pr_mode) {
- pval.intval = POWER_SUPPLY_TYPEC_PR_DUAL;
- if (power_supply_set_property(mbhc->usb_psy,
- POWER_SUPPLY_PROP_TYPEC_POWER_ROLE, &pval))
- dev_info(mbhc->codec->dev, "%s: force PR_DUAL mode unsuccessful\n",
- __func__);
-
- mbhc->usbc_force_pr_mode = false;
- }
-
- mbhc->usbc_mode = POWER_SUPPLY_TYPEC_NONE;
- if (mbhc->mbhc_cfg->swap_gnd_mic)
- mbhc->mbhc_cfg->swap_gnd_mic(mbhc->codec, false);
+ if (mode == POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER) {
+ /* insertion detected, enable L_DET_EN */
+ WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
}
-
- return rc;
-}
-
-/* workqueue */
-static void wcd_mbhc_usbc_analog_work_fn(struct work_struct *work)
-{
- struct wcd_mbhc *mbhc =
- container_of(work, struct wcd_mbhc, usbc_analog_work);
-
- wcd_mbhc_usb_c_analog_setup_gpios(mbhc,
- mbhc->usbc_mode != POWER_SUPPLY_TYPEC_NONE);
-}
-
-/* this callback function is used to process PMI notification */
-static int wcd_mbhc_usb_c_event_changed(struct notifier_block *nb,
- unsigned long evt, void *ptr)
-{
- int ret;
- union power_supply_propval mode;
- struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, psy_nb);
- struct snd_soc_codec *codec = mbhc->codec;
-
- if (ptr != mbhc->usb_psy || evt != PSY_EVENT_PROP_CHANGED)
- return 0;
-
- ret = power_supply_get_property(mbhc->usb_psy,
- POWER_SUPPLY_PROP_TYPEC_MODE, &mode);
- if (ret) {
- dev_err(codec->dev, "%s: Unable to read USB TYPEC_MODE: %d\n",
- __func__, ret);
- return ret;
- }
-
- dev_dbg(codec->dev, "%s: USB change event received\n",
- __func__);
- dev_dbg(codec->dev, "%s: supply mode %d, expected %d\n", __func__,
- mode.intval, POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER);
-
- switch (mode.intval) {
- case POWER_SUPPLY_TYPEC_SINK_AUDIO_ADAPTER:
- case POWER_SUPPLY_TYPEC_NONE:
- dev_dbg(codec->dev, "%s: usbc_mode: %d; mode.intval: %d\n",
- __func__, mbhc->usbc_mode, mode.intval);
-
- if (mbhc->usbc_mode == mode.intval)
- break; /* filter notifications received before */
- mbhc->usbc_mode = mode.intval;
-
- dev_dbg(codec->dev, "%s: queueing usbc_analog_work\n",
- __func__);
- schedule_work(&mbhc->usbc_analog_work);
- break;
- default:
- break;
- }
- return ret;
-}
-
-/* PMI registration code */
-static int wcd_mbhc_usb_c_analog_init(struct wcd_mbhc *mbhc)
-{
- int ret = 0;
- struct snd_soc_codec *codec = mbhc->codec;
-
- dev_dbg(mbhc->codec->dev, "%s: usb-c analog setup start\n", __func__);
- INIT_WORK(&mbhc->usbc_analog_work, wcd_mbhc_usbc_analog_work_fn);
-
- mbhc->usb_psy = power_supply_get_by_name("usb");
- if (IS_ERR_OR_NULL(mbhc->usb_psy)) {
- dev_err(codec->dev, "%s: could not get USB psy info\n",
- __func__);
- ret = -EPROBE_DEFER;
- if (IS_ERR(mbhc->usb_psy))
- ret = PTR_ERR(mbhc->usb_psy);
- mbhc->usb_psy = NULL;
- goto err;
- }
-
- ret = wcd_mbhc_usb_c_analog_setup_gpios(mbhc, false);
- if (ret) {
- dev_err(codec->dev, "%s: error while setting USBC ana gpios\n",
- __func__);
- goto err;
- }
-
- mbhc->psy_nb.notifier_call = wcd_mbhc_usb_c_event_changed;
- mbhc->psy_nb.priority = 0;
- ret = power_supply_reg_notifier(&mbhc->psy_nb);
- if (ret) {
- dev_err(codec->dev, "%s: power supply registration failed\n",
- __func__);
- goto err;
- }
-
- /*
- * as part of the init sequence check if there is a connected
- * USB C analog adapter
- */
- dev_dbg(mbhc->codec->dev, "%s: verify if USB adapter is already inserted\n",
- __func__);
- ret = wcd_mbhc_usb_c_event_changed(&mbhc->psy_nb,
- PSY_EVENT_PROP_CHANGED,
- mbhc->usb_psy);
-
-err:
- return ret;
-}
-
-static int wcd_mbhc_usb_c_analog_deinit(struct wcd_mbhc *mbhc)
-{
- wcd_mbhc_usb_c_analog_setup_gpios(mbhc, false);
-
- /* deregister from PMI */
- power_supply_unreg_notifier(&mbhc->psy_nb);
-
return 0;
}
-static int wcd_mbhc_init_gpio(struct wcd_mbhc *mbhc,
- struct wcd_mbhc_config *mbhc_cfg,
- const char *gpio_dt_str,
- int *gpio, struct device_node **gpio_dn)
-{
- int rc = 0;
- struct snd_soc_codec *codec = mbhc->codec;
- struct snd_soc_card *card = codec->component.card;
-
- dev_dbg(mbhc->codec->dev, "%s: gpio %s\n", __func__, gpio_dt_str);
-
- *gpio_dn = of_parse_phandle(card->dev->of_node, gpio_dt_str, 0);
-
- if (!(*gpio_dn)) {
- *gpio = of_get_named_gpio(card->dev->of_node, gpio_dt_str, 0);
- if (!gpio_is_valid(*gpio)) {
- dev_err(card->dev, "%s, property %s not in node %s",
- __func__, gpio_dt_str,
- card->dev->of_node->full_name);
- rc = -EINVAL;
- }
- }
-
- return rc;
-}
-
int wcd_mbhc_start(struct wcd_mbhc *mbhc, struct wcd_mbhc_config *mbhc_cfg)
{
int rc = 0;
- struct usbc_ana_audio_config *config;
struct snd_soc_codec *codec;
struct snd_soc_card *card;
const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported";
@@ -1683,7 +1521,6 @@
if (!mbhc || !mbhc_cfg)
return -EINVAL;
- config = &mbhc_cfg->usbc_analog_cfg;
codec = mbhc->codec;
card = codec->component.card;
@@ -1699,42 +1536,24 @@
&mbhc_cfg->enable_usbc_analog);
}
if (mbhc_cfg->enable_usbc_analog == 0 || rc != 0) {
- dev_info(card->dev,
+ dev_dbg(card->dev,
"%s: %s in dt node is missing or false\n",
__func__, usb_c_dt);
- dev_info(card->dev,
+ dev_dbg(card->dev,
"%s: skipping USB c analog configuration\n", __func__);
}
- /* initialize GPIOs */
+ /* Parse fsa switch handle */
if (mbhc_cfg->enable_usbc_analog) {
dev_dbg(mbhc->codec->dev, "%s: usbc analog enabled\n",
__func__);
mbhc->swap_thr = GND_MIC_USBC_SWAP_THRESHOLD;
- rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg,
- "qcom,usbc-analog-en1-gpio",
- &config->usbc_en1_gpio,
- &config->usbc_en1_gpio_p);
- if (rc)
- goto err;
-
- if (of_find_property(card->dev->of_node,
- "qcom,usbc-analog-force_detect_gpio",
- NULL)) {
- rc = wcd_mbhc_init_gpio(mbhc, mbhc_cfg,
- "qcom,usbc-analog-force_detect_gpio",
- &config->usbc_force_gpio,
- &config->usbc_force_gpio_p);
- if (rc)
- goto err;
- }
-
- dev_dbg(mbhc->codec->dev, "%s: calling usb_c_analog_init\n",
- __func__);
- /* init PMI notifier */
- rc = wcd_mbhc_usb_c_analog_init(mbhc);
- if (rc) {
- rc = EPROBE_DEFER;
+ mbhc->fsa_np = of_parse_phandle(card->dev->of_node,
+ "fsa4480-i2c-handle", 0);
+ if (!mbhc->fsa_np) {
+ dev_err(card->dev, "%s: fsa4480 i2c node not found\n",
+ __func__);
+ rc = -EINVAL;
goto err;
}
}
@@ -1747,6 +1566,11 @@
(mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_fw) ||
(mbhc->mbhc_cfg->read_fw_bin && mbhc->mbhc_cal)) {
rc = wcd_mbhc_initialise(mbhc);
+ if (rc) {
+ dev_err(card->dev, "%s: wcd mbhc initialize failed\n",
+ __func__);
+ goto err;
+ }
} else {
if (!mbhc->mbhc_fw || !mbhc->mbhc_cal)
schedule_delayed_work(&mbhc->mbhc_firmware_dwork,
@@ -1756,24 +1580,14 @@
__func__, mbhc->mbhc_fw, mbhc->mbhc_cal);
}
+ if (mbhc_cfg->enable_usbc_analog) {
+ mbhc->fsa_nb.notifier_call = wcd_mbhc_usbc_ana_event_handler;
+ mbhc->fsa_nb.priority = 0;
+ rc = fsa4480_reg_notifier(&mbhc->fsa_nb, mbhc->fsa_np);
+ }
+
return rc;
err:
- if (config->usbc_en1_gpio > 0) {
- dev_dbg(card->dev, "%s free usb en1 gpio %d\n",
- __func__, config->usbc_en1_gpio);
- gpio_free(config->usbc_en1_gpio);
- config->usbc_en1_gpio = 0;
- }
- if (config->usbc_force_gpio > 0) {
- dev_dbg(card->dev, "%s free usb_force gpio %d\n",
- __func__, config->usbc_force_gpio);
- gpio_free(config->usbc_force_gpio);
- config->usbc_force_gpio = 0;
- }
- if (config->usbc_en1_gpio_p)
- of_node_put(config->usbc_en1_gpio_p);
- if (config->usbc_force_gpio_p)
- of_node_put(config->usbc_force_gpio_p);
dev_dbg(mbhc->codec->dev, "%s: leave %d\n", __func__, rc);
return rc;
}
@@ -1781,8 +1595,6 @@
void wcd_mbhc_stop(struct wcd_mbhc *mbhc)
{
- struct usbc_ana_audio_config *config = &mbhc->mbhc_cfg->usbc_analog_cfg;
-
pr_debug("%s: enter\n", __func__);
if (mbhc->current_plug != MBHC_PLUG_TYPE_NONE) {
@@ -1807,19 +1619,8 @@
mbhc->mbhc_cal = NULL;
}
- if (mbhc->mbhc_cfg->enable_usbc_analog) {
- wcd_mbhc_usb_c_analog_deinit(mbhc);
- /* free GPIOs */
- if (config->usbc_en1_gpio > 0)
- gpio_free(config->usbc_en1_gpio);
- if (config->usbc_force_gpio)
- gpio_free(config->usbc_force_gpio);
-
- if (config->usbc_en1_gpio_p)
- of_node_put(config->usbc_en1_gpio_p);
- if (config->usbc_force_gpio_p)
- of_node_put(config->usbc_force_gpio_p);
- }
+ if (mbhc->mbhc_cfg->enable_usbc_analog)
+ fsa4480_unreg_notifier(&mbhc->fsa_nb, mbhc->fsa_np);
pr_debug("%s: leave\n", __func__);
}
diff --git a/asoc/codecs/wcd-mbhc-v2.h b/asoc/codecs/wcd-mbhc-v2.h
index 94f096a..2fb09ff 100644
--- a/asoc/codecs/wcd-mbhc-v2.h
+++ b/asoc/codecs/wcd-mbhc-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -399,6 +399,22 @@
I_3P0_UA,
};
+enum mbhc_hs_pullup_iref_v2 {
+ HS_PULLUP_I_DEFAULT = -1,
+ HS_PULLUP_I_3P0_UA = 0,
+ HS_PULLUP_I_2P25_UA,
+ HS_PULLUP_I_1P5_UA,
+ HS_PULLUP_I_0P75_UA,
+ HS_PULLUP_I_1P125_UA = 0x05,
+ HS_PULLUP_I_0P375_UA = 0x07,
+ HS_PULLUP_I_2P0_UA,
+ HS_PULLUP_I_1P0_UA = 0x0A,
+ HS_PULLUP_I_0P5_UA,
+ HS_PULLUP_I_0P25_UA = 0x0F,
+ HS_PULLUP_I_0P125_UA = 0x17,
+ HS_PULLUP_I_OFF,
+};
+
enum mbhc_moisture_rref {
R_OFF,
R_24_KOHM,
@@ -406,15 +422,6 @@
R_184_KOHM,
};
-struct usbc_ana_audio_config {
- int usbc_en1_gpio;
- int usbc_en2_gpio;
- int usbc_force_gpio;
- struct device_node *usbc_en1_gpio_p; /* used by pinctrl API */
- struct device_node *usbc_en2_gpio_p; /* used by pinctrl API */
- struct device_node *usbc_force_gpio_p; /* used by pinctrl API */
-};
-
struct wcd_mbhc_config {
bool read_fw_bin;
void *calibration;
@@ -430,7 +437,6 @@
int anc_micbias;
bool enable_anc_mic_detect;
u32 enable_usbc_analog;
- struct usbc_ana_audio_config usbc_analog_cfg;
};
struct wcd_mbhc_intr {
@@ -495,6 +501,7 @@
void (*update_anc_state)(struct snd_soc_codec *codec,
bool enable, int anc_num);
bool (*is_anc_on)(struct wcd_mbhc *mbhc);
+ void (*hph_pull_up_control_v2)(struct snd_soc_codec *, int);
};
struct wcd_mbhc_fn {
@@ -582,14 +589,10 @@
unsigned long intr_status;
bool is_hph_ocp_pending;
- bool usbc_force_pr_mode;
- int usbc_mode;
- struct notifier_block psy_nb;
- struct power_supply *usb_psy;
- struct work_struct usbc_analog_work;
-
struct wcd_mbhc_fn *mbhc_fn;
bool force_linein;
+ struct device_node *fsa_np;
+ struct notifier_block fsa_nb;
};
void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc,
diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c
index 072a753..a25c9a6 100644
--- a/asoc/codecs/wcd-spi.c
+++ b/asoc/codecs/wcd-spi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -603,8 +603,11 @@
if (ret < 0)
dev_err(&spi->dev, "%s: Failed, err = %d\n",
__func__, ret);
- else
- clear_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask);
+ /*
+ * clear this bit even if clock disable failed
+ * as the source clocks might get turned off.
+ */
+ clear_bit(WCD_SPI_CLK_STATE_ENABLED, &wcd_spi->status_mask);
return ret;
}
diff --git a/asoc/codecs/wcd934x/Android.mk b/asoc/codecs/wcd934x/Android.mk
index 0fe519f..200f6c3 100644
--- a/asoc/codecs/wcd934x/Android.mk
+++ b/asoc/codecs/wcd934x/Android.mk
@@ -7,13 +7,17 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM845=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
ifeq ($(call is-board-platform-in-list,msm8953 sdm670 qcs605),true)
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/asoc/codecs/wcd934x/Kbuild b/asoc/codecs/wcd934x/Kbuild
index 7ea91ce..60b2485 100644
--- a/asoc/codecs/wcd934x/Kbuild
+++ b/asoc/codecs/wcd934x/Kbuild
@@ -31,6 +31,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
# As per target team, build is done as follows:
diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c
index 35e1224..58987ad 100644
--- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c
+++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1007,7 +1007,7 @@
{
struct wcd_dsp_cntl *cntl = container_of(filep->private_data,
struct wcd_dsp_cntl, miscdev);
- char val[count];
+ char val[WCD_MISCDEV_CMD_MAX_LEN];
bool vote;
int ret = 0;
diff --git a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h
index 2f71d0e..0127a0d 100644
--- a/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h
+++ b/asoc/codecs/wcd934x/wcd934x-dsp-cntl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,7 @@
#ifndef __WCD934X_DSP_CNTL_H__
#define __WCD934X_DSP_CNTL_H__
+#include <linux/miscdevice.h>
#include <sound/soc.h>
#include <sound/wcd-dsp-mgr.h>
diff --git a/asoc/codecs/wcd934x/wcd934x-routing.h b/asoc/codecs/wcd934x/wcd934x-routing.h
index 93a1ad3..8adeef7 100644
--- a/asoc/codecs/wcd934x/wcd934x-routing.h
+++ b/asoc/codecs/wcd934x/wcd934x-routing.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,13 +17,9 @@
const struct snd_soc_dapm_route tavil_slim_audio_map[] = {
- /* Virtual input widgets */
- {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
- {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
- {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
{"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
- /* Virtual input widget Mixer */
+ /* Virtual input widget Mixer SLIMBUS*/
{"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0"},
{"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1"},
{"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2"},
@@ -68,6 +64,21 @@
{"AIF4_MAD Mixer", "SLIM TX13", "SLIM TX13"},
+ /* CDC Tx interface with SLIMBUS */
+ {"SLIM TX0", NULL, "CDC_IF TX0 MUX"},
+ {"SLIM TX1", NULL, "CDC_IF TX1 MUX"},
+ {"SLIM TX2", NULL, "CDC_IF TX2 MUX"},
+ {"SLIM TX3", NULL, "CDC_IF TX3 MUX"},
+ {"SLIM TX4", NULL, "CDC_IF TX4 MUX"},
+ {"SLIM TX5", NULL, "CDC_IF TX5 MUX"},
+ {"SLIM TX6", NULL, "CDC_IF TX6 MUX"},
+ {"SLIM TX7", NULL, "CDC_IF TX7 MUX"},
+ {"SLIM TX8", NULL, "CDC_IF TX8 MUX"},
+ {"SLIM TX9", NULL, "CDC_IF TX9 MUX"},
+ {"SLIM TX10", NULL, "CDC_IF TX10 MUX"},
+ {"SLIM TX11", NULL, "CDC_IF TX11 MUX"},
+ {"SLIM TX13", NULL, "CDC_IF TX13 MUX"},
+
{"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
{"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
{"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
@@ -113,10 +124,100 @@
{"SLIM RX6", NULL, "SLIM RX6 MUX"},
{"SLIM RX7", NULL, "SLIM RX7 MUX"},
+ /* CDC Rx interface with SLIMBUS */
+ {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"},
+ {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"},
+ {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"},
+ {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"},
+ {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"},
+ {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"},
+ {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"},
+ {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"},
+
+ /* VI Feedback */
+ {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
+ {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
+ {"AIF4 VI", NULL, "AIF4_VI Mixer"},
+
+};
+
+const struct snd_soc_dapm_route tavil_i2s_audio_map[] = {
+
+ /* Virtual input widget Mixer I2S*/
+ {"AIF1_CAP Mixer", "I2S TX1", "I2S TX1"},
+ {"AIF1_CAP Mixer", "I2S TX2", "I2S TX2"},
+ {"AIF1_CAP Mixer", "I2S TX3", "I2S TX3"},
+ {"AIF1_CAP Mixer", "I2S TX4", "I2S TX4"},
+ {"AIF1_CAP Mixer", "I2S TX5", "I2S TX5"},
+ {"AIF1_CAP Mixer", "I2S TX6", "I2S TX6"},
+ {"AIF1_CAP Mixer", "I2S TX7", "I2S TX7"},
+
+ {"AIF2_CAP Mixer", "I2S TX8", "I2S TX8"},
+ {"AIF2_CAP Mixer", "I2S TX11", "I2S TX11"},
+
+ {"AIF3_CAP Mixer", "I2S TX0", "I2S TX0"},
+ {"AIF3_CAP Mixer", "I2S TX1", "I2S TX1"},
+
+ /* CDC Tx interface with I2S */
+ {"I2S TX0", NULL, "CDC_IF TX0 MUX"},
+ {"I2S TX1", NULL, "CDC_IF TX1 MUX"},
+ {"I2S TX2", NULL, "CDC_IF TX2 MUX"},
+ {"I2S TX3", NULL, "CDC_IF TX3 MUX"},
+ {"I2S TX4", NULL, "CDC_IF TX4 MUX"},
+ {"I2S TX5", NULL, "CDC_IF TX5 MUX"},
+ {"I2S TX6", NULL, "CDC_IF TX6 MUX"},
+ {"I2S TX7", NULL, "CDC_IF TX7 MUX"},
+ {"I2S TX8", NULL, "CDC_IF TX8 MUX"},
+ {"I2S TX11", NULL, "CDC_IF TX11 MUX"},
+
+ {"I2S RX0 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX1 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX2 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX3 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX4 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX5 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX6 MUX", "AIF1_PB", "AIF1 PB"},
+ {"I2S RX7 MUX", "AIF1_PB", "AIF1 PB"},
+
+ {"I2S RX2 MUX", "AIF2_PB", "AIF2 PB"},
+ {"I2S RX3 MUX", "AIF2_PB", "AIF2 PB"},
+
+ {"I2S RX4 MUX", "AIF3_PB", "AIF3 PB"},
+ {"I2S RX5 MUX", "AIF3_PB", "AIF3 PB"},
+
+ {"I2S RX0", NULL, "I2S RX0 MUX"},
+ {"I2S RX1", NULL, "I2S RX1 MUX"},
+ {"I2S RX2", NULL, "I2S RX2 MUX"},
+ {"I2S RX3", NULL, "I2S RX3 MUX"},
+ {"I2S RX4", NULL, "I2S RX4 MUX"},
+ {"I2S RX5", NULL, "I2S RX5 MUX"},
+ {"I2S RX6", NULL, "I2S RX6 MUX"},
+ {"I2S RX7", NULL, "I2S RX7 MUX"},
+
+ /* CDC Rx interface with I2S */
+ {"CDC_IF RX0 MUX", "I2S RX0", "I2S RX0"},
+ {"CDC_IF RX1 MUX", "I2S RX1", "I2S RX1"},
+ {"CDC_IF RX2 MUX", "I2S RX2", "I2S RX2"},
+ {"CDC_IF RX3 MUX", "I2S RX3", "I2S RX3"},
+ {"CDC_IF RX4 MUX", "I2S RX4", "I2S RX4"},
+ {"CDC_IF RX5 MUX", "I2S RX5", "I2S RX5"},
+ {"CDC_IF RX6 MUX", "I2S RX6", "I2S RX6"},
+ {"CDC_IF RX7 MUX", "I2S RX7", "I2S RX7"},
+
};
const struct snd_soc_dapm_route tavil_audio_map[] = {
+ /*
+ * AIF CAP to Mixer routes are common
+ * for both SLIM as well as I2S
+ */
+
+ /* Virtual input widgets */
+ {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
+ {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
+ {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
+
/* WDMA3 */
{"WDMA3 PORT0 MUX", "DEC0", "ADC MUX0"},
{"WDMA3 PORT0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
@@ -195,26 +296,6 @@
{"MAD_CPE_OUT1", NULL, "MAD_CPE1"},
{"MAD_CPE_OUT2", NULL, "MAD_CPE2"},
- /* VI Feedback */
- {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
- {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
- {"AIF4 VI", NULL, "AIF4_VI Mixer"},
-
- /* CDC Tx interface with SLIMBUS */
- {"SLIM TX0", NULL, "CDC_IF TX0 MUX"},
- {"SLIM TX1", NULL, "CDC_IF TX1 MUX"},
- {"SLIM TX2", NULL, "CDC_IF TX2 MUX"},
- {"SLIM TX3", NULL, "CDC_IF TX3 MUX"},
- {"SLIM TX4", NULL, "CDC_IF TX4 MUX"},
- {"SLIM TX5", NULL, "CDC_IF TX5 MUX"},
- {"SLIM TX6", NULL, "CDC_IF TX6 MUX"},
- {"SLIM TX7", NULL, "CDC_IF TX7 MUX"},
- {"SLIM TX8", NULL, "CDC_IF TX8 MUX"},
- {"SLIM TX9", NULL, "CDC_IF TX9 MUX"},
- {"SLIM TX10", NULL, "CDC_IF TX10 MUX"},
- {"SLIM TX11", NULL, "CDC_IF TX11 MUX"},
- {"SLIM TX13", NULL, "CDC_IF TX13 MUX"},
-
{"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"},
{"CDC_IF TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
{"CDC_IF TX0 MUX", "DEC0_192", "ADC US MUX0"},
@@ -568,16 +649,6 @@
{"ADC3", NULL, "AMIC3"},
{"ADC4", NULL, "AMIC4_5 SEL"},
- /* CDC Rx interface with SLIMBUS */
- {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"},
- {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"},
- {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"},
- {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"},
- {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"},
- {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"},
- {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"},
- {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"},
-
{"RX INT0_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"},
{"RX INT0_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"},
{"RX INT0_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"},
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index b68cc9a..9083aa6 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -127,6 +127,7 @@
#define WCD934X_STRING_LEN 100
#define WCD934X_CDC_SIDETONE_IIR_COEFF_MAX 5
+#define WCD934X_CDC_REPEAT_WRITES_MAX 16
#define WCD934X_DIG_CORE_REG_MIN WCD934X_CDC_ANC0_CLK_RESET_CTL
#define WCD934X_DIG_CORE_REG_MAX 0xFFF
@@ -628,8 +629,8 @@
struct tavil_idle_detect_config idle_det_cfg;
int power_active_ref;
- int sidetone_coeff_array[IIR_MAX][BAND_MAX]
- [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX];
+ u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
+ [WCD934X_CDC_SIDETONE_IIR_COEFF_MAX * 4];
struct spi_device *spi;
struct platform_device *pdev_child_devices
@@ -896,7 +897,6 @@
struct wcd9xxx_anc_header *anc_head;
struct firmware_cal *hwdep_cal = NULL;
u32 anc_writes_size = 0;
- u32 anc_cal_size = 0;
int anc_size_remaining;
u32 *anc_ptr;
u16 reg;
@@ -985,8 +985,16 @@
goto err;
}
- anc_cal_size = anc_writes_size;
- for (i = 0; i < anc_writes_size; i++) {
+ i = 0;
+
+ if (!strcmp(w->name, "RX INT1 DAC") ||
+ !strcmp(w->name, "RX INT3 DAC"))
+ anc_writes_size = anc_writes_size / 2;
+ else if (!strcmp(w->name, "RX INT2 DAC") ||
+ !strcmp(w->name, "RX INT4 DAC"))
+ i = anc_writes_size / 2;
+
+ for (; i < anc_writes_size; i++) {
WCD934X_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
snd_soc_write(codec, reg, (val & mask));
}
@@ -1273,6 +1281,93 @@
return 0;
}
+static int i2s_tx_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = tavil_p->tx_port_value;
+ return 0;
+}
+
+static int i2s_tx_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_update *update = NULL;
+ struct soc_multi_mixer_control *mixer =
+ (struct soc_multi_mixer_control *)kcontrol->private_value;
+ u32 dai_id = widget->shift;
+ u32 port_id = mixer->shift;
+ u32 enable = ucontrol->value.integer.value[0];
+ u32 vtable;
+
+ dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
+ __func__,
+ widget->name, ucontrol->id.name, tavil_p->tx_port_value,
+ widget->shift, ucontrol->value.integer.value[0]);
+
+ mutex_lock(&tavil_p->codec_mutex);
+ if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) {
+ dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n",
+ __func__, dai_id);
+ mutex_unlock(&tavil_p->codec_mutex);
+ return -EINVAL;
+ }
+ vtable = vport_slim_check_table[dai_id];
+
+ switch (dai_id) {
+ case AIF1_CAP:
+ case AIF2_CAP:
+ case AIF3_CAP:
+ /* only add to the list if value not set */
+ if (enable && !(tavil_p->tx_port_value & 1 << port_id)) {
+ if (wcd9xxx_tx_vport_validation(vtable, port_id,
+ tavil_p->dai, NUM_CODEC_DAIS)) {
+ dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
+ __func__, port_id);
+ mutex_unlock(&tavil_p->codec_mutex);
+ return 0;
+ }
+ tavil_p->tx_port_value |= 1 << port_id;
+ } else if (!enable && (tavil_p->tx_port_value &
+ 1 << port_id)) {
+ tavil_p->tx_port_value &= ~(1 << port_id);
+ } else {
+ if (enable)
+ dev_dbg(codec->dev, "%s: TX%u port is used by\n"
+ "this virtual port\n",
+ __func__, port_id);
+ else
+ dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
+ "this virtual port\n",
+ __func__, port_id);
+ /* avoid update power function */
+ mutex_unlock(&tavil_p->codec_mutex);
+ return 0;
+ }
+ break;
+ default:
+ dev_err(codec->dev, "Unknown AIF %d\n", dai_id);
+ mutex_unlock(&tavil_p->codec_mutex);
+ return -EINVAL;
+ }
+ dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n",
+ __func__, widget->name, widget->sname, tavil_p->tx_port_value,
+ widget->shift);
+
+ mutex_unlock(&tavil_p->codec_mutex);
+ snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
+
+ return 0;
+}
+
static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -1477,10 +1572,193 @@
}
}
-static int tavil_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
+static int tavil_codec_set_i2s_rx_ch(struct snd_soc_dapm_widget *w,
+ u32 i2s_reg, bool up)
+{
+ int rx_fs_rate = -EINVAL;
+ int i2s_bit_mode;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_codec_dai_data *dai;
+
+ dai = &tavil_p->dai[w->shift];
+ dev_dbg(tavil_p->dev, "%s: %d up/down, %d width, %d rate\n",
+ __func__, up, dai->bit_width, dai->rate);
+ if (up) {
+ if (dai->bit_width == 16)
+ i2s_bit_mode = 0x01;
+ else
+ i2s_bit_mode = 0x00;
+
+ switch (dai->rate) {
+ case 8000:
+ rx_fs_rate = 0;
+ break;
+ case 16000:
+ rx_fs_rate = 1;
+ break;
+ case 32000:
+ rx_fs_rate = 2;
+ break;
+ case 48000:
+ rx_fs_rate = 3;
+ break;
+ case 96000:
+ rx_fs_rate = 4;
+ break;
+ case 192000:
+ rx_fs_rate = 5;
+ break;
+ case 384000:
+ rx_fs_rate = 6;
+ break;
+ default:
+ dev_err(tavil_p->dev, "%s: Invalid RX sample rate: %d\n",
+ __func__, dai->rate);
+ return -EINVAL;
+ };
+ snd_soc_update_bits(codec, i2s_reg,
+ 0x40, i2s_bit_mode << 6);
+ snd_soc_update_bits(codec, i2s_reg,
+ 0x3c, (rx_fs_rate << 2));
+ } else {
+ snd_soc_update_bits(codec, i2s_reg,
+ 0x40, 0x00);
+ snd_soc_update_bits(codec, i2s_reg,
+ 0x3c, 0x00);
+ }
+ return 0;
+}
+
+static int tavil_codec_set_i2s_tx_ch(struct snd_soc_dapm_widget *w,
+ u32 i2s_reg, bool up)
+{
+ int tx_fs_rate = -EINVAL;
+ int i2s_bit_mode;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_codec_dai_data *dai;
+
+ dai = &tavil_p->dai[w->shift];
+ if (up) {
+ if (dai->bit_width == 16)
+ i2s_bit_mode = 0x01;
+ else
+ i2s_bit_mode = 0x00;
+
+ snd_soc_update_bits(codec, i2s_reg, 0x40, i2s_bit_mode << 6);
+
+ switch (dai->rate) {
+ case 8000:
+ tx_fs_rate = 0;
+ break;
+ case 16000:
+ tx_fs_rate = 1;
+ break;
+ case 32000:
+ tx_fs_rate = 2;
+ break;
+ case 48000:
+ tx_fs_rate = 3;
+ break;
+ case 96000:
+ tx_fs_rate = 4;
+ break;
+ case 192000:
+ tx_fs_rate = 5;
+ break;
+ case 384000:
+ tx_fs_rate = 6;
+ break;
+ default:
+ dev_err(tavil_p->dev, "%s: Invalid sample rate: %d\n",
+ __func__, dai->rate);
+ return -EINVAL;
+ };
+
+ snd_soc_update_bits(codec, i2s_reg, 0x3c, tx_fs_rate << 2);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX0_CFG,
+ 0x03, 0x01);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX0_CFG,
+ 0x0C, 0x01);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX1_0_CFG,
+ 0x03, 0x01);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX1_1_CFG,
+ 0x05, 0x05);
+ } else {
+ snd_soc_update_bits(codec, i2s_reg, 0x40, 0x00);
+ snd_soc_update_bits(codec, i2s_reg, 0x3c, 0x00);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX0_CFG,
+ 0x03, 0x00);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX0_CFG,
+ 0x0C, 0x00);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX1_0_CFG,
+ 0x03, 0x00);
+
+ snd_soc_update_bits(codec,
+ WCD934X_DATA_HUB_I2S_TX1_1_CFG,
+ 0x05, 0x00);
+ }
+ return 0;
+}
+
+static int tavil_codec_enable_rx_i2c(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+ int ret = -EINVAL;
+ u32 i2s_reg;
+
+ switch (tavil_p->rx_port_value[w->shift]) {
+ case AIF1_PB:
+ case AIF1_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL;
+ break;
+ case AIF2_PB:
+ case AIF2_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL;
+ break;
+ case AIF3_PB:
+ case AIF3_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL;
+ break;
+ default:
+ dev_err(codec->dev, "%s Invalid i2s Id received", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ ret = tavil_codec_set_i2s_rx_ch(w, i2s_reg, true);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = tavil_codec_set_i2s_rx_ch(w, i2s_reg, false);
+ break;
+ }
+
+ return ret;
+}
+
+static int tavil_codec_enable_rx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
struct wcd9xxx *core;
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
@@ -1499,6 +1777,11 @@
dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n",
__func__, w->name, w->shift, event);
+ if (tavil_p->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
+ ret = tavil_codec_enable_rx_i2c(w, kcontrol, event);
+ return ret;
+ }
+
switch (event) {
case SND_SOC_DAPM_POST_PMU:
dai->bus_down_in_recovery = false;
@@ -1530,12 +1813,51 @@
return ret;
}
-static int tavil_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
+static int tavil_codec_enable_tx_i2c(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+ int ret = -EINVAL;
+ u32 i2s_reg;
+
+ switch (tavil_p->rx_port_value[w->shift]) {
+ case AIF1_PB:
+ case AIF1_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL;
+ break;
+ case AIF2_PB:
+ case AIF2_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL;
+ break;
+ case AIF3_PB:
+ case AIF3_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL;
+ break;
+ default:
+ dev_err(codec->dev, "%s Invalid i2s Id received", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ ret = tavil_codec_set_i2s_tx_ch(w, i2s_reg, true);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = tavil_codec_set_i2s_tx_ch(w, i2s_reg, false);
+ break;
+ }
+
+ return ret;
+}
+
+static int tavil_codec_enable_tx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
struct wcd9xxx_codec_dai_data *dai;
struct wcd9xxx *core;
int ret = 0;
@@ -1548,6 +1870,11 @@
dai = &tavil_p->dai[w->shift];
core = dev_get_drvdata(codec->dev->parent);
+ if (tavil_p->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
+ ret = tavil_codec_enable_tx_i2c(w, kcontrol, event);
+ return ret;
+ }
+
switch (event) {
case SND_SOC_DAPM_POST_PMU:
dai->bus_down_in_recovery = false;
@@ -1858,6 +2185,18 @@
tavil_codec_set_tx_hold(tavil->codec, WCD934X_ANA_AMIC4, false);
}
+
+static void tavil_ocp_control(struct snd_soc_codec *codec, bool enable)
+{
+ if (enable) {
+ snd_soc_update_bits(codec, WCD934X_HPH_OCP_CTL, 0x10, 0x10);
+ snd_soc_update_bits(codec, WCD934X_RX_OCP_CTL, 0x0F, 0x02);
+ } else {
+ snd_soc_update_bits(codec, WCD934X_RX_OCP_CTL, 0x0F, 0x0F);
+ snd_soc_update_bits(codec, WCD934X_HPH_OCP_CTL, 0x10, 0x00);
+ }
+}
+
static int tavil_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
@@ -1871,6 +2210,7 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ tavil_ocp_control(codec, false);
if (TAVIL_IS_1_0(tavil->wcd9xxx))
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
0x06, (0x03 << 1));
@@ -1967,8 +2307,10 @@
ret = tavil_codec_enable_anc(w, kcontrol, event);
}
tavil_codec_override(codec, tavil->hph_mode, event);
+ tavil_ocp_control(codec, true);
break;
case SND_SOC_DAPM_PRE_PMD:
+ tavil_ocp_control(codec, false);
blocking_notifier_call_chain(&tavil->mbhc->notifier,
WCD_EVENT_PRE_HPHR_PA_OFF,
&tavil->mbhc->wcd_mbhc);
@@ -2007,6 +2349,7 @@
WCD934X_CDC_RX2_RX_PATH_CFG0,
0x10, 0x00);
}
+ tavil_ocp_control(codec, true);
break;
};
@@ -2026,6 +2369,7 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ tavil_ocp_control(codec, false);
if (TAVIL_IS_1_0(tavil->wcd9xxx))
snd_soc_update_bits(codec, WCD934X_HPH_REFBUFF_LP_CTL,
0x06, (0x03 << 1));
@@ -2119,8 +2463,10 @@
ret = tavil_codec_enable_anc(w, kcontrol, event);
}
tavil_codec_override(codec, tavil->hph_mode, event);
+ tavil_ocp_control(codec, true);
break;
case SND_SOC_DAPM_PRE_PMD:
+ tavil_ocp_control(codec, false);
blocking_notifier_call_chain(&tavil->mbhc->notifier,
WCD_EVENT_PRE_HPHL_PA_OFF,
&tavil->mbhc->wcd_mbhc);
@@ -2160,6 +2506,7 @@
snd_soc_update_bits(codec,
WCD934X_CDC_RX1_RX_PATH_CFG0, 0x10, 0x00);
}
+ tavil_ocp_control(codec, true);
break;
};
@@ -2234,6 +2581,83 @@
return 0;
}
+static int i2s_rx_mux_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] =
+ tavil_p->rx_port_value[widget->shift];
+ return 0;
+}
+
+static int i2s_rx_mux_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct snd_soc_dapm_update *update = NULL;
+ unsigned int rx_port_value;
+ u32 port_id = widget->shift;
+
+ tavil_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
+ rx_port_value = tavil_p->rx_port_value[port_id];
+
+ dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
+ __func__, widget->name, ucontrol->id.name,
+ rx_port_value, widget->shift,
+ ucontrol->value.integer.value[0]);
+
+ snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
+ rx_port_value, e, update);
+ return 0;
+}
+
+static int tavil_codec_enable_i2s_path(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ int ret = 0;
+ u32 i2s_reg;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tavil_priv *tavil_p = snd_soc_codec_get_drvdata(codec);
+
+ switch (tavil_p->rx_port_value[w->shift]) {
+ case AIF1_PB:
+ case AIF1_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL;
+ break;
+ case AIF2_PB:
+ case AIF2_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL;
+ break;
+ case AIF3_PB:
+ case AIF3_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL;
+ break;
+ default:
+ dev_err(codec->dev, "%s Invalid i2s Id received", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = snd_soc_update_bits(codec, i2s_reg, 0x01, 0x01);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = snd_soc_update_bits(codec, i2s_reg, 0x01, 0x00);
+ break;
+ }
+
+ return ret;
+}
+
static int tavil_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol,
int event)
@@ -2533,6 +2957,11 @@
tavil = snd_soc_codec_get_drvdata(codec);
+ if (!tavil->swr.ctrl_data)
+ return -EINVAL;
+ if (!tavil->swr.ctrl_data[0].swr_pdev)
+ return -EINVAL;
+
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) ||
@@ -3715,7 +4144,7 @@
if (adc_mux_n < 3) {
adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
- adc_mux_n;
+ 2 * adc_mux_n;
mask = 0x03;
shift = 0;
amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
@@ -3728,7 +4157,7 @@
2 * adc_mux_n;
} else if (adc_mux_n < 7) {
adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
- (adc_mux_n - 4);
+ 2 * (adc_mux_n - 4);
mask = 0x0C;
shift = 2;
amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
@@ -3741,24 +4170,25 @@
adc_mux_n - 4;
} else if (adc_mux_n < 12) {
adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
- ((adc_mux_n == 8) ? (adc_mux_n - 8) :
- (adc_mux_n - 9));
+ 2 * (((adc_mux_n == 8) ? (adc_mux_n - 8) :
+ (adc_mux_n - 9)));
mask = 0x30;
shift = 4;
- amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
- adc_mux_n - 4;
+ amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0 +
+ ((adc_mux_n == 8) ? (adc_mux_n - 8) :
+ (adc_mux_n - 9));
} else if (adc_mux_n < 13) {
adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1;
mask = 0x30;
shift = 4;
amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
- adc_mux_n - 4;
+ adc_mux_n - 5;
} else {
adc_mux_in_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1;
mask = 0xC0;
shift = 6;
amic_mux_sel_reg = WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
- adc_mux_n - 4;
+ adc_mux_n - 5;
}
is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift)
@@ -4927,6 +5357,36 @@
return 0;
}
+static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx,
+ int band_idx)
+{
+ u16 reg_add;
+ int no_of_reg = 0;
+
+ regmap_write(tavil->wcd9xxx->regmap,
+ (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+ reg_add = WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
+
+ if (tavil->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+ return;
+ /*
+ * Since wcd9xxx_slim_write_repeat() supports only maximum of 16
+ * registers at a time, split total 20 writes(5 coefficients per
+ * band and 4 writes per coefficient) into 16 and 4.
+ */
+ no_of_reg = WCD934X_CDC_REPEAT_WRITES_MAX;
+ wcd9xxx_slim_write_repeat(tavil->wcd9xxx, reg_add, no_of_reg,
+ &tavil->sidetone_coeff_array[iir_idx][band_idx][0]);
+
+ no_of_reg = (WCD934X_CDC_SIDETONE_IIR_COEFF_MAX * 4) -
+ WCD934X_CDC_REPEAT_WRITES_MAX;
+ wcd9xxx_slim_write_repeat(tavil->wcd9xxx, reg_add, no_of_reg,
+ &tavil->sidetone_coeff_array[iir_idx][band_idx]
+ [WCD934X_CDC_REPEAT_WRITES_MAX]);
+}
+
static int tavil_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -4951,6 +5411,7 @@
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tavil_priv *tavil = snd_soc_codec_get_drvdata(codec);
int iir_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->reg;
int band_idx = ((struct soc_multi_mixer_control *)
@@ -4959,6 +5420,8 @@
int value = ucontrol->value.integer.value[0];
u16 iir_reg = WCD934X_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
+ tavil_restore_iir_coeff(tavil, iir_idx, band_idx);
+
/* Mask first 5 bits, 6-8 are reserved */
snd_soc_update_bits(codec, iir_reg, (1 << band_idx),
(value << band_idx));
@@ -5085,7 +5548,7 @@
kcontrol->private_value)->reg;
int band_idx = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
- int coeff_idx;
+ int coeff_idx, idx = 0;
/*
* Mask top bit it is reserved
@@ -5098,11 +5561,19 @@
/* Store the coefficients in sidetone coeff array */
for (coeff_idx = 0; coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
coeff_idx++) {
- tavil->sidetone_coeff_array[iir_idx][band_idx][coeff_idx] =
- ucontrol->value.integer.value[coeff_idx];
- set_iir_band_coeff(codec, iir_idx, band_idx,
- tavil->sidetone_coeff_array[iir_idx][band_idx]
- [coeff_idx]);
+ uint32_t value = ucontrol->value.integer.value[coeff_idx];
+
+ set_iir_band_coeff(codec, iir_idx, band_idx, value);
+
+ /* Four 8 bit values(one 32 bit) per coefficient */
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value & 0xFF);
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value >> 8) & 0xFF;
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value >> 16) & 0xFF;
+ tavil->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value >> 24) & 0xFF;
}
pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
@@ -5123,33 +5594,6 @@
return 0;
}
-static void tavil_restore_iir_coeff(struct tavil_priv *tavil, int iir_idx)
-{
- int band_idx = 0, coeff_idx = 0;
- struct snd_soc_codec *codec = tavil->codec;
-
- /*
- * snd_soc_write call crashes at rmmod if there is no machine
- * driver and hence no codec pointer available
- */
- if (!codec)
- return;
-
- for (band_idx = 0; band_idx < BAND_MAX; band_idx++) {
- snd_soc_write(codec,
- (WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
- (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
-
- for (coeff_idx = 0;
- coeff_idx < WCD934X_CDC_SIDETONE_IIR_COEFF_MAX;
- coeff_idx++) {
- set_iir_band_coeff(codec, iir_idx, band_idx,
- tavil->sidetone_coeff_array[iir_idx][band_idx]
- [coeff_idx]);
- }
- }
-}
-
static int tavil_compander_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -6285,29 +6729,45 @@
"ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB"
};
+static const char *const i2s_rx01_mux_text[] = {
+ "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
+};
+
+static const char *const i2s_rx23_mux_text[] = {
+ "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
+};
+
+static const char *const i2s_rx45_mux_text[] = {
+ "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
+};
+
+static const char *const i2s_rx67_mux_text[] = {
+ "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB"
+};
+
static const char *const cdc_if_rx0_mux_text[] = {
- "SLIM RX0", "I2S_0 RX0"
+ "SLIM RX0", "I2S RX0"
};
static const char *const cdc_if_rx1_mux_text[] = {
- "SLIM RX1", "I2S_0 RX1"
+ "SLIM RX1", "I2S RX1"
};
static const char *const cdc_if_rx2_mux_text[] = {
- "SLIM RX2", "I2S_0 RX2"
+ "SLIM RX2", "I2S RX2"
};
static const char *const cdc_if_rx3_mux_text[] = {
- "SLIM RX3", "I2S_0 RX3"
+ "SLIM RX3", "I2S RX3"
};
static const char *const cdc_if_rx4_mux_text[] = {
- "SLIM RX4", "I2S_0 RX4"
+ "SLIM RX4", "I2S RX4"
};
static const char *const cdc_if_rx5_mux_text[] = {
- "SLIM RX5", "I2S_0 RX5"
+ "SLIM RX5", "I2S RX5"
};
static const char *const cdc_if_rx6_mux_text[] = {
- "SLIM RX6", "I2S_0 RX6"
+ "SLIM RX6", "I2S RX6"
};
static const char *const cdc_if_rx7_mux_text[] = {
- "SLIM RX7", "I2S_0 RX7"
+ "SLIM RX7", "I2S RX7"
};
static const char * const asrc0_mux_text[] = {
@@ -6370,7 +6830,7 @@
tavil_vi_feed_mixer_get, tavil_vi_feed_mixer_put),
};
-static const struct snd_kcontrol_new aif1_cap_mixer[] = {
+static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = {
SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0,
slim_tx_mixer_get, slim_tx_mixer_put),
SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0,
@@ -6399,7 +6859,24 @@
slim_tx_mixer_get, slim_tx_mixer_put),
};
-static const struct snd_kcontrol_new aif2_cap_mixer[] = {
+static const struct snd_kcontrol_new aif1_i2s_cap_mixer[] = {
+ SOC_SINGLE_EXT("I2S TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX2", SND_SOC_NOPM, WCD934X_TX2, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX3", SND_SOC_NOPM, WCD934X_TX3, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX4", SND_SOC_NOPM, WCD934X_TX4, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX5", SND_SOC_NOPM, WCD934X_TX5, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX6", SND_SOC_NOPM, WCD934X_TX6, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX7", SND_SOC_NOPM, WCD934X_TX7, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif2_slim_cap_mixer[] = {
SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0,
slim_tx_mixer_get, slim_tx_mixer_put),
SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0,
@@ -6428,7 +6905,14 @@
slim_tx_mixer_get, slim_tx_mixer_put),
};
-static const struct snd_kcontrol_new aif3_cap_mixer[] = {
+static const struct snd_kcontrol_new aif2_i2s_cap_mixer[] = {
+ SOC_SINGLE_EXT("I2S TX8", SND_SOC_NOPM, WCD934X_TX8, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX11", SND_SOC_NOPM, WCD934X_TX11, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif3_slim_cap_mixer[] = {
SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0,
slim_tx_mixer_get, slim_tx_mixer_put),
SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0,
@@ -6457,9 +6941,16 @@
slim_tx_mixer_get, slim_tx_mixer_put),
};
-static const struct snd_kcontrol_new aif4_mad_mixer[] = {
+static const struct snd_kcontrol_new aif3_i2s_cap_mixer[] = {
+ SOC_SINGLE_EXT("I2S TX0", SND_SOC_NOPM, WCD934X_TX0, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+ SOC_SINGLE_EXT("I2S TX1", SND_SOC_NOPM, WCD934X_TX1, 1, 0,
+ i2s_tx_mixer_get, i2s_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif4_slim_mad_mixer[] = {
SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD934X_TX13, 1, 0,
- slim_tx_mixer_get, slim_tx_mixer_put),
+ slim_tx_mixer_get, slim_tx_mixer_put),
};
WCD_DAPM_ENUM_EXT(slim_rx0, SND_SOC_NOPM, 0, slim_rx_mux_text,
@@ -6768,6 +7259,22 @@
WCD_DAPM_ENUM(anc0_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text);
WCD_DAPM_ENUM(anc1_fb, WCD934X_CDC_RX_INP_MUX_ANC_CFG0, 3, anc1_fb_mux_text);
+WCD_DAPM_ENUM_EXT(i2s_rx0, SND_SOC_NOPM, 0, i2s_rx01_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx1, SND_SOC_NOPM, 0, i2s_rx01_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx2, SND_SOC_NOPM, 0, i2s_rx23_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx3, SND_SOC_NOPM, 0, i2s_rx23_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx4, SND_SOC_NOPM, 0, i2s_rx45_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx5, SND_SOC_NOPM, 0, i2s_rx45_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx6, SND_SOC_NOPM, 0, i2s_rx67_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
+WCD_DAPM_ENUM_EXT(i2s_rx7, SND_SOC_NOPM, 0, i2s_rx67_mux_text,
+ i2s_rx_mux_get, i2s_rx_mux_put);
WCD_DAPM_ENUM(wdma3_port0, WCD934X_DMA_WDMA3_PRT_CFG, 0, wdma3_port0_text);
WCD_DAPM_ENUM(wdma3_port1, WCD934X_DMA_WDMA3_PRT_CFG, 1, wdma3_port1_text);
@@ -6852,6 +7359,89 @@
static const struct snd_kcontrol_new wdma3_onoff_switch =
SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+static const struct snd_soc_dapm_widget tavil_dapm_i2s_widgets[] = {
+
+ SND_SOC_DAPM_MUX_E("I2S RX0 MUX", SND_SOC_NOPM, WCD934X_RX0, 0,
+ &i2s_rx0_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX1 MUX", SND_SOC_NOPM, WCD934X_RX1, 0,
+ &i2s_rx1_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX2 MUX", SND_SOC_NOPM, WCD934X_RX2, 0,
+ &i2s_rx2_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX3 MUX", SND_SOC_NOPM, WCD934X_RX3, 0,
+ &i2s_rx3_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX4 MUX", SND_SOC_NOPM, WCD934X_RX4, 0,
+ &i2s_rx4_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX5 MUX", SND_SOC_NOPM, WCD934X_RX5, 0,
+ &i2s_rx5_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX6 MUX", SND_SOC_NOPM, WCD934X_RX6, 0,
+ &i2s_rx6_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("I2S RX7 MUX", SND_SOC_NOPM, WCD934X_RX7, 0,
+ &i2s_rx7_mux, tavil_codec_enable_i2s_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("I2S RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I2S RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER_E("I2S TX0", SND_SOC_NOPM, WCD934X_TX0, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX1", SND_SOC_NOPM, WCD934X_TX1, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX2", SND_SOC_NOPM, WCD934X_TX2, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX3", SND_SOC_NOPM, WCD934X_TX3, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX4", SND_SOC_NOPM, WCD934X_TX4, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX5", SND_SOC_NOPM, WCD934X_TX5, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX6", SND_SOC_NOPM, WCD934X_TX6, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX7", SND_SOC_NOPM, WCD934X_TX7, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX8", SND_SOC_NOPM, WCD934X_TX8, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("I2S TX11", SND_SOC_NOPM, WCD934X_TX11, 0, NULL, 0,
+ tavil_codec_enable_i2s_path, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+ aif1_i2s_cap_mixer, ARRAY_SIZE(aif1_i2s_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
+ aif2_i2s_cap_mixer, ARRAY_SIZE(aif2_i2s_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
+ aif3_i2s_cap_mixer, ARRAY_SIZE(aif3_i2s_cap_mixer)),
+};
+
static int tavil_dsd_mixer_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -6917,19 +7507,22 @@
tavil_dsd_mixer_get, tavil_dsd_mixer_put),
};
-static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
- SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
- AIF1_PB, 0, tavil_codec_enable_slimrx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
- AIF2_PB, 0, tavil_codec_enable_slimrx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
- AIF3_PB, 0, tavil_codec_enable_slimrx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+static const struct snd_soc_dapm_widget tavil_dapm_slim_widgets[] = {
SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
- AIF4_PB, 0, tavil_codec_enable_slimrx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ AIF4_PB, 0, tavil_codec_enable_rx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
+ AIF4_VIFEED, 0,
+ tavil_codec_enable_slimvi_feedback,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0,
+ SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
+ aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
+ SND_SOC_DAPM_INPUT("VIINPUT"),
WCD_DAPM_MUX("SLIM RX0 MUX", WCD934X_RX0, slim_rx0),
WCD_DAPM_MUX("SLIM RX1 MUX", WCD934X_RX1, slim_rx1),
@@ -6949,6 +7542,31 @@
SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+ aif1_slim_cap_mixer,
+ ARRAY_SIZE(aif1_slim_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
+ aif2_slim_cap_mixer,
+ ARRAY_SIZE(aif2_slim_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
+ aif3_slim_cap_mixer,
+ ARRAY_SIZE(aif3_slim_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
+ aif4_slim_mad_mixer,
+ ARRAY_SIZE(aif4_slim_mad_mixer)),
+};
+
+static const struct snd_soc_dapm_widget tavil_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
+ AIF1_PB, 0, tavil_codec_enable_rx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
+ AIF2_PB, 0, tavil_codec_enable_rx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
+ AIF3_PB, 0, tavil_codec_enable_rx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
WCD_DAPM_MUX("CDC_IF RX0 MUX", WCD934X_RX0, cdc_if_rx0),
WCD_DAPM_MUX("CDC_IF RX1 MUX", WCD934X_RX1, cdc_if_rx1),
WCD_DAPM_MUX("CDC_IF RX2 MUX", WCD934X_RX2, cdc_if_rx2),
@@ -7237,33 +7855,14 @@
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
- AIF1_CAP, 0, tavil_codec_enable_slimtx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ AIF1_CAP, 0, tavil_codec_enable_tx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
- AIF2_CAP, 0, tavil_codec_enable_slimtx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ AIF2_CAP, 0, tavil_codec_enable_tx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
- AIF3_CAP, 0, tavil_codec_enable_slimtx,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
- SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
- aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
- SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
- aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
- SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
- aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
- SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
- aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
-
- SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
- AIF4_VIFEED, 0, tavil_codec_enable_slimvi_feedback,
- SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
-
- SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0,
- SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
- aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
- SND_SOC_DAPM_INPUT("VIINPUT"),
+ AIF3_CAP, 0, tavil_codec_enable_tx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0),
@@ -8047,6 +8646,43 @@
return 0;
}
+static int tavil_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ u32 i2s_reg;
+
+ switch (dai->id) {
+ case AIF1_PB:
+ case AIF1_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_0_CTL;
+ break;
+ case AIF2_PB:
+ case AIF2_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_1_CTL;
+ break;
+ case AIF3_PB:
+ case AIF3_CAP:
+ i2s_reg = WCD934X_DATA_HUB_I2S_2_CTL;
+ break;
+ default:
+ dev_err(dai->codec->dev, "%s Invalid i2s Id", __func__);
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ /* CPU is master */
+ snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x0);
+ break;
+ case SND_SOC_DAIFMT_CBM_CFM:
+ /* CPU is slave */
+ snd_soc_update_bits(dai->codec, i2s_reg, 0x2, 0x2);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
static struct snd_soc_dai_ops tavil_dai_ops = {
.startup = tavil_startup,
.shutdown = tavil_shutdown,
@@ -8056,13 +8692,21 @@
.get_channel_map = tavil_get_channel_map,
};
+static struct snd_soc_dai_ops tavil_i2s_dai_ops = {
+ .startup = tavil_startup,
+ .shutdown = tavil_shutdown,
+ .hw_params = tavil_hw_params,
+ .prepare = tavil_prepare,
+ .set_fmt = tavil_set_dai_fmt,
+};
+
static struct snd_soc_dai_ops tavil_vi_dai_ops = {
.hw_params = tavil_vi_hw_params,
.set_channel_map = tavil_set_channel_map,
.get_channel_map = tavil_get_channel_map,
};
-static struct snd_soc_dai_driver tavil_dai[] = {
+static struct snd_soc_dai_driver tavil_slim_dai[] = {
{
.name = "tavil_rx1",
.id = AIF1_PB,
@@ -8191,6 +8835,93 @@
},
};
+static struct snd_soc_dai_driver tavil_i2s_dai[] = {
+ {
+ .name = "tavil_i2s_rx1",
+ .id = AIF1_PB,
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .rates = WCD934X_RATES_MASK,
+ .formats = WCD934X_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tavil_i2s_dai_ops,
+ },
+ {
+ .name = "tavil_i2s_tx1",
+ .id = AIF1_CAP,
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .rates = WCD934X_RATES_MASK,
+ .formats = WCD934X_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tavil_i2s_dai_ops,
+ },
+ {
+ .name = "tavil_i2s_rx2",
+ .id = AIF2_PB,
+ .playback = {
+ .stream_name = "AIF2 Playback",
+ .rates = WCD934X_RATES_MASK,
+ .formats = WCD934X_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tavil_i2s_dai_ops,
+ },
+ {
+ .name = "tavil_i2s_tx2",
+ .id = AIF2_CAP,
+ .capture = {
+ .stream_name = "AIF2 Capture",
+ .rates = WCD934X_RATES_MASK,
+ .formats = WCD934X_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tavil_i2s_dai_ops,
+ },
+ {
+ .name = "tavil_i2s_rx3",
+ .id = AIF3_PB,
+ .playback = {
+ .stream_name = "AIF3 Playback",
+ .rates = WCD934X_RATES_MASK,
+ .formats = WCD934X_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tavil_i2s_dai_ops,
+ },
+ {
+ .name = "tavil_i2s_tx3",
+ .id = AIF3_CAP,
+ .capture = {
+ .stream_name = "AIF3 Capture",
+ .rates = WCD934X_RATES_MASK,
+ .formats = WCD934X_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tavil_i2s_dai_ops,
+ },
+};
+
static void tavil_codec_power_gate_digital_core(struct tavil_priv *tavil)
{
mutex_lock(&tavil->power_lock);
@@ -8250,8 +8981,6 @@
WCD934X_DIG_CORE_REG_MIN,
WCD934X_DIG_CORE_REG_MAX);
- tavil_restore_iir_coeff(tavil, IIR0);
- tavil_restore_iir_coeff(tavil, IIR1);
return 0;
}
@@ -8747,6 +9476,22 @@
}
}
+static const struct tavil_reg_mask_val tavil_codec_reg_i2c_defaults[] = {
+ {WCD934X_CLK_SYS_MCLK_PRG, 0x40, 0x00},
+ {WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x01},
+ {WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x00},
+ {WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x05, 0x05},
+ {WCD934X_DATA_HUB_RX0_CFG, 0x71, 0x31},
+ {WCD934X_DATA_HUB_RX1_CFG, 0x71, 0x31},
+ {WCD934X_DATA_HUB_RX2_CFG, 0x03, 0x01},
+ {WCD934X_DATA_HUB_RX3_CFG, 0x03, 0x01},
+ {WCD934X_DATA_HUB_I2S_TX0_CFG, 0x01, 0x01},
+ {WCD934X_DATA_HUB_I2S_TX0_CFG, 0x04, 0x01},
+ {WCD934X_DATA_HUB_I2S_TX1_0_CFG, 0x01, 0x01},
+ {WCD934X_DATA_HUB_I2S_TX1_1_CFG, 0x05, 0x05},
+ {WCD934X_CHIP_TIER_CTRL_ALT_FUNC_EN, 0x1, 0x1},
+};
+
static void tavil_update_reg_defaults(struct tavil_priv *tavil)
{
u32 i;
@@ -8758,6 +9503,15 @@
tavil_codec_reg_defaults[i].reg,
tavil_codec_reg_defaults[i].mask,
tavil_codec_reg_defaults[i].val);
+
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
+ for (i = 0; i < ARRAY_SIZE(tavil_codec_reg_i2c_defaults); i++) {
+ regmap_update_bits(wcd9xxx->regmap,
+ tavil_codec_reg_i2c_defaults[i].reg,
+ tavil_codec_reg_i2c_defaults[i].mask,
+ tavil_codec_reg_i2c_defaults[i].val);
+ }
+ }
}
static void tavil_update_cpr_defaults(struct tavil_priv *tavil)
@@ -9272,8 +10026,8 @@
else if (control->mclk_rate == WCD934X_MCLK_CLK_9P6MHZ)
snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
0x03, 0x01);
- wcd_resmgr_post_ssr_v2(tavil->resmgr);
tavil_update_reg_defaults(tavil);
+ wcd_resmgr_post_ssr_v2(tavil->resmgr);
tavil_codec_init_reg(tavil);
__tavil_enable_efuse_sensing(tavil);
tavil_mclk2_reg_defaults(tavil);
@@ -9402,19 +10156,29 @@
goto err_hwdep;
}
- snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map,
- ARRAY_SIZE(tavil_slim_audio_map));
for (i = 0; i < NUM_CODEC_DAIS; i++) {
INIT_LIST_HEAD(&tavil->dai[i].wcd9xxx_ch_list);
init_waitqueue_head(&tavil->dai[i].dai_wait);
}
- tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la =
- control->slim_slave->laddr;
- tavil_slimbus_slave_port_cfg.slave_dev_pgd_la =
- control->slim->laddr;
- tavil_slimbus_slave_port_cfg.slave_port_mapping[0] =
- WCD934X_TX13;
- tavil_init_slim_slave_cfg(codec);
+
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
+ snd_soc_dapm_new_controls(dapm, tavil_dapm_slim_widgets,
+ ARRAY_SIZE(tavil_dapm_slim_widgets));
+ snd_soc_dapm_add_routes(dapm, tavil_slim_audio_map,
+ ARRAY_SIZE(tavil_slim_audio_map));
+ tavil_slimbus_slave_port_cfg.slave_dev_intfdev_la =
+ control->slim_slave->laddr;
+ tavil_slimbus_slave_port_cfg.slave_dev_pgd_la =
+ control->slim->laddr;
+ tavil_slimbus_slave_port_cfg.slave_port_mapping[0] =
+ WCD934X_TX13;
+ tavil_init_slim_slave_cfg(codec);
+ } else {
+ snd_soc_dapm_new_controls(dapm, tavil_dapm_i2s_widgets,
+ ARRAY_SIZE(tavil_dapm_i2s_widgets));
+ snd_soc_dapm_add_routes(dapm, tavil_i2s_audio_map,
+ ARRAY_SIZE(tavil_i2s_audio_map));
+ }
control->num_rx_port = WCD934X_RX_MAX;
control->rx_chs = ptr;
@@ -9469,9 +10233,11 @@
snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
- snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
- snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
- snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
+ snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
+ }
snd_soc_dapm_sync(dapm);
@@ -9577,6 +10343,39 @@
};
#endif
+static int wcd9xxx_swrm_i2c_bulk_write(struct wcd9xxx *wcd9xxx,
+ struct wcd9xxx_reg_val *bulk_reg,
+ size_t len)
+{
+ int i, ret = 0;
+ unsigned short swr_wr_addr_base;
+ unsigned short swr_wr_data_base;
+
+ swr_wr_addr_base = WCD934X_SWR_AHB_BRIDGE_WR_ADDR_0;
+ swr_wr_data_base = WCD934X_SWR_AHB_BRIDGE_WR_DATA_0;
+
+ for (i = 0; i < (len * 2); i += 2) {
+ /* First Write the Data to register */
+ ret = regmap_bulk_write(wcd9xxx->regmap,
+ swr_wr_data_base, bulk_reg[i].buf, 4);
+ if (ret < 0) {
+ dev_err(wcd9xxx->dev, "%s: WR Data Failure\n",
+ __func__);
+ break;
+ }
+ /* Next Write Address */
+ ret = regmap_bulk_write(wcd9xxx->regmap,
+ swr_wr_addr_base,
+ bulk_reg[i+1].buf, 4);
+ if (ret < 0) {
+ dev_err(wcd9xxx->dev, "%s: WR Addr Failure\n",
+ __func__);
+ break;
+ }
+ }
+ return ret;
+}
+
static int tavil_swrm_read(void *handle, int reg)
{
struct tavil_priv *tavil;
@@ -9655,8 +10454,11 @@
}
mutex_lock(&tavil->swr.write_mutex);
- ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
- (len * 2), false);
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+ ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
+ (len * 2), false);
+ else
+ ret = wcd9xxx_swrm_i2c_bulk_write(wcd9xxx, bulk_reg, len);
if (ret) {
dev_err(tavil->dev, "%s: swrm bulk write failed, ret: %d\n",
__func__, ret);
@@ -9695,7 +10497,10 @@
bulk_reg[1].bytes = 4;
mutex_lock(&tavil->swr.write_mutex);
- ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+ ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
+ else
+ ret = wcd9xxx_swrm_i2c_bulk_write(wcd9xxx, bulk_reg, 1);
if (ret < 0)
dev_err(tavil->dev, "%s: WR Data Failure\n", __func__);
mutex_unlock(&tavil->swr.write_mutex);
@@ -10081,6 +10886,21 @@
if (!tavil)
return -ENOMEM;
+ tavil->intf_type = wcd9xxx_get_intf_type();
+ if (tavil->intf_type != WCD9XXX_INTERFACE_TYPE_I2C &&
+ tavil->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
+ devm_kfree(&pdev->dev, tavil);
+ return -EPROBE_DEFER;
+ }
+
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C) {
+ if (apr_get_subsys_state() == APR_SUBSYS_DOWN) {
+ dev_dbg(&pdev->dev, "%s: dsp down\n", __func__);
+ devm_kfree(&pdev->dev, tavil);
+ return -EPROBE_DEFER;
+ }
+ }
+
platform_set_drvdata(pdev, tavil);
tavil->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
@@ -10161,8 +10981,15 @@
tavil_update_cpr_defaults(tavil);
/* Register with soc framework */
- ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil,
- tavil_dai, ARRAY_SIZE(tavil_dai));
+ if (tavil->intf_type == WCD9XXX_INTERFACE_TYPE_I2C)
+ ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil,
+ tavil_i2s_dai,
+ ARRAY_SIZE(tavil_i2s_dai));
+ else
+ ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_tavil,
+ tavil_slim_dai,
+ ARRAY_SIZE(tavil_slim_dai));
+
if (ret) {
dev_err(&pdev->dev, "%s: Codec registration failed\n",
__func__);
diff --git a/asoc/codecs/wcd9360/Android.mk b/asoc/codecs/wcd9360/Android.mk
new file mode 100644
index 0000000..bf65cff
--- /dev/null
+++ b/asoc/codecs/wcd9360/Android.mk
@@ -0,0 +1,50 @@
+# Android makefile for audio kernel modules
+
+# Assume no targets will be supported
+
+# Check if this driver needs be built for current target
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
+AUDIO_CHIPSET := audio
+# Build/Package only in case of supported target
+ifeq ($(call is-board-platform-in-list,msmnile),true)
+
+LOCAL_PATH := $(call my-dir)
+
+# This makefile is only for DLKM
+ifneq ($(findstring vendor,$(LOCAL_PATH)),)
+
+ifneq ($(findstring opensource,$(LOCAL_PATH)),)
+ AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/vendor/qcom/opensource/audio-kernel
+endif # opensource
+
+DLKM_DIR := $(TOP)/device/qcom/common/dlkm
+
+# Build audio.ko as $(AUDIO_CHIPSET)_audio.ko
+###########################################################
+# This is set once per LOCAL_PATH, not per (kernel) module
+KBUILD_OPTIONS := AUDIO_ROOT=$(AUDIO_BLD_DIR)
+
+# We are actually building audio.ko here, as per the
+# requirement we are specifying <chipset>_audio.ko as LOCAL_MODULE.
+# This means we need to rename the module to <chipset>_audio.ko
+# after audio.ko is built.
+KBUILD_OPTIONS += MODNAME=wcd9360_dlkm
+KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
+KBUILD_OPTIONS += $(AUDIO_SELECT)
+
+###########################################################
+include $(CLEAR_VARS)
+LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9360.ko
+LOCAL_MODULE_KBUILD_NAME := wcd9360_dlkm.ko
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_DEBUG_ENABLE := true
+LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
+include $(DLKM_DIR)/AndroidKernelModule.mk
+###########################################################
+###########################################################
+
+endif # DLKM check
+endif # supported target check
diff --git a/asoc/codecs/wcd9360/Kbuild b/asoc/codecs/wcd9360/Kbuild
new file mode 100644
index 0000000..a1b5fe4
--- /dev/null
+++ b/asoc/codecs/wcd9360/Kbuild
@@ -0,0 +1,104 @@
+# We can build either as part of a standalone Kernel build or as
+# an external module. Determine which mechanism is being used
+ifeq ($(MODNAME),)
+ KERNEL_BUILD := 1
+else
+ KERNEL_BUILD := 0
+endif
+
+
+
+ifeq ($(KERNEL_BUILD), 1)
+ # These are configurable via Kconfig for kernel-based builds
+ # Need to explicitly configure for Android-based builds
+ AUDIO_BLD_DIR := $(ANDROID_BUILD_TOP)/kernel/msm-4.14
+ AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
+endif
+
+# As per target team, build is done as follows:
+# Defconfig : build with default flags
+# Slub : defconfig + CONFIG_SLUB_DEBUG := y +
+# CONFIG_SLUB_DEBUG_ON := y + CONFIG_PAGE_POISONING := y
+# Perf : Using appropriate msmXXXX-perf_defconfig
+#
+# Shipment builds (user variants) should not have any debug feature
+# enabled. This is identified using 'TARGET_BUILD_VARIANT'. Slub builds
+# are identified using the CONFIG_SLUB_DEBUG_ON configuration. Since
+# there is no other way to identify defconfig builds, QTI internal
+# representation of perf builds (identified using the string 'perf'),
+# is used to identify if the build is a slub or defconfig one. This
+# way no critical debug feature will be enabled for perf and shipment
+# builds. Other OEMs are also protected using the TARGET_BUILD_VARIANT
+# config.
+
+############ UAPI ############
+UAPI_DIR := uapi
+UAPI_INC := -I$(AUDIO_ROOT)/include/$(UAPI_DIR)
+
+############ COMMON ############
+COMMON_DIR := include
+COMMON_INC := -I$(AUDIO_ROOT)/$(COMMON_DIR)
+
+############ WCD934X ############
+
+# for WCD9360 Codec
+ifdef CONFIG_SND_SOC_WCD9360
+ WCD9360_OBJS += wcd9360.o
+ WCD9360_OBJS += wcd9360-dsp-cntl.o
+endif
+
+LINUX_INC += -Iinclude/linux
+
+INCS += $(COMMON_INC) \
+ $(UAPI_INC)
+
+EXTRA_CFLAGS += $(INCS)
+
+
+CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \
+ -DANI_LITTLE_BIT_ENDIAN \
+ -DDOT11F_LITTLE_ENDIAN_HOST \
+ -DANI_COMPILER_TYPE_GCC \
+ -DANI_OS_TYPE_ANDROID=6 \
+ -DPTT_SOCK_SVC_ENABLE \
+ -Wall\
+ -Werror\
+ -D__linux__
+
+KBUILD_CPPFLAGS += $(CDEFINES)
+
+# Currently, for versions of gcc which support it, the kernel Makefile
+# is disabling the maybe-uninitialized warning. Re-enable it for the
+# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it
+# will override the kernel settings.
+ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y)
+EXTRA_CFLAGS += -Wmaybe-uninitialized
+endif
+#EXTRA_CFLAGS += -Wmissing-prototypes
+
+ifeq ($(call cc-option-yn, -Wheader-guard),y)
+EXTRA_CFLAGS += -Wheader-guard
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
+endif
+
+# Module information used by KBuild framework
+obj-$(CONFIG_SND_SOC_WCD9360) += wcd9360_dlkm.o
+wcd9360_dlkm-y := $(WCD9360_OBJS)
+
+# inject some build related information
+DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"
diff --git a/asoc/codecs/wcd9360/wcd9360-defaults.h b/asoc/codecs/wcd9360/wcd9360-defaults.h
new file mode 100644
index 0000000..5557dda
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360-defaults.h
@@ -0,0 +1,2231 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __WCD9360_DEFAULTS_H__
+#define __WCD9360_DEFAULTS_H__
+
+#include <linux/types.h>
+#include <asoc/wcd9360-registers.h>
+
+#define WCD9360_REG(reg) ((reg) & 0xFF)
+
+static const struct reg_default wcd9360_defaults[] = {
+{WCD9360_PAGE0_PAGE_REGISTER, 0x00},
+{WCD9360_CODEC_RPM_CLK_BYPASS, 0x00},
+{WCD9360_CODEC_RPM_CLK_GATE, 0x1F},
+{WCD9360_CODEC_RPM_CLK_MCLK_CFG, 0x00},
+{WCD9360_CODEC_RPM_CLK_MCLK2_CFG, 0x02},
+{WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL, 0x00},
+{WCD9360_CODEC_RPM_RST_CTL, 0x00},
+{WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04},
+{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0, 0x10},
+{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1, 0x60},
+{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2, 0x93},
+{WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3, 0x01},
+{WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x10},
+{WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0, 0x00},
+{WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1, 0x00},
+{WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS, 0x00},
+{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO, 0x0D},
+{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1, 0x00},
+{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2, 0x00},
+{WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3, 0x00},
+{WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL, 0x44},
+{WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE, 0x00},
+{WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN, 0x00},
+{WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE, 0x00},
+{WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA, 0x00},
+{WCD9360_DATA_HUB_RX0_CFG, 0x00},
+{WCD9360_DATA_HUB_RX1_CFG, 0x00},
+{WCD9360_DATA_HUB_RX2_CFG, 0x00},
+{WCD9360_DATA_HUB_RX3_CFG, 0x00},
+{WCD9360_DATA_HUB_RX4_CFG, 0x00},
+{WCD9360_DATA_HUB_RX5_CFG, 0x00},
+{WCD9360_DATA_HUB_RX6_CFG, 0x00},
+{WCD9360_DATA_HUB_RX7_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX0_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX1_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX2_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX3_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX4_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX5_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX6_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX7_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX8_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX9_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX10_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX12_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX14_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_SB_TX15_INP_CFG, 0x00},
+{WCD9360_DATA_HUB_I2S_TX0_CFG, 0x00},
+{WCD9360_DATA_HUB_I2S_TX0_CFG2, 0x00},
+{WCD9360_DATA_HUB_I2S_TX1_0_CFG, 0x00},
+{WCD9360_DATA_HUB_I2S_TX1_1_CFG, 0x00},
+{WCD9360_DATA_HUB_DATA_HUB_CFG, 0x03},
+{WCD9360_DATA_HUB_I2S_0_CTL, 0x0C},
+{WCD9360_DATA_HUB_I2S_1_CTL, 0x0C},
+{WCD9360_DATA_HUB_I2S_0_CTL2, 0x01},
+{WCD9360_DATA_HUB_I2S_1_CTL2, 0x01},
+{WCD9360_DATA_HUB_I2S_CLKSRC_CTL, 0x00},
+{WCD9360_DATA_HUB_I2S_COMMON_CTL, 0x00},
+{WCD9360_DATA_HUB_I2S_0_TDM_CTL, 0x00},
+{WCD9360_DATA_HUB_I2S_0_TDM_CTL2, 0x05},
+{WCD9360_DATA_HUB_I2S_0_TDM_CH_RX, 0x00},
+{WCD9360_DATA_HUB_I2S_0_TDM_CH_TX, 0x00},
+{WCD9360_DATA_HUB_I2S_0_TDM_CFG, 0x00},
+{WCD9360_DATA_HUB_I2S_0_TDM_STRETCH, 0x00},
+{WCD9360_DATA_HUB_I2S_RESET_CTL, 0x00},
+{WCD9360_DMA_RDMA_CTL_0, 0x00},
+{WCD9360_DMA_RDMA_CTL_1, 0x00},
+{WCD9360_DMA_RDMA_CTL_2, 0x00},
+{WCD9360_DMA_RDMA_CTL_3, 0x00},
+{WCD9360_DMA_RDMA_CTL_4, 0x00},
+{WCD9360_DMA_CH_2_3_CFG_RDMA_0, 0xFF},
+{WCD9360_DMA_CH_2_3_CFG_RDMA_1, 0xFF},
+{WCD9360_DMA_CH_2_3_CFG_RDMA_2, 0xFF},
+{WCD9360_DMA_CH_2_3_CFG_RDMA_3, 0xFF},
+{WCD9360_DMA_CH_2_3_CFG_RDMA_4, 0xFF},
+{WCD9360_DMA_CH_0_1_CFG_RDMA_0, 0xFF},
+{WCD9360_DMA_CH_0_1_CFG_RDMA_1, 0xFF},
+{WCD9360_DMA_CH_0_1_CFG_RDMA_2, 0xFF},
+{WCD9360_DMA_CH_0_1_CFG_RDMA_3, 0xFF},
+{WCD9360_DMA_CH_0_1_CFG_RDMA_4, 0xFF},
+{WCD9360_DMA_RDMA4_PRT_CFG, 0x00},
+{WCD9360_DMA_RDMA_SBTX0_7_CFG, 0x00},
+{WCD9360_DMA_RDMA_SBTX8_10_CFG, 0x00},
+{WCD9360_DMA_WDMA_CTL_0, 0x00},
+{WCD9360_DMA_WDMA_CTL_1, 0x00},
+{WCD9360_DMA_WDMA_CTL_2, 0x00},
+{WCD9360_DMA_WDMA_CTL_3, 0x00},
+{WCD9360_DMA_WDMA_CTL_4, 0x00},
+{WCD9360_DMA_CH_4_5_CFG_WDMA_0, 0x00},
+{WCD9360_DMA_CH_4_5_CFG_WDMA_1, 0x00},
+{WCD9360_DMA_CH_4_5_CFG_WDMA_2, 0x00},
+{WCD9360_DMA_CH_4_5_CFG_WDMA_3, 0x00},
+{WCD9360_DMA_CH_4_5_CFG_WDMA_4, 0x00},
+{WCD9360_DMA_CH_2_3_CFG_WDMA_0, 0x00},
+{WCD9360_DMA_CH_2_3_CFG_WDMA_1, 0x00},
+{WCD9360_DMA_CH_2_3_CFG_WDMA_2, 0x00},
+{WCD9360_DMA_CH_2_3_CFG_WDMA_3, 0x00},
+{WCD9360_DMA_CH_2_3_CFG_WDMA_4, 0x00},
+{WCD9360_DMA_CH_0_1_CFG_WDMA_0, 0x00},
+{WCD9360_DMA_CH_0_1_CFG_WDMA_1, 0x00},
+{WCD9360_DMA_CH_0_1_CFG_WDMA_2, 0x00},
+{WCD9360_DMA_CH_0_1_CFG_WDMA_3, 0x00},
+{WCD9360_DMA_CH_0_1_CFG_WDMA_4, 0x00},
+{WCD9360_DMA_WDMA0_PRT_CFG, 0x00},
+{WCD9360_DMA_WDMA3_PRT_CFG, 0x00},
+{WCD9360_DMA_WDMA4_PRT0_3_CFG, 0x00},
+{WCD9360_DMA_WDMA4_PRT4_7_CFG, 0x00},
+{WCD9360_PAGE1_PAGE_REGISTER, 0x00},
+{WCD9360_CPE_FLL_USER_CTL_0, 0x71},
+{WCD9360_CPE_FLL_USER_CTL_1, 0x34},
+{WCD9360_CPE_FLL_USER_CTL_2, 0x0B},
+{WCD9360_CPE_FLL_USER_CTL_3, 0x02},
+{WCD9360_CPE_FLL_USER_CTL_4, 0x04},
+{WCD9360_CPE_FLL_USER_CTL_5, 0x02},
+{WCD9360_CPE_FLL_USER_CTL_6, 0x6E},
+{WCD9360_CPE_FLL_USER_CTL_7, 0x00},
+{WCD9360_CPE_FLL_USER_CTL_8, 0x94},
+{WCD9360_CPE_FLL_USER_CTL_9, 0x50},
+{WCD9360_CPE_FLL_L_VAL_CTL_0, 0x53},
+{WCD9360_CPE_FLL_L_VAL_CTL_1, 0x00},
+{WCD9360_CPE_FLL_DSM_FRAC_CTL_0, 0x00},
+{WCD9360_CPE_FLL_DSM_FRAC_CTL_1, 0xFF},
+{WCD9360_CPE_FLL_CONFIG_CTL_0, 0x6B},
+{WCD9360_CPE_FLL_CONFIG_CTL_1, 0x05},
+{WCD9360_CPE_FLL_CONFIG_CTL_2, 0x20},
+{WCD9360_CPE_FLL_CONFIG_CTL_3, 0x00},
+{WCD9360_CPE_FLL_CONFIG_CTL_4, 0x10},
+{WCD9360_CPE_FLL_TEST_CTL_0, 0x80},
+{WCD9360_CPE_FLL_TEST_CTL_1, 0x00},
+{WCD9360_CPE_FLL_TEST_CTL_2, 0x00},
+{WCD9360_CPE_FLL_TEST_CTL_3, 0x00},
+{WCD9360_CPE_FLL_TEST_CTL_4, 0x00},
+{WCD9360_CPE_FLL_TEST_CTL_5, 0x00},
+{WCD9360_CPE_FLL_TEST_CTL_6, 0x04},
+{WCD9360_CPE_FLL_TEST_CTL_7, 0x33},
+{WCD9360_CPE_FLL_FREQ_CTL_0, 0x00},
+{WCD9360_CPE_FLL_FREQ_CTL_1, 0x00},
+{WCD9360_CPE_FLL_FREQ_CTL_2, 0x00},
+{WCD9360_CPE_FLL_FREQ_CTL_3, 0x00},
+{WCD9360_CPE_FLL_SSC_CTL_0, 0x00},
+{WCD9360_CPE_FLL_SSC_CTL_1, 0x00},
+{WCD9360_CPE_FLL_SSC_CTL_2, 0x00},
+{WCD9360_CPE_FLL_SSC_CTL_3, 0x00},
+{WCD9360_CPE_FLL_FLL_MODE, 0x20},
+{WCD9360_CPE_FLL_STATUS_0, 0x00},
+{WCD9360_CPE_FLL_STATUS_1, 0x00},
+{WCD9360_CPE_FLL_STATUS_2, 0x00},
+{WCD9360_CPE_FLL_STATUS_3, 0x00},
+{WCD9360_I2S_FLL_USER_CTL_0, 0x41},
+{WCD9360_I2S_FLL_USER_CTL_1, 0x94},
+{WCD9360_I2S_FLL_USER_CTL_2, 0x08},
+{WCD9360_I2S_FLL_USER_CTL_3, 0x02},
+{WCD9360_I2S_FLL_USER_CTL_4, 0x04},
+{WCD9360_I2S_FLL_USER_CTL_5, 0x02},
+{WCD9360_I2S_FLL_USER_CTL_6, 0x40},
+{WCD9360_I2S_FLL_USER_CTL_7, 0x00},
+{WCD9360_I2S_FLL_USER_CTL_8, 0x5F},
+{WCD9360_I2S_FLL_USER_CTL_9, 0x02},
+{WCD9360_I2S_FLL_L_VAL_CTL_0, 0x40},
+{WCD9360_I2S_FLL_L_VAL_CTL_1, 0x00},
+{WCD9360_I2S_FLL_DSM_FRAC_CTL_0, 0x00},
+{WCD9360_I2S_FLL_DSM_FRAC_CTL_1, 0xFF},
+{WCD9360_I2S_FLL_CONFIG_CTL_0, 0x6B},
+{WCD9360_I2S_FLL_CONFIG_CTL_1, 0x05},
+{WCD9360_I2S_FLL_CONFIG_CTL_2, 0x20},
+{WCD9360_I2S_FLL_CONFIG_CTL_3, 0x00},
+{WCD9360_I2S_FLL_CONFIG_CTL_4, 0x30},
+{WCD9360_I2S_FLL_TEST_CTL_0, 0x80},
+{WCD9360_I2S_FLL_TEST_CTL_1, 0x00},
+{WCD9360_I2S_FLL_TEST_CTL_2, 0x00},
+{WCD9360_I2S_FLL_TEST_CTL_3, 0x00},
+{WCD9360_I2S_FLL_TEST_CTL_4, 0x00},
+{WCD9360_I2S_FLL_TEST_CTL_5, 0x00},
+{WCD9360_I2S_FLL_TEST_CTL_6, 0x04},
+{WCD9360_I2S_FLL_TEST_CTL_7, 0xFF},
+{WCD9360_I2S_FLL_FREQ_CTL_0, 0x00},
+{WCD9360_I2S_FLL_FREQ_CTL_1, 0x00},
+{WCD9360_I2S_FLL_FREQ_CTL_2, 0x00},
+{WCD9360_I2S_FLL_FREQ_CTL_3, 0x00},
+{WCD9360_I2S_FLL_SSC_CTL_0, 0x00},
+{WCD9360_I2S_FLL_SSC_CTL_1, 0x00},
+{WCD9360_I2S_FLL_SSC_CTL_2, 0x00},
+{WCD9360_I2S_FLL_SSC_CTL_3, 0x00},
+{WCD9360_I2S_FLL_FLL_MODE, 0x00},
+{WCD9360_I2S_FLL_STATUS_0, 0x00},
+{WCD9360_I2S_FLL_STATUS_1, 0x00},
+{WCD9360_I2S_FLL_STATUS_2, 0x00},
+{WCD9360_I2S_FLL_STATUS_3, 0x00},
+{WCD9360_PAGE2_PAGE_REGISTER, 0x00},
+{WCD9360_CPE_SS_CPE_CTL, 0x05},
+{WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0, 0x01},
+{WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1, 0x00},
+{WCD9360_CPE_SS_PWR_CPEFLL_CTL, 0x02},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x03},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0, 0xFF},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1, 0xFF},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2, 0xFF},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3, 0xFF},
+{WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4, 0xFF},
+{WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN, 0x07},
+{WCD9360_CPE_SS_US_BUF_INT_PERIOD, 0x5F},
+{WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x13},
+{WCD9360_CPE_SS_SVA_CFG, 0x41},
+{WCD9360_CPE_SS_US_CFG, 0x00},
+{WCD9360_CPE_SS_MAD_CTL, 0x00},
+{WCD9360_CPE_SS_CPAR_CTL, 0x00},
+{WCD9360_CPE_SS_DMIC0_CTL, 0x00},
+{WCD9360_CPE_SS_DMIC1_CTL, 0x00},
+{WCD9360_CPE_SS_DMIC2_CTL, 0x00},
+{WCD9360_CPE_SS_DMIC_CFG, 0x80},
+{WCD9360_CPE_SS_CPAR_CFG, 0x00},
+{WCD9360_CPE_SS_WDOG_CFG, 0x01},
+{WCD9360_CPE_SS_BACKUP_INT, 0x00},
+{WCD9360_CPE_SS_STATUS, 0x00},
+{WCD9360_CPE_SS_CPE_OCD_CFG, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF},
+{WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0x3F},
+{WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A, 0xFF},
+{WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B, 0x3F},
+{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A, 0x00},
+{WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B, 0x00},
+{WCD9360_CPE_SS_DMIC3_CTL, 0x00},
+{WCD9360_CPE_SS_WDOG_RESET, 0x00},
+{WCD9360_CPE_SS_LPASS_MCLK_PRG, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_0, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_1, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_2, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_3, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_4, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_5, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_6, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_7, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_8, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_9, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_10, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_11, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_12, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_13, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_14, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_IN_15, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_0, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_1, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_2, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_3, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_4, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_5, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_6, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_7, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_8, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_9, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_10, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_11, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_12, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_13, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_14, 0x00},
+{WCD9360_CPE_SS_LPASS_IPC_OUT_15, 0x00},
+{WCD9360_CPE_SS_LPASS_ARB_CTL, 0x00},
+{WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0, 0x00},
+{WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1, 0x00},
+{WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0, 0x00},
+{WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1, 0x00},
+{WCD9360_SOC_MAD_MAIN_CTL_1, 0x00},
+{WCD9360_SOC_MAD_MAIN_CTL_2, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_1, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_2, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_3, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_4, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_5, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_6, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_7, 0x00},
+{WCD9360_SOC_MAD_AUDIO_CTL_8, 0x00},
+{WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR, 0x00},
+{WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL, 0x40},
+{WCD9360_SOC_MAD_ULTR_CTL_1, 0x00},
+{WCD9360_SOC_MAD_ULTR_CTL_2, 0x00},
+{WCD9360_SOC_MAD_ULTR_CTL_3, 0x00},
+{WCD9360_SOC_MAD_ULTR_CTL_4, 0x00},
+{WCD9360_SOC_MAD_ULTR_CTL_5, 0x00},
+{WCD9360_SOC_MAD_ULTR_CTL_6, 0x00},
+{WCD9360_SOC_MAD_ULTR_CTL_7, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_1, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_2, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_3, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_4, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_5, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_6, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_7, 0x00},
+{WCD9360_SOC_MAD_BEACON_CTL_8, 0x00},
+{WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR, 0x00},
+{WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL, 0x00},
+{WCD9360_SOC_MAD_INP_SEL, 0x00},
+{WCD9360_SOC_MAD_MAD2_INP_SEL, 0x00},
+{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL, 0x00},
+{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS, 0x00},
+{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS, 0x00},
+{WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14, 0x00},
+{WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15, 0x00},
+{WCD9360_PAGE4_PAGE_REGISTER, 0x00},
+{WCD9360_INTR_CFG, 0x00},
+{WCD9360_INTR_CLR_COMMIT, 0x00},
+{WCD9360_INTR_PIN1_MASK0, 0xFF},
+{WCD9360_INTR_PIN1_MASK1, 0xFF},
+{WCD9360_INTR_PIN1_MASK2, 0xFF},
+{WCD9360_INTR_PIN1_MASK3, 0xFF},
+{WCD9360_INTR_PIN1_STATUS0, 0x00},
+{WCD9360_INTR_PIN1_STATUS1, 0x00},
+{WCD9360_INTR_PIN1_STATUS2, 0x00},
+{WCD9360_INTR_PIN1_STATUS3, 0x00},
+{WCD9360_INTR_PIN1_CLEAR0, 0x00},
+{WCD9360_INTR_PIN1_CLEAR1, 0x00},
+{WCD9360_INTR_PIN1_CLEAR2, 0x00},
+{WCD9360_INTR_PIN1_CLEAR3, 0x00},
+{WCD9360_INTR_PIN2_MASK3, 0xFF},
+{WCD9360_INTR_PIN2_STATUS3, 0x00},
+{WCD9360_INTR_PIN2_CLEAR3, 0x00},
+{WCD9360_INTR_CPESS_SUMRY_MASK2, 0xFF},
+{WCD9360_INTR_CPESS_SUMRY_MASK3, 0xFF},
+{WCD9360_INTR_CPESS_SUMRY_STATUS2, 0x00},
+{WCD9360_INTR_CPESS_SUMRY_STATUS3, 0x00},
+{WCD9360_INTR_CPESS_SUMRY_CLEAR2, 0x00},
+{WCD9360_INTR_CPESS_SUMRY_CLEAR3, 0x00},
+{WCD9360_INTR_LEVEL0, 0x3B},
+{WCD9360_INTR_LEVEL1, 0x00},
+{WCD9360_INTR_LEVEL2, 0xD0},
+{WCD9360_INTR_LEVEL3, 0x00},
+{WCD9360_INTR_BYPASS0, 0x00},
+{WCD9360_INTR_BYPASS1, 0x00},
+{WCD9360_INTR_BYPASS2, 0x00},
+{WCD9360_INTR_BYPASS3, 0x00},
+{WCD9360_INTR_SET0, 0x00},
+{WCD9360_INTR_SET1, 0x00},
+{WCD9360_INTR_SET2, 0x00},
+{WCD9360_INTR_SET3, 0x00},
+{WCD9360_INTR_CODEC_MISC_MASK, 0x73},
+{WCD9360_INTR_CODEC_MISC_STATUS, 0x00},
+{WCD9360_INTR_CODEC_MISC_CLEAR, 0x00},
+{WCD9360_ANA_PAGE_REGISTER, 0x00},
+{WCD9360_ANA_BIAS, 0x00},
+{WCD9360_ANA_RCO, 0x00},
+{WCD9360_ANA_BUCK_CTL, 0x00},
+{WCD9360_ANA_BUCK_STATUS, 0x00},
+{WCD9360_ANA_EAR, 0x00},
+{WCD9360_ANA_MAD_SETUP, 0x01},
+{WCD9360_ANA_AMIC1, 0x20},
+{WCD9360_ANA_AMIC2, 0x00},
+{WCD9360_ANA_AMIC3, 0x20},
+{WCD9360_ANA_AMIC4, 0x00},
+{WCD9360_ANA_MICB1, 0x10},
+{WCD9360_ANA_MICB2, 0x10},
+{WCD9360_ANA_MICB3, 0x10},
+{WCD9360_ANA_MICB4, 0x10},
+{WCD9360_BIAS_CTL, 0x2A},
+{WCD9360_BIAS_VBG_FINE_ADJ, 0x55},
+{WCD9360_RCO_CTRL_1, 0x44},
+{WCD9360_RCO_CTRL_2, 0x48},
+{WCD9360_RCO_CAL, 0x00},
+{WCD9360_RCO_CAL_1, 0x00},
+{WCD9360_RCO_CAL_2, 0x00},
+{WCD9360_RCO_TEST_CTRL, 0x00},
+{WCD9360_RCO_CAL_OUT_1, 0x00},
+{WCD9360_RCO_CAL_OUT_2, 0x00},
+{WCD9360_RCO_CAL_OUT_3, 0x00},
+{WCD9360_RCO_CAL_OUT_4, 0x00},
+{WCD9360_RCO_CAL_OUT_5, 0x00},
+{WCD9360_SIDO_MODE_1, 0x84},
+{WCD9360_SIDO_MODE_2, 0xFE},
+{WCD9360_SIDO_MODE_3, 0xF6},
+{WCD9360_SIDO_MODE_4, 0x56},
+{WCD9360_SIDO_VCL_1, 0x00},
+{WCD9360_SIDO_VCL_2, 0x6C},
+{WCD9360_SIDO_VCL_3, 0x44},
+{WCD9360_SIDO_CCL_1, 0x57},
+{WCD9360_SIDO_CCL_2, 0x92},
+{WCD9360_SIDO_CCL_3, 0x35},
+{WCD9360_SIDO_CCL_4, 0x61},
+{WCD9360_SIDO_CCL_5, 0x6D},
+{WCD9360_SIDO_CCL_6, 0x60},
+{WCD9360_SIDO_CCL_7, 0x6F},
+{WCD9360_SIDO_CCL_8, 0x6F},
+{WCD9360_SIDO_CCL_9, 0x6E},
+{WCD9360_SIDO_CCL_10, 0x26},
+{WCD9360_SIDO_FILTER_1, 0x92},
+{WCD9360_SIDO_FILTER_2, 0x54},
+{WCD9360_SIDO_DRIVER_1, 0x77},
+{WCD9360_SIDO_DRIVER_2, 0x55},
+{WCD9360_SIDO_DRIVER_3, 0x55},
+{WCD9360_SIDO_CAL_CODE_EXT_1, 0x9C},
+{WCD9360_SIDO_CAL_CODE_EXT_2, 0x82},
+{WCD9360_SIDO_CAL_CODE_OUT_1, 0x00},
+{WCD9360_SIDO_CAL_CODE_OUT_2, 0x00},
+{WCD9360_SIDO_TEST_1, 0x00},
+{WCD9360_SIDO_TEST_2, 0x00},
+{WCD9360_LDOH_MODE, 0x2B},
+{WCD9360_LDOH_BIAS, 0x68},
+{WCD9360_LDOH_STB_LOADS, 0x00},
+{WCD9360_LDOH_SLOWRAMP, 0x50},
+{WCD9360_MICB1_TEST_CTL_1, 0x1A},
+{WCD9360_MICB1_TEST_CTL_2, 0x18},
+{WCD9360_MICB1_TEST_CTL_3, 0xA4},
+{WCD9360_MICB2_TEST_CTL_1, 0x1A},
+{WCD9360_MICB2_TEST_CTL_2, 0x18},
+{WCD9360_MICB2_TEST_CTL_3, 0xA4},
+{WCD9360_MICB3_TEST_CTL_1, 0x1A},
+{WCD9360_MICB3_TEST_CTL_2, 0x18},
+{WCD9360_MICB3_TEST_CTL_3, 0xA4},
+{WCD9360_MICB4_TEST_CTL_1, 0x1A},
+{WCD9360_MICB4_TEST_CTL_2, 0x18},
+{WCD9360_MICB4_TEST_CTL_3, 0xA4},
+{WCD9360_TX_COM_ADC_VCM, 0x39},
+{WCD9360_TX_COM_BIAS_ATEST, 0xC0},
+{WCD9360_TX_COM_ADC_INT1_IB, 0x6F},
+{WCD9360_TX_COM_ADC_INT2_IB, 0x4F},
+{WCD9360_TX_COM_TXFE_DIV_CTL, 0x2E},
+{WCD9360_TX_COM_TXFE_DIV_START, 0x00},
+{WCD9360_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7},
+{WCD9360_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF},
+{WCD9360_TX_1_2_TEST_EN, 0xCC},
+{WCD9360_TX_1_2_ADC_IB, 0x09},
+{WCD9360_TX_1_2_ATEST_REFCTL, 0x0A},
+{WCD9360_TX_1_2_TEST_CTL, 0x38},
+{WCD9360_TX_1_2_TEST_BLK_EN, 0xFF},
+{WCD9360_TX_1_2_TXFE_CLKDIV, 0x00},
+{WCD9360_TX_1_2_SAR1_ERR, 0x00},
+{WCD9360_TX_1_2_SAR2_ERR, 0x00},
+{WCD9360_TX_3_4_TEST_EN, 0xCC},
+{WCD9360_TX_3_4_ADC_IB, 0x09},
+{WCD9360_TX_3_4_ATEST_REFCTL, 0x0A},
+{WCD9360_TX_3_4_TEST_CTL, 0x38},
+{WCD9360_TX_3_4_TEST_BLK_EN, 0xFF},
+{WCD9360_TX_3_4_TXFE_CLKDIV, 0x00},
+{WCD9360_TX_3_4_SAR1_ERR, 0x00},
+{WCD9360_TX_3_4_SAR2_ERR, 0x00},
+{WCD9360_RX_RX_EAR_BIAS_CON_1, 0x2A},
+{WCD9360_RX_RX_EAR_BIAS_CON_2, 0x8A},
+{WCD9360_RX_RX_AUX_BIAS_CON_1, 0x2A},
+{WCD9360_RX_RX_AUX_BIAS_CON_2, 0x8A},
+{WCD9360_RX_RX_BIAS_ATEST, 0x0C},
+{WCD9360_RX_RXTOP_RESERVED, 0x00},
+{WCD9360_EAR_EAR_EN_REG, 0x22},
+{WCD9360_EAR_EAR_PA_CON, 0x44},
+{WCD9360_EAR_EAR_SP_CON, 0xDB},
+{WCD9360_EAR_EAR_DAC_CON, 0x00},
+{WCD9360_EAR_EAR_CNP_FSM_CON, 0xB6},
+{WCD9360_EAR_DAC_CTL_TEST, 0x00},
+{WCD9360_EAR_STATUS_REG, 0x00},
+{WCD9360_EAR_EAR_COMPANDER_CON, 0x02},
+{WCD9360_ANA_NEW_PAGE_REGISTER, 0x00},
+{WCD9360_CLK_SYS_PLL_ENABLES, 0x00},
+{WCD9360_CLK_SYS_PLL_PRESET, 0x00},
+{WCD9360_CLK_SYS_PLL_STATUS, 0x00},
+{WCD9360_CLK_SYS_MCLK_PRG, 0x10},
+{WCD9360_CLK_SYS_MCLK2_PRG1, 0x00},
+{WCD9360_CLK_SYS_MCLK_MISC, 0x00},
+{WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x17},
+{WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x0D},
+{WCD9360_SIDO_NEW_VOUT_D_FREQ1, 0x07},
+{WCD9360_SIDO_NEW_VOUT_D_FREQ2, 0x00},
+{WCD9360_AUX_ANA_EAR, 0x00},
+{WCD9360_LDORXTX_LDORXTX, 0x10},
+{WCD9360_DIE_CRACK_CTL, 0x00},
+{WCD9360_DIE_CRACK_OUT, 0x00},
+{WCD9360_LOOP_BACK_EN, 0x00},
+{WCD9360_CLK_SYS_INT_POST_DIV_REG0, 0x00},
+{WCD9360_CLK_SYS_INT_POST_DIV_REG1, 0x00},
+{WCD9360_CLK_SYS_INT_REF_DIV_REG0, 0x00},
+{WCD9360_CLK_SYS_INT_REF_DIV_REG1, 0x00},
+{WCD9360_CLK_SYS_INT_FILTER_REG0, 0x00},
+{WCD9360_CLK_SYS_INT_FILTER_REG1, 0x00},
+{WCD9360_CLK_SYS_INT_PLL_L_VAL, 0x00},
+{WCD9360_CLK_SYS_INT_PLL_M_VAL, 0x00},
+{WCD9360_CLK_SYS_INT_PLL_N_VAL, 0x00},
+{WCD9360_CLK_SYS_INT_TEST_REG0, 0x00},
+{WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG, 0x00},
+{WCD9360_CLK_SYS_INT_VCO_PROG, 0x00},
+{WCD9360_CLK_SYS_INT_TEST_REG1, 0x00},
+{WCD9360_CLK_SYS_INT_LDO_LOCK_CFG, 0x00},
+{WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0x00},
+{WCD9360_CLK_SYS_INT_CLK_TEST1, 0x00},
+{WCD9360_CLK_SYS_INT_CLK_TEST2, 0x00},
+{WCD9360_CLK_SYS_INT_CLK_TEST3, 0x00},
+{WCD9360_SIDO_NEW_INT_RAMP_STATUS, 0x00},
+{WCD9360_SIDO_NEW_INT_SPARE_1, 0x00},
+{WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A, 0x64},
+{WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D, 0x40},
+{WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT, 0x24},
+{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL, 0x09},
+{WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL, 0x7D},
+{WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST, 0x00},
+{WCD9360_SIDO_NEW_INT_RAMP_CTL_A, 0x14},
+{WCD9360_SIDO_NEW_INT_RAMP_CTL_D, 0x14},
+{WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD, 0x33},
+{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1, 0x3F},
+{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2, 0x74},
+{WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3, 0x33},
+{WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1, 0x1D},
+{WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2, 0x0A},
+{WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8},
+{WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1, 0x42},
+{WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2, 0x22},
+{WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00},
+{WCD9360_AUX_INT_AUX_EN_REG, 0x22},
+{WCD9360_AUX_INT_AUX_PA_CON, 0x46},
+{WCD9360_AUX_INT_AUX_SP_CON, 0xD2},
+{WCD9360_AUX_INT_AUX_DAC_CON, 0x00},
+{WCD9360_AUX_INT_AUX_CNP_FSM_CON, 0xB6},
+{WCD9360_AUX_INT_AUX_TEST, 0x00},
+{WCD9360_AUX_INT_STATUS_REG, 0x00},
+{WCD9360_AUX_INT_AUX_MISC, 0x00},
+{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1, 0xFF},
+{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2, 0xD8},
+{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3, 0x80},
+{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4, 0xFF},
+{WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5, 0x09},
+{WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS, 0x00},
+{WCD9360_DIE_CRACK_INT_INT1, 0x02},
+{WCD9360_DIE_CRACK_INT_INT2, 0x60},
+{WCD9360_LOOP_BACK_INT_SPARE, 0x00},
+{WCD9360_PAGE10_PAGE_REGISTER, 0x00},
+{WCD9360_CDC_ANC0_CLK_RESET_CTL, 0x00},
+{WCD9360_CDC_ANC0_MODE_1_CTL, 0x00},
+{WCD9360_CDC_ANC0_MODE_2_CTL, 0x00},
+{WCD9360_CDC_ANC0_FF_SHIFT, 0x00},
+{WCD9360_CDC_ANC0_FB_SHIFT, 0x00},
+{WCD9360_CDC_ANC0_LPF_FF_A_CTL, 0x00},
+{WCD9360_CDC_ANC0_LPF_FF_B_CTL, 0x00},
+{WCD9360_CDC_ANC0_LPF_FB_CTL, 0x00},
+{WCD9360_CDC_ANC0_SMLPF_CTL, 0x00},
+{WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL, 0x00},
+{WCD9360_CDC_ANC0_IIR_ADAPT_CTL, 0x00},
+{WCD9360_CDC_ANC0_IIR_COEFF_1_CTL, 0x00},
+{WCD9360_CDC_ANC0_IIR_COEFF_2_CTL, 0x00},
+{WCD9360_CDC_ANC0_FF_A_GAIN_CTL, 0x00},
+{WCD9360_CDC_ANC0_FF_B_GAIN_CTL, 0x00},
+{WCD9360_CDC_ANC0_FB_GAIN_CTL, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX0_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX0_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX0_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX0_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX0_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX0_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX0_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX1_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX1_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX1_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX1_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX1_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX1_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX1_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX2_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX2_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX2_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX2_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX2_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX2_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX2_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX3_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX3_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX3_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX3_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX3_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX3_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX3_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX4_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX4_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX4_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX4_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX4_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX4_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX4_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX5_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX5_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX5_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX5_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX5_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX5_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX5_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX6_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX6_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX6_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX6_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX6_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX6_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX6_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX7_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX7_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX7_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX7_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX7_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX7_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX7_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_CTL, 0x04},
+{WCD9360_CDC_TX8_TX_PATH_CFG0, 0x10},
+{WCD9360_CDC_TX8_TX_PATH_CFG1, 0x03},
+{WCD9360_CDC_TX8_TX_VOL_CTL, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_192_CTL, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_192_CFG, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_SEC0, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_SEC1, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_SEC2, 0x01},
+{WCD9360_CDC_TX8_TX_PATH_SEC3, 0x3C},
+{WCD9360_CDC_TX8_TX_PATH_SEC4, 0x20},
+{WCD9360_CDC_TX8_TX_PATH_SEC5, 0x00},
+{WCD9360_CDC_TX8_TX_PATH_SEC6, 0x00},
+{WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x02},
+{WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x00},
+{WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x02},
+{WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x00},
+{WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x02},
+{WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x00},
+{WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x02},
+{WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x00},
+{WCD9360_PAGE11_PAGE_REGISTER, 0x00},
+{WCD9360_CDC_COMPANDER0_CTL0, 0x60},
+{WCD9360_CDC_COMPANDER0_CTL1, 0xDB},
+{WCD9360_CDC_COMPANDER0_CTL2, 0xFF},
+{WCD9360_CDC_COMPANDER0_CTL3, 0x35},
+{WCD9360_CDC_COMPANDER0_CTL4, 0xFF},
+{WCD9360_CDC_COMPANDER0_CTL5, 0x00},
+{WCD9360_CDC_COMPANDER0_CTL6, 0x01},
+{WCD9360_CDC_COMPANDER0_CTL7, 0x06},
+{WCD9360_CDC_COMPANDER7_CTL0, 0x60},
+{WCD9360_CDC_COMPANDER7_CTL1, 0xDB},
+{WCD9360_CDC_COMPANDER7_CTL2, 0xFF},
+{WCD9360_CDC_COMPANDER7_CTL3, 0x35},
+{WCD9360_CDC_COMPANDER7_CTL4, 0xFF},
+{WCD9360_CDC_COMPANDER7_CTL5, 0x00},
+{WCD9360_CDC_COMPANDER7_CTL6, 0x01},
+{WCD9360_CDC_COMPANDER7_CTL7, 0x06},
+{WCD9360_CDC_COMPANDER8_CTL0, 0x60},
+{WCD9360_CDC_COMPANDER8_CTL1, 0xDB},
+{WCD9360_CDC_COMPANDER8_CTL2, 0xFF},
+{WCD9360_CDC_COMPANDER8_CTL3, 0x35},
+{WCD9360_CDC_COMPANDER8_CTL4, 0xFF},
+{WCD9360_CDC_COMPANDER8_CTL5, 0x00},
+{WCD9360_CDC_COMPANDER8_CTL6, 0x01},
+{WCD9360_CDC_COMPANDER8_CTL7, 0x06},
+{WCD9360_CDC_RX0_RX_PATH_CTL, 0x04},
+{WCD9360_CDC_RX0_RX_PATH_CFG0, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_CFG1, 0x64},
+{WCD9360_CDC_RX0_RX_PATH_CFG2, 0x80},
+{WCD9360_CDC_RX0_RX_VOL_CTL, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_MIX_CTL, 0x04},
+{WCD9360_CDC_RX0_RX_PATH_MIX_CFG, 0x12},
+{WCD9360_CDC_RX0_RX_VOL_MIX_CTL, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_SEC0, 0xFC},
+{WCD9360_CDC_RX0_RX_PATH_SEC1, 0x08},
+{WCD9360_CDC_RX0_RX_PATH_SEC2, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_SEC3, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_SEC5, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_SEC6, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_SEC7, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_MIX_SEC0, 0x08},
+{WCD9360_CDC_RX0_RX_PATH_MIX_SEC1, 0x00},
+{WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_CTL, 0x04},
+{WCD9360_CDC_RX9_RX_PATH_CFG0, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_CFG1, 0x64},
+{WCD9360_CDC_RX9_RX_PATH_CFG2, 0x80},
+{WCD9360_CDC_RX9_RX_VOL_CTL, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_MIX_CTL, 0x04},
+{WCD9360_CDC_RX9_RX_PATH_MIX_CFG, 0x12},
+{WCD9360_CDC_RX9_RX_VOL_MIX_CTL, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_SEC0, 0xFC},
+{WCD9360_CDC_RX9_RX_PATH_SEC1, 0x08},
+{WCD9360_CDC_RX9_RX_PATH_SEC2, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_SEC3, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_SEC5, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_SEC6, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_SEC7, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_MIX_SEC0, 0x08},
+{WCD9360_CDC_RX9_RX_PATH_MIX_SEC1, 0x00},
+{WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_CTL, 0x04},
+{WCD9360_CDC_RX7_RX_PATH_CFG0, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_CFG1, 0x64},
+{WCD9360_CDC_RX7_RX_PATH_CFG2, 0x80},
+{WCD9360_CDC_RX7_RX_VOL_CTL, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_MIX_CTL, 0x04},
+{WCD9360_CDC_RX7_RX_PATH_MIX_CFG, 0x12},
+{WCD9360_CDC_RX7_RX_VOL_MIX_CTL, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_SEC0, 0x04},
+{WCD9360_CDC_RX7_RX_PATH_SEC1, 0x08},
+{WCD9360_CDC_RX7_RX_PATH_SEC2, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_SEC3, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_SEC5, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_SEC6, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_SEC7, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_MIX_SEC0, 0x08},
+{WCD9360_CDC_RX7_RX_PATH_MIX_SEC1, 0x00},
+{WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_CTL, 0x04},
+{WCD9360_CDC_RX8_RX_PATH_CFG0, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_CFG1, 0x64},
+{WCD9360_CDC_RX8_RX_PATH_CFG2, 0x80},
+{WCD9360_CDC_RX8_RX_VOL_CTL, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_MIX_CTL, 0x04},
+{WCD9360_CDC_RX8_RX_PATH_MIX_CFG, 0x12},
+{WCD9360_CDC_RX8_RX_VOL_MIX_CTL, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_SEC0, 0x04},
+{WCD9360_CDC_RX8_RX_PATH_SEC1, 0x08},
+{WCD9360_CDC_RX8_RX_PATH_SEC2, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_SEC3, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_SEC5, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_SEC6, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_SEC7, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_MIX_SEC0, 0x08},
+{WCD9360_CDC_RX8_RX_PATH_MIX_SEC1, 0x00},
+{WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x00},
+{WCD9360_PAGE12_PAGE_REGISTER, 0x00},
+{WCD9360_CDC_BOOST0_BOOST_PATH_CTL, 0x00},
+{WCD9360_CDC_BOOST0_BOOST_CTL, 0xD0},
+{WCD9360_CDC_BOOST0_BOOST_CFG1, 0x89},
+{WCD9360_CDC_BOOST0_BOOST_CFG2, 0x04},
+{WCD9360_CDC_BOOST1_BOOST_PATH_CTL, 0x00},
+{WCD9360_CDC_BOOST1_BOOST_CTL, 0xD0},
+{WCD9360_CDC_BOOST1_BOOST_CFG1, 0x89},
+{WCD9360_CDC_BOOST1_BOOST_CFG2, 0x04},
+{WCD9360_MIXING_ASRC2_CLK_RST_CTL, 0x00},
+{WCD9360_MIXING_ASRC2_CTL0, 0x00},
+{WCD9360_MIXING_ASRC2_CTL1, 0x00},
+{WCD9360_MIXING_ASRC2_FIFO_CTL, 0xA8},
+{WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00},
+{WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00},
+{WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00},
+{WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00},
+{WCD9360_MIXING_ASRC2_STATUS_FIFO, 0x00},
+{WCD9360_MIXING_ASRC3_CLK_RST_CTL, 0x00},
+{WCD9360_MIXING_ASRC3_CTL0, 0x00},
+{WCD9360_MIXING_ASRC3_CTL1, 0x00},
+{WCD9360_MIXING_ASRC3_FIFO_CTL, 0xA8},
+{WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB, 0x00},
+{WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB, 0x00},
+{WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB, 0x00},
+{WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB, 0x00},
+{WCD9360_MIXING_ASRC3_STATUS_FIFO, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_DATA_0, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_DATA_1, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_DATA_2, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_DATA_3, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_DATA_0, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_DATA_1, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_DATA_2, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_RD_DATA_3, 0x00},
+{WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG, 0x0F},
+{WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS, 0x03},
+{WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04},
+{WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00},
+{WCD9360_SIDETONE_ASRC0_CLK_RST_CTL, 0x00},
+{WCD9360_SIDETONE_ASRC0_CTL0, 0x00},
+{WCD9360_SIDETONE_ASRC0_CTL1, 0x00},
+{WCD9360_SIDETONE_ASRC0_FIFO_CTL, 0xA8},
+{WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+{WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+{WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+{WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+{WCD9360_SIDETONE_ASRC0_STATUS_FIFO, 0x00},
+{WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
+{WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01},
+{WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
+{WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01},
+{WCD9360_EC_ASRC0_CLK_RST_CTL, 0x00},
+{WCD9360_EC_ASRC0_CTL0, 0x00},
+{WCD9360_EC_ASRC0_CTL1, 0x00},
+{WCD9360_EC_ASRC0_FIFO_CTL, 0xA8},
+{WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
+{WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
+{WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
+{WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
+{WCD9360_EC_ASRC0_STATUS_FIFO, 0x00},
+{WCD9360_EC_ASRC1_CLK_RST_CTL, 0x00},
+{WCD9360_EC_ASRC1_CTL0, 0x00},
+{WCD9360_EC_ASRC1_CTL1, 0x00},
+{WCD9360_EC_ASRC1_FIFO_CTL, 0xA8},
+{WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
+{WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
+{WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
+{WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
+{WCD9360_EC_ASRC1_STATUS_FIFO, 0x00},
+{WCD9360_PAGE13_PAGE_REGISTER, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 0x00},
+{WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00},
+{WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 0x00},
+{WCD9360_CDC_RX_INP_MUX_ANC_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 0x00},
+{WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0x00},
+{WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0x00},
+{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00},
+{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00},
+{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00},
+{WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00},
+{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 0x00},
+{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 0x00},
+{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 0x00},
+{WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0x00},
+{WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
+{WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+{WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL, 0x00},
+{WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x0A},
+{WCD9360_CDC_PROX_DETECT_PROX_CTL, 0x08},
+{WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1, 0x4B},
+{WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_STATUS, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD, 0x00},
+{WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_CTL, 0x40},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00},
+{WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00},
+{WCD9360_CDC_TOP_TOP_CFG0, 0x00},
+{WCD9360_CDC_TOP_TOP_CFG1, 0x00},
+{WCD9360_CDC_TOP_TOP_CFG7, 0x00},
+{WCD9360_CDC_TOP_EAR_COMP_WR_LSB, 0x00},
+{WCD9360_CDC_TOP_EAR_COMP_WR_MSB, 0x00},
+{WCD9360_CDC_TOP_EAR_COMP_LUT, 0x00},
+{WCD9360_CDC_TOP_EAR_COMP_RD_LSB, 0x00},
+{WCD9360_CDC_TOP_EAR_COMP_RD_MSB, 0x00},
+{WCD9360_CDC_TOP_TOP_DEBUG, 0x00},
+{WCD9360_PAGE80_PAGE_REGISTER, 0x00},
+{WCD9360_CODEC_CPR_WR_DATA_0, 0x00},
+{WCD9360_CODEC_CPR_WR_DATA_1, 0x00},
+{WCD9360_CODEC_CPR_WR_DATA_2, 0x00},
+{WCD9360_CODEC_CPR_WR_DATA_3, 0x00},
+{WCD9360_CODEC_CPR_WR_ADDR_0, 0x00},
+{WCD9360_CODEC_CPR_WR_ADDR_1, 0x00},
+{WCD9360_CODEC_CPR_WR_ADDR_2, 0x00},
+{WCD9360_CODEC_CPR_WR_ADDR_3, 0x00},
+{WCD9360_CODEC_CPR_RD_ADDR_0, 0x00},
+{WCD9360_CODEC_CPR_RD_ADDR_1, 0x00},
+{WCD9360_CODEC_CPR_RD_ADDR_2, 0x00},
+{WCD9360_CODEC_CPR_RD_ADDR_3, 0x00},
+{WCD9360_CODEC_CPR_RD_DATA_0, 0x00},
+{WCD9360_CODEC_CPR_RD_DATA_1, 0x00},
+{WCD9360_CODEC_CPR_RD_DATA_2, 0x00},
+{WCD9360_CODEC_CPR_RD_DATA_3, 0x00},
+{WCD9360_CODEC_CPR_ACCESS_CFG, 0x0F},
+{WCD9360_CODEC_CPR_ACCESS_STATUS, 0x03},
+{WCD9360_CODEC_CPR_NOM_CX_VDD, 0xB4},
+{WCD9360_CODEC_CPR_SVS_CX_VDD, 0x7C},
+{WCD9360_CODEC_CPR_SVS2_CX_VDD, 0x58},
+{WCD9360_CODEC_CPR_NOM_MX_VDD, 0xB4},
+{WCD9360_CODEC_CPR_SVS_MX_VDD, 0xB4},
+{WCD9360_CODEC_CPR_SVS2_MX_VDD, 0xA0},
+{WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD, 0x2C},
+{WCD9360_CODEC_CPR_MAX_SVS2_STEP, 0x08},
+{WCD9360_CODEC_CPR_CTL, 0x00},
+{WCD9360_CODEC_CPR_SW_MODECHNG_STATUS, 0x00},
+{WCD9360_CODEC_CPR_SW_MODECHNG_START, 0x00},
+{WCD9360_CODEC_CPR_CPR_STATUS, 0x00},
+{WCD9360_PAGE128_PAGE_REGISTER, 0x00},
+{WCD9360_TLMM_JTCK_PINCFG, 0x00},
+{WCD9360_TLMM_INTR1_PINCFG, 0x00},
+{WCD9360_TLMM_INTR2_PINCFG, 0x00},
+{WCD9360_TLMM_SWR_DATA_PINCFG, 0x00},
+{WCD9360_TLMM_SWR_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_SLIMBUS_DATA1_PINCFG, 0x00},
+{WCD9360_TLMM_SLIMBUS_DATA2_PINCFG, 0x00},
+{WCD9360_TLMM_SLIMBUS_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_I2C_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_I2C_DATA_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_0_RX_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_0_TX_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_0_SCK_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_0_WS_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_1_RX_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_1_TX_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_1_SCK_PINCFG, 0x00},
+{WCD9360_TLMM_I2S_1_WS_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC1_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC1_DATA_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC2_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC2_DATA_PINCFG, 0x00},
+{WCD9360_TLMM_GPIO1_PINCFG, 0x00},
+{WCD9360_TLMM_GPIO2_PINCFG, 0x00},
+{WCD9360_TLMM_GPIO3_PINCFG, 0x00},
+{WCD9360_TLMM_GPIO4_PINCFG, 0x00},
+{WCD9360_TLMM_SPI_S_CSN_PINCFG, 0x00},
+{WCD9360_TLMM_SPI_S_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_SPI_S_DOUT_PINCFG, 0x00},
+{WCD9360_TLMM_SPI_S_DIN_PINCFG, 0x00},
+{WCD9360_TLMM_GPIO0_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC3_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC3_DATA_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC4_CLK_PINCFG, 0x00},
+{WCD9360_TLMM_DMIC4_DATA_PINCFG, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_OE_0, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_OE_1, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_OE_2, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_OE_3, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_OE_4, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_DATA_0, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_DATA_1, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_DATA_2, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_DATA_3, 0x00},
+{WCD9360_TEST_DEBUG_PIN_CTL_DATA_4, 0x00},
+{WCD9360_TEST_DEBUG_PAD_DRVCTL_0, 0x00},
+{WCD9360_TEST_DEBUG_PAD_DRVCTL_1, 0x00},
+{WCD9360_TEST_DEBUG_PIN_STATUS, 0x00},
+{WCD9360_TEST_DEBUG_NPL_DLY_TEST_1, 0x10},
+{WCD9360_TEST_DEBUG_NPL_DLY_TEST_2, 0x60},
+{WCD9360_TEST_DEBUG_MEM_CTRL, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_BUS_SEL, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_JTAG, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_EN_1, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_EN_2, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_EN_3, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_EN_4, 0x00},
+{WCD9360_TEST_DEBUG_DEBUG_EN_5, 0x00},
+{WCD9360_TEST_DEBUG_ANA_DTEST_DIR, 0x00},
+{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0, 0x00},
+{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1, 0x00},
+{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2, 0x00},
+{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3, 0x00},
+{WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4, 0x00},
+{WCD9360_TEST_DEBUG_SYSMEM_CTRL, 0x00},
+{WCD9360_TEST_DEBUG_LVAL_NOM_LOW, 0x96},
+{WCD9360_TEST_DEBUG_LVAL_NOM_HIGH, 0x00},
+{WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW, 0x53},
+{WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, 0x00},
+{WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR, 0x00},
+{WCD9360_TEST_DEBUG_CODEC_DIAGS, 0x00},
+};
+
+
+const u8 wcd9360_page0_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE0_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_CLK_BYPASS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_CLK_GATE)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_CLK_MCLK_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_CLK_MCLK2_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_RST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX0_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX1_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX2_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX3_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX4_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX5_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX6_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_RX7_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX0_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX1_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX2_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX3_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX4_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX5_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX6_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX7_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX8_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX9_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX10_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX11_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX12_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX13_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX14_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_SB_TX15_INP_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX0_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX0_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX1_0_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_TX1_1_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_DATA_HUB_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_1_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_CTL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_1_CTL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_CLKSRC_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_COMMON_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CTL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CH_RX)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CH_TX)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_0_TDM_STRETCH)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DATA_HUB_I2S_RESET_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_RDMA_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_RDMA_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA4_PRT_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_SBTX0_7_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_RDMA_SBTX8_10_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_4_5_CFG_WDMA_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_2_3_CFG_WDMA_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_CH_0_1_CFG_WDMA_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA0_PRT_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA3_PRT_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA4_PRT0_3_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DMA_WDMA4_PRT4_7_CFG)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page1_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE1_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_8)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_USER_CTL_9)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_L_VAL_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_L_VAL_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_DSM_FRAC_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_DSM_FRAC_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_CONFIG_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_TEST_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_FREQ_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_SSC_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_FLL_MODE)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_FLL_STATUS_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_FLL_STATUS_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_FLL_STATUS_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_FLL_STATUS_3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_8)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_USER_CTL_9)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_L_VAL_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_L_VAL_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_DSM_FRAC_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_DSM_FRAC_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_CONFIG_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_TEST_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_FREQ_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_SSC_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_FLL_MODE)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_I2S_FLL_STATUS_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_I2S_FLL_STATUS_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_I2S_FLL_STATUS_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_I2S_FLL_STATUS_3)] = WCD9360_RO,
+};
+
+const u8 wcd9360_page2_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE2_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_CPE_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPEFLL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_US_BUF_INT_PERIOD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_SVA_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_US_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_MAD_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_CPAR_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_DMIC0_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_DMIC1_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_DMIC2_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_DMIC_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_CPAR_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_WDOG_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_BACKUP_INT)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_STATUS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_CPE_OCD_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_DMIC3_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_WDOG_RESET)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_MCLK_PRG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_0)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_1)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_2)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_3)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_4)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_5)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_6)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_7)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_8)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_9)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_10)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_11)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_12)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_13)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_14)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_IN_15)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_4)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_5)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_6)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_7)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_8)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_9)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_10)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_11)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_12)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_13)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_14)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_IPC_OUT_15)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_LPASS_ARB_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_MAIN_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_MAIN_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_CTL_8)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_ULTR_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_CTL_8)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_INP_SEL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SOC_MAD_MAD2_INP_SEL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15)] = WCD9360_RO,
+};
+
+const u8 wcd9360_page4_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE4_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_CLR_COMMIT)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_PIN1_MASK0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_PIN1_MASK1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_PIN1_MASK2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_PIN1_MASK3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_PIN1_STATUS0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_PIN1_STATUS1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_PIN1_STATUS2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_PIN1_STATUS3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR0)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR1)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR2)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_PIN1_CLEAR3)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_PIN2_MASK3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_PIN2_STATUS3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_PIN2_CLEAR3)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_MASK2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_MASK3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_STATUS2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_STATUS3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_CLEAR2)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_CPESS_SUMRY_CLEAR3)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_INTR_LEVEL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_LEVEL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_LEVEL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_LEVEL3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_BYPASS0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_BYPASS1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_BYPASS2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_BYPASS3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_SET0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_SET1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_SET2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_SET3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_CODEC_MISC_MASK)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_INTR_CODEC_MISC_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_INTR_CODEC_MISC_CLEAR)] = WCD9360_WO,
+};
+
+const u8 wcd9360_page6_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_ANA_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_BIAS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_AMIC_INPUT_SWITCH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_RCO)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_BUCK_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_BUCK_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_ANA_EAR)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_MAD_SETUP)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_AMIC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_AMIC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_AMIC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_AMIC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_MICB1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_MICB2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_MICB3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_ANA_MICB4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_BIAS_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_BIAS_VBG_FINE_ADJ)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_CTRL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_CTRL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_CAL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_CAL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_CAL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_TEST_CTRL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RCO_CAL_OUT_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_RCO_CAL_OUT_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_RCO_CAL_OUT_3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_RCO_CAL_OUT_4)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_RCO_CAL_OUT_5)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDO_MODE_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_MODE_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_MODE_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_MODE_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_VCL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_VCL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_VCL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_8)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_9)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CCL_10)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_FILTER_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_FILTER_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_DRIVER_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_DRIVER_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_DRIVER_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CAL_CODE_EXT_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CAL_CODE_EXT_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_CAL_CODE_OUT_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDO_CAL_CODE_OUT_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDO_TEST_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_TEST_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDOH_MODE)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDOH_BIAS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDOH_STB_LOADS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDOH_SLOWRAMP)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB1_TEST_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB1_TEST_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB1_TEST_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB2_TEST_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB2_TEST_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB2_TEST_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB3_TEST_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB3_TEST_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB3_TEST_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB4_TEST_CTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB4_TEST_CTL_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MICB4_TEST_CTL_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_ADC_VCM)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_BIAS_ATEST)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_ADC_INT1_IB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_ADC_INT2_IB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_START)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_STOP_9P6M)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_COM_TXFE_DIV_STOP_12P288M)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_TEST_EN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_ADC_IB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_ATEST_REFCTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_TEST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_TEST_BLK_EN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_TXFE_CLKDIV)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_1_2_SAR1_ERR)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TX_1_2_SAR2_ERR)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TX_3_4_TEST_EN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_3_4_ADC_IB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_3_4_ATEST_REFCTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_3_4_TEST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_3_4_TEST_BLK_EN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_3_4_TXFE_CLKDIV)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TX_3_4_SAR1_ERR)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TX_3_4_SAR2_ERR)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_RX_RX_EAR_BIAS_CON_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RX_RX_EAR_BIAS_CON_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RX_RX_AUX_BIAS_CON_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RX_RX_AUX_BIAS_CON_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RX_RX_BIAS_ATEST)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_RX_RXTOP_RESERVED)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_EAR_EN_REG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_EAR_PA_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_EAR_SP_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_EAR_DAC_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_EAR_CNP_FSM_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_DAC_CTL_TEST)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_STATUS_REG)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EAR_EAR_COMPANDER_CON)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page7_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_ANA_NEW_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_PLL_ENABLES)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_PLL_PRESET)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_PLL_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CLK_SYS_MCLK_PRG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_MCLK2_PRG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_MCLK_MISC)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_A_STARTUP)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_STARTUP)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_FREQ1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_VOUT_D_FREQ2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_ANA_EAR)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_LDORXTX)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DIE_CRACK_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DIE_CRACK_OUT)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_LOOP_BACK_EN)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_POST_DIV_REG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_POST_DIV_REG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_REF_DIV_REG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_REF_DIV_REG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_FILTER_REG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_FILTER_REG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_L_VAL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_M_VAL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_PLL_N_VAL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_TEST_REG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_VCO_PROG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_TEST_REG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_LDO_LOCK_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CLK_SYS_INT_CLK_TEST3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_SPARE_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_CTL_A)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_CTL_D)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_EN_REG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_PA_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_SP_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_DAC_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_CNP_FSM_CON)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_TEST)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_AUX_INT_STATUS_REG)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_AUX_INT_AUX_MISC)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_DIE_CRACK_INT_INT1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_DIE_CRACK_INT_INT2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_LOOP_BACK_INT_SPARE)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page10_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE10_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_CLK_RESET_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_MODE_1_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_MODE_2_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_FF_SHIFT)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_FB_SHIFT)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FF_A_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FF_B_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_LPF_FB_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_SMLPF_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_IIR_ADAPT_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_IIR_COEFF_1_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_IIR_COEFF_2_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_FF_A_GAIN_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_FF_B_GAIN_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_ANC0_FB_GAIN_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX0_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX1_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX2_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX3_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX4_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX5_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX6_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX7_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_192_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_192_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX8_TX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page11_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE11_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL6)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_COMPANDER0_CTL7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL6)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_COMPANDER7_CTL7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL6)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_COMPANDER8_CTL7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_VOL_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_SEC7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_MIX_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_VOL_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_SEC7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_MIX_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_VOL_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_SEC7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_MIX_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_VOL_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_VOL_MIX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_SEC7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_SEC0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_MIX_SEC1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page12_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE12_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST0_BOOST_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_BOOST1_BOOST_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_CLK_RST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_FIFO_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC2_STATUS_FIFO)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_CLK_RST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_FIFO_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_MIXING_ASRC3_STATUS_FIFO)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_DATA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_RD_DATA_3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CLK_RST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_FIFO_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_SIDETONE_ASRC0_STATUS_FIFO)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC0_CLK_RST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC0_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC0_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC0_FIFO_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC0_STATUS_FIFO)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC1_CLK_RST_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC1_CTL0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC1_CTL1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC1_FIFO_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_EC_ASRC1_STATUS_FIFO)] = WCD9360_RO,
+};
+
+const u8 wcd9360_page13_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE13_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_ANC_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_TOP_CFG7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_WR_LSB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_WR_MSB)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_LUT)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_RD_LSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_TOP_EAR_COMP_RD_MSB)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CDC_TOP_TOP_DEBUG)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page80_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE80_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_DATA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_WR_ADDR_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_ADDR_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_1)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_2)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CODEC_CPR_RD_DATA_3)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CODEC_CPR_ACCESS_CFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_ACCESS_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CODEC_CPR_NOM_CX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_SVS_CX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_CX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_NOM_MX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_SVS_MX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_MX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_MAX_SVS2_STEP)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_CTL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_CODEC_CPR_SW_MODECHNG_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_CODEC_CPR_SW_MODECHNG_START)] = WCD9360_WO,
+[WCD9360_REG(WCD9360_CODEC_CPR_CPR_STATUS)] = WCD9360_RW,
+};
+
+const u8 wcd9360_page128_reg_access[WCD9360_PAGE_SIZE] = {
+[WCD9360_REG(WCD9360_PAGE128_PAGE_REGISTER)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_JTCK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_INTR1_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_INTR2_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SWR_DATA_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SWR_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SLIMBUS_DATA1_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SLIMBUS_DATA2_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SLIMBUS_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2C_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2C_DATA_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_0_RX_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_0_TX_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_0_SCK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_0_WS_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_1_RX_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_1_TX_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_1_SCK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_I2S_1_WS_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC1_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC1_DATA_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC2_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC2_DATA_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_GPIO1_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_GPIO2_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_GPIO3_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_GPIO4_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SPI_S_CSN_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SPI_S_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SPI_S_DOUT_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_SPI_S_DIN_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_GPIO0_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC3_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC3_DATA_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC4_CLK_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TLMM_DMIC4_DATA_PINCFG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_OE_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_CTL_DATA_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_DRVCTL_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_DRVCTL_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PIN_STATUS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TEST_DEBUG_NPL_DLY_TEST_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_NPL_DLY_TEST_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_MEM_CTRL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_BUS_SEL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_JTAG)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_EN_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_ANA_DTEST_DIR)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_SYSMEM_CTRL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_NOM_LOW)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_NOM_HIGH)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_CODEC_DIAGS)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TEST_DEBUG_PAD_TEST)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_0)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_1)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_2)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_3)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_4)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_5)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_6)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_7)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_8)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_9)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_10)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_11)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_12)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_13)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_14)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_15)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_16)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_17)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_18)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_19)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_20)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_21)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_22)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_23)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_24)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_25)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_26)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_27)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_28)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_29)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_30)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_31)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_CTRL)] = WCD9360_RW,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_7_0)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_15_8)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_23_16)] = WCD9360_RO,
+[WCD9360_REG(WCD9360_TEST_DEBUG_DEBUG_MUX_RD_31_24)] = WCD9360_RO,
+
+};
+
+const u8 * const wcd9360_reg[WCD9360_PAGE_MAX] = {
+[WCD9360_PAGE_0] = wcd9360_page0_reg_access,
+[WCD9360_PAGE_1] = wcd9360_page1_reg_access,
+[WCD9360_PAGE_2] = wcd9360_page2_reg_access,
+[WCD9360_PAGE_4] = wcd9360_page4_reg_access,
+[WCD9360_PAGE_6] = wcd9360_page6_reg_access,
+[WCD9360_PAGE_7] = wcd9360_page7_reg_access,
+[WCD9360_PAGE_10] = wcd9360_page10_reg_access,
+[WCD9360_PAGE_11] = wcd9360_page11_reg_access,
+[WCD9360_PAGE_12] = wcd9360_page12_reg_access,
+[WCD9360_PAGE_13] = wcd9360_page13_reg_access,
+[WCD9360_PAGE_80] = wcd9360_page80_reg_access,
+[WCD9360_PAGE_128] = wcd9360_page128_reg_access,
+};
+
+#endif
diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c
new file mode 100644
index 0000000..863024a
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.c
@@ -0,0 +1,1355 @@
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/component.h>
+#include <linux/debugfs.h>
+#include <sound/soc.h>
+#include <sound/wcd-dsp-mgr.h>
+#include <asoc/wcd9360-registers.h>
+#include "wcd9360.h"
+#include "wcd9360-dsp-cntl.h"
+#include "../wcd9xxx-irq.h"
+#include "../core.h"
+
+#define WCD_CNTL_DIR_NAME_LEN_MAX 32
+#define WCD_CPE_FLL_MAX_RETRIES 5
+#define WCD_MEM_ENABLE_MAX_RETRIES 20
+#define WCD_DSP_BOOT_TIMEOUT_MS 3000
+#define WCD_SYSFS_ENTRY_MAX_LEN 8
+#define WCD_PROCFS_ENTRY_MAX_LEN 16
+#define WCD_9360_RAMDUMP_START_ADDR 0x20100000
+#define WCD_9360_RAMDUMP_SIZE ((1024 * 1024) - 128)
+#define WCD_MISCDEV_CMD_MAX_LEN 2
+
+#define WCD_CNTL_MUTEX_LOCK(codec, lock) \
+{ \
+ dev_dbg(codec->dev, "%s: mutex_lock(%s)\n", \
+ __func__, __stringify_1(lock)); \
+ mutex_lock(&lock); \
+}
+
+#define WCD_CNTL_MUTEX_UNLOCK(codec, lock) \
+{ \
+ dev_dbg(codec->dev, "%s: mutex_unlock(%s)\n", \
+ __func__, __stringify_1(lock)); \
+ mutex_unlock(&lock); \
+}
+
+enum wcd_mem_type {
+ WCD_MEM_TYPE_ALWAYS_ON,
+ WCD_MEM_TYPE_SWITCHABLE,
+};
+
+struct wcd_cntl_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct wcd_dsp_cntl *cntl, char *buf);
+ ssize_t (*store)(struct wcd_dsp_cntl *cntl, const char *buf,
+ ssize_t count);
+};
+
+#define WCD_CNTL_ATTR(_name, _mode, _show, _store) \
+static struct wcd_cntl_attribute cntl_attr_##_name = { \
+ .attr = {.name = __stringify(_name), .mode = _mode}, \
+ .show = _show, \
+ .store = _store, \
+}
+
+#define to_wcd_cntl_attr(a) \
+ container_of((a), struct wcd_cntl_attribute, attr)
+
+#define to_wcd_cntl(kobj) \
+ container_of((kobj), struct wcd_dsp_cntl, wcd_kobj)
+
+static u8 mem_enable_values[] = {
+ 0xFE, 0xFC, 0xF8, 0xF0,
+ 0xE0, 0xC0, 0x80, 0x00,
+};
+
+static ssize_t wdsp_boot_show(struct wcd_dsp_cntl *cntl, char *buf)
+{
+ return snprintf(buf, WCD_SYSFS_ENTRY_MAX_LEN,
+ "%u", cntl->boot_reqs);
+}
+
+static ssize_t wdsp_boot_store(struct wcd_dsp_cntl *cntl,
+ const char *buf, ssize_t count)
+{
+ u32 val;
+ bool vote;
+ int ret;
+
+ ret = kstrtou32(buf, 10, &val);
+ if (ret) {
+ dev_err(cntl->codec->dev,
+ "%s: Invalid entry, ret = %d\n", __func__, ret);
+ return -EINVAL;
+ }
+
+ if (val > 0) {
+ cntl->boot_reqs++;
+ vote = true;
+ } else {
+ cntl->boot_reqs--;
+ vote = false;
+ }
+
+ if (cntl->m_dev && cntl->m_ops &&
+ cntl->m_ops->vote_for_dsp)
+ ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote);
+ else
+ ret = -EINVAL;
+
+ if (ret < 0)
+ dev_err(cntl->codec->dev,
+ "%s: failed to %s dsp\n", __func__,
+ vote ? "enable" : "disable");
+ return count;
+}
+
+WCD_CNTL_ATTR(boot, 0660, wdsp_boot_show, wdsp_boot_store);
+
+static ssize_t wcd_cntl_sysfs_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr);
+ struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj);
+ ssize_t ret = -EINVAL;
+
+ if (cntl && wcd_attr->show)
+ ret = wcd_attr->show(cntl, buf);
+
+ return ret;
+}
+
+static ssize_t wcd_cntl_sysfs_store(struct kobject *kobj,
+ struct attribute *attr, const char *buf,
+ size_t count)
+{
+ struct wcd_cntl_attribute *wcd_attr = to_wcd_cntl_attr(attr);
+ struct wcd_dsp_cntl *cntl = to_wcd_cntl(kobj);
+ ssize_t ret = -EINVAL;
+
+ if (cntl && wcd_attr->store)
+ ret = wcd_attr->store(cntl, buf, count);
+
+ return ret;
+}
+
+static const struct sysfs_ops wcd_cntl_sysfs_ops = {
+ .show = wcd_cntl_sysfs_show,
+ .store = wcd_cntl_sysfs_store,
+};
+
+static struct kobj_type wcd_cntl_ktype = {
+ .sysfs_ops = &wcd_cntl_sysfs_ops,
+};
+
+static void wcd_cntl_change_online_state(struct wcd_dsp_cntl *cntl,
+ u8 online)
+{
+ struct wdsp_ssr_entry *ssr_entry = &cntl->ssr_entry;
+ unsigned long ret;
+
+ WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex);
+ ssr_entry->offline = !online;
+ /* Make sure the write is complete */
+ wmb();
+ ret = xchg(&ssr_entry->offline_change, 1);
+ wake_up_interruptible(&ssr_entry->offline_poll_wait);
+ dev_dbg(cntl->codec->dev,
+ "%s: requested %u, offline %u offline_change %u, ret = %ldn",
+ __func__, online, ssr_entry->offline,
+ ssr_entry->offline_change, ret);
+ WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex);
+}
+
+static ssize_t wdsp_ssr_entry_read(struct snd_info_entry *entry,
+ void *file_priv_data, struct file *file,
+ char __user *buf, size_t count, loff_t pos)
+{
+ int len = 0;
+ char buffer[WCD_PROCFS_ENTRY_MAX_LEN];
+ struct wcd_dsp_cntl *cntl;
+ struct wdsp_ssr_entry *ssr_entry;
+ ssize_t ret;
+ u8 offline;
+
+ cntl = (struct wcd_dsp_cntl *) entry->private_data;
+ if (!cntl) {
+ pr_err("%s: Invalid private data for SSR procfs entry\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ ssr_entry = &cntl->ssr_entry;
+
+ WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex);
+ offline = ssr_entry->offline;
+ /* Make sure the read is complete */
+ rmb();
+ dev_dbg(cntl->codec->dev, "%s: offline = %s\n", __func__,
+ offline ? "true" : "false");
+ len = snprintf(buffer, sizeof(buffer), "%s\n",
+ offline ? "OFFLINE" : "ONLINE");
+ ret = simple_read_from_buffer(buf, count, &pos, buffer, len);
+ WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex);
+
+ return ret;
+}
+
+static unsigned int wdsp_ssr_entry_poll(struct snd_info_entry *entry,
+ void *private_data, struct file *file,
+ poll_table *wait)
+{
+ struct wcd_dsp_cntl *cntl;
+ struct wdsp_ssr_entry *ssr_entry;
+ unsigned int ret = 0;
+
+ if (!entry || !entry->private_data) {
+ pr_err("%s: %s is NULL\n", __func__,
+ (!entry) ? "entry" : "private_data");
+ return -EINVAL;
+ }
+
+ cntl = (struct wcd_dsp_cntl *) entry->private_data;
+ ssr_entry = &cntl->ssr_entry;
+
+ dev_dbg(cntl->codec->dev, "%s: Poll wait, offline = %u\n",
+ __func__, ssr_entry->offline);
+ poll_wait(file, &ssr_entry->offline_poll_wait, wait);
+ dev_dbg(cntl->codec->dev, "%s: Woken up Poll wait, offline = %u\n",
+ __func__, ssr_entry->offline);
+
+ WCD_CNTL_MUTEX_LOCK(cntl->codec, cntl->ssr_mutex);
+ if (xchg(&ssr_entry->offline_change, 0))
+ ret = POLLIN | POLLPRI | POLLRDNORM;
+ dev_dbg(cntl->codec->dev, "%s: ret (%d) from poll_wait\n",
+ __func__, ret);
+ WCD_CNTL_MUTEX_UNLOCK(cntl->codec, cntl->ssr_mutex);
+
+ return ret;
+}
+
+static struct snd_info_entry_ops wdsp_ssr_entry_ops = {
+ .read = wdsp_ssr_entry_read,
+ .poll = wdsp_ssr_entry_poll,
+};
+
+static int wcd_cntl_cpe_fll_calibrate(struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret = 0, retry = 0;
+ u8 cal_lsb, cal_msb;
+ u8 lock_det;
+
+ /* Make sure clocks are gated */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL,
+ 0x05, 0x00);
+
+ /* Enable CPE FLL reference clock */
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1,
+ 0x80, 0x80);
+
+ snd_soc_update_bits(codec, WCD9360_CPE_FLL_USER_CTL_5,
+ 0xF3, 0x13);
+ snd_soc_write(codec, WCD9360_CPE_FLL_L_VAL_CTL_0, 0x50);
+
+ /* Disable CPAR reset and Enable CPAR clk */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL,
+ 0x02, 0x02);
+
+ /* Write calibration l-value based on cdc clk rate */
+ if (cntl->clk_rate == 9600000) {
+ cal_lsb = 0x6d;
+ cal_msb = 0x00;
+ } else {
+ cal_lsb = 0x56;
+ cal_msb = 0x00;
+ }
+ snd_soc_write(codec, WCD9360_CPE_FLL_USER_CTL_6, cal_lsb);
+ snd_soc_write(codec, WCD9360_CPE_FLL_USER_CTL_7, cal_msb);
+
+ /* FLL mode to follow power up sequence */
+ snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE,
+ 0x60, 0x00);
+
+ /* HW controlled CPE FLL */
+ snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE,
+ 0x80, 0x80);
+
+ /* Force on CPE FLL */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG,
+ 0x04, 0x04);
+
+ do {
+ /* Time for FLL calibration to complete */
+ usleep_range(1000, 1100);
+ lock_det = snd_soc_read(codec, WCD9360_CPE_FLL_STATUS_3);
+ retry++;
+ } while (!(lock_det & 0x01) &&
+ retry <= WCD_CPE_FLL_MAX_RETRIES);
+
+ if (!(lock_det & 0x01)) {
+ dev_err(codec->dev, "%s: lock detect not set, 0x%02x\n",
+ __func__, lock_det);
+ ret = -EIO;
+ goto err_lock_det;
+ }
+
+ snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE,
+ 0x60, 0x20);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG,
+ 0x04, 0x00);
+ return ret;
+
+err_lock_det:
+ /* Undo the register settings */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG,
+ 0x04, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CPE_FLL_FLL_MODE,
+ 0x80, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL,
+ 0x02, 0x00);
+ return ret;
+}
+
+static void wcd_cntl_config_cpar(struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ u8 nom_lo, nom_hi, svs2_lo, svs2_hi;
+
+ /* Configure CPAR */
+ nom_hi = svs2_hi = 0;
+ if (cntl->clk_rate == 9600000) {
+ nom_lo = 0x90;
+ svs2_lo = 0x50;
+ } else {
+ nom_lo = 0x70;
+ svs2_lo = 0x3e;
+ }
+
+ snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_NOM_LOW, nom_lo);
+ snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_NOM_HIGH, nom_hi);
+ snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW, svs2_lo);
+ snd_soc_write(codec, WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH, svs2_hi);
+
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_PWR_CPEFLL_CTL,
+ 0x03, 0x03);
+}
+
+static int wcd_cntl_cpe_fll_ctrl(struct wcd_dsp_cntl *cntl,
+ bool enable)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret = 0;
+
+ if (enable) {
+ ret = wcd_cntl_cpe_fll_calibrate(cntl);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: cpe_fll_cal failed, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ wcd_cntl_config_cpar(cntl);
+
+ /* Enable AHB CLK and CPE CLK*/
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL,
+ 0x05, 0x05);
+ } else {
+ /* Disable AHB CLK and CPE CLK */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL,
+ 0x05, 0x00);
+ /* Reset the CPAR mode for CPE FLL */
+ snd_soc_write(codec, WCD9360_CPE_FLL_FLL_MODE, 0x20);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CFG,
+ 0x04, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL,
+ 0x02, 0x00);
+ }
+done:
+ return ret;
+}
+
+static int wcd_cntl_clocks_enable(struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret;
+
+ WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex);
+ /* Enable codec clock */
+ if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en)
+ ret = cntl->cdc_cb->cdc_clk_en(codec, true);
+ else
+ ret = -EINVAL;
+
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Failed to enable cdc clk, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+ /* Pull CPAR out of reset */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x00);
+
+ /* Configure and Enable CPE FLL clock */
+ ret = wcd_cntl_cpe_fll_ctrl(cntl, true);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Failed to enable cpe clk, err = %d\n",
+ __func__, ret);
+ goto err_cpe_clk;
+ }
+ cntl->is_clk_enabled = true;
+
+ /* Ungate the CPR clock */
+ snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, 0x10, 0x00);
+done:
+ WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex);
+ return ret;
+
+err_cpe_clk:
+ if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en)
+ cntl->cdc_cb->cdc_clk_en(codec, false);
+
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x04);
+ WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex);
+ return ret;
+}
+
+static int wcd_cntl_clocks_disable(struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret = 0;
+
+ WCD_CNTL_MUTEX_LOCK(codec, cntl->clk_mutex);
+ if (!cntl->is_clk_enabled) {
+ dev_info(codec->dev, "%s: clocks already disabled\n",
+ __func__);
+ goto done;
+ }
+
+ /* Gate the CPR clock */
+ snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE, 0x10, 0x10);
+
+ /* Disable CPE FLL clock */
+ ret = wcd_cntl_cpe_fll_ctrl(cntl, false);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "%s: Failed to disable cpe clk, err = %d\n",
+ __func__, ret);
+
+ /*
+ * Even if CPE FLL disable failed, go ahead and disable
+ * the codec clock
+ */
+ if (cntl->cdc_cb && cntl->cdc_cb->cdc_clk_en)
+ ret = cntl->cdc_cb->cdc_clk_en(codec, false);
+ else
+ ret = -EINVAL;
+
+ cntl->is_clk_enabled = false;
+
+ /* Put CPAR in reset */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x04, 0x04);
+done:
+ WCD_CNTL_MUTEX_UNLOCK(codec, cntl->clk_mutex);
+ return ret;
+}
+
+static void wcd_cntl_cpar_ctrl(struct wcd_dsp_cntl *cntl,
+ bool enable)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+
+ if (enable)
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x03, 0x03);
+ else
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPAR_CTL, 0x03, 0x00);
+}
+
+static int wcd_cntl_enable_memory(struct wcd_dsp_cntl *cntl,
+ enum wcd_mem_type mem_type)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
+ int loop_cnt = 0;
+ u8 status = 0;
+ int ret = 0;
+
+
+ switch (mem_type) {
+
+ case WCD_MEM_TYPE_ALWAYS_ON:
+
+ /* 512KB of always on region */
+ wcd9xxx_slim_write_repeat(wcd9xxx,
+ WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0,
+ ARRAY_SIZE(mem_enable_values),
+ mem_enable_values);
+ wcd9xxx_slim_write_repeat(wcd9xxx,
+ WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1,
+ ARRAY_SIZE(mem_enable_values),
+ mem_enable_values);
+ break;
+
+ case WCD_MEM_TYPE_SWITCHABLE:
+
+ snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_MEM_CTRL,
+ 0x80, 0x80);
+ do {
+ loop_cnt++;
+ /* Time to enable the power domain for memory */
+ usleep_range(100, 150);
+ } while ((status & 0x02) != 0x02 &&
+ loop_cnt != WCD_MEM_ENABLE_MAX_RETRIES);
+
+ if ((status & 0x02) != 0x02) {
+ dev_err(cntl->codec->dev,
+ "%s: power domain not enabled, status = 0x%02x\n",
+ __func__, status);
+ ret = -EIO;
+ goto done;
+ }
+
+ /* Rest of the memory */
+ wcd9xxx_slim_write_repeat(wcd9xxx,
+ WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2,
+ ARRAY_SIZE(mem_enable_values),
+ mem_enable_values);
+ wcd9xxx_slim_write_repeat(wcd9xxx,
+ WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3,
+ ARRAY_SIZE(mem_enable_values),
+ mem_enable_values);
+
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN,
+ 0x05);
+ break;
+
+ default:
+ dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n",
+ __func__, mem_type);
+ ret = -EINVAL;
+ break;
+ }
+done:
+ /* Make sure Deep sleep of memories is enabled for all banks */
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F);
+
+ return ret;
+}
+
+static void wcd_cntl_disable_memory(struct wcd_dsp_cntl *cntl,
+ enum wcd_mem_type mem_type)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+
+ switch (mem_type) {
+ case WCD_MEM_TYPE_ALWAYS_ON:
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1,
+ 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0,
+ 0xFF);
+ break;
+ case WCD_MEM_TYPE_SWITCHABLE:
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3,
+ 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2,
+ 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN,
+ 0x07);
+
+ snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_MEM_CTRL,
+ 0x80, 0x00);
+ break;
+ default:
+ dev_err(cntl->codec->dev, "%s: Invalid mem_type %d\n",
+ __func__, mem_type);
+ break;
+ }
+
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0, 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1, 0x0F);
+}
+
+static void wcd_cntl_do_shutdown(struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+
+ /* Disable WDOG */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG,
+ 0x3F, 0x01);
+
+ /* Put WDSP in reset state */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL,
+ 0x02, 0x00);
+
+ /* If DSP transitions from boot to shutdown, then vote for SVS */
+ if (cntl->is_wdsp_booted)
+ cntl->cdc_cb->cdc_vote_svs(codec, true);
+ cntl->is_wdsp_booted = false;
+}
+
+static int wcd_cntl_do_boot(struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret = 0;
+
+ /*
+ * Debug mode is set from debugfs file node. If debug_mode
+ * is set, then do not configure the watchdog timer. This
+ * will be required for debugging the DSP firmware.
+ */
+ if (cntl->debug_mode) {
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG,
+ 0x3F, 0x01);
+ } else {
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG,
+ 0x3F, 0x21);
+ }
+
+ /* Make sure all the error interrupts are cleared */
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A, 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B, 0xFF);
+
+ reinit_completion(&cntl->boot_complete);
+
+ /* Remove WDSP out of reset */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_CPE_CTL,
+ 0x02, 0x02);
+
+ /*
+ * In debug mode, DSP may not boot up normally,
+ * wait indefinitely for DSP to boot.
+ */
+ if (cntl->debug_mode) {
+ wait_for_completion(&cntl->boot_complete);
+ dev_dbg(codec->dev, "%s: WDSP booted in dbg mode\n", __func__);
+ cntl->is_wdsp_booted = true;
+ goto done;
+ }
+
+ /* Boot in normal mode */
+ ret = wait_for_completion_timeout(&cntl->boot_complete,
+ msecs_to_jiffies(WCD_DSP_BOOT_TIMEOUT_MS));
+ if (!ret) {
+ dev_err(codec->dev, "%s: WDSP boot timed out\n",
+ __func__);
+ ret = -ETIMEDOUT;
+ goto err_boot;
+ } else {
+ /*
+ * Re-initialize the return code to 0, as in success case,
+ * it will hold the remaining time for completion timeout
+ */
+ ret = 0;
+ }
+
+ dev_dbg(codec->dev, "%s: WDSP booted in normal mode\n", __func__);
+ cntl->is_wdsp_booted = true;
+
+ /* Enable WDOG */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_WDOG_CFG,
+ 0x10, 0x10);
+done:
+ /* If dsp booted up, then remove vote on SVS */
+ if (cntl->is_wdsp_booted)
+ cntl->cdc_cb->cdc_vote_svs(codec, false);
+
+ return ret;
+err_boot:
+ /* call shutdown to perform cleanup */
+ wcd_cntl_do_shutdown(cntl);
+ return ret;
+}
+
+static irqreturn_t wcd_cntl_ipc_irq(int irq, void *data)
+{
+ struct wcd_dsp_cntl *cntl = data;
+ int ret;
+
+ complete(&cntl->boot_complete);
+
+ if (cntl->m_dev && cntl->m_ops &&
+ cntl->m_ops->signal_handler)
+ ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_IPC1_INTR,
+ NULL);
+ else
+ ret = -EINVAL;
+
+ if (ret < 0)
+ dev_err(cntl->codec->dev,
+ "%s: Failed to handle irq %d\n", __func__, irq);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t wcd_cntl_err_irq(int irq, void *data)
+{
+ struct wcd_dsp_cntl *cntl = data;
+ struct snd_soc_codec *codec = cntl->codec;
+ struct wdsp_err_signal_arg arg;
+ u16 status = 0;
+ u8 reg_val;
+ int ret = 0;
+
+ reg_val = snd_soc_read(codec, WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A);
+ status = status | reg_val;
+
+ reg_val = snd_soc_read(codec, WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B);
+ status = status | (reg_val << 8);
+
+ dev_info(codec->dev, "%s: error interrupt status = 0x%x\n",
+ __func__, status);
+
+ if ((status & cntl->irqs.fatal_irqs) &&
+ (cntl->m_dev && cntl->m_ops && cntl->m_ops->signal_handler)) {
+ arg.mem_dumps_enabled = cntl->ramdump_enable;
+ arg.remote_start_addr = WCD_9360_RAMDUMP_START_ADDR;
+ arg.dump_size = WCD_9360_RAMDUMP_SIZE;
+ ret = cntl->m_ops->signal_handler(cntl->m_dev, WDSP_ERR_INTR,
+ &arg);
+ if (ret < 0)
+ dev_err(cntl->codec->dev,
+ "%s: Failed to handle fatal irq 0x%x\n",
+ __func__, status & cntl->irqs.fatal_irqs);
+ wcd_cntl_change_online_state(cntl, 0);
+ } else {
+ dev_err(cntl->codec->dev, "%s: Invalid signal_handler\n",
+ __func__);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int wcd_control_handler(struct device *dev, void *priv_data,
+ enum wdsp_event_type event, void *data)
+{
+ struct wcd_dsp_cntl *cntl = priv_data;
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret = 0;
+
+ switch (event) {
+ case WDSP_EVENT_POST_INIT:
+ case WDSP_EVENT_POST_DLOAD_CODE:
+ case WDSP_EVENT_DLOAD_FAILED:
+ case WDSP_EVENT_POST_SHUTDOWN:
+
+ /* Disable CPAR */
+ wcd_cntl_cpar_ctrl(cntl, false);
+ /* Disable all the clocks */
+ ret = wcd_cntl_clocks_disable(cntl);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "%s: Failed to disable clocks, err = %d\n",
+ __func__, ret);
+
+ if (event == WDSP_EVENT_POST_DLOAD_CODE)
+ /* Mark DSP online since code download is complete */
+ wcd_cntl_change_online_state(cntl, 1);
+ break;
+
+ case WDSP_EVENT_PRE_DLOAD_DATA:
+ case WDSP_EVENT_PRE_DLOAD_CODE:
+
+ /* Enable all the clocks */
+ ret = wcd_cntl_clocks_enable(cntl);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Failed to enable clocks, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ /* Enable CPAR */
+ wcd_cntl_cpar_ctrl(cntl, true);
+
+ if (event == WDSP_EVENT_PRE_DLOAD_CODE)
+ wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_ALWAYS_ON);
+ else if (event == WDSP_EVENT_PRE_DLOAD_DATA)
+ wcd_cntl_enable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE);
+ break;
+
+ case WDSP_EVENT_DO_BOOT:
+
+ ret = wcd_cntl_do_boot(cntl);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "%s: WDSP boot failed, err = %d\n",
+ __func__, ret);
+ break;
+
+ case WDSP_EVENT_DO_SHUTDOWN:
+
+ wcd_cntl_do_shutdown(cntl);
+ wcd_cntl_disable_memory(cntl, WCD_MEM_TYPE_SWITCHABLE);
+ break;
+
+ default:
+ dev_dbg(codec->dev, "%s: unhandled event %d\n",
+ __func__, event);
+ }
+
+done:
+ return ret;
+}
+
+static int wcd_cntl_sysfs_init(char *dir, struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+ int ret = 0;
+
+ ret = kobject_init_and_add(&cntl->wcd_kobj, &wcd_cntl_ktype,
+ kernel_kobj, dir);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Failed to add kobject %s, err = %d\n",
+ __func__, dir, ret);
+ goto done;
+ }
+
+ ret = sysfs_create_file(&cntl->wcd_kobj, &cntl_attr_boot.attr);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Failed to add wdsp_boot sysfs entry to %s\n",
+ __func__, dir);
+ goto fail_create_file;
+ }
+
+ return ret;
+
+fail_create_file:
+ kobject_put(&cntl->wcd_kobj);
+done:
+ return ret;
+}
+
+static void wcd_cntl_sysfs_remove(struct wcd_dsp_cntl *cntl)
+{
+ sysfs_remove_file(&cntl->wcd_kobj, &cntl_attr_boot.attr);
+ kobject_put(&cntl->wcd_kobj);
+}
+
+static void wcd_cntl_debugfs_init(char *dir, struct wcd_dsp_cntl *cntl)
+{
+ struct snd_soc_codec *codec = cntl->codec;
+
+ cntl->entry = debugfs_create_dir(dir, NULL);
+ if (IS_ERR_OR_NULL(dir)) {
+ dev_err(codec->dev, "%s debugfs_create_dir failed for %s\n",
+ __func__, dir);
+ goto done;
+ }
+
+ debugfs_create_u32("debug_mode", 0644,
+ cntl->entry, &cntl->debug_mode);
+ debugfs_create_bool("ramdump_enable", 0644,
+ cntl->entry, &cntl->ramdump_enable);
+done:
+ return;
+}
+
+static void wcd_cntl_debugfs_remove(struct wcd_dsp_cntl *cntl)
+{
+ if (cntl)
+ debugfs_remove(cntl->entry);
+}
+
+static int wcd_miscdev_release(struct inode *inode, struct file *filep)
+{
+ struct wcd_dsp_cntl *cntl = container_of(filep->private_data,
+ struct wcd_dsp_cntl, miscdev);
+ if (!cntl->m_dev || !cntl->m_ops ||
+ !cntl->m_ops->vote_for_dsp) {
+ dev_err(cntl->codec->dev,
+ "%s: DSP not ready to boot\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Make sure the DSP users goes to zero upon closing dev node */
+ while (cntl->boot_reqs > 0) {
+ cntl->m_ops->vote_for_dsp(cntl->m_dev, false);
+ cntl->boot_reqs--;
+ }
+
+ return 0;
+}
+
+static ssize_t wcd_miscdev_write(struct file *filep, const char __user *ubuf,
+ size_t count, loff_t *pos)
+{
+ struct wcd_dsp_cntl *cntl = container_of(filep->private_data,
+ struct wcd_dsp_cntl, miscdev);
+ char val[WCD_MISCDEV_CMD_MAX_LEN];
+ bool vote;
+ int ret = 0;
+
+ if (count == 0 || count > WCD_MISCDEV_CMD_MAX_LEN) {
+ pr_err("%s: Invalid count = %zd\n", __func__, count);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = copy_from_user(val, ubuf, count);
+ if (ret < 0) {
+ dev_err(cntl->codec->dev,
+ "%s: copy_from_user failed, err = %d\n",
+ __func__, ret);
+ ret = -EFAULT;
+ goto done;
+ }
+
+ if (val[0] == '1') {
+ cntl->boot_reqs++;
+ vote = true;
+ } else if (val[0] == '0') {
+ if (cntl->boot_reqs == 0) {
+ dev_err(cntl->codec->dev,
+ "%s: WDSP already disabled\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ cntl->boot_reqs--;
+ vote = false;
+ } else {
+ dev_err(cntl->codec->dev, "%s: Invalid value %s\n",
+ __func__, val);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ dev_dbg(cntl->codec->dev,
+ "%s: booted = %s, ref_cnt = %d, vote = %s\n",
+ __func__, cntl->is_wdsp_booted ? "true" : "false",
+ cntl->boot_reqs, vote ? "true" : "false");
+
+ if (cntl->m_dev && cntl->m_ops &&
+ cntl->m_ops->vote_for_dsp)
+ ret = cntl->m_ops->vote_for_dsp(cntl->m_dev, vote);
+ else
+ ret = -EINVAL;
+done:
+ if (ret)
+ return ret;
+ else
+ return count;
+}
+
+static const struct file_operations wcd_miscdev_fops = {
+ .write = wcd_miscdev_write,
+ .release = wcd_miscdev_release,
+};
+
+static int wcd_cntl_miscdev_create(struct wcd_dsp_cntl *cntl)
+{
+ snprintf(cntl->miscdev_name, ARRAY_SIZE(cntl->miscdev_name),
+ "wcd_dsp%u_control", cntl->dsp_instance);
+ cntl->miscdev.minor = MISC_DYNAMIC_MINOR;
+ cntl->miscdev.name = cntl->miscdev_name;
+ cntl->miscdev.fops = &wcd_miscdev_fops;
+ cntl->miscdev.parent = cntl->codec->dev;
+
+ return misc_register(&cntl->miscdev);
+}
+
+static void wcd_cntl_miscdev_destroy(struct wcd_dsp_cntl *cntl)
+{
+ misc_deregister(&cntl->miscdev);
+}
+
+static int wcd_control_init(struct device *dev, void *priv_data)
+{
+ struct wcd_dsp_cntl *cntl = priv_data;
+ struct snd_soc_codec *codec = cntl->codec;
+ struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
+ struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res;
+ int ret;
+ bool err_irq_requested = false;
+
+ ret = wcd9xxx_request_irq(core_res,
+ cntl->irqs.cpe_ipc1_irq,
+ wcd_cntl_ipc_irq, "CPE IPC1",
+ cntl);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: Failed to request cpe ipc irq, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ /* Unmask the fatal irqs */
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A,
+ ~(cntl->irqs.fatal_irqs & 0xFF));
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B,
+ ~((cntl->irqs.fatal_irqs >> 8) & 0xFF));
+
+ /*
+ * CPE ERR irq is used only for error reporting from WCD DSP,
+ * even if this request fails, DSP can be function normally.
+ * Continuing with init even if the CPE ERR irq request fails.
+ */
+ if (wcd9xxx_request_irq(core_res, cntl->irqs.cpe_err_irq,
+ wcd_cntl_err_irq, "CPE ERR", cntl))
+ dev_info(codec->dev, "%s: Failed request_irq(cpe_err_irq)",
+ __func__);
+ else
+ err_irq_requested = true;
+
+
+ /* Enable all the clocks */
+ ret = wcd_cntl_clocks_enable(cntl);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: Failed to enable clocks, err = %d\n",
+ __func__, ret);
+ goto err_clk_enable;
+ }
+ wcd_cntl_cpar_ctrl(cntl, true);
+
+ return 0;
+
+err_clk_enable:
+ /* Mask all error interrupts */
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF);
+
+ /* Free the irq's requested */
+ wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl);
+
+ if (err_irq_requested)
+ wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl);
+done:
+ return ret;
+}
+
+static int wcd_control_deinit(struct device *dev, void *priv_data)
+{
+ struct wcd_dsp_cntl *cntl = priv_data;
+ struct snd_soc_codec *codec = cntl->codec;
+ struct wcd9xxx *wcd9xxx = dev_get_drvdata(codec->dev->parent);
+ struct wcd9xxx_core_resource *core_res = &wcd9xxx->core_res;
+
+ wcd_cntl_clocks_disable(cntl);
+ wcd_cntl_cpar_ctrl(cntl, false);
+
+ /* Mask all error interrupts */
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A, 0xFF);
+ snd_soc_write(codec, WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B, 0xFF);
+
+ /* Free the irq's requested */
+ wcd9xxx_free_irq(core_res, cntl->irqs.cpe_err_irq, cntl);
+ wcd9xxx_free_irq(core_res, cntl->irqs.cpe_ipc1_irq, cntl);
+
+ return 0;
+}
+
+static struct wdsp_cmpnt_ops control_ops = {
+ .init = wcd_control_init,
+ .deinit = wcd_control_deinit,
+ .event_handler = wcd_control_handler,
+};
+
+static int wcd_ctrl_component_bind(struct device *dev,
+ struct device *master,
+ void *data)
+{
+ struct wcd_dsp_cntl *cntl;
+ struct snd_soc_codec *codec;
+ struct snd_card *card;
+ struct snd_info_entry *entry;
+ char proc_name[WCD_PROCFS_ENTRY_MAX_LEN];
+ char wcd_cntl_dir_name[WCD_CNTL_DIR_NAME_LEN_MAX];
+ int ret = 0;
+
+ if (!dev || !master || !data) {
+ pr_err("%s: Invalid parameters\n", __func__);
+ return -EINVAL;
+ }
+
+ cntl = (struct wcd_dsp_cntl *) pahu_get_wcd_dsp_cntl(dev);
+ if (!cntl) {
+ dev_err(dev, "%s: Failed to get cntl reference\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ cntl->m_dev = master;
+ cntl->m_ops = data;
+
+ if (!cntl->m_ops->register_cmpnt_ops) {
+ dev_err(dev, "%s: invalid master callback register_cmpnt_ops\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = cntl->m_ops->register_cmpnt_ops(master, dev, cntl, &control_ops);
+ if (ret) {
+ dev_err(dev, "%s: register_cmpnt_ops failed, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = wcd_cntl_miscdev_create(cntl);
+ if (ret < 0) {
+ dev_err(dev, "%s: misc dev register failed, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ snprintf(wcd_cntl_dir_name, WCD_CNTL_DIR_NAME_LEN_MAX,
+ "%s%d", "wdsp", cntl->dsp_instance);
+ ret = wcd_cntl_sysfs_init(wcd_cntl_dir_name, cntl);
+ if (ret < 0) {
+ dev_err(dev, "%s: sysfs_init failed, err = %d\n",
+ __func__, ret);
+ goto err_sysfs_init;
+ }
+
+ wcd_cntl_debugfs_init(wcd_cntl_dir_name, cntl);
+
+ codec = cntl->codec;
+ card = codec->component.card->snd_card;
+ snprintf(proc_name, WCD_PROCFS_ENTRY_MAX_LEN, "%s%d%s", "cpe",
+ cntl->dsp_instance, "_state");
+ entry = snd_info_create_card_entry(card, proc_name, card->proc_root);
+ if (!entry) {
+ /* Do not treat this as Fatal error */
+ dev_err(dev, "%s: Failed to create procfs entry %s\n",
+ __func__, proc_name);
+ goto err_sysfs_init;
+ }
+
+ cntl->ssr_entry.entry = entry;
+ cntl->ssr_entry.offline = 1;
+ entry->size = WCD_PROCFS_ENTRY_MAX_LEN;
+ entry->content = SNDRV_INFO_CONTENT_DATA;
+ entry->c.ops = &wdsp_ssr_entry_ops;
+ entry->private_data = cntl;
+ ret = snd_info_register(entry);
+ if (ret < 0) {
+ dev_err(dev, "%s: Failed to register entry %s, err = %d\n",
+ __func__, proc_name, ret);
+ snd_info_free_entry(entry);
+ /* Let bind still happen even if creating the entry failed */
+ ret = 0;
+ }
+done:
+ return ret;
+
+err_sysfs_init:
+ wcd_cntl_miscdev_destroy(cntl);
+ return ret;
+}
+
+static void wcd_ctrl_component_unbind(struct device *dev,
+ struct device *master,
+ void *data)
+{
+ struct wcd_dsp_cntl *cntl;
+
+ if (!dev) {
+ pr_err("%s: Invalid device\n", __func__);
+ return;
+ }
+
+ cntl = (struct wcd_dsp_cntl *) pahu_get_wcd_dsp_cntl(dev);
+ if (!cntl) {
+ dev_err(dev, "%s: Failed to get cntl reference\n",
+ __func__);
+ return;
+ }
+
+ cntl->m_dev = NULL;
+ cntl->m_ops = NULL;
+
+ /* Remove the sysfs entries */
+ wcd_cntl_sysfs_remove(cntl);
+
+ /* Remove the debugfs entries */
+ wcd_cntl_debugfs_remove(cntl);
+
+ /* Remove the misc device */
+ wcd_cntl_miscdev_destroy(cntl);
+}
+
+static const struct component_ops wcd_ctrl_component_ops = {
+ .bind = wcd_ctrl_component_bind,
+ .unbind = wcd_ctrl_component_unbind,
+};
+
+/*
+ * wcd9360_dsp_ssr_event: handle the SSR event raised by caller.
+ * @cntl: Handle to the wcd_dsp_cntl structure
+ * @event: The SSR event to be handled
+ *
+ * Notifies the manager driver about the SSR event.
+ * Returns 0 on success and negative error code on error.
+ */
+int wcd9360_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event)
+{
+ int ret = 0;
+
+ if (!cntl) {
+ pr_err("%s: Invalid handle to control\n", __func__);
+ return -EINVAL;
+ }
+
+ if (!cntl->m_dev || !cntl->m_ops || !cntl->m_ops->signal_handler) {
+ dev_err(cntl->codec->dev,
+ "%s: Invalid signal_handler callback\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case WCD_CDC_DOWN_EVENT:
+ ret = cntl->m_ops->signal_handler(cntl->m_dev,
+ WDSP_CDC_DOWN_SIGNAL,
+ NULL);
+ if (ret < 0)
+ dev_err(cntl->codec->dev,
+ "%s: WDSP_CDC_DOWN_SIGNAL failed, err = %d\n",
+ __func__, ret);
+ wcd_cntl_change_online_state(cntl, 0);
+ break;
+ case WCD_CDC_UP_EVENT:
+ ret = cntl->m_ops->signal_handler(cntl->m_dev,
+ WDSP_CDC_UP_SIGNAL,
+ NULL);
+ if (ret < 0)
+ dev_err(cntl->codec->dev,
+ "%s: WDSP_CDC_UP_SIGNAL failed, err = %d\n",
+ __func__, ret);
+ break;
+ default:
+ dev_err(cntl->codec->dev, "%s: Invalid event %d\n",
+ __func__, event);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(wcd9360_dsp_ssr_event);
+
+/*
+ * wcd9360_dsp_cntl_init: Initialize the wcd-dsp control
+ * @codec: pointer to the codec handle
+ * @params: Parameters required to initialize wcd-dsp control
+ *
+ * This API is expected to be invoked by the codec driver and
+ * provide information essential for the wcd dsp control to
+ * configure and initialize the dsp
+ */
+void wcd9360_dsp_cntl_init(struct snd_soc_codec *codec,
+ struct wcd_dsp_params *params,
+ struct wcd_dsp_cntl **cntl)
+{
+ struct wcd_dsp_cntl *control;
+ int ret;
+
+ if (!codec || !params) {
+ pr_err("%s: Invalid handle to %s\n", __func__,
+ (!codec) ? "codec" : "params");
+ *cntl = NULL;
+ return;
+ }
+
+ if (*cntl) {
+ pr_err("%s: cntl is non NULL, maybe already initialized ?\n",
+ __func__);
+ return;
+ }
+
+ if (!params->cb || !params->cb->cdc_clk_en ||
+ !params->cb->cdc_vote_svs) {
+ dev_err(codec->dev,
+ "%s: clk_en and vote_svs callbacks must be provided\n",
+ __func__);
+ return;
+ }
+
+ control = kzalloc(sizeof(*control), GFP_KERNEL);
+ if (!(control))
+ return;
+
+ control->codec = codec;
+ control->clk_rate = params->clk_rate;
+ control->cdc_cb = params->cb;
+ control->dsp_instance = params->dsp_instance;
+ memcpy(&control->irqs, ¶ms->irqs, sizeof(control->irqs));
+ init_completion(&control->boot_complete);
+ mutex_init(&control->clk_mutex);
+ mutex_init(&control->ssr_mutex);
+ init_waitqueue_head(&control->ssr_entry.offline_poll_wait);
+
+ /*
+ * The default state of WDSP is in SVS mode.
+ * Vote for SVS now, the vote will be removed only
+ * after DSP is booted up.
+ */
+ control->cdc_cb->cdc_vote_svs(codec, true);
+
+ /*
+ * If this is the last component needed by master to be ready,
+ * then component_bind will be called within the component_add.
+ * Hence, the data pointer should be assigned before component_add,
+ * so that we can access it during this component's bind call.
+ */
+ *cntl = control;
+ ret = component_add(codec->dev, &wcd_ctrl_component_ops);
+ if (ret) {
+ dev_err(codec->dev, "%s: component_add failed, err = %d\n",
+ __func__, ret);
+ kfree(*cntl);
+ *cntl = NULL;
+ }
+}
+EXPORT_SYMBOL(wcd9360_dsp_cntl_init);
+
+/*
+ * wcd9360_dsp_cntl_deinit: De-initialize the wcd-dsp control
+ * @cntl: The struct wcd_dsp_cntl to de-initialize
+ *
+ * This API is intended to be invoked by the codec driver
+ * to de-initialize the wcd dsp control
+ */
+void wcd9360_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl)
+{
+ struct wcd_dsp_cntl *control = *cntl;
+ struct snd_soc_codec *codec;
+
+ /* If control is NULL, there is nothing to de-initialize */
+ if (!control)
+ return;
+ codec = control->codec;
+
+ /*
+ * Calling shutdown will cleanup all register states,
+ * irrespective of DSP was booted up or not.
+ */
+ wcd_cntl_do_shutdown(control);
+ wcd_cntl_disable_memory(control, WCD_MEM_TYPE_SWITCHABLE);
+ wcd_cntl_disable_memory(control, WCD_MEM_TYPE_ALWAYS_ON);
+
+ component_del(codec->dev, &wcd_ctrl_component_ops);
+
+ mutex_destroy(&control->clk_mutex);
+ mutex_destroy(&control->ssr_mutex);
+ kfree(*cntl);
+ *cntl = NULL;
+}
+EXPORT_SYMBOL(wcd9360_dsp_cntl_deinit);
diff --git a/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h
new file mode 100644
index 0000000..db8b431
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360-dsp-cntl.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __WCD9360_DSP_CNTL_H__
+#define __WCD9360_DSP_CNTL_H__
+
+#include <linux/miscdevice.h>
+#include <sound/soc.h>
+#include <sound/wcd-dsp-mgr.h>
+
+enum cdc_ssr_event {
+ WCD_CDC_DOWN_EVENT,
+ WCD_CDC_UP_EVENT,
+};
+
+struct wcd_dsp_cdc_cb {
+ /* Callback to enable codec clock */
+ int (*cdc_clk_en)(struct snd_soc_codec *, bool);
+ /* Callback to vote and unvote for SVS2 mode */
+ void (*cdc_vote_svs)(struct snd_soc_codec *, bool);
+};
+
+struct wcd_dsp_irq_info {
+ /* IPC interrupt */
+ int cpe_ipc1_irq;
+
+ /* CPE error summary interrupt */
+ int cpe_err_irq;
+
+ /*
+ * Bit mask to indicate which of the
+ * error interrupts are to be considered
+ * as fatal.
+ */
+ u16 fatal_irqs;
+};
+
+struct wcd_dsp_params {
+ struct wcd_dsp_cdc_cb *cb;
+ struct wcd_dsp_irq_info irqs;
+
+ /* Rate at which the codec clock operates */
+ u32 clk_rate;
+
+ /*
+ * Represents the dsp instance, will be used
+ * to create sysfs and debugfs entries with
+ * directory wdsp<dsp-instance>
+ */
+ u32 dsp_instance;
+};
+
+struct wdsp_ssr_entry {
+ u8 offline;
+ u8 offline_change;
+ wait_queue_head_t offline_poll_wait;
+ struct snd_info_entry *entry;
+};
+
+struct wcd_dsp_cntl {
+ /* Handle to codec */
+ struct snd_soc_codec *codec;
+
+ /* Clk rate of the codec clock */
+ u32 clk_rate;
+
+ /* Callbacks to codec driver */
+ const struct wcd_dsp_cdc_cb *cdc_cb;
+
+ /* Completion to indicate WDSP boot done */
+ struct completion boot_complete;
+
+ struct wcd_dsp_irq_info irqs;
+ u32 dsp_instance;
+
+ /* Sysfs entries related */
+ int boot_reqs;
+ struct kobject wcd_kobj;
+
+ /* Debugfs related */
+ struct dentry *entry;
+ u32 debug_mode;
+ bool ramdump_enable;
+
+ /* WDSP manager drivers data */
+ struct device *m_dev;
+ struct wdsp_mgr_ops *m_ops;
+
+ /* clk related */
+ struct mutex clk_mutex;
+ bool is_clk_enabled;
+
+ /* Keep track of WDSP boot status */
+ bool is_wdsp_booted;
+
+ /* SSR related */
+ struct wdsp_ssr_entry ssr_entry;
+ struct mutex ssr_mutex;
+
+ /* Misc device related */
+ char miscdev_name[256];
+ struct miscdevice miscdev;
+};
+
+void wcd9360_dsp_cntl_init(struct snd_soc_codec *codec,
+ struct wcd_dsp_params *params,
+ struct wcd_dsp_cntl **cntl);
+void wcd9360_dsp_cntl_deinit(struct wcd_dsp_cntl **cntl);
+int wcd9360_dsp_ssr_event(struct wcd_dsp_cntl *cntl, enum cdc_ssr_event event);
+#endif /* end __WCD_DSP_CONTROL_H__ */
diff --git a/asoc/codecs/wcd9360/wcd9360-irq.h b/asoc/codecs/wcd9360/wcd9360-irq.h
new file mode 100644
index 0000000..fa79447
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360-irq.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __WCD9360_IRQ_H_
+#define __WCD9360_IRQ_H_
+
+enum {
+ /* INTR_REG 0 */
+ WCD9360_IRQ_MISC = 1,
+ WCD9360_IRQ_RESERVED_0,
+ WCD9360_IRQ_LDO_RXTX_SCD,
+ WCD9360_IRQ_EAR_PA_SCD,
+ WCD9360_IRQ_AUX_PA_SCD,
+ WCD9360_IRQ_AUX_PA_CNP_COMPLETE,
+ WCD9360_IRQ_EAR_PA_CNP_COMPLETE,
+ /* INTR_REG 1 */
+ WCD9360_IRQ_RESERVED_1,
+ WCD9360_IRQ_RESERVED_2,
+ WCD9360_IRQ_RESERVED_3,
+ WCD9360_IRQ_RESERVED_4,
+ WCD9360_IRQ_RESERVED_5,
+ WCD9360_IRQ_RESERVED_6,
+ WCD9360_IRQ_RESERVED_7,
+ WCD9360_IRQ_RESERVED_8,
+ /* INTR_REG 2 */
+ WCD9360_IRQ_RESERVED_9,
+ WCD9360_IRQ_RESERVED_10,
+ WCD9360_IRQ_RESERVED_11,
+ WCD9360_IRQ_RESERVED_12,
+ WCD9360_IRQ_SOUNDWIRE,
+ WCD9360_IRQ_RESERVED_13,
+ WCD9360_IRQ_RCO_ERROR,
+ WCD9360_IRQ_CPE_ERROR,
+ /* INTR_REG 3 */
+ WCD9360_IRQ_MAD_AUDIO,
+ WCD9360_IRQ_MAD_BEACON,
+ WCD9360_IRQ_MAD_ULTRASOUND,
+ WCD9360_IRQ_RESERVED_14,
+ WCD9360_IRQ_RESERVED_15,
+ WCD9360_IRQ_CPE1_INTR,
+ WCD9360_IRQ_CPE2_INTR,
+ WCD9360_IRQ_CPE_LPASS_ACK,
+ WCD9360_NUM_IRQS,
+};
+
+#endif
diff --git a/asoc/codecs/wcd9360/wcd9360-regmap.c b/asoc/codecs/wcd9360/wcd9360-regmap.c
new file mode 100644
index 0000000..b74c1fb
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360-regmap.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/regmap.h>
+#include <linux/device.h>
+#include <asoc/wcd9360-registers.h>
+#include "../core.h"
+#include "../wcd9xxx-regmap.h"
+#include "wcd9360-defaults.h"
+
+static bool wcd9360_is_readable_register(struct device *dev, unsigned int reg)
+{
+ u8 pg_num, reg_offset;
+ const u8 *reg_tbl = NULL;
+
+ /*
+ * Get the page number from MSB of codec register. If its 0x80, assign
+ * the corresponding page index PAGE_0x80.
+ */
+ pg_num = reg >> 8;
+ if (pg_num == 128)
+ pg_num = WCD9360_PAGE_128;
+ else if (pg_num == 80)
+ pg_num = WCD9360_PAGE_80;
+ else if (pg_num > 15)
+ return false;
+
+ reg_tbl = wcd9360_reg[pg_num];
+ reg_offset = reg & 0xFF;
+
+ if (reg_tbl && reg_tbl[reg_offset])
+ return true;
+ else
+ return false;
+}
+
+static bool wcd9360_is_volatile_register(struct device *dev, unsigned int reg)
+{
+ u8 pg_num, reg_offset;
+ const u8 *reg_tbl = NULL;
+
+ pg_num = reg >> 8;
+
+ if (pg_num == 1 || pg_num == 2 ||
+ pg_num == 6 || pg_num == 7)
+ return true;
+ else if (pg_num == 128)
+ pg_num = WCD9360_PAGE_128;
+ else if (pg_num == 80)
+ pg_num = WCD9360_PAGE_80;
+ else if (pg_num > 15)
+ return false;
+
+ reg_tbl = wcd9360_reg[pg_num];
+ reg_offset = reg & 0xFF;
+
+ if (reg_tbl && reg_tbl[reg_offset] == WCD9360_RO)
+ return true;
+
+ if ((reg >= WCD9360_CODEC_RPM_RST_CTL) &&
+ (reg <= WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN))
+ return true;
+
+ if ((reg >= WCD9360_CDC_ANC0_IIR_COEFF_1_CTL) &&
+ (reg <= WCD9360_CDC_ANC0_FB_GAIN_CTL))
+ return true;
+
+ if ((reg >= WCD9360_CODEC_CPR_WR_DATA_0) &&
+ (reg <= WCD9360_CODEC_CPR_RD_DATA_3))
+ return true;
+
+ /*
+ * Need to mark volatile for registers that are writable but
+ * only few bits are read-only
+ */
+ switch (reg) {
+ case WCD9360_CODEC_RPM_CLK_BYPASS:
+ case WCD9360_CODEC_RPM_CLK_GATE:
+ case WCD9360_CODEC_RPM_CLK_MCLK_CFG:
+ case WCD9360_CODEC_CPR_SVS_CX_VDD:
+ case WCD9360_CODEC_CPR_SVS2_CX_VDD:
+ case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL:
+ case WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL:
+ return true;
+ }
+
+ return false;
+}
+
+struct regmap_config wcd9360_regmap_config = {
+ .reg_bits = 16,
+ .val_bits = 8,
+ .cache_type = REGCACHE_RBTREE,
+ .reg_defaults = wcd9360_defaults,
+ .num_reg_defaults = ARRAY_SIZE(wcd9360_defaults),
+ .max_register = WCD9360_MAX_REGISTER,
+ .volatile_reg = wcd9360_is_volatile_register,
+ .readable_reg = wcd9360_is_readable_register,
+ .can_multi_write = true,
+};
diff --git a/asoc/codecs/wcd9360/wcd9360-routing.h b/asoc/codecs/wcd9360/wcd9360-routing.h
new file mode 100644
index 0000000..1d41c0a
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360-routing.h
@@ -0,0 +1,877 @@
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __WCD9360_ROUTING_H__
+#define __WCD9360_ROUTING_H__
+
+#include <sound/soc-dapm.h>
+
+const struct snd_soc_dapm_route pahu_slim_audio_map[] = {
+
+ {"AIF4 MAD", NULL, "AIF4_MAD Mixer"},
+
+ /* Virtual input widget Mixer SLIMBUS */
+ {"AIF1_CAP Mixer", "SLIM TX0", "SLIM TX0"},
+ {"AIF1_CAP Mixer", "SLIM TX1", "SLIM TX1"},
+ {"AIF1_CAP Mixer", "SLIM TX2", "SLIM TX2"},
+ {"AIF1_CAP Mixer", "SLIM TX3", "SLIM TX3"},
+ {"AIF1_CAP Mixer", "SLIM TX4", "SLIM TX4"},
+ {"AIF1_CAP Mixer", "SLIM TX5", "SLIM TX5"},
+ {"AIF1_CAP Mixer", "SLIM TX6", "SLIM TX6"},
+ {"AIF1_CAP Mixer", "SLIM TX7", "SLIM TX7"},
+ {"AIF1_CAP Mixer", "SLIM TX8", "SLIM TX8"},
+ {"AIF1_CAP Mixer", "SLIM TX9", "SLIM TX9"},
+ {"AIF1_CAP Mixer", "SLIM TX10", "SLIM TX10"},
+ {"AIF1_CAP Mixer", "SLIM TX11", "SLIM TX11"},
+ {"AIF1_CAP Mixer", "SLIM TX13", "SLIM TX13"},
+
+ {"AIF2_CAP Mixer", "SLIM TX0", "SLIM TX0"},
+ {"AIF2_CAP Mixer", "SLIM TX1", "SLIM TX1"},
+ {"AIF2_CAP Mixer", "SLIM TX2", "SLIM TX2"},
+ {"AIF2_CAP Mixer", "SLIM TX3", "SLIM TX3"},
+ {"AIF2_CAP Mixer", "SLIM TX4", "SLIM TX4"},
+ {"AIF2_CAP Mixer", "SLIM TX5", "SLIM TX5"},
+ {"AIF2_CAP Mixer", "SLIM TX6", "SLIM TX6"},
+ {"AIF2_CAP Mixer", "SLIM TX7", "SLIM TX7"},
+ {"AIF2_CAP Mixer", "SLIM TX8", "SLIM TX8"},
+ {"AIF2_CAP Mixer", "SLIM TX9", "SLIM TX9"},
+ {"AIF2_CAP Mixer", "SLIM TX10", "SLIM TX10"},
+ {"AIF2_CAP Mixer", "SLIM TX11", "SLIM TX11"},
+ {"AIF2_CAP Mixer", "SLIM TX13", "SLIM TX13"},
+
+ {"AIF3_CAP Mixer", "SLIM TX0", "SLIM TX0"},
+ {"AIF3_CAP Mixer", "SLIM TX1", "SLIM TX1"},
+ {"AIF3_CAP Mixer", "SLIM TX2", "SLIM TX2"},
+ {"AIF3_CAP Mixer", "SLIM TX3", "SLIM TX3"},
+ {"AIF3_CAP Mixer", "SLIM TX4", "SLIM TX4"},
+ {"AIF3_CAP Mixer", "SLIM TX5", "SLIM TX5"},
+ {"AIF3_CAP Mixer", "SLIM TX6", "SLIM TX6"},
+ {"AIF3_CAP Mixer", "SLIM TX7", "SLIM TX7"},
+ {"AIF3_CAP Mixer", "SLIM TX8", "SLIM TX8"},
+ {"AIF3_CAP Mixer", "SLIM TX9", "SLIM TX9"},
+ {"AIF3_CAP Mixer", "SLIM TX10", "SLIM TX10"},
+ {"AIF3_CAP Mixer", "SLIM TX11", "SLIM TX11"},
+ {"AIF3_CAP Mixer", "SLIM TX13", "SLIM TX13"},
+
+ {"AIF4_MAD Mixer", "SLIM TX13", "SLIM TX13"},
+
+ /* CDC Tx interface with SLIMBUS */
+ {"SLIM TX0", NULL, "CDC_IF TX0 MUX"},
+ {"SLIM TX1", NULL, "CDC_IF TX1 MUX"},
+ {"SLIM TX2", NULL, "CDC_IF TX2 MUX"},
+ {"SLIM TX3", NULL, "CDC_IF TX3 MUX"},
+ {"SLIM TX4", NULL, "CDC_IF TX4 MUX"},
+ {"SLIM TX5", NULL, "CDC_IF TX5 MUX"},
+ {"SLIM TX6", NULL, "CDC_IF TX6 MUX"},
+ {"SLIM TX7", NULL, "CDC_IF TX7 MUX"},
+ {"SLIM TX8", NULL, "CDC_IF TX8 MUX"},
+ {"SLIM TX9", NULL, "CDC_IF TX9 MUX"},
+ {"SLIM TX10", NULL, "CDC_IF TX10 MUX2"},
+ {"SLIM TX11", NULL, "CDC_IF TX11 MUX2"},
+ {"SLIM TX13", NULL, "CDC_IF TX13 MUX"},
+
+ {"SLIM RX0 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX1 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX2 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX3 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX4 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX5 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX6 MUX", "AIF1_PB", "AIF1 PB"},
+ {"SLIM RX7 MUX", "AIF1_PB", "AIF1 PB"},
+
+ {"SLIM RX0 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX1 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX2 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX3 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX4 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX5 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX6 MUX", "AIF2_PB", "AIF2 PB"},
+ {"SLIM RX7 MUX", "AIF2_PB", "AIF2 PB"},
+
+ {"SLIM RX0 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX1 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX2 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX3 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX4 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX5 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX6 MUX", "AIF3_PB", "AIF3 PB"},
+ {"SLIM RX7 MUX", "AIF3_PB", "AIF3 PB"},
+
+ {"SLIM RX0 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX1 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX2 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX3 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX4 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX5 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX6 MUX", "AIF4_PB", "AIF4 PB"},
+ {"SLIM RX7 MUX", "AIF4_PB", "AIF4 PB"},
+
+ {"SLIM RX0", NULL, "SLIM RX0 MUX"},
+ {"SLIM RX1", NULL, "SLIM RX1 MUX"},
+ {"SLIM RX2", NULL, "SLIM RX2 MUX"},
+ {"SLIM RX3", NULL, "SLIM RX3 MUX"},
+ {"SLIM RX4", NULL, "SLIM RX4 MUX"},
+ {"SLIM RX5", NULL, "SLIM RX5 MUX"},
+ {"SLIM RX6", NULL, "SLIM RX6 MUX"},
+ {"SLIM RX7", NULL, "SLIM RX7 MUX"},
+
+ /* CDC Rx interface with SLIMBUS */
+ {"CDC_IF RX0 MUX", "SLIM RX0", "SLIM RX0"},
+ {"CDC_IF RX1 MUX", "SLIM RX1", "SLIM RX1"},
+ {"CDC_IF RX2 MUX", "SLIM RX2", "SLIM RX2"},
+ {"CDC_IF RX3 MUX", "SLIM RX3", "SLIM RX3"},
+ {"CDC_IF RX4 MUX", "SLIM RX4", "SLIM RX4"},
+ {"CDC_IF RX5 MUX", "SLIM RX5", "SLIM RX5"},
+ {"CDC_IF RX6 MUX", "SLIM RX6", "SLIM RX6"},
+ {"CDC_IF RX7 MUX", "SLIM RX7", "SLIM RX7"},
+
+ /* VI Feedback */
+ {"AIF4_VI Mixer", "SPKR_VI_1", "VIINPUT"},
+ {"AIF4_VI Mixer", "SPKR_VI_2", "VIINPUT"},
+ {"AIF4 VI", NULL, "AIF4_VI Mixer"},
+};
+
+const struct snd_soc_dapm_route pahu_audio_map[] = {
+
+ /* Virtual input widgets */
+ {"AIF1 CAP", NULL, "AIF1_CAP Mixer"},
+ {"AIF2 CAP", NULL, "AIF2_CAP Mixer"},
+ {"AIF3 CAP", NULL, "AIF3_CAP Mixer"},
+
+ /* WDMA3 */
+ {"WDMA3 PORT0 MUX", "DEC0", "ADC MUX0"},
+ {"WDMA3 PORT0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
+ {"WDMA3 PORT1 MUX", "DEC1", "ADC MUX1"},
+ {"WDMA3 PORT1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
+ {"WDMA3 PORT2 MUX", "DEC2", "ADC MUX2"},
+ {"WDMA3 PORT2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
+ {"WDMA3 PORT3 MUX", "DEC3", "ADC MUX3"},
+ {"WDMA3 PORT3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
+ {"WDMA3 PORT4 MUX", "DEC4", "ADC MUX4"},
+ {"WDMA3 PORT4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
+ {"WDMA3 PORT5 MUX", "DEC5", "ADC MUX5"},
+ {"WDMA3 PORT5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
+ {"WDMA3 PORT6 MUX", "DEC6", "ADC MUX6"},
+ {"WDMA3 PORT6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
+
+ {"WDMA3 CH0 MUX", "PORT_0", "WDMA3 PORT0 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_1", "WDMA3 PORT1 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_2", "WDMA3 PORT2 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_3", "WDMA3 PORT3 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_4", "WDMA3 PORT4 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_5", "WDMA3 PORT5 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_6", "WDMA3 PORT6 MUX"},
+ {"WDMA3 CH0 MUX", "PORT_7", "ADC MUX7"},
+ {"WDMA3 CH0 MUX", "PORT_8", "ADC MUX8"},
+
+ {"WDMA3 CH1 MUX", "PORT_0", "WDMA3 PORT0 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_1", "WDMA3 PORT1 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_2", "WDMA3 PORT2 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_3", "WDMA3 PORT3 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_4", "WDMA3 PORT4 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_5", "WDMA3 PORT5 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_6", "WDMA3 PORT6 MUX"},
+ {"WDMA3 CH1 MUX", "PORT_7", "ADC MUX7"},
+ {"WDMA3 CH1 MUX", "PORT_8", "ADC MUX8"},
+
+ {"WDMA3 CH2 MUX", "PORT_0", "WDMA3 PORT0 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_1", "WDMA3 PORT1 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_2", "WDMA3 PORT2 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_3", "WDMA3 PORT3 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_4", "WDMA3 PORT4 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_5", "WDMA3 PORT5 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_6", "WDMA3 PORT6 MUX"},
+ {"WDMA3 CH2 MUX", "PORT_7", "ADC MUX7"},
+ {"WDMA3 CH2 MUX", "PORT_8", "ADC MUX8"},
+
+ {"WDMA3 CH3 MUX", "PORT_0", "WDMA3 PORT0 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_1", "WDMA3 PORT1 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_2", "WDMA3 PORT2 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_3", "WDMA3 PORT3 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_4", "WDMA3 PORT4 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_5", "WDMA3 PORT5 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_6", "WDMA3 PORT6 MUX"},
+ {"WDMA3 CH3 MUX", "PORT_7", "ADC MUX7"},
+ {"WDMA3 CH3 MUX", "PORT_8", "ADC MUX8"},
+
+ {"WDMA3_CH_MIXER", NULL, "WDMA3 CH0 MUX"},
+ {"WDMA3_CH_MIXER", NULL, "WDMA3 CH1 MUX"},
+ {"WDMA3_CH_MIXER", NULL, "WDMA3 CH2 MUX"},
+ {"WDMA3_CH_MIXER", NULL, "WDMA3 CH3 MUX"},
+
+ {"WDMA3_ON_OFF", "Switch", "WDMA3_CH_MIXER"},
+ {"WDMA3_OUT", NULL, "WDMA3_ON_OFF"},
+
+ /* MAD */
+ {"MAD_SEL MUX", "SPE", "MAD_CPE_INPUT"},
+ {"MAD_SEL MUX", "MSM", "MADINPUT"},
+
+ {"MAD_INP MUX", "MAD", "MAD_SEL MUX"},
+ {"MAD_INP MUX", "DEC1", "ADC MUX1"},
+
+ {"MAD_BROADCAST", "Switch", "MAD_INP MUX"},
+ {"MAD_CPE1", "Switch", "MAD_INP MUX"},
+ {"MAD_CPE2", "Switch", "MAD_INP MUX"},
+
+ {"MAD_CPE_OUT1", NULL, "MAD_CPE1"},
+ {"MAD_CPE_OUT2", NULL, "MAD_CPE2"},
+
+ {"CDC_IF TX0 MUX", "DEC0", "ADC MUX0"},
+ {"CDC_IF TX0 MUX", "RX_MIX_TX0", "RX MIX TX0 MUX"},
+ {"CDC_IF TX0 MUX", "DEC0_192", "ADC US MUX0"},
+
+ {"CDC_IF TX1 MUX", "DEC1", "ADC MUX1"},
+ {"CDC_IF TX1 MUX", "RX_MIX_TX1", "RX MIX TX1 MUX"},
+ {"CDC_IF TX1 MUX", "DEC1_192", "ADC US MUX1"},
+
+ {"CDC_IF TX2 MUX", "DEC2", "ADC MUX2"},
+ {"CDC_IF TX2 MUX", "RX_MIX_TX2", "RX MIX TX2 MUX"},
+ {"CDC_IF TX2 MUX", "DEC2_192", "ADC US MUX2"},
+
+ {"CDC_IF TX3 MUX", "DEC3", "ADC MUX3"},
+ {"CDC_IF TX3 MUX", "RX_MIX_TX3", "RX MIX TX3 MUX"},
+ {"CDC_IF TX3 MUX", "DEC3_192", "ADC US MUX3"},
+
+ {"CDC_IF TX4 MUX", "DEC4", "ADC MUX4"},
+ {"CDC_IF TX4 MUX", "RX_MIX_TX4", "RX MIX TX4 MUX"},
+ {"CDC_IF TX4 MUX", "DEC4_192", "ADC US MUX4"},
+
+ {"CDC_IF TX5 MUX", "DEC5", "ADC MUX5"},
+ {"CDC_IF TX5 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
+ {"CDC_IF TX5 MUX", "DEC5_192", "ADC US MUX5"},
+
+ {"CDC_IF TX6 MUX", "DEC6", "ADC MUX6"},
+ {"CDC_IF TX6 MUX", "RX_MIX_TX6", "RX MIX TX6 MUX"},
+ {"CDC_IF TX6 MUX", "DEC6_192", "ADC US MUX6"},
+
+ {"CDC_IF TX7 MUX", "DEC7", "ADC MUX7"},
+ {"CDC_IF TX7 MUX", "RX_MIX_TX7", "RX MIX TX7 MUX"},
+ {"CDC_IF TX7 MUX", "DEC7_192", "ADC US MUX7"},
+
+ {"CDC_IF TX8 MUX", "DEC8", "ADC MUX8"},
+ {"CDC_IF TX8 MUX", "RX_MIX_TX8", "RX MIX TX8 MUX"},
+ {"CDC_IF TX8 MUX", "DEC8_192", "ADC US MUX8"},
+
+ {"CDC_IF TX9 MUX", "DEC7", "ADC MUX7"},
+ {"CDC_IF TX9 MUX", "DEC7_192", "ADC US MUX7"},
+ {"CDC_IF TX10 MUX", "DEC6", "ADC MUX6"},
+ {"CDC_IF TX10 MUX", "DEC6_192", "ADC US MUX6"},
+ {"CDC_IF TX10 MUX2", "TX10_MUX1", "CDC_IF TX10 MUX"},
+
+ {"CDC_IF TX11 MUX2", "TX11_MUX1", "CDC_IF TX11 MUX"},
+ {"CDC_IF TX11 MUX", "DEC_0_5", "CDC_IF TX11 INP1 MUX"},
+ {"CDC_IF TX11 MUX", "DEC_9_12", "CDC_IF TX11 INP1 MUX"},
+ {"CDC_IF TX11 INP1 MUX", "DEC0", "ADC MUX0"},
+ {"CDC_IF TX11 INP1 MUX", "DEC1", "ADC MUX1"},
+ {"CDC_IF TX11 INP1 MUX", "DEC2", "ADC MUX2"},
+ {"CDC_IF TX11 INP1 MUX", "DEC3", "ADC MUX3"},
+ {"CDC_IF TX11 INP1 MUX", "DEC4", "ADC MUX4"},
+ {"CDC_IF TX11 INP1 MUX", "DEC5", "ADC MUX5"},
+ {"CDC_IF TX11 INP1 MUX", "RX_MIX_TX5", "RX MIX TX5 MUX"},
+
+ {"CDC_IF TX13 MUX", "MAD_BRDCST", "MAD_BROADCAST"},
+ {"CDC_IF TX13 MUX", "CDC_DEC_5", "CDC_IF TX13 INP1 MUX"},
+ {"CDC_IF TX13 INP1 MUX", "DEC5", "ADC MUX5"},
+ {"CDC_IF TX13 INP1 MUX", "DEC5_192", "ADC US MUX5"},
+
+ {"RX MIX TX0 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX0 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX0 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX0 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX1 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX1 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX1 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX1 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX2 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX2 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX2 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX2 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX3 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX3 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX3 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX3 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX4 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX4 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX4 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX4 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX5 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX5 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX5 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX5 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX6 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX6 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX6 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX6 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX7 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX7 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX7 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX7 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"RX MIX TX8 MUX", "RX_MIX0", "RX INT0 SEC MIX"},
+ {"RX MIX TX8 MUX", "RX_MIX7", "RX INT7 SEC MIX"},
+ {"RX MIX TX8 MUX", "RX_MIX8", "RX INT8 SEC MIX"},
+ {"RX MIX TX8 MUX", "RX_MIX9", "RX INT9 SEC MIX"},
+
+ {"ADC US MUX0", "US_Switch", "ADC MUX0"},
+ {"ADC US MUX1", "US_Switch", "ADC MUX1"},
+ {"ADC US MUX2", "US_Switch", "ADC MUX2"},
+ {"ADC US MUX3", "US_Switch", "ADC MUX3"},
+ {"ADC US MUX4", "US_Switch", "ADC MUX4"},
+ {"ADC US MUX5", "US_Switch", "ADC MUX5"},
+ {"ADC US MUX6", "US_Switch", "ADC MUX6"},
+ {"ADC US MUX7", "US_Switch", "ADC MUX7"},
+ {"ADC US MUX8", "US_Switch", "ADC MUX8"},
+
+ {"ADC MUX0", "DMIC", "DMIC MUX0"},
+ {"ADC MUX0", "AMIC", "AMIC MUX0"},
+ {"ADC MUX1", "DMIC", "DMIC MUX1"},
+ {"ADC MUX1", "AMIC", "AMIC MUX1"},
+ {"ADC MUX2", "DMIC", "DMIC MUX2"},
+ {"ADC MUX2", "AMIC", "AMIC MUX2"},
+ {"ADC MUX3", "DMIC", "DMIC MUX3"},
+ {"ADC MUX3", "AMIC", "AMIC MUX3"},
+ {"ADC MUX4", "DMIC", "DMIC MUX4"},
+ {"ADC MUX4", "AMIC", "AMIC MUX4"},
+ {"ADC MUX5", "DMIC", "DMIC MUX5"},
+ {"ADC MUX5", "AMIC", "AMIC MUX5"},
+ {"ADC MUX6", "DMIC", "DMIC MUX6"},
+ {"ADC MUX6", "AMIC", "AMIC MUX6"},
+ {"ADC MUX7", "DMIC", "DMIC MUX7"},
+ {"ADC MUX7", "AMIC", "AMIC MUX7"},
+ {"ADC MUX8", "DMIC", "DMIC MUX8"},
+ {"ADC MUX8", "AMIC", "AMIC MUX8"},
+ {"ADC MUX10", "DMIC", "DMIC MUX10"},
+ {"ADC MUX10", "AMIC", "AMIC MUX10"},
+ {"ADC MUX11", "DMIC", "DMIC MUX11"},
+ {"ADC MUX11", "AMIC", "AMIC MUX11"},
+
+ {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX0", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX1", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX2", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX3", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX4", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX5", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX6", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX7", "ANC_FB_TUNE1", "ADC MUX11"},
+ {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX10"},
+ {"ADC MUX8", "ANC_FB_TUNE1", "ADC MUX11"},
+
+ {"DMIC MUX0", "DMIC0", "DMIC0"},
+ {"DMIC MUX0", "DMIC1", "DMIC1"},
+ {"DMIC MUX0", "DMIC2", "DMIC2"},
+ {"DMIC MUX0", "DMIC3", "DMIC3"},
+ {"DMIC MUX0", "DMIC4", "DMIC4"},
+ {"DMIC MUX0", "DMIC5", "DMIC5"},
+ {"DMIC MUX0", "DMIC6", "DMIC6"},
+ {"DMIC MUX0", "DMIC7", "DMIC7"},
+ {"AMIC MUX0", "ADC1", "ADC1"},
+ {"AMIC MUX0", "ADC2", "ADC2"},
+ {"AMIC MUX0", "ADC3", "ADC3"},
+ {"AMIC MUX0", "ADC4", "ADC4"},
+
+ {"DMIC MUX1", "DMIC0", "DMIC0"},
+ {"DMIC MUX1", "DMIC1", "DMIC1"},
+ {"DMIC MUX1", "DMIC2", "DMIC2"},
+ {"DMIC MUX1", "DMIC3", "DMIC3"},
+ {"DMIC MUX1", "DMIC4", "DMIC4"},
+ {"DMIC MUX1", "DMIC5", "DMIC5"},
+ {"DMIC MUX1", "DMIC6", "DMIC6"},
+ {"DMIC MUX1", "DMIC7", "DMIC7"},
+ {"AMIC MUX1", "ADC1", "ADC1"},
+ {"AMIC MUX1", "ADC2", "ADC2"},
+ {"AMIC MUX1", "ADC3", "ADC3"},
+ {"AMIC MUX1", "ADC4", "ADC4"},
+
+ {"DMIC MUX2", "DMIC0", "DMIC0"},
+ {"DMIC MUX2", "DMIC1", "DMIC1"},
+ {"DMIC MUX2", "DMIC2", "DMIC2"},
+ {"DMIC MUX2", "DMIC3", "DMIC3"},
+ {"DMIC MUX2", "DMIC4", "DMIC4"},
+ {"DMIC MUX2", "DMIC5", "DMIC5"},
+ {"DMIC MUX2", "DMIC6", "DMIC6"},
+ {"DMIC MUX2", "DMIC7", "DMIC7"},
+ {"AMIC MUX2", "ADC1", "ADC1"},
+ {"AMIC MUX2", "ADC2", "ADC2"},
+ {"AMIC MUX2", "ADC3", "ADC3"},
+ {"AMIC MUX2", "ADC4", "ADC4"},
+
+ {"DMIC MUX3", "DMIC0", "DMIC0"},
+ {"DMIC MUX3", "DMIC1", "DMIC1"},
+ {"DMIC MUX3", "DMIC2", "DMIC2"},
+ {"DMIC MUX3", "DMIC3", "DMIC3"},
+ {"DMIC MUX3", "DMIC4", "DMIC4"},
+ {"DMIC MUX3", "DMIC5", "DMIC5"},
+ {"DMIC MUX3", "DMIC6", "DMIC6"},
+ {"DMIC MUX3", "DMIC7", "DMIC7"},
+ {"AMIC MUX3", "ADC1", "ADC1"},
+ {"AMIC MUX3", "ADC2", "ADC2"},
+ {"AMIC MUX3", "ADC3", "ADC3"},
+ {"AMIC MUX3", "ADC4", "ADC4"},
+
+ {"DMIC MUX4", "DMIC0", "DMIC0"},
+ {"DMIC MUX4", "DMIC1", "DMIC1"},
+ {"DMIC MUX4", "DMIC2", "DMIC2"},
+ {"DMIC MUX4", "DMIC3", "DMIC3"},
+ {"DMIC MUX4", "DMIC4", "DMIC4"},
+ {"DMIC MUX4", "DMIC5", "DMIC5"},
+ {"DMIC MUX4", "DMIC6", "DMIC6"},
+ {"DMIC MUX4", "DMIC7", "DMIC7"},
+ {"AMIC MUX4", "ADC1", "ADC1"},
+ {"AMIC MUX4", "ADC2", "ADC2"},
+ {"AMIC MUX4", "ADC3", "ADC3"},
+ {"AMIC MUX4", "ADC4", "ADC4"},
+
+ {"DMIC MUX5", "DMIC0", "DMIC0"},
+ {"DMIC MUX5", "DMIC1", "DMIC1"},
+ {"DMIC MUX5", "DMIC2", "DMIC2"},
+ {"DMIC MUX5", "DMIC3", "DMIC3"},
+ {"DMIC MUX5", "DMIC4", "DMIC4"},
+ {"DMIC MUX5", "DMIC5", "DMIC5"},
+ {"DMIC MUX5", "DMIC6", "DMIC6"},
+ {"DMIC MUX5", "DMIC7", "DMIC7"},
+ {"AMIC MUX5", "ADC1", "ADC1"},
+ {"AMIC MUX5", "ADC2", "ADC2"},
+ {"AMIC MUX5", "ADC3", "ADC3"},
+ {"AMIC MUX5", "ADC4", "ADC4"},
+
+ {"DMIC MUX6", "DMIC0", "DMIC0"},
+ {"DMIC MUX6", "DMIC1", "DMIC1"},
+ {"DMIC MUX6", "DMIC2", "DMIC2"},
+ {"DMIC MUX6", "DMIC3", "DMIC3"},
+ {"DMIC MUX6", "DMIC4", "DMIC4"},
+ {"DMIC MUX6", "DMIC5", "DMIC5"},
+ {"DMIC MUX6", "DMIC6", "DMIC6"},
+ {"DMIC MUX6", "DMIC7", "DMIC7"},
+ {"AMIC MUX6", "ADC1", "ADC1"},
+ {"AMIC MUX6", "ADC2", "ADC2"},
+ {"AMIC MUX6", "ADC3", "ADC3"},
+ {"AMIC MUX6", "ADC4", "ADC4"},
+
+ {"DMIC MUX7", "DMIC0", "DMIC0"},
+ {"DMIC MUX7", "DMIC1", "DMIC1"},
+ {"DMIC MUX7", "DMIC2", "DMIC2"},
+ {"DMIC MUX7", "DMIC3", "DMIC3"},
+ {"DMIC MUX7", "DMIC4", "DMIC4"},
+ {"DMIC MUX7", "DMIC5", "DMIC5"},
+ {"DMIC MUX7", "DMIC6", "DMIC6"},
+ {"DMIC MUX7", "DMIC7", "DMIC7"},
+ {"AMIC MUX7", "ADC1", "ADC1"},
+ {"AMIC MUX7", "ADC2", "ADC2"},
+ {"AMIC MUX7", "ADC3", "ADC3"},
+ {"AMIC MUX7", "ADC4", "ADC4"},
+
+ {"DMIC MUX8", "DMIC0", "DMIC0"},
+ {"DMIC MUX8", "DMIC1", "DMIC1"},
+ {"DMIC MUX8", "DMIC2", "DMIC2"},
+ {"DMIC MUX8", "DMIC3", "DMIC3"},
+ {"DMIC MUX8", "DMIC4", "DMIC4"},
+ {"DMIC MUX8", "DMIC5", "DMIC5"},
+ {"DMIC MUX8", "DMIC6", "DMIC6"},
+ {"DMIC MUX8", "DMIC7", "DMIC7"},
+ {"AMIC MUX8", "ADC1", "ADC1"},
+ {"AMIC MUX8", "ADC2", "ADC2"},
+ {"AMIC MUX8", "ADC3", "ADC3"},
+ {"AMIC MUX8", "ADC4", "ADC4"},
+
+ {"DMIC MUX10", "DMIC0", "DMIC0"},
+ {"DMIC MUX10", "DMIC1", "DMIC1"},
+ {"DMIC MUX10", "DMIC2", "DMIC2"},
+ {"DMIC MUX10", "DMIC3", "DMIC3"},
+ {"DMIC MUX10", "DMIC4", "DMIC4"},
+ {"DMIC MUX10", "DMIC5", "DMIC5"},
+ {"DMIC MUX10", "DMIC6", "DMIC6"},
+ {"DMIC MUX10", "DMIC7", "DMIC7"},
+ {"AMIC MUX10", "ADC1", "ADC1"},
+ {"AMIC MUX10", "ADC2", "ADC2"},
+ {"AMIC MUX10", "ADC3", "ADC3"},
+ {"AMIC MUX10", "ADC4", "ADC4"},
+
+ {"DMIC MUX11", "DMIC0", "DMIC0"},
+ {"DMIC MUX11", "DMIC1", "DMIC1"},
+ {"DMIC MUX11", "DMIC2", "DMIC2"},
+ {"DMIC MUX11", "DMIC3", "DMIC3"},
+ {"DMIC MUX11", "DMIC4", "DMIC4"},
+ {"DMIC MUX11", "DMIC5", "DMIC5"},
+ {"DMIC MUX11", "DMIC6", "DMIC6"},
+ {"DMIC MUX11", "DMIC7", "DMIC7"},
+ {"AMIC MUX11", "ADC1", "ADC1"},
+ {"AMIC MUX11", "ADC2", "ADC2"},
+ {"AMIC MUX11", "ADC3", "ADC3"},
+ {"AMIC MUX11", "ADC4", "ADC4"},
+
+ {"ADC2_IN", "AMIC1", "AMIC1"},
+ {"ADC2_IN", "AMIC2", "AMIC2"},
+ {"ADC4_IN", "AMIC3", "AMIC3"},
+ {"ADC4_IN", "AMIC4", "AMIC4"},
+
+ {"ADC1", NULL, "AMIC1"},
+ {"ADC2", NULL, "ADC2_IN"},
+ {"ADC3", NULL, "AMIC3"},
+ {"ADC4", NULL, "ADC4_IN"},
+
+ {"ADC1", NULL, "LDO_RXTX"},
+ {"ADC2", NULL, "LDO_RXTX"},
+ {"ADC3", NULL, "LDO_RXTX"},
+ {"ADC4", NULL, "LDO_RXTX"},
+
+ {"RX INT0_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT0_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT0_1 MIX1 INP0", "IIR0", "IIR0"},
+ {"RX INT0_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT0_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT0_1 MIX1 INP1", "IIR0", "IIR0"},
+ {"RX INT0_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT0_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT0_1 MIX1 INP2", "IIR0", "IIR0"},
+
+ {"RX INT7_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT7_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT7_1 MIX1 INP0", "IIR0", "IIR0"},
+ {"RX INT7_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT7_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT7_1 MIX1 INP1", "IIR0", "IIR0"},
+ {"RX INT7_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT7_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT7_1 MIX1 INP2", "IIR0", "IIR0"},
+
+ {"RX INT8_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT8_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT8_1 MIX1 INP0", "IIR0", "IIR0"},
+ {"RX INT8_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT8_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT8_1 MIX1 INP1", "IIR0", "IIR0"},
+ {"RX INT8_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT8_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT8_1 MIX1 INP2", "IIR0", "IIR0"},
+
+ {"RX INT9_1 MIX1 INP0", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT9_1 MIX1 INP0", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT9_1 MIX1 INP0", "IIR0", "IIR0"},
+ {"RX INT9_1 MIX1 INP1", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT9_1 MIX1 INP1", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT9_1 MIX1 INP1", "IIR0", "IIR0"},
+ {"RX INT9_1 MIX1 INP2", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT9_1 MIX1 INP2", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT9_1 MIX1 INP2", "IIR0", "IIR0"},
+
+ {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP0"},
+ {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP1"},
+ {"RX INT0_1 MIX1", NULL, "RX INT0_1 MIX1 INP2"},
+ {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP0"},
+ {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP1"},
+ {"RX INT7_1 MIX1", NULL, "RX INT7_1 MIX1 INP2"},
+ {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP0"},
+ {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP1"},
+ {"RX INT8_1 MIX1", NULL, "RX INT8_1 MIX1 INP2"},
+ {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP0"},
+ {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP1"},
+ {"RX INT9_1 MIX1", NULL, "RX INT9_1 MIX1 INP2"},
+
+ /* Mixing path INT0 */
+ {"RX INT0_2 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT0_2 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT0_2 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT0_2 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT0_2 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT0_2 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT0_2 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT0_2 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT0_2 INTERP", NULL, "RX INT0_2 MUX"},
+ {"RX INT0 SEC MIX", NULL, "RX INT0_2 INTERP"},
+
+ /* Mixing path INT7 */
+ {"RX INT7_2 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT7_2 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT7_2 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT7_2 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT7_2 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT7_2 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT7_2 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT7_2 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT7_2 INTERP", NULL, "RX INT7_2 MUX"},
+ {"RX INT7 SEC MIX", NULL, "RX INT7_2 INTERP"},
+
+ /* Mixing path INT8 */
+ {"RX INT8_2 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT8_2 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT8_2 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT8_2 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT8_2 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT8_2 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT8_2 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT8_2 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT8_2 INTERP", NULL, "RX INT8_2 MUX"},
+ {"RX INT8 SEC MIX", NULL, "RX INT8_2 INTERP"},
+
+ /* Mixing path INT9 */
+ {"RX INT9_2 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"RX INT9_2 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"RX INT9_2 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"RX INT9_2 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"RX INT9_2 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"RX INT9_2 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"RX INT9_2 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"RX INT9_2 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"RX INT9_2 INTERP", NULL, "RX INT9_2 MUX"},
+ {"RX INT9 SEC MIX", NULL, "RX INT9_2 INTERP"},
+
+ {"RX INT0_1 INTERP", NULL, "RX INT0_1 MIX1"},
+ {"RX INT0 SEC MIX", NULL, "RX INT0_1 INTERP"},
+ {"RX INT0 MIX2", NULL, "RX INT0 SEC MIX"},
+ {"RX INT0 MIX2", NULL, "RX INT0 MIX2 INP"},
+ {"RX INT0 DEM MUX", NULL, "RX INT0 MIX2"},
+ {"RX INT0 DAC", NULL, "RX INT0 DEM MUX"},
+ {"RX INT0 DAC", NULL, "LDO_RXTX"},
+ {"EAR PA", NULL, "RX INT0 DAC"},
+ {"EAR", NULL, "EAR PA"},
+
+ {"RX INT7_1 INTERP", NULL, "RX INT7_1 MIX1"},
+ {"RX INT7 SEC MIX", NULL, "RX INT7_1 INTERP"},
+ {"RX INT7 MIX2", NULL, "RX INT7 SEC MIX"},
+ {"RX INT7 MIX2", NULL, "RX INT7 MIX2 INP"},
+ {"RX INT7 CHAIN", NULL, "RX INT7 MIX2"},
+ {"SPK1 OUT", NULL, "RX INT7 CHAIN"},
+
+ {"RX INT8_1 INTERP", NULL, "RX INT8_1 MIX1"},
+ {"RX INT8 SEC MIX", NULL, "RX INT8_1 INTERP"},
+ {"RX INT8 SEC MIX", NULL, "RX INT8_1 MIX1"},
+ {"RX INT8 CHAIN", NULL, "RX INT8 SEC MIX"},
+ {"SPK2 OUT", NULL, "RX INT8 CHAIN"},
+
+ {"RX INT9_1 INTERP", NULL, "RX INT9_1 MIX1"},
+ {"RX INT9 SEC MIX", NULL, "RX INT9_1 INTERP"},
+ {"RX INT9 MIX2", NULL, "RX INT9 SEC MIX"},
+ {"RX INT9 MIX2", NULL, "RX INT9 MIX2 INP"},
+ {"RX INT9 DEM MUX", NULL, "RX INT9 MIX2"},
+ {"RX INT9 DAC", NULL, "RX INT9 DEM MUX"},
+ {"RX INT9 DAC", NULL, "LDO_RXTX"},
+ {"AUX PA", NULL, "RX INT9 DAC"},
+ {"AUX", NULL, "AUX PA"},
+
+ /* ANC Routing */
+ {"ANC0 FB MUX", "ANC_IN_EAR", "RX INT0 MIX2"},
+ {"ANC0 FB MUX", "ANC_IN_EAR_SPKR", "RX INT7 MIX2"},
+
+ {"ANC OUT EAR Enable", "Switch", "ADC MUX10"},
+ {"ANC OUT EAR Enable", "Switch", "ADC MUX11"},
+ {"RX INT0 MIX2", NULL, "ANC OUT EAR Enable"},
+
+ {"ANC EAR PA", NULL, "RX INT0 DAC"},
+ {"ANC EAR", NULL, "ANC EAR PA"},
+
+ {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX10"},
+ {"ANC OUT EAR SPKR Enable", "Switch", "ADC MUX11"},
+ {"RX INT7 MIX2", NULL, "ANC OUT EAR SPKR Enable"},
+
+ {"ANC SPKR PA Enable", "Switch", "RX INT7 CHAIN"},
+ {"ANC SPK1 PA", NULL, "ANC SPKR PA Enable"},
+ {"SPK1 OUT", NULL, "ANC SPK1 PA"},
+
+ /*
+ * SRC0 input to Sidetone RX Mixer
+ * on RX0, RX1, RX2, RX3, RX4 and RX7 chains
+ */
+ {"IIR0", NULL, "IIR0 INP0 MUX"},
+ {"IIR0 INP0 MUX", "DEC0", "ADC MUX0"},
+ {"IIR0 INP0 MUX", "DEC1", "ADC MUX1"},
+ {"IIR0 INP0 MUX", "DEC2", "ADC MUX2"},
+ {"IIR0 INP0 MUX", "DEC3", "ADC MUX3"},
+ {"IIR0 INP0 MUX", "DEC4", "ADC MUX4"},
+ {"IIR0 INP0 MUX", "DEC5", "ADC MUX5"},
+ {"IIR0 INP0 MUX", "DEC6", "ADC MUX6"},
+ {"IIR0 INP0 MUX", "DEC7", "ADC MUX7"},
+ {"IIR0 INP0 MUX", "DEC8", "ADC MUX8"},
+ {"IIR0 INP0 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"IIR0 INP0 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"IIR0 INP0 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"IIR0 INP0 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"IIR0 INP0 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"IIR0 INP0 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"IIR0 INP0 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"IIR0 INP0 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"IIR0", NULL, "IIR0 INP1 MUX"},
+ {"IIR0 INP1 MUX", "DEC0", "ADC MUX0"},
+ {"IIR0 INP1 MUX", "DEC1", "ADC MUX1"},
+ {"IIR0 INP1 MUX", "DEC2", "ADC MUX2"},
+ {"IIR0 INP1 MUX", "DEC3", "ADC MUX3"},
+ {"IIR0 INP1 MUX", "DEC4", "ADC MUX4"},
+ {"IIR0 INP1 MUX", "DEC5", "ADC MUX5"},
+ {"IIR0 INP1 MUX", "DEC6", "ADC MUX6"},
+ {"IIR0 INP1 MUX", "DEC7", "ADC MUX7"},
+ {"IIR0 INP1 MUX", "DEC8", "ADC MUX8"},
+ {"IIR0 INP1 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"IIR0 INP1 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"IIR0 INP1 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"IIR0 INP1 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"IIR0 INP1 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"IIR0 INP1 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"IIR0 INP1 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"IIR0 INP1 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"IIR0", NULL, "IIR0 INP2 MUX"},
+ {"IIR0 INP2 MUX", "DEC0", "ADC MUX0"},
+ {"IIR0 INP2 MUX", "DEC1", "ADC MUX1"},
+ {"IIR0 INP2 MUX", "DEC2", "ADC MUX2"},
+ {"IIR0 INP2 MUX", "DEC3", "ADC MUX3"},
+ {"IIR0 INP2 MUX", "DEC4", "ADC MUX4"},
+ {"IIR0 INP2 MUX", "DEC5", "ADC MUX5"},
+ {"IIR0 INP2 MUX", "DEC6", "ADC MUX6"},
+ {"IIR0 INP2 MUX", "DEC7", "ADC MUX7"},
+ {"IIR0 INP2 MUX", "DEC8", "ADC MUX8"},
+ {"IIR0 INP2 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"IIR0 INP2 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"IIR0 INP2 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"IIR0 INP2 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"IIR0 INP2 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"IIR0 INP2 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"IIR0 INP2 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"IIR0 INP2 MUX", "RX7", "CDC_IF RX7 MUX"},
+ {"IIR0", NULL, "IIR0 INP3 MUX"},
+ {"IIR0 INP3 MUX", "DEC0", "ADC MUX0"},
+ {"IIR0 INP3 MUX", "DEC1", "ADC MUX1"},
+ {"IIR0 INP3 MUX", "DEC2", "ADC MUX2"},
+ {"IIR0 INP3 MUX", "DEC3", "ADC MUX3"},
+ {"IIR0 INP3 MUX", "DEC4", "ADC MUX4"},
+ {"IIR0 INP3 MUX", "DEC5", "ADC MUX5"},
+ {"IIR0 INP3 MUX", "DEC6", "ADC MUX6"},
+ {"IIR0 INP3 MUX", "DEC7", "ADC MUX7"},
+ {"IIR0 INP3 MUX", "DEC8", "ADC MUX8"},
+ {"IIR0 INP3 MUX", "RX0", "CDC_IF RX0 MUX"},
+ {"IIR0 INP3 MUX", "RX1", "CDC_IF RX1 MUX"},
+ {"IIR0 INP3 MUX", "RX2", "CDC_IF RX2 MUX"},
+ {"IIR0 INP3 MUX", "RX3", "CDC_IF RX3 MUX"},
+ {"IIR0 INP3 MUX", "RX4", "CDC_IF RX4 MUX"},
+ {"IIR0 INP3 MUX", "RX5", "CDC_IF RX5 MUX"},
+ {"IIR0 INP3 MUX", "RX6", "CDC_IF RX6 MUX"},
+ {"IIR0 INP3 MUX", "RX7", "CDC_IF RX7 MUX"},
+
+ {"SRC0", NULL, "IIR0"},
+ {"RX INT0 MIX2 INP", "SRC0", "SRC0"},
+ {"RX INT7 MIX2 INP", "SRC0", "SRC0"},
+ {"RX INT9 MIX2 INP", "SRC0", "SRC0"},
+
+ /* Native clk mix path routing */
+ {"RX INT7_2 NATIVE MUX", "ON", "RX INT7_2 MUX"},
+ {"RX INT7_2 INTERP", NULL, "RX INT7_2 NATIVE MUX"},
+ {"RX INT7_2 NATIVE MUX", NULL, "RX INT7 NATIVE SUPPLY"},
+
+ {"RX INT8_2 NATIVE MUX", "ON", "RX INT8_2 MUX"},
+ {"RX INT8_2 INTERP", NULL, "RX INT8_2 NATIVE MUX"},
+ {"RX INT8_2 NATIVE MUX", NULL, "RX INT8 NATIVE SUPPLY"},
+
+ /* ASRC Routing */
+ {"ASRC2 MUX", "ASRC_IN_SPKR1", "RX INT7_2 INTERP"},
+ {"RX INT7 SEC MIX", NULL, "ASRC2 MUX"},
+
+ {"ASRC3 MUX", "ASRC_IN_SPKR2", "RX INT8_2 INTERP"},
+ {"RX INT8 SEC MIX", NULL, "ASRC3 MUX"},
+
+ /* SLIMBUS-I2S Bridge interface */
+ {"I2S TX1_0 MUX", "AIF4_PB", "AIF4 PB"},
+ {"I2S TX1_1 MUX", "AIF4_PB", "AIF4 PB"},
+ {"I2S TX1 MIXER", NULL, "I2S TX1_0 MUX"},
+ {"I2S TX1 MIXER", NULL, "I2S TX1_1 MUX"},
+ {"I2S1 CAP", NULL, "I2S TX1 MIXER"},
+
+ {"CDC_IF TX10 MUX2", "I2SRX1_0_BRDG", "CDC_IF RX2 MUX"},
+ {"CDC_IF TX11 MUX2", "I2SRX1_1_BRDG", "CDC_IF RX3 MUX"},
+ {"CDC_IF RX2 MUX", "I2SRX1_0", "I2S1 PB"},
+ {"CDC_IF RX3 MUX", "I2SRX1_1", "I2S1 PB"},
+};
+
+#endif
diff --git a/asoc/codecs/wcd9360/wcd9360.c b/asoc/codecs/wcd9360/wcd9360.c
new file mode 100644
index 0000000..5b8da20
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360.c
@@ -0,0 +1,8093 @@
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/printk.h>
+#include <linux/ratelimit.h>
+#include <linux/wait.h>
+#include <linux/bitops.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+#include <soc/swr-wcd.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/tlv.h>
+#include <sound/info.h>
+#include <asoc/wcd9360-registers.h>
+#include "wcd9360.h"
+#include "wcd9360-routing.h"
+#include "wcd9360-dsp-cntl.h"
+#include "wcd9360-irq.h"
+#include "../core.h"
+#include "../pdata.h"
+#include "../wcd9xxx-irq.h"
+#include "../wcd9xxx-common-v2.h"
+#include "../wcd9xxx-resmgr-v2.h"
+#include "../wcdcal-hwdep.h"
+#include "../msm-cdc-supply.h"
+
+
+#define WCD9360_RATES_MASK (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000 |\
+ SNDRV_PCM_RATE_384000)
+/* Fractional Rates */
+#define WCD9360_FRAC_RATES_MASK (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_176400)
+
+#define WCD9360_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE)
+
+#define WCD9360_FORMATS_S16_S24_S32_LE (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+#define WCD9360_FORMATS_S16_LE (SNDRV_PCM_FMTBIT_S16_LE)
+
+/* Macros for packing register writes into a U32 */
+#define WCD9360_PACKED_REG_SIZE sizeof(u32)
+#define WCD9360_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \
+ do { \
+ ((reg) = ((packed >> 16) & (0xffff))); \
+ ((mask) = ((packed >> 8) & (0xff))); \
+ ((val) = ((packed) & (0xff))); \
+ } while (0)
+
+#define STRING(name) #name
+#define WCD_DAPM_ENUM(name, reg, offset, text) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+ SOC_DAPM_ENUM(STRING(name), name##_enum)
+
+#define WCD_DAPM_ENUM_EXT(name, reg, offset, text, getname, putname) \
+static SOC_ENUM_SINGLE_DECL(name##_enum, reg, offset, text); \
+static const struct snd_kcontrol_new name##_mux = \
+ SOC_DAPM_ENUM_EXT(STRING(name), name##_enum, getname, putname)
+
+#define WCD_DAPM_MUX(name, shift, kctl) \
+ SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, shift, 0, &kctl##_mux)
+
+/*
+ * Timeout in milli seconds and it is the wait time for
+ * slim channel removal interrupt to receive.
+ */
+#define WCD9360_SLIM_CLOSE_TIMEOUT 1000
+#define WCD9360_SLIM_IRQ_OVERFLOW (1 << 0)
+#define WCD9360_SLIM_IRQ_UNDERFLOW (1 << 1)
+#define WCD9360_SLIM_IRQ_PORT_CLOSED (1 << 2)
+
+#define WCD9360_MCLK_CLK_9P6MHZ 9600000
+
+#define WCD9360_INTERP_MUX_NUM_INPUTS 3
+#define WCD9360_NUM_INTERPOLATORS 10
+#define WCD9360_NUM_DECIMATORS 9
+#define WCD9360_RX_PATH_CTL_OFFSET 20
+#define WCD9360_TLMM_DMIC_PINCFG_OFFSET 15
+
+#define BYTE_BIT_MASK(nr) (1 << ((nr) % BITS_PER_BYTE))
+
+#define WCD9360_REG_BITS 8
+#define WCD9360_MAX_VALID_ADC_MUX 11
+#define WCD9360_INVALID_ADC_MUX 9
+
+#define WCD9360_AMIC_PWR_LEVEL_LP 0
+#define WCD9360_AMIC_PWR_LEVEL_DEFAULT 1
+#define WCD9360_AMIC_PWR_LEVEL_HP 2
+#define WCD9360_AMIC_PWR_LVL_MASK 0x60
+#define WCD9360_AMIC_PWR_LVL_SHIFT 0x5
+
+#define WCD9360_DEC_PWR_LVL_MASK 0x06
+#define WCD9360_DEC_PWR_LVL_LP 0x02
+#define WCD9360_DEC_PWR_LVL_HP 0x04
+#define WCD9360_DEC_PWR_LVL_DF 0x00
+#define WCD9360_STRING_LEN 100
+
+#define WCD9360_CDC_SIDETONE_IIR_COEFF_MAX 5
+#define WCD9360_CDC_REPEAT_WRITES_MAX 16
+#define WCD9360_DIG_CORE_REG_MIN WCD9360_CDC_ANC0_CLK_RESET_CTL
+#define WCD9360_DIG_CORE_REG_MAX 0xFFF
+
+#define WCD9360_CHILD_DEVICES_MAX 6
+
+#define WCD9360_MAX_MICBIAS 4
+#define DAPM_MICBIAS1_STANDALONE "MIC BIAS1 Standalone"
+#define DAPM_MICBIAS2_STANDALONE "MIC BIAS2 Standalone"
+#define DAPM_MICBIAS3_STANDALONE "MIC BIAS3 Standalone"
+#define DAPM_MICBIAS4_STANDALONE "MIC BIAS4 Standalone"
+
+#define WCD9360_LDO_RXTX_SUPPLY_NAME "vdd_ldo_rxtx_supply"
+
+#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
+#define CF_MIN_3DB_4HZ 0x0
+#define CF_MIN_3DB_75HZ 0x1
+#define CF_MIN_3DB_150HZ 0x2
+
+#define CPE_ERR_WDOG_BITE BIT(0)
+#define CPE_FATAL_IRQS CPE_ERR_WDOG_BITE
+
+#define WCD9360_MAD_AUDIO_FIRMWARE_PATH "wcd9360/wcd9360_mad_audio.bin"
+
+#define PAHU_VERSION_ENTRY_SIZE 17
+
+#define WCD9360_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000)
+
+enum {
+ INTERP_EAR = 0,
+ /* Headset and Lineout are not avalible in pahu */
+ INTERP_HPHL_NA,
+ INTERP_HPHR_NA,
+ INTERP_LO1_NA,
+ INTERP_LO2_NA,
+ INTERP_LO3_NA,
+ INTERP_LO4_NA,
+ INTERP_SPKR1,
+ INTERP_SPKR2,
+ INTERP_AUX,
+ INTERP_MAX,
+};
+
+enum {
+ POWER_COLLAPSE,
+ POWER_RESUME,
+};
+
+static int dig_core_collapse_enable = 1;
+module_param(dig_core_collapse_enable, int, 0664);
+MODULE_PARM_DESC(dig_core_collapse_enable, "enable/disable power gating");
+
+/* dig_core_collapse timer in seconds */
+static int dig_core_collapse_timer = (WCD9360_DIG_CORE_COLLAPSE_TIMER_MS/1000);
+module_param(dig_core_collapse_timer, int, 0664);
+MODULE_PARM_DESC(dig_core_collapse_timer, "timer for power gating");
+
+enum {
+ VI_SENSE_1,
+ VI_SENSE_2,
+ CLK_INTERNAL,
+ CLK_MODE,
+};
+
+enum {
+ AIF1_PB = 0,
+ AIF1_CAP,
+ AIF2_PB,
+ AIF2_CAP,
+ AIF3_PB,
+ AIF3_CAP,
+ AIF4_PB,
+ AIF4_VIFEED,
+ AIF4_MAD_TX,
+ I2S1_PB,
+ I2S1_CAP,
+ NUM_CODEC_DAIS,
+};
+
+enum {
+ INTn_1_INP_SEL_ZERO = 0,
+ INTn_1_INP_SEL_DEC0,
+ INTn_1_INP_SEL_DEC1,
+ INTn_1_INP_SEL_IIR0,
+ INTn_1_INP_SEL_NA,
+ INTn_1_INP_SEL_RX0,
+ INTn_1_INP_SEL_RX1,
+ INTn_1_INP_SEL_RX2,
+ INTn_1_INP_SEL_RX3,
+ INTn_1_INP_SEL_RX4,
+ INTn_1_INP_SEL_RX5,
+ INTn_1_INP_SEL_RX6,
+ INTn_1_INP_SEL_RX7,
+};
+
+enum {
+ INTn_2_INP_SEL_ZERO = 0,
+ INTn_2_INP_SEL_RX0,
+ INTn_2_INP_SEL_RX1,
+ INTn_2_INP_SEL_RX2,
+ INTn_2_INP_SEL_RX3,
+ INTn_2_INP_SEL_RX4,
+ INTn_2_INP_SEL_RX5,
+ INTn_2_INP_SEL_RX6,
+ INTn_2_INP_SEL_RX7,
+ INTn_2_INP_SEL_PROXIMITY,
+};
+
+enum {
+ INTERP_MAIN_PATH,
+ INTERP_MIX_PATH,
+};
+
+struct pahu_cpr_reg_defaults {
+ int wr_data;
+ int wr_addr;
+};
+
+struct interp_sample_rate {
+ int sample_rate;
+ int rate_val;
+};
+
+static struct interp_sample_rate sr_val_tbl[] = {
+ {8000, 0x0}, {16000, 0x1}, {32000, 0x3}, {48000, 0x4}, {96000, 0x5},
+ {192000, 0x6}, {384000, 0x7}, {44100, 0x9}, {88200, 0xA},
+ {176400, 0xB}, {352800, 0xC},
+};
+
+static const struct wcd9xxx_ch pahu_rx_chs[WCD9360_RX_MAX] = {
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER, 0),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 1, 1),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 2, 2),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 3, 3),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 4, 4),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 5, 5),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 6, 6),
+ WCD9XXX_CH(WCD9360_RX_PORT_START_NUMBER + 7, 7),
+};
+
+static const struct wcd9xxx_ch pahu_tx_chs[WCD9360_TX_MAX] = {
+ WCD9XXX_CH(0, 0),
+ WCD9XXX_CH(1, 1),
+ WCD9XXX_CH(2, 2),
+ WCD9XXX_CH(3, 3),
+ WCD9XXX_CH(4, 4),
+ WCD9XXX_CH(5, 5),
+ WCD9XXX_CH(6, 6),
+ WCD9XXX_CH(7, 7),
+ WCD9XXX_CH(8, 8),
+ WCD9XXX_CH(9, 9),
+ WCD9XXX_CH(10, 10),
+ WCD9XXX_CH(11, 11),
+ WCD9XXX_CH(12, 12),
+ WCD9XXX_CH(13, 13),
+ WCD9XXX_CH(14, 14),
+ WCD9XXX_CH(15, 15),
+};
+
+static const u32 vport_slim_check_table[NUM_CODEC_DAIS] = {
+ 0, /* AIF1_PB */
+ BIT(AIF2_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF1_CAP */
+ 0, /* AIF2_PB */
+ BIT(AIF1_CAP) | BIT(AIF3_CAP) | BIT(AIF4_MAD_TX), /* AIF2_CAP */
+ 0, /* AIF3_PB */
+ BIT(AIF1_CAP) | BIT(AIF2_CAP) | BIT(AIF4_MAD_TX), /* AIF3_CAP */
+ 0, /* AIF4_PB */
+};
+
+/* Codec supports 2 IIR filters */
+enum {
+ IIR0 = 0,
+ IIR_MAX,
+};
+
+/* Each IIR has 5 Filter Stages */
+enum {
+ BAND1 = 0,
+ BAND2,
+ BAND3,
+ BAND4,
+ BAND5,
+ BAND_MAX,
+};
+
+enum {
+ COMPANDER_0, /* EAR */
+ COMPANDER_1, /* HPH_L */
+ COMPANDER_2, /* HPH_R */
+ COMPANDER_3, /* LO1_DIFF */
+ COMPANDER_4, /* LO2_DIFF */
+ COMPANDER_5, /* LO3_SE */
+ COMPANDER_6, /* LO4_SE */
+ COMPANDER_7, /* SWR SPK CH1 */
+ COMPANDER_8, /* SWR SPK CH2 */
+ COMPANDER_9, /* AUX */
+ COMPANDER_MAX,
+};
+
+enum {
+ ASRC_IN_SPKR1,
+ ASRC_IN_SPKR2,
+ ASRC_INVALID,
+};
+
+enum {
+ ASRC2,
+ ASRC3,
+ ASRC_MAX,
+};
+
+enum {
+ CONV_88P2K_TO_384K,
+ CONV_96K_TO_352P8K,
+ CONV_352P8K_TO_384K,
+ CONV_384K_TO_352P8K,
+ CONV_384K_TO_384K,
+ CONV_96K_TO_384K,
+};
+
+static struct afe_param_slimbus_slave_port_cfg pahu_slimbus_slave_port_cfg = {
+ .minor_version = 1,
+ .slimbus_dev_id = AFE_SLIMBUS_DEVICE_1,
+ .slave_dev_pgd_la = 0,
+ .slave_dev_intfdev_la = 0,
+ .bit_width = 16,
+ .data_format = 0,
+ .num_channels = 1
+};
+
+static struct afe_param_cdc_reg_page_cfg pahu_cdc_reg_page_cfg = {
+ .minor_version = AFE_API_VERSION_CDC_REG_PAGE_CFG,
+ .enable = 1,
+ .proc_id = AFE_CDC_REG_PAGE_ASSIGN_PROC_ID_1,
+};
+
+static struct afe_param_cdc_reg_cfg audio_reg_cfg[] = {
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_MAIN_CTL_1),
+ HW_MAD_AUDIO_ENABLE, 0x1, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_AUDIO_CTL_3),
+ HW_MAD_AUDIO_SLEEP_TIME, 0xF, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SOC_MAD_AUDIO_CTL_4),
+ HW_MAD_TX_AUDIO_SWITCH_OFF, 0x1, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_CFG),
+ MAD_AUDIO_INT_DEST_SELECT_REG, 0x2, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_MASK3),
+ MAD_AUDIO_INT_MASK_REG, 0x1, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_STATUS3),
+ MAD_AUDIO_INT_STATUS_REG, 0x1, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_INTR_PIN2_CLEAR3),
+ MAD_AUDIO_INT_CLEAR_REG, 0x1, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_TX_BASE),
+ SB_PGD_PORT_TX_WATERMARK_N, 0x1E, WCD9360_REG_BITS, 0x1
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_TX_BASE),
+ SB_PGD_PORT_TX_ENABLE_N, 0x1, WCD9360_REG_BITS, 0x1
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_RX_BASE),
+ SB_PGD_PORT_RX_WATERMARK_N, 0x1E, WCD9360_REG_BITS, 0x1
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET + WCD9360_SB_PGD_PORT_RX_BASE),
+ SB_PGD_PORT_RX_ENABLE_N, 0x1, WCD9360_REG_BITS, 0x1
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ WCD9360_CDC_ANC0_IIR_ADAPT_CTL),
+ AANC_FF_GAIN_ADAPTIVE, 0x4, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ WCD9360_CDC_ANC0_IIR_ADAPT_CTL),
+ AANC_FFGAIN_ADAPTIVE_EN, 0x8, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ WCD9360_CDC_ANC0_FF_A_GAIN_CTL),
+ AANC_GAIN_CONTROL, 0xFF, WCD9360_REG_BITS, 0
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ SB_PGD_TX_PORT_MULTI_CHANNEL_0(0)),
+ SB_PGD_TX_PORTn_MULTI_CHNL_0, 0xFF, WCD9360_REG_BITS, 0x4
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ SB_PGD_TX_PORT_MULTI_CHANNEL_1(0)),
+ SB_PGD_TX_PORTn_MULTI_CHNL_1, 0xFF, WCD9360_REG_BITS, 0x4
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x180, 0)),
+ SB_PGD_RX_PORTn_MULTI_CHNL_0, 0xFF, WCD9360_REG_BITS, 0x4
+ },
+ {
+ 1,
+ (WCD9360_REGISTER_START_OFFSET +
+ SB_PGD_RX_PORT_MULTI_CHANNEL_0(0x181, 0)),
+ SB_PGD_RX_PORTn_MULTI_CHNL_1, 0xFF, WCD9360_REG_BITS, 0x4
+ },
+};
+
+static struct afe_param_cdc_reg_cfg_data pahu_audio_reg_cfg = {
+ .num_registers = ARRAY_SIZE(audio_reg_cfg),
+ .reg_data = audio_reg_cfg,
+};
+
+static struct afe_param_id_cdc_aanc_version pahu_cdc_aanc_version = {
+ .cdc_aanc_minor_version = AFE_API_VERSION_CDC_AANC_VERSION,
+ .aanc_hw_version = AANC_HW_BLOCK_VERSION_2,
+};
+
+static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
+static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1);
+
+#define WCD9360_TX_UNMUTE_DELAY_MS 40
+
+static int tx_unmute_delay = WCD9360_TX_UNMUTE_DELAY_MS;
+module_param(tx_unmute_delay, int, 0664);
+MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
+
+static void pahu_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
+
+/* Hold instance to soundwire platform device */
+struct pahu_swr_ctrl_data {
+ struct platform_device *swr_pdev;
+};
+
+struct wcd_swr_ctrl_platform_data {
+ void *handle; /* holds codec private data */
+ int (*read)(void *handle, int reg);
+ int (*write)(void *handle, int reg, int val);
+ int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
+ int (*clk)(void *handle, bool enable);
+ int (*handle_irq)(void *handle,
+ irqreturn_t (*swrm_irq_handler)(int irq, void *data),
+ void *swrm_handle, int action);
+};
+
+/* Holds all Soundwire and speaker related information */
+struct wcd9360_swr {
+ struct pahu_swr_ctrl_data *ctrl_data;
+ struct wcd_swr_ctrl_platform_data plat_data;
+ struct mutex read_mutex;
+ struct mutex write_mutex;
+ struct mutex clk_mutex;
+ int spkr_gain_offset;
+ int spkr_mode;
+ int clk_users;
+ int rx_7_count;
+ int rx_8_count;
+};
+
+struct tx_mute_work {
+ struct pahu_priv *pahu;
+ u8 decimator;
+ struct delayed_work dwork;
+};
+
+#define WCD9360_SPK_ANC_EN_DELAY_MS 550
+static int spk_anc_en_delay = WCD9360_SPK_ANC_EN_DELAY_MS;
+module_param(spk_anc_en_delay, int, 0664);
+MODULE_PARM_DESC(spk_anc_en_delay, "delay to enable anc in speaker path");
+
+struct spk_anc_work {
+ struct pahu_priv *pahu;
+ struct delayed_work dwork;
+};
+
+struct hpf_work {
+ struct pahu_priv *pahu;
+ u8 decimator;
+ u8 hpf_cut_off_freq;
+ struct delayed_work dwork;
+};
+
+struct pahu_priv {
+ struct device *dev;
+ struct wcd9xxx *wcd9xxx;
+ struct snd_soc_codec *codec;
+ s32 ldo_rxtx_cnt;
+ s32 dmic_0_1_clk_cnt;
+ s32 dmic_2_3_clk_cnt;
+ s32 dmic_4_5_clk_cnt;
+ s32 dmic_6_7_clk_cnt;
+ s32 micb_ref[PAHU_MAX_MICBIAS];
+ s32 pullup_ref[PAHU_MAX_MICBIAS];
+
+ /* ANC related */
+ u32 anc_slot;
+ bool anc_func;
+
+ /* compander */
+ int comp_enabled[COMPANDER_MAX];
+ int ear_spkr_gain;
+
+ /* Mad switch reference count */
+ int mad_switch_cnt;
+
+ /* track pahu interface type */
+ u8 intf_type;
+
+ /* to track the status */
+ unsigned long status_mask;
+
+ struct afe_param_cdc_slimbus_slave_cfg slimbus_slave_cfg;
+
+ /* num of slim ports required */
+ struct wcd9xxx_codec_dai_data dai[NUM_CODEC_DAIS];
+ /* Port values for Rx and Tx codec_dai */
+ unsigned int rx_port_value[WCD9360_RX_MAX];
+ unsigned int tx_port_value;
+
+ struct wcd9xxx_resmgr_v2 *resmgr;
+ struct wcd9360_swr swr;
+ struct mutex micb_lock;
+
+ struct delayed_work power_gate_work;
+ struct mutex power_lock;
+
+ struct clk *wcd_ext_clk;
+
+ struct mutex codec_mutex;
+ struct work_struct pahu_add_child_devices_work;
+ struct hpf_work tx_hpf_work[WCD9360_NUM_DECIMATORS];
+ struct tx_mute_work tx_mute_dwork[WCD9360_NUM_DECIMATORS];
+ struct spk_anc_work spk_anc_dwork;
+
+ unsigned int vi_feed_value;
+
+ /* DSP control */
+ struct wcd_dsp_cntl *wdsp_cntl;
+
+ /* cal info for codec */
+ struct fw_info *fw_data;
+
+ /* Entry for version info */
+ struct snd_info_entry *entry;
+ struct snd_info_entry *version_entry;
+
+ /* SVS voting related */
+ struct mutex svs_mutex;
+ int svs_ref_cnt;
+
+ int native_clk_users;
+ /* ASRC users count */
+ int asrc_users[ASRC_MAX];
+ int asrc_output_mode[ASRC_MAX];
+ /* Main path clock users count */
+ int main_clk_users[WCD9360_NUM_INTERPOLATORS];
+
+ int power_active_ref;
+ u8 sidetone_coeff_array[IIR_MAX][BAND_MAX]
+ [WCD9360_CDC_SIDETONE_IIR_COEFF_MAX * 4];
+
+ struct spi_device *spi;
+ struct platform_device *pdev_child_devices
+ [WCD9360_CHILD_DEVICES_MAX];
+ int child_count;
+ int i2s_ref_cnt;
+};
+
+static const struct pahu_reg_mask_val pahu_spkr_default[] = {
+ {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x80},
+ {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x80},
+ {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01},
+ {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01},
+ {WCD9360_CDC_BOOST0_BOOST_CTL, 0x7C, 0x50},
+ {WCD9360_CDC_BOOST1_BOOST_CTL, 0x7C, 0x50},
+};
+
+static const struct pahu_reg_mask_val pahu_spkr_mode1[] = {
+ {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x00},
+ {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x00},
+ {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x00},
+ {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x00},
+ {WCD9360_CDC_BOOST0_BOOST_CTL, 0x7C, 0x44},
+ {WCD9360_CDC_BOOST1_BOOST_CTL, 0x7C, 0x44},
+};
+
+static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu);
+
+/**
+ * pahu_set_spkr_gain_offset - offset the speaker path
+ * gain with the given offset value.
+ *
+ * @codec: codec instance
+ * @offset: Indicates speaker path gain offset value.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset)
+{
+ struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+ if (!priv)
+ return -EINVAL;
+
+ priv->swr.spkr_gain_offset = offset;
+ return 0;
+}
+EXPORT_SYMBOL(pahu_set_spkr_gain_offset);
+
+/**
+ * pahu_set_spkr_mode - Configures speaker compander and smartboost
+ * settings based on speaker mode.
+ *
+ * @codec: codec instance
+ * @mode: Indicates speaker configuration mode.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode)
+{
+ struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec);
+ int i;
+ const struct pahu_reg_mask_val *regs;
+ int size;
+
+ if (!priv)
+ return -EINVAL;
+
+ switch (mode) {
+ case WCD9360_SPKR_MODE_1:
+ regs = pahu_spkr_mode1;
+ size = ARRAY_SIZE(pahu_spkr_mode1);
+ break;
+ default:
+ regs = pahu_spkr_default;
+ size = ARRAY_SIZE(pahu_spkr_default);
+ break;
+ }
+
+ priv->swr.spkr_mode = mode;
+ for (i = 0; i < size; i++)
+ snd_soc_update_bits(codec, regs[i].reg,
+ regs[i].mask, regs[i].val);
+ return 0;
+}
+EXPORT_SYMBOL(pahu_set_spkr_mode);
+
+/**
+ * pahu_get_afe_config - returns specific codec configuration to afe to write
+ *
+ * @codec: codec instance
+ * @config_type: Indicates type of configuration to write.
+ */
+void *pahu_get_afe_config(struct snd_soc_codec *codec,
+ enum afe_config_type config_type)
+{
+ struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+ switch (config_type) {
+ case AFE_SLIMBUS_SLAVE_CONFIG:
+ return &priv->slimbus_slave_cfg;
+ case AFE_CDC_REGISTERS_CONFIG:
+ return &pahu_audio_reg_cfg;
+ case AFE_SLIMBUS_SLAVE_PORT_CONFIG:
+ return &pahu_slimbus_slave_port_cfg;
+ case AFE_AANC_VERSION:
+ return &pahu_cdc_aanc_version;
+ case AFE_CDC_REGISTER_PAGE_CONFIG:
+ return &pahu_cdc_reg_page_cfg;
+ default:
+ dev_info(codec->dev, "%s: Unknown config_type 0x%x\n",
+ __func__, config_type);
+ return NULL;
+ }
+}
+EXPORT_SYMBOL(pahu_get_afe_config);
+
+static void pahu_vote_svs(struct pahu_priv *pahu, bool vote)
+{
+ struct wcd9xxx *wcd9xxx;
+
+ wcd9xxx = pahu->wcd9xxx;
+
+ mutex_lock(&pahu->svs_mutex);
+ if (vote) {
+ pahu->svs_ref_cnt++;
+ if (pahu->svs_ref_cnt == 1)
+ regmap_update_bits(wcd9xxx->regmap,
+ WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0,
+ 0x01, 0x01);
+ } else {
+ /* Do not decrement ref count if it is already 0 */
+ if (pahu->svs_ref_cnt == 0)
+ goto done;
+
+ pahu->svs_ref_cnt--;
+ if (pahu->svs_ref_cnt == 0)
+ regmap_update_bits(wcd9xxx->regmap,
+ WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0,
+ 0x01, 0x00);
+ }
+done:
+ dev_dbg(pahu->dev, "%s: vote = %s, updated ref cnt = %u\n", __func__,
+ vote ? "vote" : "Unvote", pahu->svs_ref_cnt);
+ mutex_unlock(&pahu->svs_mutex);
+}
+
+static int pahu_get_anc_slot(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = pahu->anc_slot;
+ return 0;
+}
+
+static int pahu_put_anc_slot(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ pahu->anc_slot = ucontrol->value.integer.value[0];
+ return 0;
+}
+
+static int pahu_get_anc_func(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = (pahu->anc_func == true ? 1 : 0);
+ return 0;
+}
+
+static int pahu_put_anc_func(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+
+ mutex_lock(&pahu->codec_mutex);
+ pahu->anc_func = (!ucontrol->value.integer.value[0] ? false : true);
+ dev_dbg(codec->dev, "%s: anc_func %x", __func__, pahu->anc_func);
+
+ if (pahu->anc_func == true) {
+ snd_soc_dapm_enable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_enable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
+ snd_soc_dapm_disable_pin(dapm, "EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "EAR");
+ } else {
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_disable_pin(dapm, "ANC SPK1 PA");
+ snd_soc_dapm_enable_pin(dapm, "EAR PA");
+ snd_soc_dapm_enable_pin(dapm, "EAR");
+ }
+ mutex_unlock(&pahu->codec_mutex);
+
+ snd_soc_dapm_sync(dapm);
+ return 0;
+}
+
+static int pahu_codec_enable_anc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ const char *filename;
+ const struct firmware *fw;
+ int i;
+ int ret = 0;
+ int num_anc_slots;
+ struct wcd9xxx_anc_header *anc_head;
+ struct firmware_cal *hwdep_cal = NULL;
+ u32 anc_writes_size = 0;
+ int anc_size_remaining;
+ u32 *anc_ptr;
+ u16 reg;
+ u8 mask, val;
+ size_t cal_size;
+ const void *data;
+
+ if (!pahu->anc_func)
+ return 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ hwdep_cal = wcdcal_get_fw_cal(pahu->fw_data, WCD9XXX_ANC_CAL);
+ if (hwdep_cal) {
+ data = hwdep_cal->data;
+ cal_size = hwdep_cal->size;
+ dev_dbg(codec->dev, "%s: using hwdep calibration, cal_size %zd",
+ __func__, cal_size);
+ } else {
+ filename = "wcd9360/WCD9360_anc.bin";
+ ret = request_firmware(&fw, filename, codec->dev);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: Failed to acquire ANC data: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ if (!fw) {
+ dev_err(codec->dev, "%s: Failed to get anc fw\n",
+ __func__);
+ return -ENODEV;
+ }
+ data = fw->data;
+ cal_size = fw->size;
+ dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
+ __func__);
+ }
+ if (cal_size < sizeof(struct wcd9xxx_anc_header)) {
+ dev_err(codec->dev, "%s: Invalid cal_size %zd\n",
+ __func__, cal_size);
+ ret = -EINVAL;
+ goto err;
+ }
+ /* First number is the number of register writes */
+ anc_head = (struct wcd9xxx_anc_header *)(data);
+ anc_ptr = (u32 *)(data + sizeof(struct wcd9xxx_anc_header));
+ anc_size_remaining = cal_size -
+ sizeof(struct wcd9xxx_anc_header);
+ num_anc_slots = anc_head->num_anc_slots;
+
+ if (pahu->anc_slot >= num_anc_slots) {
+ dev_err(codec->dev, "%s: Invalid ANC slot selected\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ for (i = 0; i < num_anc_slots; i++) {
+ if (anc_size_remaining < WCD9360_PACKED_REG_SIZE) {
+ dev_err(codec->dev, "%s: Invalid register format\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ anc_writes_size = (u32)(*anc_ptr);
+ anc_size_remaining -= sizeof(u32);
+ anc_ptr += 1;
+
+ if ((anc_writes_size * WCD9360_PACKED_REG_SIZE) >
+ anc_size_remaining) {
+ dev_err(codec->dev, "%s: Invalid register format\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (pahu->anc_slot == i)
+ break;
+
+ anc_size_remaining -= (anc_writes_size *
+ WCD9360_PACKED_REG_SIZE);
+ anc_ptr += anc_writes_size;
+ }
+ if (i == num_anc_slots) {
+ dev_err(codec->dev, "%s: Selected ANC slot not present\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ for (i = 0; i < anc_writes_size; i++) {
+ WCD9360_CODEC_UNPACK_ENTRY(anc_ptr[i], reg, mask, val);
+ snd_soc_write(codec, reg, (val & mask));
+ }
+
+ if (!hwdep_cal)
+ release_firmware(fw);
+ break;
+
+ case SND_SOC_DAPM_POST_PMU:
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ if (!strcmp(w->name, "ANC EAR PA") ||
+ !strcmp(w->name, "ANC SPK1 PA")) {
+ snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_1_CTL,
+ 0x30, 0x00);
+ msleep(50);
+ snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_1_CTL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_ANC0_CLK_RESET_CTL,
+ 0x38, 0x38);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_ANC0_CLK_RESET_CTL,
+ 0x07, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_ANC0_CLK_RESET_CTL,
+ 0x38, 0x00);
+ }
+ break;
+ }
+
+ return 0;
+err:
+ if (!hwdep_cal)
+ release_firmware(fw);
+ return ret;
+}
+
+static int pahu_get_clkmode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+
+ if (test_bit(CLK_MODE, &pahu_p->status_mask))
+ ucontrol->value.enumerated.item[0] = 1;
+ else
+ ucontrol->value.enumerated.item[0] = 0;
+
+ dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__,
+ test_bit(CLK_MODE, &pahu_p->status_mask) ? "true" : "false");
+
+ return 0;
+}
+
+static int pahu_put_clkmode(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+
+ if (ucontrol->value.enumerated.item[0])
+ set_bit(CLK_MODE, &pahu_p->status_mask);
+ else
+ clear_bit(CLK_MODE, &pahu_p->status_mask);
+
+ dev_dbg(codec->dev, "%s: is_low_power_clock: %s\n", __func__,
+ test_bit(CLK_MODE, &pahu_p->status_mask) ? "true" : "false");
+
+ return 0;
+}
+
+static int pahu_vi_feed_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = pahu_p->vi_feed_value;
+
+ return 0;
+}
+
+static int pahu_vi_feed_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
+ struct soc_multi_mixer_control *mixer =
+ ((struct soc_multi_mixer_control *)kcontrol->private_value);
+ u32 dai_id = widget->shift;
+ u32 port_id = mixer->shift;
+ u32 enable = ucontrol->value.integer.value[0];
+
+ dev_dbg(codec->dev, "%s: enable: %d, port_id:%d, dai_id: %d\n",
+ __func__, enable, port_id, dai_id);
+
+ pahu_p->vi_feed_value = ucontrol->value.integer.value[0];
+
+ mutex_lock(&pahu_p->codec_mutex);
+ if (enable) {
+ if (port_id == WCD9360_TX14 && !test_bit(VI_SENSE_1,
+ &pahu_p->status_mask)) {
+ list_add_tail(&core->tx_chs[WCD9360_TX14].list,
+ &pahu_p->dai[dai_id].wcd9xxx_ch_list);
+ set_bit(VI_SENSE_1, &pahu_p->status_mask);
+ }
+ if (port_id == WCD9360_TX15 && !test_bit(VI_SENSE_2,
+ &pahu_p->status_mask)) {
+ list_add_tail(&core->tx_chs[WCD9360_TX15].list,
+ &pahu_p->dai[dai_id].wcd9xxx_ch_list);
+ set_bit(VI_SENSE_2, &pahu_p->status_mask);
+ }
+ } else {
+ if (port_id == WCD9360_TX14 && test_bit(VI_SENSE_1,
+ &pahu_p->status_mask)) {
+ list_del_init(&core->tx_chs[WCD9360_TX14].list);
+ clear_bit(VI_SENSE_1, &pahu_p->status_mask);
+ }
+ if (port_id == WCD9360_TX15 && test_bit(VI_SENSE_2,
+ &pahu_p->status_mask)) {
+ list_del_init(&core->tx_chs[WCD9360_TX15].list);
+ clear_bit(VI_SENSE_2, &pahu_p->status_mask);
+ }
+ }
+ mutex_unlock(&pahu_p->codec_mutex);
+ snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, NULL);
+
+ return 0;
+}
+
+static int slim_tx_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = pahu_p->tx_port_value;
+ return 0;
+}
+
+static int slim_tx_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
+ struct snd_soc_dapm_update *update = NULL;
+ struct soc_multi_mixer_control *mixer =
+ ((struct soc_multi_mixer_control *)kcontrol->private_value);
+ u32 dai_id = widget->shift;
+ u32 port_id = mixer->shift;
+ u32 enable = ucontrol->value.integer.value[0];
+ u32 vtable;
+
+ dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
+ __func__,
+ widget->name, ucontrol->id.name, pahu_p->tx_port_value,
+ widget->shift, ucontrol->value.integer.value[0]);
+
+ mutex_lock(&pahu_p->codec_mutex);
+ if (dai_id >= ARRAY_SIZE(vport_slim_check_table)) {
+ dev_err(codec->dev, "%s: dai_id: %d, out of bounds\n",
+ __func__, dai_id);
+ mutex_unlock(&pahu_p->codec_mutex);
+ return -EINVAL;
+ }
+ vtable = vport_slim_check_table[dai_id];
+
+ switch (dai_id) {
+ case AIF1_CAP:
+ case AIF2_CAP:
+ case AIF3_CAP:
+ /* only add to the list if value not set */
+ if (enable && !(pahu_p->tx_port_value & 1 << port_id)) {
+ if (wcd9xxx_tx_vport_validation(vtable, port_id,
+ pahu_p->dai, NUM_CODEC_DAIS)) {
+ dev_dbg(codec->dev, "%s: TX%u is used by other virtual port\n",
+ __func__, port_id);
+ mutex_unlock(&pahu_p->codec_mutex);
+ return 0;
+ }
+ pahu_p->tx_port_value |= 1 << port_id;
+ list_add_tail(&core->tx_chs[port_id].list,
+ &pahu_p->dai[dai_id].wcd9xxx_ch_list);
+ } else if (!enable && (pahu_p->tx_port_value &
+ 1 << port_id)) {
+ pahu_p->tx_port_value &= ~(1 << port_id);
+ list_del_init(&core->tx_chs[port_id].list);
+ } else {
+ if (enable)
+ dev_dbg(codec->dev, "%s: TX%u port is used by\n"
+ "this virtual port\n",
+ __func__, port_id);
+ else
+ dev_dbg(codec->dev, "%s: TX%u port is not used by\n"
+ "this virtual port\n",
+ __func__, port_id);
+ /* avoid update power function */
+ mutex_unlock(&pahu_p->codec_mutex);
+ return 0;
+ }
+ break;
+ case AIF4_MAD_TX:
+ break;
+ default:
+ dev_err(codec->dev, "Unknown AIF %d\n", dai_id);
+ mutex_unlock(&pahu_p->codec_mutex);
+ return -EINVAL;
+ }
+ dev_dbg(codec->dev, "%s: name %s sname %s updated value %u shift %d\n",
+ __func__, widget->name, widget->sname, pahu_p->tx_port_value,
+ widget->shift);
+
+ mutex_unlock(&pahu_p->codec_mutex);
+ snd_soc_dapm_mixer_update_power(widget->dapm, kcontrol, enable, update);
+
+ return 0;
+}
+
+static int slim_rx_mux_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.enumerated.item[0] =
+ pahu_p->rx_port_value[widget->shift];
+ return 0;
+}
+
+static int slim_rx_mux_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx *core = dev_get_drvdata(codec->dev->parent);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct snd_soc_dapm_update *update = NULL;
+ unsigned int rx_port_value;
+ u32 port_id = widget->shift;
+
+ pahu_p->rx_port_value[port_id] = ucontrol->value.enumerated.item[0];
+ rx_port_value = pahu_p->rx_port_value[port_id];
+
+ mutex_lock(&pahu_p->codec_mutex);
+ dev_dbg(codec->dev, "%s: wname %s cname %s value %u shift %d item %ld\n",
+ __func__, widget->name, ucontrol->id.name,
+ rx_port_value, widget->shift,
+ ucontrol->value.integer.value[0]);
+
+ /* value need to match the Virtual port and AIF number */
+ switch (rx_port_value) {
+ case 0:
+ list_del_init(&core->rx_chs[port_id].list);
+ break;
+ case 1:
+ if (wcd9xxx_rx_vport_validation(port_id +
+ WCD9360_RX_PORT_START_NUMBER,
+ &pahu_p->dai[AIF1_PB].wcd9xxx_ch_list)) {
+ dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
+ __func__, port_id);
+ goto rtn;
+ }
+ list_add_tail(&core->rx_chs[port_id].list,
+ &pahu_p->dai[AIF1_PB].wcd9xxx_ch_list);
+ break;
+ case 2:
+ if (wcd9xxx_rx_vport_validation(port_id +
+ WCD9360_RX_PORT_START_NUMBER,
+ &pahu_p->dai[AIF2_PB].wcd9xxx_ch_list)) {
+ dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
+ __func__, port_id);
+ goto rtn;
+ }
+ list_add_tail(&core->rx_chs[port_id].list,
+ &pahu_p->dai[AIF2_PB].wcd9xxx_ch_list);
+ break;
+ case 3:
+ if (wcd9xxx_rx_vport_validation(port_id +
+ WCD9360_RX_PORT_START_NUMBER,
+ &pahu_p->dai[AIF3_PB].wcd9xxx_ch_list)) {
+ dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
+ __func__, port_id);
+ goto rtn;
+ }
+ list_add_tail(&core->rx_chs[port_id].list,
+ &pahu_p->dai[AIF3_PB].wcd9xxx_ch_list);
+ break;
+ case 4:
+ if (wcd9xxx_rx_vport_validation(port_id +
+ WCD9360_RX_PORT_START_NUMBER,
+ &pahu_p->dai[AIF4_PB].wcd9xxx_ch_list)) {
+ dev_dbg(codec->dev, "%s: RX%u is used by current requesting AIF_PB itself\n",
+ __func__, port_id);
+ goto rtn;
+ }
+ list_add_tail(&core->rx_chs[port_id].list,
+ &pahu_p->dai[AIF4_PB].wcd9xxx_ch_list);
+ break;
+ default:
+ dev_err(codec->dev, "Unknown AIF %d\n", rx_port_value);
+ goto err;
+ }
+rtn:
+ mutex_unlock(&pahu_p->codec_mutex);
+ snd_soc_dapm_mux_update_power(widget->dapm, kcontrol,
+ rx_port_value, e, update);
+
+ return 0;
+err:
+ mutex_unlock(&pahu_p->codec_mutex);
+ return -EINVAL;
+}
+
+static void pahu_codec_enable_slim_port_intr(
+ struct wcd9xxx_codec_dai_data *dai,
+ struct snd_soc_codec *codec)
+{
+ struct wcd9xxx_ch *ch;
+ int port_num = 0;
+ unsigned short reg = 0;
+ u8 val = 0;
+ struct pahu_priv *pahu_p;
+
+ if (!dai || !codec) {
+ pr_err("%s: Invalid params\n", __func__);
+ return;
+ }
+
+ pahu_p = snd_soc_codec_get_drvdata(codec);
+ list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
+ if (ch->port >= WCD9360_RX_PORT_START_NUMBER) {
+ port_num = ch->port - WCD9360_RX_PORT_START_NUMBER;
+ reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + (port_num / 8);
+ val = wcd9xxx_interface_reg_read(pahu_p->wcd9xxx,
+ reg);
+ if (!(val & BYTE_BIT_MASK(port_num))) {
+ val |= BYTE_BIT_MASK(port_num);
+ wcd9xxx_interface_reg_write(
+ pahu_p->wcd9xxx, reg, val);
+ val = wcd9xxx_interface_reg_read(
+ pahu_p->wcd9xxx, reg);
+ }
+ } else {
+ port_num = ch->port;
+ reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 + (port_num / 8);
+ val = wcd9xxx_interface_reg_read(pahu_p->wcd9xxx,
+ reg);
+ if (!(val & BYTE_BIT_MASK(port_num))) {
+ val |= BYTE_BIT_MASK(port_num);
+ wcd9xxx_interface_reg_write(pahu_p->wcd9xxx,
+ reg, val);
+ val = wcd9xxx_interface_reg_read(
+ pahu_p->wcd9xxx, reg);
+ }
+ }
+ }
+}
+
+static int pahu_codec_enable_slim_chmask(struct wcd9xxx_codec_dai_data *dai,
+ bool up)
+{
+ int ret = 0;
+ struct wcd9xxx_ch *ch;
+
+ if (up) {
+ list_for_each_entry(ch, &dai->wcd9xxx_ch_list, list) {
+ ret = wcd9xxx_get_slave_port(ch->ch_num);
+ if (ret < 0) {
+ pr_err("%s: Invalid slave port ID: %d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ } else {
+ set_bit(ret, &dai->ch_mask);
+ }
+ }
+ } else {
+ ret = wait_event_timeout(dai->dai_wait, (dai->ch_mask == 0),
+ msecs_to_jiffies(
+ WCD9360_SLIM_CLOSE_TIMEOUT));
+ if (!ret) {
+ pr_err("%s: Slim close tx/rx wait timeout, ch_mask:0x%lx\n",
+ __func__, dai->ch_mask);
+ ret = -ETIMEDOUT;
+ } else {
+ ret = 0;
+ }
+ }
+ return ret;
+}
+
+static int pahu_codec_enable_slimrx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct wcd9xxx *core;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+ struct wcd9xxx_codec_dai_data *dai;
+
+ core = dev_get_drvdata(codec->dev->parent);
+
+ dev_dbg(codec->dev, "%s: event called! codec name %s num_dai %d\n"
+ "stream name %s event %d\n",
+ __func__, codec->component.name,
+ codec->component.num_dai, w->sname, event);
+
+ dai = &pahu_p->dai[w->shift];
+ dev_dbg(codec->dev, "%s: w->name %s w->shift %d event %d\n",
+ __func__, w->name, w->shift, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ dai->bus_down_in_recovery = false;
+ pahu_codec_enable_slim_port_intr(dai, codec);
+ (void) pahu_codec_enable_slim_chmask(dai, true);
+ ret = wcd9xxx_cfg_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
+ dai->rate, dai->bit_width,
+ &dai->grph);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = wcd9xxx_disconnect_port(core, &dai->wcd9xxx_ch_list,
+ dai->grph);
+ dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n",
+ __func__, ret);
+
+ if (!dai->bus_down_in_recovery)
+ ret = pahu_codec_enable_slim_chmask(dai, false);
+ else
+ dev_dbg(codec->dev,
+ "%s: bus in recovery skip enable slim_chmask",
+ __func__);
+ ret = wcd9xxx_close_slim_sch_rx(core, &dai->wcd9xxx_ch_list,
+ dai->grph);
+ break;
+ }
+ return ret;
+}
+
+static int pahu_codec_enable_slimtx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu_p = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_codec_dai_data *dai;
+ struct wcd9xxx *core;
+ int ret = 0;
+
+ dev_dbg(codec->dev,
+ "%s: w->name %s, w->shift = %d, num_dai %d stream name %s\n",
+ __func__, w->name, w->shift,
+ codec->component.num_dai, w->sname);
+
+ dai = &pahu_p->dai[w->shift];
+ core = dev_get_drvdata(codec->dev->parent);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ dai->bus_down_in_recovery = false;
+ pahu_codec_enable_slim_port_intr(dai, codec);
+ (void) pahu_codec_enable_slim_chmask(dai, true);
+ ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
+ dai->rate, dai->bit_width,
+ &dai->grph);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
+ dai->grph);
+ if (!dai->bus_down_in_recovery)
+ ret = pahu_codec_enable_slim_chmask(dai, false);
+ if (ret < 0) {
+ ret = wcd9xxx_disconnect_port(core,
+ &dai->wcd9xxx_ch_list,
+ dai->grph);
+ dev_dbg(codec->dev, "%s: Disconnect RX port, ret = %d\n",
+ __func__, ret);
+ }
+ break;
+ }
+ return ret;
+}
+
+static int pahu_codec_enable_slimvi_feedback(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct wcd9xxx *core = NULL;
+ struct snd_soc_codec *codec = NULL;
+ struct pahu_priv *pahu_p = NULL;
+ int ret = 0;
+ struct wcd9xxx_codec_dai_data *dai = NULL;
+
+ codec = snd_soc_dapm_to_codec(w->dapm);
+ pahu_p = snd_soc_codec_get_drvdata(codec);
+ core = dev_get_drvdata(codec->dev->parent);
+
+ dev_dbg(codec->dev,
+ "%s: num_dai %d stream name %s w->name %s event %d shift %d\n",
+ __func__, codec->component.num_dai, w->sname,
+ w->name, event, w->shift);
+
+ if (w->shift != AIF4_VIFEED) {
+ pr_err("%s Error in enabling the tx path\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+ dai = &pahu_p->dai[w->shift];
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ if (test_bit(VI_SENSE_1, &pahu_p->status_mask)) {
+ dev_dbg(codec->dev, "%s: spkr1 enabled\n", __func__);
+ /* Enable V&I sensing */
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
+ 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x0F, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x0F,
+ 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x10);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
+ 0x10);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
+ 0x00);
+ }
+ if (test_bit(VI_SENSE_2, &pahu_p->status_mask)) {
+ pr_debug("%s: spkr2 enabled\n", __func__);
+ /* Enable V&I sensing */
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
+ 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
+ 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x0F,
+ 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x0F,
+ 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
+ 0x10);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
+ 0x10);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
+ 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
+ 0x00);
+ }
+ dai->bus_down_in_recovery = false;
+ pahu_codec_enable_slim_port_intr(dai, codec);
+ (void) pahu_codec_enable_slim_chmask(dai, true);
+ ret = wcd9xxx_cfg_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
+ dai->rate, dai->bit_width,
+ &dai->grph);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = wcd9xxx_close_slim_sch_tx(core, &dai->wcd9xxx_ch_list,
+ dai->grph);
+ if (ret)
+ dev_err(codec->dev, "%s error in close_slim_sch_tx %d\n",
+ __func__, ret);
+ if (!dai->bus_down_in_recovery)
+ ret = pahu_codec_enable_slim_chmask(dai, false);
+ if (ret < 0) {
+ ret = wcd9xxx_disconnect_port(core,
+ &dai->wcd9xxx_ch_list,
+ dai->grph);
+ dev_dbg(codec->dev, "%s: Disconnect TX port, ret = %d\n",
+ __func__, ret);
+ }
+ if (test_bit(VI_SENSE_1, &pahu_p->status_mask)) {
+ /* Disable V&I sensing */
+ dev_dbg(codec->dev, "%s: spkr1 disabled\n", __func__);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x20, 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x20,
+ 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL, 0x10, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL, 0x10,
+ 0x00);
+ }
+ if (test_bit(VI_SENSE_2, &pahu_p->status_mask)) {
+ /* Disable V&I sensing */
+ dev_dbg(codec->dev, "%s: spkr2 disabled\n", __func__);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x20,
+ 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x20,
+ 0x20);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL, 0x10,
+ 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL, 0x10,
+ 0x00);
+ }
+ break;
+ }
+done:
+ return ret;
+}
+
+static void pahu_codec_enable_i2s(struct snd_soc_codec *codec, bool enable)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ if (enable) {
+ if (++pahu->i2s_ref_cnt == 1)
+ snd_soc_update_bits(codec, WCD9360_DATA_HUB_I2S_1_CTL,
+ 0x01, 0x01);
+ } else {
+ if (--pahu->i2s_ref_cnt == 0)
+ snd_soc_update_bits(codec, WCD9360_DATA_HUB_I2S_1_CTL,
+ 0x01, 0x00);
+ }
+}
+
+static int pahu_i2s_aif_rx_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+ switch(event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu_cdc_mclk_enable(codec, true);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ pahu_codec_enable_i2s(codec, true);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ pahu_codec_enable_i2s(codec, false);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pahu_cdc_mclk_enable(codec, false);
+ break;
+ }
+
+ return 0;
+}
+
+static int pahu_i2s_aif_tx_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+ switch(event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu_cdc_mclk_enable(codec, true);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ pahu_codec_enable_i2s(codec, true);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ pahu_codec_enable_i2s(codec, false);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pahu_cdc_mclk_enable(codec, false);
+ break;
+ }
+
+ return 0;
+}
+
+static int pahu_codec_enable_ldo_rxtx(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu->ldo_rxtx_cnt++;
+ if (pahu->ldo_rxtx_cnt == 1) {
+ /* Enable VDD_LDO_RxTx regulator */
+ msm_cdc_enable_ondemand_supply(pahu->wcd9xxx->dev,
+ pahu->wcd9xxx->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ WCD9360_LDO_RXTX_SUPPLY_NAME);
+
+ snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX,
+ 0x80, 0x80);
+ /*
+ * 200us sleep is required after LDO_RXTX is enabled as per
+ * HW requirement
+ */
+ usleep_range(200, 250);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pahu->ldo_rxtx_cnt--;
+ if (pahu->ldo_rxtx_cnt < 0)
+ pahu->ldo_rxtx_cnt = 0;
+
+ if (!pahu->ldo_rxtx_cnt) {
+ snd_soc_update_bits(codec, WCD9360_LDORXTX_LDORXTX,
+ 0x80, 0x00);
+ /* Disable VDD_LDO_RxTx regulator */
+ msm_cdc_disable_ondemand_supply(pahu->wcd9xxx->dev,
+ pahu->wcd9xxx->supplies,
+ pdata->regulator,
+ pdata->num_supplies,
+ WCD9360_LDO_RXTX_SUPPLY_NAME);
+ }
+ break;
+ };
+ dev_dbg(codec->dev, "%s: Current LDO RXTX user count: %d\n", __func__,
+ pahu->ldo_rxtx_cnt);
+
+ return 0;
+}
+
+static void pahu_spk_anc_update_callback(struct work_struct *work)
+{
+ struct spk_anc_work *spk_anc_dwork;
+ struct pahu_priv *pahu;
+ struct delayed_work *delayed_work;
+ struct snd_soc_codec *codec;
+
+ delayed_work = to_delayed_work(work);
+ spk_anc_dwork = container_of(delayed_work, struct spk_anc_work, dwork);
+ pahu = spk_anc_dwork->pahu;
+ codec = pahu->codec;
+
+ snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_CFG0, 0x10, 0x10);
+}
+
+static int pahu_codec_enable_spkr_anc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ if (!pahu->anc_func)
+ return 0;
+
+ dev_dbg(codec->dev, "%s: w: %s event: %d anc: %d\n", __func__,
+ w->name, event, pahu->anc_func);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ ret = pahu_codec_enable_anc(w, kcontrol, event);
+ schedule_delayed_work(&pahu->spk_anc_dwork.dwork,
+ msecs_to_jiffies(spk_anc_en_delay));
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ cancel_delayed_work_sync(&pahu->spk_anc_dwork.dwork);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_CFG0,
+ 0x10, 0x00);
+ ret = pahu_codec_enable_anc(w, kcontrol, event);
+ break;
+ }
+ return ret;
+}
+
+static int pahu_codec_enable_aux_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ /*
+ * 5ms sleep is required after PA is enabled as per
+ * HW requirement
+ */
+ usleep_range(5000, 5500);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX9_RX_PATH_CTL,
+ 0x10, 0x00);
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec, WCD9360_CDC_RX9_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX9_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ break;
+ default:
+ break;
+ };
+
+ return ret;
+}
+
+static int pahu_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ /*
+ * 5ms sleep is required after PA is enabled as per
+ * HW requirement
+ */
+ usleep_range(5000, 5500);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CTL,
+ 0x10, 0x00);
+ /* Remove mix path mute if it is enabled */
+ if ((snd_soc_read(codec, WCD9360_CDC_RX0_RX_PATH_MIX_CTL)) &
+ 0x10)
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX0_RX_PATH_MIX_CTL,
+ 0x10, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /*
+ * 5ms sleep is required after PA is disabled as per
+ * HW requirement
+ */
+ usleep_range(5000, 5500);
+
+ if (!(strcmp(w->name, "ANC EAR PA"))) {
+ ret = pahu_codec_enable_anc(w, kcontrol, event);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CFG0,
+ 0x10, 0x00);
+ }
+ break;
+ };
+
+ return ret;
+}
+
+static int pahu_codec_ear_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (pahu->anc_func) {
+ ret = pahu_codec_enable_anc(w, kcontrol, event);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX0_RX_PATH_CFG0,
+ 0x10, 0x10);
+ }
+ break;
+ default:
+ break;
+ };
+
+ return ret;
+}
+
+static int pahu_codec_spk_boost_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ u16 boost_path_ctl, boost_path_cfg1;
+ u16 reg, reg_mix;
+
+ dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
+
+ if (!strcmp(w->name, "RX INT7 CHAIN")) {
+ boost_path_ctl = WCD9360_CDC_BOOST0_BOOST_PATH_CTL;
+ boost_path_cfg1 = WCD9360_CDC_RX7_RX_PATH_CFG1;
+ reg = WCD9360_CDC_RX7_RX_PATH_CTL;
+ reg_mix = WCD9360_CDC_RX7_RX_PATH_MIX_CTL;
+ } else if (!strcmp(w->name, "RX INT8 CHAIN")) {
+ boost_path_ctl = WCD9360_CDC_BOOST1_BOOST_PATH_CTL;
+ boost_path_cfg1 = WCD9360_CDC_RX8_RX_PATH_CFG1;
+ reg = WCD9360_CDC_RX8_RX_PATH_CTL;
+ reg_mix = WCD9360_CDC_RX8_RX_PATH_MIX_CTL;
+ } else {
+ dev_err(codec->dev, "%s: unknown widget: %s\n",
+ __func__, w->name);
+ return -EINVAL;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x01);
+ snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x10);
+ snd_soc_update_bits(codec, reg, 0x10, 0x00);
+ if ((snd_soc_read(codec, reg_mix)) & 0x10)
+ snd_soc_update_bits(codec, reg_mix, 0x10, 0x00);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, boost_path_ctl, 0x10, 0x00);
+ snd_soc_update_bits(codec, boost_path_cfg1, 0x01, 0x00);
+ break;
+ };
+
+ return 0;
+}
+
+static int __pahu_codec_enable_swr(struct snd_soc_dapm_widget *w, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu;
+ int ch_cnt = 0;
+
+ pahu = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) ||
+ (strnstr(w->name, "INT7 MIX2",
+ sizeof("RX INT7 MIX2")))))
+ pahu->swr.rx_7_count++;
+ if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
+ !pahu->swr.rx_8_count)
+ pahu->swr.rx_8_count++;
+ ch_cnt = !!(pahu->swr.rx_7_count) + pahu->swr.rx_8_count;
+
+ swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev,
+ SWR_DEVICE_UP, NULL);
+ swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev,
+ SWR_SET_NUM_RX_CH, &ch_cnt);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ if ((strnstr(w->name, "INT7_", sizeof("RX INT7_"))) ||
+ (strnstr(w->name, "INT7 MIX2",
+ sizeof("RX INT7 MIX2"))))
+ pahu->swr.rx_7_count--;
+ if ((strnstr(w->name, "INT8_", sizeof("RX INT8_"))) &&
+ pahu->swr.rx_8_count)
+ pahu->swr.rx_8_count--;
+ ch_cnt = !!(pahu->swr.rx_7_count) + pahu->swr.rx_8_count;
+
+ swrm_wcd_notify(pahu->swr.ctrl_data[0].swr_pdev,
+ SWR_SET_NUM_RX_CH, &ch_cnt);
+
+ break;
+ }
+ dev_dbg(pahu->dev, "%s: %s: current swr ch cnt: %d\n",
+ __func__, w->name, ch_cnt);
+
+ return 0;
+}
+
+static int pahu_codec_enable_swr(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ return __pahu_codec_enable_swr(w, event);
+}
+
+static int pahu_codec_config_mad(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ int idx;
+ const struct firmware *fw;
+ struct firmware_cal *hwdep_cal = NULL;
+ struct wcd_mad_audio_cal *mad_cal = NULL;
+ const void *data;
+ const char *filename = WCD9360_MAD_AUDIO_FIRMWARE_PATH;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ size_t cal_size;
+
+ hwdep_cal = wcdcal_get_fw_cal(pahu->fw_data, WCD9XXX_MAD_CAL);
+ if (hwdep_cal) {
+ data = hwdep_cal->data;
+ cal_size = hwdep_cal->size;
+ dev_dbg(codec->dev, "%s: using hwdep calibration\n",
+ __func__);
+ } else {
+ ret = request_firmware(&fw, filename, codec->dev);
+ if (ret || !fw) {
+ dev_err(codec->dev,
+ "%s: MAD firmware acquire failed, err = %d\n",
+ __func__, ret);
+ return -ENODEV;
+ }
+ data = fw->data;
+ cal_size = fw->size;
+ dev_dbg(codec->dev, "%s: using request_firmware calibration\n",
+ __func__);
+ }
+
+ if (cal_size < sizeof(*mad_cal)) {
+ dev_err(codec->dev,
+ "%s: Incorrect size %zd for MAD Cal, expected %zd\n",
+ __func__, cal_size, sizeof(*mad_cal));
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ mad_cal = (struct wcd_mad_audio_cal *) (data);
+ if (!mad_cal) {
+ dev_err(codec->dev,
+ "%s: Invalid calibration data\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ snd_soc_write(codec, WCD9360_SOC_MAD_MAIN_CTL_2,
+ mad_cal->microphone_info.cycle_time);
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_MAIN_CTL_1, 0xFF << 3,
+ ((uint16_t)mad_cal->microphone_info.settle_time)
+ << 3);
+
+ /* Audio */
+ snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_8,
+ mad_cal->audio_info.rms_omit_samples);
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_1,
+ 0x07 << 4, mad_cal->audio_info.rms_comp_time << 4);
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2, 0x03 << 2,
+ mad_cal->audio_info.detection_mechanism << 2);
+ snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_7,
+ mad_cal->audio_info.rms_diff_threshold & 0x3F);
+ snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_5,
+ mad_cal->audio_info.rms_threshold_lsb);
+ snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_CTL_6,
+ mad_cal->audio_info.rms_threshold_msb);
+
+ for (idx = 0; idx < ARRAY_SIZE(mad_cal->audio_info.iir_coefficients);
+ idx++) {
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR,
+ 0x3F, idx);
+ snd_soc_write(codec, WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL,
+ mad_cal->audio_info.iir_coefficients[idx]);
+ dev_dbg(codec->dev, "%s:MAD Audio IIR Coef[%d] = 0X%x",
+ __func__, idx,
+ mad_cal->audio_info.iir_coefficients[idx]);
+ }
+
+ /* Beacon */
+ snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_8,
+ mad_cal->beacon_info.rms_omit_samples);
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_CTL_1,
+ 0x07 << 4, mad_cal->beacon_info.rms_comp_time << 4);
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_CTL_2, 0x03 << 2,
+ mad_cal->beacon_info.detection_mechanism << 2);
+ snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_7,
+ mad_cal->beacon_info.rms_diff_threshold & 0x1F);
+ snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_5,
+ mad_cal->beacon_info.rms_threshold_lsb);
+ snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_CTL_6,
+ mad_cal->beacon_info.rms_threshold_msb);
+
+ for (idx = 0; idx < ARRAY_SIZE(mad_cal->beacon_info.iir_coefficients);
+ idx++) {
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR,
+ 0x3F, idx);
+ snd_soc_write(codec, WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL,
+ mad_cal->beacon_info.iir_coefficients[idx]);
+ dev_dbg(codec->dev, "%s:MAD Beacon IIR Coef[%d] = 0X%x",
+ __func__, idx,
+ mad_cal->beacon_info.iir_coefficients[idx]);
+ }
+
+ /* Ultrasound */
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_ULTR_CTL_1,
+ 0x07 << 4,
+ mad_cal->ultrasound_info.rms_comp_time << 4);
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_ULTR_CTL_2, 0x03 << 2,
+ mad_cal->ultrasound_info.detection_mechanism << 2);
+ snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_7,
+ mad_cal->ultrasound_info.rms_diff_threshold & 0x1F);
+ snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_5,
+ mad_cal->ultrasound_info.rms_threshold_lsb);
+ snd_soc_write(codec, WCD9360_SOC_MAD_ULTR_CTL_6,
+ mad_cal->ultrasound_info.rms_threshold_msb);
+
+done:
+ if (!hwdep_cal)
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int __pahu_codec_enable_mad(struct snd_soc_codec *codec, bool enable)
+{
+ int rc = 0;
+
+ /* Return if CPE INPUT is DEC1 */
+ if (snd_soc_read(codec, WCD9360_CPE_SS_SVA_CFG) & 0x04) {
+ dev_dbg(codec->dev, "%s: MAD is bypassed, skip mad %s\n",
+ __func__, enable ? "enable" : "disable");
+ return rc;
+ }
+
+ dev_dbg(codec->dev, "%s: enable = %s\n", __func__,
+ enable ? "enable" : "disable");
+
+ if (enable) {
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2,
+ 0x03, 0x03);
+ rc = pahu_codec_config_mad(codec);
+ if (rc < 0) {
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2,
+ 0x03, 0x00);
+ goto done;
+ }
+
+ /* Turn on MAD clk */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL,
+ 0x01, 0x01);
+
+ /* Undo reset for MAD */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_MCLK_CFG,
+ 0x04, 0x04);
+ } else {
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_AUDIO_CTL_2,
+ 0x03, 0x00);
+ /* Reset the MAD block */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL,
+ 0x02, 0x02);
+ /* Turn off MAD clk */
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_MAD_CTL,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_MCLK_CFG,
+ 0x04, 0x00);
+ }
+done:
+ return rc;
+}
+
+static int pahu_codec_ape_enable_mad(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int rc = 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x40, 0x40);
+ rc = __pahu_codec_enable_mad(codec, true);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x40, 0x00);
+ __pahu_codec_enable_mad(codec, false);
+ break;
+ }
+
+ dev_dbg(pahu->dev, "%s: event = %d\n", __func__, event);
+ return rc;
+}
+
+static int pahu_codec_cpe_mad_ctl(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int rc = 0;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu->mad_switch_cnt++;
+ if (pahu->mad_switch_cnt != 1)
+ goto done;
+
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x20, 0x20);
+ rc = __pahu_codec_enable_mad(codec, true);
+ if (rc < 0) {
+ pahu->mad_switch_cnt--;
+ goto done;
+ }
+
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ pahu->mad_switch_cnt--;
+ if (pahu->mad_switch_cnt != 0)
+ goto done;
+
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_SVA_CFG, 0x20, 0x00);
+ __pahu_codec_enable_mad(codec, false);
+ break;
+ }
+done:
+ dev_dbg(pahu->dev, "%s: event = %d, mad_switch_cnt = %d\n",
+ __func__, event, pahu->mad_switch_cnt);
+ return rc;
+}
+
+static int pahu_get_asrc_mode(struct pahu_priv *pahu, int asrc,
+ u8 main_sr, u8 mix_sr)
+{
+ u8 asrc_output_mode;
+ int asrc_mode = CONV_88P2K_TO_384K;
+
+ if ((asrc < 0) || (asrc >= ASRC_MAX))
+ return 0;
+
+ asrc_output_mode = pahu->asrc_output_mode[asrc];
+
+ if (asrc_output_mode) {
+ /*
+ * If Mix sample rate is < 96KHz, use 96K to 352.8K
+ * conversion, or else use 384K to 352.8K conversion
+ */
+ if (mix_sr < 5)
+ asrc_mode = CONV_96K_TO_352P8K;
+ else
+ asrc_mode = CONV_384K_TO_352P8K;
+ } else {
+ /* Integer main and Fractional mix path */
+ if (main_sr < 8 && mix_sr > 9) {
+ asrc_mode = CONV_352P8K_TO_384K;
+ } else if (main_sr > 8 && mix_sr < 8) {
+ /* Fractional main and Integer mix path */
+ if (mix_sr < 5)
+ asrc_mode = CONV_96K_TO_352P8K;
+ else
+ asrc_mode = CONV_384K_TO_352P8K;
+ } else if (main_sr < 8 && mix_sr < 8) {
+ /* Integer main and Integer mix path */
+ asrc_mode = CONV_96K_TO_384K;
+ }
+ }
+
+ return asrc_mode;
+}
+
+static int pahu_codec_wdma3_ctl(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /* Fix to 16KHz */
+ snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3,
+ 0xF0, 0x10);
+ /* Select mclk_1 */
+ snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3,
+ 0x02, 0x00);
+ /* Enable DMA */
+ snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3,
+ 0x01, 0x01);
+ break;
+
+ case SND_SOC_DAPM_POST_PMD:
+ /* Disable DMA */
+ snd_soc_update_bits(codec, WCD9360_DMA_WDMA_CTL_3,
+ 0x01, 0x00);
+ break;
+
+ };
+
+ return 0;
+}
+static int pahu_codec_enable_asrc(struct snd_soc_codec *codec,
+ int asrc_in, int event)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ u16 cfg_reg, ctl_reg, clk_reg, asrc_ctl, mix_ctl_reg, paired_reg;
+ int asrc, ret = 0;
+ u8 main_sr, mix_sr, asrc_mode = 0;
+
+ switch (asrc_in) {
+ case ASRC_IN_SPKR1:
+ cfg_reg = WCD9360_CDC_RX7_RX_PATH_CFG0;
+ ctl_reg = WCD9360_CDC_RX7_RX_PATH_CTL;
+ clk_reg = WCD9360_MIXING_ASRC2_CLK_RST_CTL;
+ paired_reg = WCD9360_MIXING_ASRC2_CLK_RST_CTL;
+ asrc_ctl = WCD9360_MIXING_ASRC2_CTL1;
+ asrc = ASRC2;
+ break;
+ case ASRC_IN_SPKR2:
+ cfg_reg = WCD9360_CDC_RX8_RX_PATH_CFG0;
+ ctl_reg = WCD9360_CDC_RX8_RX_PATH_CTL;
+ clk_reg = WCD9360_MIXING_ASRC3_CLK_RST_CTL;
+ paired_reg = WCD9360_MIXING_ASRC3_CLK_RST_CTL;
+ asrc_ctl = WCD9360_MIXING_ASRC3_CTL1;
+ asrc = ASRC3;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid asrc input :%d\n", __func__,
+ asrc_in);
+ ret = -EINVAL;
+ goto done;
+ };
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (pahu->asrc_users[asrc] == 0) {
+ if ((snd_soc_read(codec, clk_reg) & 0x02) ||
+ (snd_soc_read(codec, paired_reg) & 0x02)) {
+ snd_soc_update_bits(codec, clk_reg,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec, paired_reg,
+ 0x02, 0x00);
+ }
+ snd_soc_update_bits(codec, cfg_reg, 0x80, 0x80);
+ snd_soc_update_bits(codec, clk_reg, 0x01, 0x01);
+ main_sr = snd_soc_read(codec, ctl_reg) & 0x0F;
+ mix_ctl_reg = ctl_reg + 5;
+ mix_sr = snd_soc_read(codec, mix_ctl_reg) & 0x0F;
+ asrc_mode = pahu_get_asrc_mode(pahu, asrc,
+ main_sr, mix_sr);
+ dev_dbg(codec->dev, "%s: main_sr:%d mix_sr:%d asrc_mode %d\n",
+ __func__, main_sr, mix_sr, asrc_mode);
+ snd_soc_update_bits(codec, asrc_ctl, 0x07, asrc_mode);
+ }
+ pahu->asrc_users[asrc]++;
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pahu->asrc_users[asrc]--;
+ if (pahu->asrc_users[asrc] <= 0) {
+ pahu->asrc_users[asrc] = 0;
+ snd_soc_update_bits(codec, asrc_ctl, 0x07, 0x00);
+ snd_soc_update_bits(codec, cfg_reg, 0x80, 0x00);
+ snd_soc_update_bits(codec, clk_reg, 0x03, 0x02);
+ }
+ break;
+ };
+
+ dev_dbg(codec->dev, "%s: ASRC%d, users: %d\n",
+ __func__, asrc, pahu->asrc_users[asrc]);
+
+done:
+ return ret;
+}
+
+static int pahu_codec_enable_asrc_resampler(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int ret = 0;
+ u8 cfg, asrc_in;
+
+ cfg = snd_soc_read(codec, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0);
+ if (!(cfg & 0xFF)) {
+ dev_err(codec->dev, "%s: ASRC%u input not selected\n",
+ __func__, w->shift);
+ return -EINVAL;
+ }
+
+ switch (w->shift) {
+ case ASRC2:
+ asrc_in = ((cfg & 0x30) == 0x20) ? ASRC_IN_SPKR1 : ASRC_INVALID;
+ ret = pahu_codec_enable_asrc(codec, asrc_in, event);
+ break;
+ case ASRC3:
+ asrc_in = ((cfg & 0xC0) == 0x80) ? ASRC_IN_SPKR2 : ASRC_INVALID;
+ ret = pahu_codec_enable_asrc(codec, asrc_in, event);
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid asrc:%u\n", __func__,
+ w->shift);
+ ret = -EINVAL;
+ break;
+ };
+
+ return ret;
+}
+
+static int pahu_enable_native_supply(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (++pahu->native_clk_users == 1) {
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_PLL_ENABLES,
+ 0x01, 0x01);
+ usleep_range(100, 120);
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1,
+ 0x06, 0x02);
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE,
+ 0x04, 0x00);
+ /* Add sleep as per HW register sequence */
+ usleep_range(30, 50);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x02, 0x02);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x10, 0x10);
+ }
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ if (pahu->native_clk_users &&
+ (--pahu->native_clk_users == 0)) {
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
+ 0x10, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL,
+ 0x02, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CODEC_RPM_CLK_GATE,
+ 0x04, 0x04);
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_MCLK2_PRG1,
+ 0x06, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CLK_SYS_PLL_ENABLES,
+ 0x01, 0x00);
+ }
+ break;
+ }
+
+ dev_dbg(codec->dev, "%s: native_clk_users: %d, event: %d\n",
+ __func__, pahu->native_clk_users, event);
+
+ return 0;
+}
+
+static int pahu_codec_config_ear_spkr_gain(struct snd_soc_codec *codec,
+ int event, int gain_reg)
+{
+ int comp_gain_offset, val;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ switch (pahu->swr.spkr_mode) {
+ /* Compander gain in SPKR_MODE1 case is 12 dB */
+ case WCD9360_SPKR_MODE_1:
+ comp_gain_offset = -12;
+ break;
+ /* Default case compander gain is 15 dB */
+ default:
+ comp_gain_offset = -15;
+ break;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ /* Apply ear spkr gain only if compander is enabled */
+ if (pahu->comp_enabled[COMPANDER_7] &&
+ (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL ||
+ gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL) &&
+ (pahu->ear_spkr_gain != 0)) {
+ /* For example, val is -8(-12+5-1) for 4dB of gain */
+ val = comp_gain_offset + pahu->ear_spkr_gain - 1;
+ snd_soc_write(codec, gain_reg, val);
+
+ dev_dbg(codec->dev, "%s: RX7 Volume %d dB\n",
+ __func__, val);
+ }
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /*
+ * Reset RX7 volume to 0 dB if compander is enabled and
+ * ear_spkr_gain is non-zero.
+ */
+ if (pahu->comp_enabled[COMPANDER_7] &&
+ (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL ||
+ gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL) &&
+ (pahu->ear_spkr_gain != 0)) {
+ snd_soc_write(codec, gain_reg, 0x0);
+
+ dev_dbg(codec->dev, "%s: Reset RX7 Volume to 0 dB\n",
+ __func__);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int pahu_config_compander(struct snd_soc_codec *codec, int interp_n,
+ int event)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int comp;
+ u16 comp_ctl0_reg, rx_path_cfg0_reg;
+
+ /* HPH, LO are not valid and AUX does not have compander */
+ if (((interp_n >= INTERP_HPHL_NA) && (interp_n <= INTERP_LO4_NA)) ||
+ (interp_n == INTERP_AUX))
+ return 0;
+
+ comp = interp_n;
+ dev_dbg(codec->dev, "%s: event %d compander %d, enabled %d\n",
+ __func__, event, comp, pahu->comp_enabled[comp]);
+
+ if (!pahu->comp_enabled[comp])
+ return 0;
+
+ comp_ctl0_reg = WCD9360_CDC_COMPANDER0_CTL0 + (comp * 8);
+ rx_path_cfg0_reg = WCD9360_CDC_RX0_RX_PATH_CFG0 + (comp * 20);
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ /* Enable Compander Clock */
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x01);
+ /* Soft reset */
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
+ /* Compander enable */
+ snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x02);
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ snd_soc_update_bits(codec, rx_path_cfg0_reg, 0x02, 0x00);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x04);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x02);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x02, 0x00);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x01, 0x00);
+ snd_soc_update_bits(codec, comp_ctl0_reg, 0x04, 0x00);
+ }
+
+ return 0;
+}
+
+/**
+ * pahu_codec_enable_interp_clk - Enable main path Interpolator
+ * clock.
+ *
+ * @codec: Codec instance
+ * @event: Indicates speaker path gain offset value
+ * @intp_idx: Interpolator index
+ * Returns number of main clock users
+ */
+int pahu_codec_enable_interp_clk(struct snd_soc_codec *codec,
+ int event, int interp_idx)
+{
+ struct pahu_priv *pahu;
+ u16 main_reg;
+
+ if (!codec) {
+ pr_err("%s: codec is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ pahu = snd_soc_codec_get_drvdata(codec);
+
+ main_reg = WCD9360_CDC_RX0_RX_PATH_CTL +
+ (interp_idx * WCD9360_RX_PATH_CTL_OFFSET);
+
+ if (interp_idx == INTERP_AUX)
+ main_reg = WCD9360_CDC_RX9_RX_PATH_CTL;
+
+ if (SND_SOC_DAPM_EVENT_ON(event)) {
+ if (pahu->main_clk_users[interp_idx] == 0) {
+ /* Main path PGA mute enable */
+ snd_soc_update_bits(codec, main_reg, 0x10, 0x10);
+ /* Clk enable */
+ snd_soc_update_bits(codec, main_reg, 0x20, 0x20);
+ pahu_config_compander(codec, interp_idx, event);
+ }
+ pahu->main_clk_users[interp_idx]++;
+ }
+
+ if (SND_SOC_DAPM_EVENT_OFF(event)) {
+ pahu->main_clk_users[interp_idx]--;
+ if (pahu->main_clk_users[interp_idx] <= 0) {
+ pahu->main_clk_users[interp_idx] = 0;
+ pahu_config_compander(codec, interp_idx, event);
+ /* Clk Disable */
+ snd_soc_update_bits(codec, main_reg, 0x20, 0x00);
+ /* Reset enable and disable */
+ snd_soc_update_bits(codec, main_reg, 0x40, 0x40);
+ snd_soc_update_bits(codec, main_reg, 0x40, 0x00);
+ /* Reset rate to 48K*/
+ snd_soc_update_bits(codec, main_reg, 0x0F, 0x04);
+ }
+ }
+
+ dev_dbg(codec->dev, "%s event %d main_clk_users %d\n",
+ __func__, event, pahu->main_clk_users[interp_idx]);
+
+ return pahu->main_clk_users[interp_idx];
+}
+EXPORT_SYMBOL(pahu_codec_enable_interp_clk);
+
+static int pahu_codec_enable_mix_path(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ u16 gain_reg, mix_reg;
+ int offset_val = 0;
+ int val = 0;
+
+ if (w->shift >= WCD9360_NUM_INTERPOLATORS ||
+ ((w->shift >= INTERP_HPHL_NA) && (w->shift <= INTERP_LO4_NA))) {
+ dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n",
+ __func__, w->shift, w->name);
+ return -EINVAL;
+ };
+
+ gain_reg = WCD9360_CDC_RX0_RX_VOL_MIX_CTL +
+ (w->shift * WCD9360_RX_PATH_CTL_OFFSET);
+ mix_reg = WCD9360_CDC_RX0_RX_PATH_MIX_CTL +
+ (w->shift * WCD9360_RX_PATH_CTL_OFFSET);
+
+ if (w->shift == INTERP_AUX) {
+ gain_reg = WCD9360_CDC_RX9_RX_VOL_MIX_CTL;
+ mix_reg = WCD9360_CDC_RX9_RX_PATH_MIX_CTL;
+ }
+
+ if (w->shift == INTERP_SPKR1 || w->shift == INTERP_SPKR2)
+ __pahu_codec_enable_swr(w, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu_codec_enable_interp_clk(codec, event, w->shift);
+ /* Clk enable */
+ snd_soc_update_bits(codec, mix_reg, 0x20, 0x20);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ if ((pahu->swr.spkr_gain_offset ==
+ WCD9360_RX_GAIN_OFFSET_M1P5_DB) &&
+ (pahu->comp_enabled[COMPANDER_7] ||
+ pahu->comp_enabled[COMPANDER_8]) &&
+ (gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL ||
+ gain_reg == WCD9360_CDC_RX8_RX_VOL_MIX_CTL)) {
+ snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX7_RX_PATH_MIX_SEC0,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX8_RX_PATH_MIX_SEC0,
+ 0x01, 0x01);
+ offset_val = -2;
+ }
+ val = snd_soc_read(codec, gain_reg);
+ val += offset_val;
+ snd_soc_write(codec, gain_reg, val);
+ pahu_codec_config_ear_spkr_gain(codec, event, gain_reg);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* Clk Disable */
+ snd_soc_update_bits(codec, mix_reg, 0x20, 0x00);
+ pahu_codec_enable_interp_clk(codec, event, w->shift);
+ /* Reset enable and disable */
+ snd_soc_update_bits(codec, mix_reg, 0x40, 0x40);
+ snd_soc_update_bits(codec, mix_reg, 0x40, 0x00);
+
+ if ((pahu->swr.spkr_gain_offset ==
+ WCD9360_RX_GAIN_OFFSET_M1P5_DB) &&
+ (pahu->comp_enabled[COMPANDER_7] ||
+ pahu->comp_enabled[COMPANDER_8]) &&
+ (gain_reg == WCD9360_CDC_RX7_RX_VOL_MIX_CTL ||
+ gain_reg == WCD9360_CDC_RX8_RX_VOL_MIX_CTL)) {
+ snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX7_RX_PATH_MIX_SEC0,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX8_RX_PATH_MIX_SEC0,
+ 0x01, 0x00);
+ offset_val = 2;
+ val = snd_soc_read(codec, gain_reg);
+ val += offset_val;
+ snd_soc_write(codec, gain_reg, val);
+ }
+ pahu_codec_config_ear_spkr_gain(codec, event, gain_reg);
+ break;
+ };
+ dev_dbg(codec->dev, "%s event %d name %s\n", __func__, event, w->name);
+
+ return 0;
+}
+
+static int pahu_codec_enable_main_path(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ u16 gain_reg;
+ u16 reg;
+ int val;
+ int offset_val = 0;
+
+ dev_dbg(codec->dev, "%s %d %s\n", __func__, event, w->name);
+
+ if (w->shift >= WCD9360_NUM_INTERPOLATORS ||
+ ((w->shift >= INTERP_HPHL_NA) && (w->shift <= INTERP_LO4_NA))) {
+ dev_err(codec->dev, "%s: Invalid Interpolator value %d for name %s\n",
+ __func__, w->shift, w->name);
+ return -EINVAL;
+ };
+
+ reg = WCD9360_CDC_RX0_RX_PATH_CTL + (w->shift *
+ WCD9360_RX_PATH_CTL_OFFSET);
+ gain_reg = WCD9360_CDC_RX0_RX_VOL_CTL + (w->shift *
+ WCD9360_RX_PATH_CTL_OFFSET);
+
+ if (w->shift == INTERP_AUX) {
+ reg = WCD9360_CDC_RX9_RX_PATH_CTL;
+ gain_reg = WCD9360_CDC_RX9_RX_VOL_CTL;
+ }
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu_codec_enable_interp_clk(codec, event, w->shift);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* apply gain after int clk is enabled */
+ if ((pahu->swr.spkr_gain_offset ==
+ WCD9360_RX_GAIN_OFFSET_M1P5_DB) &&
+ (pahu->comp_enabled[COMPANDER_7] ||
+ pahu->comp_enabled[COMPANDER_8]) &&
+ (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL ||
+ gain_reg == WCD9360_CDC_RX8_RX_VOL_CTL)) {
+ snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX7_RX_PATH_MIX_SEC0,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1,
+ 0x01, 0x01);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX8_RX_PATH_MIX_SEC0,
+ 0x01, 0x01);
+ offset_val = -2;
+ }
+ val = snd_soc_read(codec, gain_reg);
+ val += offset_val;
+ snd_soc_write(codec, gain_reg, val);
+ pahu_codec_config_ear_spkr_gain(codec, event, gain_reg);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pahu_codec_enable_interp_clk(codec, event, w->shift);
+
+ if ((pahu->swr.spkr_gain_offset ==
+ WCD9360_RX_GAIN_OFFSET_M1P5_DB) &&
+ (pahu->comp_enabled[COMPANDER_7] ||
+ pahu->comp_enabled[COMPANDER_8]) &&
+ (gain_reg == WCD9360_CDC_RX7_RX_VOL_CTL ||
+ gain_reg == WCD9360_CDC_RX8_RX_VOL_CTL)) {
+ snd_soc_update_bits(codec, WCD9360_CDC_RX7_RX_PATH_SEC1,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX7_RX_PATH_MIX_SEC0,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec, WCD9360_CDC_RX8_RX_PATH_SEC1,
+ 0x01, 0x00);
+ snd_soc_update_bits(codec,
+ WCD9360_CDC_RX8_RX_PATH_MIX_SEC0,
+ 0x01, 0x00);
+ offset_val = 2;
+ val = snd_soc_read(codec, gain_reg);
+ val += offset_val;
+ snd_soc_write(codec, gain_reg, val);
+ }
+ pahu_codec_config_ear_spkr_gain(codec, event, gain_reg);
+ break;
+ };
+
+ return 0;
+}
+
+static int pahu_codec_set_iir_gain(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU: /* fall through */
+ case SND_SOC_DAPM_PRE_PMD:
+ if (strnstr(w->name, "IIR0", sizeof("IIR0"))) {
+ snd_soc_write(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL,
+ snd_soc_read(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL));
+ snd_soc_write(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL,
+ snd_soc_read(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL));
+ snd_soc_write(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL,
+ snd_soc_read(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL));
+ snd_soc_write(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL,
+ snd_soc_read(codec,
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL));
+ }
+ break;
+ }
+ return 0;
+}
+
+static int pahu_codec_find_amic_input(struct snd_soc_codec *codec,
+ int adc_mux_n)
+{
+ u16 mask, shift, adc_mux_in_reg;
+ u16 amic_mux_sel_reg;
+ bool is_amic;
+
+ if (adc_mux_n < 0 || adc_mux_n > WCD9360_MAX_VALID_ADC_MUX ||
+ adc_mux_n == WCD9360_INVALID_ADC_MUX)
+ return 0;
+
+ if (adc_mux_n < 3) {
+ adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+ 2 * adc_mux_n;
+ mask = 0x03;
+ shift = 0;
+ amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+ 2 * adc_mux_n;
+ } else if (adc_mux_n < 4) {
+ adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1;
+ mask = 0x03;
+ shift = 0;
+ amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+ 2 * adc_mux_n;
+ } else if (adc_mux_n < 7) {
+ adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+ 2 * (adc_mux_n - 4);
+ mask = 0x0C;
+ shift = 2;
+ amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
+ adc_mux_n - 4;
+ } else if (adc_mux_n < 8) {
+ adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1;
+ mask = 0x0C;
+ shift = 2;
+ amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
+ adc_mux_n - 4;
+ } else if (adc_mux_n < 12) {
+ adc_mux_in_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+ 2 * (((adc_mux_n == 8) ? (adc_mux_n - 8) :
+ (adc_mux_n - 9)));
+ mask = 0x30;
+ shift = 4;
+ amic_mux_sel_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0 +
+ ((adc_mux_n == 8) ? (adc_mux_n - 8) :
+ (adc_mux_n - 9));
+ }
+
+ is_amic = (((snd_soc_read(codec, adc_mux_in_reg) & mask) >> shift)
+ == 1);
+ if (!is_amic)
+ return 0;
+
+ return snd_soc_read(codec, amic_mux_sel_reg) & 0x07;
+}
+
+static void pahu_codec_set_tx_hold(struct snd_soc_codec *codec,
+ u16 amic_reg, bool set)
+{
+ u8 mask = 0x20;
+ u8 val;
+
+ if (amic_reg == WCD9360_ANA_AMIC1 ||
+ amic_reg == WCD9360_ANA_AMIC3)
+ mask = 0x40;
+
+ val = set ? mask : 0x00;
+
+ switch (amic_reg) {
+ case WCD9360_ANA_AMIC1:
+ case WCD9360_ANA_AMIC2:
+ snd_soc_update_bits(codec, WCD9360_ANA_AMIC2, mask, val);
+ break;
+ case WCD9360_ANA_AMIC3:
+ case WCD9360_ANA_AMIC4:
+ snd_soc_update_bits(codec, WCD9360_ANA_AMIC4, mask, val);
+ break;
+ default:
+ dev_dbg(codec->dev, "%s: invalid amic: %d\n",
+ __func__, amic_reg);
+ break;
+ }
+}
+
+static int pahu_codec_tx_adc_cfg(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ int adc_mux_n = w->shift;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int amic_n;
+
+ dev_dbg(codec->dev, "%s: event: %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ amic_n = pahu_codec_find_amic_input(codec, adc_mux_n);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static u16 pahu_codec_get_amic_pwlvl_reg(struct snd_soc_codec *codec, int amic)
+{
+ u16 pwr_level_reg = 0;
+
+ switch (amic) {
+ case 1:
+ case 2:
+ pwr_level_reg = WCD9360_ANA_AMIC1;
+ break;
+
+ case 3:
+ case 4:
+ pwr_level_reg = WCD9360_ANA_AMIC3;
+ break;
+ default:
+ dev_dbg(codec->dev, "%s: invalid amic: %d\n",
+ __func__, amic);
+ break;
+ }
+
+ return pwr_level_reg;
+}
+
+#define TX_HPF_CUT_OFF_FREQ_MASK 0x60
+#define CF_MIN_3DB_4HZ 0x0
+#define CF_MIN_3DB_75HZ 0x1
+#define CF_MIN_3DB_150HZ 0x2
+
+static void pahu_tx_hpf_corner_freq_callback(struct work_struct *work)
+{
+ struct delayed_work *hpf_delayed_work;
+ struct hpf_work *hpf_work;
+ struct pahu_priv *pahu;
+ struct snd_soc_codec *codec;
+ u16 dec_cfg_reg, amic_reg, go_bit_reg;
+ u8 hpf_cut_off_freq;
+ int amic_n;
+
+ hpf_delayed_work = to_delayed_work(work);
+ hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
+ pahu = hpf_work->pahu;
+ codec = pahu->codec;
+ hpf_cut_off_freq = hpf_work->hpf_cut_off_freq;
+
+ dec_cfg_reg = WCD9360_CDC_TX0_TX_PATH_CFG0 + 16 * hpf_work->decimator;
+ go_bit_reg = dec_cfg_reg + 7;
+
+ dev_dbg(codec->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
+ __func__, hpf_work->decimator, hpf_cut_off_freq);
+
+ amic_n = pahu_codec_find_amic_input(codec, hpf_work->decimator);
+ if (amic_n) {
+ amic_reg = WCD9360_ANA_AMIC1 + amic_n - 1;
+ pahu_codec_set_tx_hold(codec, amic_reg, false);
+ }
+ snd_soc_update_bits(codec, dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
+ hpf_cut_off_freq << 5);
+ snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x02);
+ /* Minimum 1 clk cycle delay is required as per HW spec */
+ usleep_range(1000, 1010);
+ snd_soc_update_bits(codec, go_bit_reg, 0x02, 0x00);
+}
+
+static void pahu_tx_mute_update_callback(struct work_struct *work)
+{
+ struct tx_mute_work *tx_mute_dwork;
+ struct pahu_priv *pahu;
+ struct delayed_work *delayed_work;
+ struct snd_soc_codec *codec;
+ u16 tx_vol_ctl_reg;
+
+ delayed_work = to_delayed_work(work);
+ tx_mute_dwork = container_of(delayed_work, struct tx_mute_work, dwork);
+ pahu = tx_mute_dwork->pahu;
+ codec = pahu->codec;
+
+ tx_vol_ctl_reg = WCD9360_CDC_TX0_TX_PATH_CTL +
+ 16 * tx_mute_dwork->decimator;
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
+}
+
+static int pahu_codec_enable_rx_path_clk(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ u16 sidetone_reg;
+
+ dev_dbg(codec->dev, "%s %d %d\n", __func__, event, w->shift);
+ sidetone_reg = WCD9360_CDC_RX0_RX_PATH_CFG1 + 0x14*(w->shift);
+
+ if (w->shift == INTERP_AUX)
+ sidetone_reg = WCD9360_CDC_RX9_RX_PATH_CFG1;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ if (!strcmp(w->name, "RX INT7 MIX2 INP"))
+ __pahu_codec_enable_swr(w, event);
+ pahu_codec_enable_interp_clk(codec, event, w->shift);
+ snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x10);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, sidetone_reg, 0x10, 0x00);
+ pahu_codec_enable_interp_clk(codec, event, w->shift);
+ if (!strcmp(w->name, "RX INT7 MIX2 INP"))
+ __pahu_codec_enable_swr(w, event);
+ break;
+ default:
+ break;
+ };
+ return 0;
+}
+
+static int pahu_codec_enable_dec(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ unsigned int decimator;
+ char *dec_adc_mux_name = NULL;
+ char *widget_name = NULL;
+ char *wname;
+ int ret = 0, amic_n;
+ u16 tx_vol_ctl_reg, pwr_level_reg = 0, dec_cfg_reg, hpf_gate_reg;
+ u16 tx_gain_ctl_reg;
+ char *dec;
+ u8 hpf_cut_off_freq;
+
+ dev_dbg(codec->dev, "%s %d\n", __func__, event);
+
+ widget_name = kstrndup(w->name, 15, GFP_KERNEL);
+ if (!widget_name)
+ return -ENOMEM;
+
+ wname = widget_name;
+ dec_adc_mux_name = strsep(&widget_name, " ");
+ if (!dec_adc_mux_name) {
+ dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+ __func__, w->name);
+ ret = -EINVAL;
+ goto out;
+ }
+ dec_adc_mux_name = widget_name;
+
+ dec = strpbrk(dec_adc_mux_name, "012345678");
+ if (!dec) {
+ dev_err(codec->dev, "%s: decimator index not found\n",
+ __func__);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = kstrtouint(dec, 10, &decimator);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: Invalid decimator = %s\n",
+ __func__, wname);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ dev_dbg(codec->dev, "%s(): widget = %s decimator = %u\n", __func__,
+ w->name, decimator);
+
+ tx_vol_ctl_reg = WCD9360_CDC_TX0_TX_PATH_CTL + 16 * decimator;
+ hpf_gate_reg = WCD9360_CDC_TX0_TX_PATH_SEC2 + 16 * decimator;
+ dec_cfg_reg = WCD9360_CDC_TX0_TX_PATH_CFG0 + 16 * decimator;
+ tx_gain_ctl_reg = WCD9360_CDC_TX0_TX_VOL_CTL + 16 * decimator;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ amic_n = pahu_codec_find_amic_input(codec, decimator);
+ if (amic_n)
+ pwr_level_reg = pahu_codec_get_amic_pwlvl_reg(codec,
+ amic_n);
+
+ if (pwr_level_reg) {
+ switch ((snd_soc_read(codec, pwr_level_reg) &
+ WCD9360_AMIC_PWR_LVL_MASK) >>
+ WCD9360_AMIC_PWR_LVL_SHIFT) {
+ case WCD9360_AMIC_PWR_LEVEL_LP:
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ WCD9360_DEC_PWR_LVL_MASK,
+ WCD9360_DEC_PWR_LVL_LP);
+ break;
+
+ case WCD9360_AMIC_PWR_LEVEL_HP:
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ WCD9360_DEC_PWR_LVL_MASK,
+ WCD9360_DEC_PWR_LVL_HP);
+ break;
+ case WCD9360_AMIC_PWR_LEVEL_DEFAULT:
+ default:
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ WCD9360_DEC_PWR_LVL_MASK,
+ WCD9360_DEC_PWR_LVL_DF);
+ break;
+ }
+ }
+ /* Enable TX PGA Mute */
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ hpf_cut_off_freq = (snd_soc_read(codec, dec_cfg_reg) &
+ TX_HPF_CUT_OFF_FREQ_MASK) >> 5;
+
+ pahu->tx_hpf_work[decimator].hpf_cut_off_freq =
+ hpf_cut_off_freq;
+ if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ TX_HPF_CUT_OFF_FREQ_MASK,
+ CF_MIN_3DB_150HZ << 5);
+ snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x02);
+ /*
+ * Minimum 1 clk cycle delay is required as per
+ * HW spec.
+ */
+ usleep_range(1000, 1010);
+ snd_soc_update_bits(codec, hpf_gate_reg, 0x02, 0x00);
+ }
+ /* schedule work queue to Remove Mute */
+ schedule_delayed_work(&pahu->tx_mute_dwork[decimator].dwork,
+ msecs_to_jiffies(tx_unmute_delay));
+ if (pahu->tx_hpf_work[decimator].hpf_cut_off_freq !=
+ CF_MIN_3DB_150HZ)
+ schedule_delayed_work(
+ &pahu->tx_hpf_work[decimator].dwork,
+ msecs_to_jiffies(300));
+ /* apply gain after decimator is enabled */
+ snd_soc_write(codec, tx_gain_ctl_reg,
+ snd_soc_read(codec, tx_gain_ctl_reg));
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ hpf_cut_off_freq =
+ pahu->tx_hpf_work[decimator].hpf_cut_off_freq;
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x10);
+ if (cancel_delayed_work_sync(
+ &pahu->tx_hpf_work[decimator].dwork)) {
+ if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ TX_HPF_CUT_OFF_FREQ_MASK,
+ hpf_cut_off_freq << 5);
+ snd_soc_update_bits(codec, hpf_gate_reg,
+ 0x02, 0x02);
+ /*
+ * Minimum 1 clk cycle delay is required as per
+ * HW spec.
+ */
+ usleep_range(1000, 1010);
+ snd_soc_update_bits(codec, hpf_gate_reg,
+ 0x02, 0x00);
+ }
+ }
+ cancel_delayed_work_sync(
+ &pahu->tx_mute_dwork[decimator].dwork);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ snd_soc_update_bits(codec, tx_vol_ctl_reg, 0x10, 0x00);
+ snd_soc_update_bits(codec, dec_cfg_reg,
+ WCD9360_DEC_PWR_LVL_MASK,
+ WCD9360_DEC_PWR_LVL_DF);
+ break;
+ };
+out:
+ kfree(wname);
+ return ret;
+}
+
+static u32 pahu_get_dmic_sample_rate(struct snd_soc_codec *codec,
+ unsigned int dmic,
+ struct wcd9xxx_pdata *pdata)
+{
+ u8 tx_stream_fs;
+ u8 adc_mux_index = 0, adc_mux_sel = 0;
+ bool dec_found = false;
+ u16 adc_mux_ctl_reg, tx_fs_reg;
+ u32 dmic_fs;
+
+ while (dec_found == 0 && adc_mux_index < WCD9360_MAX_VALID_ADC_MUX) {
+ if (adc_mux_index < 4) {
+ adc_mux_ctl_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+ (adc_mux_index * 2);
+ } else if (adc_mux_index < WCD9360_INVALID_ADC_MUX) {
+ adc_mux_ctl_reg = WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 +
+ adc_mux_index - 4;
+ } else if (adc_mux_index == WCD9360_INVALID_ADC_MUX) {
+ ++adc_mux_index;
+ continue;
+ }
+ adc_mux_sel = ((snd_soc_read(codec, adc_mux_ctl_reg) &
+ 0xF8) >> 3) - 1;
+
+ if (adc_mux_sel == dmic) {
+ dec_found = true;
+ break;
+ }
+
+ ++adc_mux_index;
+ }
+
+ if (dec_found && adc_mux_index <= 8) {
+ tx_fs_reg = WCD9360_CDC_TX0_TX_PATH_CTL + (16 * adc_mux_index);
+ tx_stream_fs = snd_soc_read(codec, tx_fs_reg) & 0x0F;
+ if (tx_stream_fs <= 4) {
+ if (pdata->dmic_sample_rate <=
+ WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ)
+ dmic_fs = pdata->dmic_sample_rate;
+ else
+ dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ;
+ } else
+ dmic_fs = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
+ } else {
+ dmic_fs = pdata->dmic_sample_rate;
+ }
+
+ return dmic_fs;
+}
+
+static u8 pahu_get_dmic_clk_val(struct snd_soc_codec *codec,
+ u32 dmic_clk_rate)
+{
+ u32 div_factor;
+ u8 dmic_ctl_val = WCD9360_DMIC_CLK_DIV_2;
+
+ dev_dbg(codec->dev, "%s: dmic_sample_rate = %d\n",
+ __func__, dmic_clk_rate);
+
+ if (dmic_clk_rate == 0) {
+ dev_err(codec->dev, "%s: dmic_sample_rate cannot be 0\n",
+ __func__);
+ goto done;
+ }
+
+ div_factor = WCD9360_MCLK_CLK_9P6MHZ / dmic_clk_rate;
+ switch (div_factor) {
+ case 2:
+ dmic_ctl_val = WCD9360_DMIC_CLK_DIV_2;
+ break;
+ case 3:
+ dmic_ctl_val = WCD9360_DMIC_CLK_DIV_3;
+ break;
+ case 4:
+ dmic_ctl_val = WCD9360_DMIC_CLK_DIV_4;
+ break;
+ case 6:
+ dmic_ctl_val = WCD9360_DMIC_CLK_DIV_6;
+ break;
+ case 8:
+ dmic_ctl_val = WCD9360_DMIC_CLK_DIV_8;
+ break;
+ case 16:
+ dmic_ctl_val = WCD9360_DMIC_CLK_DIV_16;
+ break;
+ default:
+ dev_err(codec->dev,
+ "%s: Invalid div_factor %u, dmic_rate(%u)\n",
+ __func__, div_factor, dmic_clk_rate);
+ break;
+ }
+
+done:
+ return dmic_ctl_val;
+}
+
+static int pahu_codec_enable_adc(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ dev_dbg(codec->dev, "%s: event:%d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ pahu_codec_set_tx_hold(codec, w->reg, true);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int pahu_codec_enable_dmic(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent);
+ u8 dmic_clk_en = 0x01;
+ u16 dmic_clk_reg;
+ s32 *dmic_clk_cnt;
+ u8 dmic_rate_val, dmic_rate_shift = 1;
+ unsigned int dmic;
+ u32 dmic_sample_rate;
+
+ dmic = w->shift;
+ switch (dmic) {
+ case 0:
+ case 1:
+ dmic_clk_cnt = &(pahu->dmic_0_1_clk_cnt);
+ dmic_clk_reg = WCD9360_CPE_SS_DMIC0_CTL;
+ break;
+ case 2:
+ case 3:
+ dmic_clk_cnt = &(pahu->dmic_2_3_clk_cnt);
+ dmic_clk_reg = WCD9360_CPE_SS_DMIC1_CTL;
+ break;
+ case 4:
+ case 5:
+ dmic_clk_cnt = &(pahu->dmic_4_5_clk_cnt);
+ dmic_clk_reg = WCD9360_CPE_SS_DMIC2_CTL;
+ break;
+ case 6:
+ case 7:
+ dmic_clk_cnt = &(pahu->dmic_6_7_clk_cnt);
+ dmic_clk_reg = WCD9360_CPE_SS_DMIC3_CTL;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid DMIC Selection\n",
+ __func__);
+ return -EINVAL;
+ };
+ dev_dbg(codec->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
+ __func__, event, dmic, *dmic_clk_cnt);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ dmic_sample_rate = pahu_get_dmic_sample_rate(codec, dmic,
+ pdata);
+ dmic_rate_val =
+ pahu_get_dmic_clk_val(codec,
+ dmic_sample_rate);
+
+ (*dmic_clk_cnt)++;
+ if (*dmic_clk_cnt == 1) {
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ 0x07 << dmic_rate_shift,
+ dmic_rate_val << dmic_rate_shift);
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ dmic_clk_en, dmic_clk_en);
+ }
+
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ dmic_rate_val =
+ pahu_get_dmic_clk_val(codec,
+ pdata->mad_dmic_sample_rate);
+ (*dmic_clk_cnt)--;
+ if (*dmic_clk_cnt == 0) {
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ dmic_clk_en, 0);
+ snd_soc_update_bits(codec, dmic_clk_reg,
+ 0x07 << dmic_rate_shift,
+ dmic_rate_val << dmic_rate_shift);
+ }
+ break;
+ };
+
+ return 0;
+}
+
+/*
+ * pahu_micbias_control: enable/disable micbias
+ * @codec: handle to snd_soc_codec *
+ * @micb_num: micbias to be enabled/disabled, e.g. micbias1 or micbias2
+ * @req: control requested, enable/disable or pullup enable/disable
+ * @is_dapm: triggered by dapm or not
+ *
+ * return 0 if control is success or error code in case of failure
+ */
+int pahu_micbias_control(struct snd_soc_codec *codec,
+ int micb_num, int req, bool is_dapm)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int micb_index = micb_num - 1;
+ u16 micb_reg;
+
+ if ((micb_index < 0) || (micb_index > PAHU_MAX_MICBIAS - 1)) {
+ dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
+ __func__, micb_index);
+ return -EINVAL;
+ }
+
+ switch (micb_num) {
+ case WCD9360_MIC_BIAS_1:
+ micb_reg = WCD9360_ANA_MICB1;
+ break;
+ case WCD9360_MIC_BIAS_2:
+ micb_reg = WCD9360_ANA_MICB2;
+ break;
+ case WCD9360_MIC_BIAS_3:
+ micb_reg = WCD9360_ANA_MICB3;
+ break;
+ case WCD9360_MIC_BIAS_4:
+ micb_reg = WCD9360_ANA_MICB4;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid micbias number: %d\n",
+ __func__, micb_num);
+ return -EINVAL;
+ }
+ mutex_lock(&pahu->micb_lock);
+
+ switch (req) {
+ case WCD9360_MICB_PULLUP_ENABLE:
+ pahu->pullup_ref[micb_index]++;
+ if ((pahu->pullup_ref[micb_index] == 1) &&
+ (pahu->micb_ref[micb_index] == 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
+ break;
+ case WCD9360_MICB_PULLUP_DISABLE:
+ if (pahu->pullup_ref[micb_index] > 0)
+ pahu->pullup_ref[micb_index]--;
+ if ((pahu->pullup_ref[micb_index] == 0) &&
+ (pahu->micb_ref[micb_index] == 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
+ break;
+ case WCD9360_MICB_ENABLE:
+ pahu->micb_ref[micb_index]++;
+ if (pahu->micb_ref[micb_index] == 1)
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x40);
+ break;
+ case WCD9360_MICB_DISABLE:
+ if (pahu->micb_ref[micb_index] > 0)
+ pahu->micb_ref[micb_index]--;
+ if ((pahu->micb_ref[micb_index] == 0) &&
+ (pahu->pullup_ref[micb_index] > 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x80);
+ else if ((pahu->micb_ref[micb_index] == 0) &&
+ (pahu->pullup_ref[micb_index] == 0))
+ snd_soc_update_bits(codec, micb_reg, 0xC0, 0x00);
+ break;
+ }
+
+ dev_dbg(codec->dev, "%s: micb_num:%d, micb_ref: %d\n",
+ __func__, micb_num, pahu->micb_ref[micb_index]);
+
+ mutex_unlock(&pahu->micb_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(pahu_micbias_control);
+
+static int __pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+ int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ int micb_num;
+
+ dev_dbg(codec->dev, "%s: wname: %s, event: %d\n",
+ __func__, w->name, event);
+
+ if (strnstr(w->name, "MIC BIAS1", sizeof("MIC BIAS1")))
+ micb_num = WCD9360_MIC_BIAS_1;
+ else if (strnstr(w->name, "MIC BIAS2", sizeof("MIC BIAS2")))
+ micb_num = WCD9360_MIC_BIAS_2;
+ else if (strnstr(w->name, "MIC BIAS3", sizeof("MIC BIAS3")))
+ micb_num = WCD9360_MIC_BIAS_3;
+ else if (strnstr(w->name, "MIC BIAS4", sizeof("MIC BIAS4")))
+ micb_num = WCD9360_MIC_BIAS_4;
+ else
+ return -EINVAL;
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ /*
+ * Use ref count to handle micbias pullup
+ * and enable requests
+ */
+ pahu_micbias_control(codec, micb_num, WCD9360_MICB_ENABLE,
+ true);
+ break;
+ case SND_SOC_DAPM_POST_PMU:
+ /* wait for cnp time */
+ usleep_range(1000, 1100);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ pahu_micbias_control(codec, micb_num, WCD9360_MICB_DISABLE,
+ true);
+ break;
+ };
+
+ return 0;
+}
+
+/*
+ * pahu_codec_enable_standalone_micbias - enable micbias standalone
+ * @codec: pointer to codec instance
+ * @micb_num: number of micbias to be enabled
+ * @enable: true to enable micbias or false to disable
+ *
+ * This function is used to enable micbias (1, 2, 3 or 4) during
+ * standalone independent of whether TX use-case is running or not
+ *
+ * Return: error code in case of failure or 0 for success
+ */
+int pahu_codec_enable_standalone_micbias(struct snd_soc_codec *codec,
+ int micb_num,
+ bool enable)
+{
+ const char * const micb_names[] = {
+ DAPM_MICBIAS1_STANDALONE, DAPM_MICBIAS2_STANDALONE,
+ DAPM_MICBIAS3_STANDALONE, DAPM_MICBIAS4_STANDALONE
+ };
+ int micb_index = micb_num - 1;
+ int rc;
+
+ if (!codec) {
+ pr_err("%s: Codec memory is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if ((micb_index < 0) || (micb_index > PAHU_MAX_MICBIAS - 1)) {
+ dev_err(codec->dev, "%s: Invalid micbias index, micb_ind:%d\n",
+ __func__, micb_index);
+ return -EINVAL;
+ }
+
+ if (enable)
+ rc = snd_soc_dapm_force_enable_pin(
+ snd_soc_codec_get_dapm(codec),
+ micb_names[micb_index]);
+ else
+ rc = snd_soc_dapm_disable_pin(snd_soc_codec_get_dapm(codec),
+ micb_names[micb_index]);
+
+ if (!rc)
+ snd_soc_dapm_sync(snd_soc_codec_get_dapm(codec));
+ else
+ dev_err(codec->dev, "%s: micbias%d force %s pin failed\n",
+ __func__, micb_num, (enable ? "enable" : "disable"));
+
+ return rc;
+}
+EXPORT_SYMBOL(pahu_codec_enable_standalone_micbias);
+
+static int pahu_codec_force_enable_micbias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ wcd_resmgr_enable_master_bias(pahu->resmgr);
+ pahu_cdc_mclk_enable(codec, true);
+ ret = __pahu_codec_enable_micbias(w, SND_SOC_DAPM_PRE_PMU);
+ /* Wait for 1ms for better cnp */
+ usleep_range(1000, 1100);
+ pahu_cdc_mclk_enable(codec, false);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ ret = __pahu_codec_enable_micbias(w, SND_SOC_DAPM_POST_PMD);
+ wcd_resmgr_disable_master_bias(pahu->resmgr);
+ break;
+ }
+
+ return ret;
+}
+
+static int pahu_codec_enable_micbias(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ return __pahu_codec_enable_micbias(w, event);
+}
+
+static void pahu_restore_iir_coeff(struct pahu_priv *pahu, int iir_idx,
+ int band_idx)
+{
+ u16 reg_add;
+ int no_of_reg = 0;
+
+ regmap_write(pahu->wcd9xxx->regmap,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+ reg_add = WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx;
+
+ if (pahu->intf_type != WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+ return;
+ /*
+ * Since wcd9xxx_slim_write_repeat() supports only maximum of 16
+ * registers at a time, split total 20 writes(5 coefficients per
+ * band and 4 writes per coefficient) into 16 and 4.
+ */
+ no_of_reg = WCD9360_CDC_REPEAT_WRITES_MAX;
+ wcd9xxx_slim_write_repeat(pahu->wcd9xxx, reg_add, no_of_reg,
+ &pahu->sidetone_coeff_array[iir_idx][band_idx][0]);
+
+ no_of_reg = (WCD9360_CDC_SIDETONE_IIR_COEFF_MAX * 4) -
+ WCD9360_CDC_REPEAT_WRITES_MAX;
+ wcd9xxx_slim_write_repeat(pahu->wcd9xxx, reg_add, no_of_reg,
+ &pahu->sidetone_coeff_array[iir_idx][band_idx]
+ [WCD9360_CDC_REPEAT_WRITES_MAX]);
+}
+
+static int pahu_iir_enable_audio_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ /* IIR filter band registers are at integer multiples of 16 */
+ u16 iir_reg = WCD9360_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
+
+ ucontrol->value.integer.value[0] = (snd_soc_read(codec, iir_reg) &
+ (1 << band_idx)) != 0;
+
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+ iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int pahu_iir_enable_audio_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ bool iir_band_en_status;
+ int value = ucontrol->value.integer.value[0];
+ u16 iir_reg = WCD9360_CDC_SIDETONE_IIR0_IIR_CTL + 16 * iir_idx;
+
+ pahu_restore_iir_coeff(pahu, iir_idx, band_idx);
+
+ /* Mask first 5 bits, 6-8 are reserved */
+ snd_soc_update_bits(codec, iir_reg, (1 << band_idx),
+ (value << band_idx));
+
+ iir_band_en_status = ((snd_soc_read(codec, iir_reg) &
+ (1 << band_idx)) != 0);
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d enable %d\n", __func__,
+ iir_idx, band_idx, iir_band_en_status);
+ return 0;
+}
+
+static uint32_t get_iir_band_coeff(struct snd_soc_codec *codec,
+ int iir_idx, int band_idx,
+ int coeff_idx)
+{
+ uint32_t value = 0;
+
+ /* Address does not automatically update if reading */
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t)) & 0x7F);
+
+ value |= snd_soc_read(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx));
+
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 1) & 0x7F);
+
+ value |= (snd_soc_read(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
+ 16 * iir_idx)) << 8);
+
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 2) & 0x7F);
+
+ value |= (snd_soc_read(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
+ 16 * iir_idx)) << 16);
+
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ ((band_idx * BAND_MAX + coeff_idx)
+ * sizeof(uint32_t) + 3) & 0x7F);
+
+ /* Mask bits top 2 bits since they are reserved */
+ value |= ((snd_soc_read(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL +
+ 16 * iir_idx)) & 0x3F) << 24);
+
+ return value;
+}
+
+static int pahu_iir_band_audio_mixer_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ ucontrol->value.integer.value[0] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 0);
+ ucontrol->value.integer.value[1] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 1);
+ ucontrol->value.integer.value[2] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 2);
+ ucontrol->value.integer.value[3] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 3);
+ ucontrol->value.integer.value[4] =
+ get_iir_band_coeff(codec, iir_idx, band_idx, 4);
+
+ dev_dbg(codec->dev, "%s: IIR #%d band #%d b0 = 0x%x\n"
+ "%s: IIR #%d band #%d b1 = 0x%x\n"
+ "%s: IIR #%d band #%d b2 = 0x%x\n"
+ "%s: IIR #%d band #%d a1 = 0x%x\n"
+ "%s: IIR #%d band #%d a2 = 0x%x\n",
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[0],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[1],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[2],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[3],
+ __func__, iir_idx, band_idx,
+ (uint32_t)ucontrol->value.integer.value[4]);
+ return 0;
+}
+
+static void set_iir_band_coeff(struct snd_soc_codec *codec,
+ int iir_idx, int band_idx,
+ uint32_t value)
+{
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
+ (value & 0xFF));
+
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
+ (value >> 8) & 0xFF);
+
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
+ (value >> 16) & 0xFF);
+
+ /* Mask top 2 bits, 7-8 are reserved */
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL + 16 * iir_idx),
+ (value >> 24) & 0x3F);
+}
+
+static int pahu_iir_band_audio_mixer_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int iir_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->reg;
+ int band_idx = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ int coeff_idx, idx = 0;
+
+ /*
+ * Mask top bit it is reserved
+ * Updates addr automatically for each B2 write
+ */
+ snd_soc_write(codec,
+ (WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL + 16 * iir_idx),
+ (band_idx * BAND_MAX * sizeof(uint32_t)) & 0x7F);
+
+ /* Store the coefficients in sidetone coeff array */
+ for (coeff_idx = 0; coeff_idx < WCD9360_CDC_SIDETONE_IIR_COEFF_MAX;
+ coeff_idx++) {
+ uint32_t value = ucontrol->value.integer.value[coeff_idx];
+
+ set_iir_band_coeff(codec, iir_idx, band_idx, value);
+
+ /* Four 8 bit values(one 32 bit) per coefficient */
+ pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ (value & 0xFF);
+ pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ ((value >> 8) & 0xFF);
+ pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ ((value >> 16) & 0xFF);
+ pahu->sidetone_coeff_array[iir_idx][band_idx][idx++] =
+ ((value >> 24) & 0xFF);
+ }
+
+ pr_debug("%s: IIR #%d band #%d b0 = 0x%x\n"
+ "%s: IIR #%d band #%d b1 = 0x%x\n"
+ "%s: IIR #%d band #%d b2 = 0x%x\n"
+ "%s: IIR #%d band #%d a1 = 0x%x\n"
+ "%s: IIR #%d band #%d a2 = 0x%x\n",
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 0),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 1),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 2),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 3),
+ __func__, iir_idx, band_idx,
+ get_iir_band_coeff(codec, iir_idx, band_idx, 4));
+ return 0;
+}
+
+static int pahu_compander_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = pahu->comp_enabled[comp];
+ return 0;
+}
+
+static int pahu_compander_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int comp = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+ int value = ucontrol->value.integer.value[0];
+
+ dev_dbg(codec->dev, "%s: Compander %d enable current %d, new %d\n",
+ __func__, comp + 1, pahu->comp_enabled[comp], value);
+ pahu->comp_enabled[comp] = value;
+
+ return 0;
+}
+
+static int pahu_dmic_pin_mode_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u16 offset;
+ u8 reg_val, pinctl_position;
+
+ pinctl_position = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ offset = pinctl_position - WCD9360_TLMM_DMIC_PINCFG_OFFSET;
+ reg_val = snd_soc_read(codec,
+ WCD9360_TLMM_DMIC1_CLK_PINCFG + offset);
+
+ ucontrol->value.integer.value[0] = !!reg_val;
+
+ return 0;
+}
+
+static int pahu_dmic_pin_mode_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ u16 ctl_reg, cfg_reg, offset;
+ u8 ctl_val, cfg_val, pinctl_position, pinctl_mode, mask;
+
+ /* 0- high or low; 1- high Z */
+ pinctl_mode = ucontrol->value.integer.value[0];
+ pinctl_position = ((struct soc_multi_mixer_control *)
+ kcontrol->private_value)->shift;
+
+ switch (pinctl_position >> 3) {
+ case 0:
+ ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_0;
+ break;
+ case 1:
+ ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_1;
+ break;
+ case 2:
+ ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_2;
+ break;
+ case 3:
+ ctl_reg = WCD9360_TEST_DEBUG_PIN_CTL_OE_3;
+ break;
+ default:
+ dev_err(codec->dev, "%s: Invalid pinctl position = %d\n",
+ __func__, pinctl_position);
+ return -EINVAL;
+ }
+
+ ctl_val = ~(pinctl_mode << (pinctl_position & 0x07));
+ mask = 1 << (pinctl_position & 0x07);
+ snd_soc_update_bits(codec, ctl_reg, mask, ctl_val);
+
+ offset = pinctl_position - WCD9360_TLMM_DMIC_PINCFG_OFFSET;
+ cfg_reg = WCD9360_TLMM_DMIC1_CLK_PINCFG + offset;
+ if (pinctl_mode) {
+ if (pahu->intf_type == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
+ cfg_val = 0x5;
+ else
+ cfg_val = 0xD;
+ } else
+ cfg_val = 0;
+ snd_soc_update_bits(codec, cfg_reg, 0x1F, cfg_val);
+
+ dev_dbg(codec->dev, "%s: reg=0x%x mask=0x%x val=%d reg=0x%x val=%d\n",
+ __func__, ctl_reg, mask, ctl_val, cfg_reg, cfg_val);
+
+ return 0;
+}
+
+static int pahu_amic_pwr_lvl_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u16 amic_reg = 0;
+
+ if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
+ amic_reg = WCD9360_ANA_AMIC1;
+ if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
+ amic_reg = WCD9360_ANA_AMIC3;
+
+ if (amic_reg)
+ ucontrol->value.integer.value[0] =
+ (snd_soc_read(codec, amic_reg) &
+ WCD9360_AMIC_PWR_LVL_MASK) >>
+ WCD9360_AMIC_PWR_LVL_SHIFT;
+ return 0;
+}
+
+static int pahu_amic_pwr_lvl_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u32 mode_val;
+ u16 amic_reg = 0;
+
+ mode_val = ucontrol->value.enumerated.item[0];
+
+ dev_dbg(codec->dev, "%s: mode: %d\n", __func__, mode_val);
+
+ if (!strcmp(kcontrol->id.name, "AMIC_1_2 PWR MODE"))
+ amic_reg = WCD9360_ANA_AMIC1;
+ if (!strcmp(kcontrol->id.name, "AMIC_3_4 PWR MODE"))
+ amic_reg = WCD9360_ANA_AMIC3;
+
+ if (amic_reg)
+ snd_soc_update_bits(codec, amic_reg, WCD9360_AMIC_PWR_LVL_MASK,
+ mode_val << WCD9360_AMIC_PWR_LVL_SHIFT);
+ return 0;
+}
+
+static const char *const pahu_conn_mad_text[] = {
+ "NOTUSED1", "ADC1", "ADC2", "ADC3", "ADC4", "NOTUSED5",
+ "NOTUSED6", "NOTUSED2", "DMIC0", "DMIC1", "DMIC2", "DMIC3",
+ "DMIC4", "DMIC5", "DMIC6", "DMIC7"
+};
+
+static const struct soc_enum pahu_conn_mad_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(pahu_conn_mad_text),
+ pahu_conn_mad_text);
+
+static int pahu_mad_input_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ u8 pahu_mad_input;
+
+ pahu_mad_input = snd_soc_read(codec, WCD9360_SOC_MAD_INP_SEL) & 0x0F;
+ ucontrol->value.integer.value[0] = pahu_mad_input;
+
+ dev_dbg(codec->dev, "%s: pahu_mad_input = %s\n", __func__,
+ pahu_conn_mad_text[pahu_mad_input]);
+
+ return 0;
+}
+
+static int pahu_mad_input_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct snd_soc_card *card = codec->component.card;
+ u8 pahu_mad_input;
+ char mad_amic_input_widget[6];
+ const char *mad_input_widget;
+ const char *source_widget = NULL;
+ u32 adc, i, mic_bias_found = 0;
+ int ret = 0;
+ char *mad_input;
+ bool is_adc_input = false;
+
+ pahu_mad_input = ucontrol->value.integer.value[0];
+
+ if (pahu_mad_input >= sizeof(pahu_conn_mad_text)/
+ sizeof(pahu_conn_mad_text[0])) {
+ dev_err(codec->dev,
+ "%s: pahu_mad_input = %d out of bounds\n",
+ __func__, pahu_mad_input);
+ return -EINVAL;
+ }
+
+ if (strnstr(pahu_conn_mad_text[pahu_mad_input], "NOTUSED",
+ sizeof("NOTUSED"))) {
+ dev_dbg(codec->dev,
+ "%s: Unsupported pahu_mad_input = %s\n",
+ __func__, pahu_conn_mad_text[pahu_mad_input]);
+ /* Make sure the MAD register is updated */
+ snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP,
+ 0x88, 0x00);
+ return -EINVAL;
+ }
+
+ if (strnstr(pahu_conn_mad_text[pahu_mad_input],
+ "ADC", sizeof("ADC"))) {
+ mad_input = strpbrk(pahu_conn_mad_text[pahu_mad_input],
+ "1234");
+ if (!mad_input) {
+ dev_err(codec->dev, "%s: Invalid MAD input %s\n",
+ __func__, pahu_conn_mad_text[pahu_mad_input]);
+ return -EINVAL;
+ }
+
+ ret = kstrtouint(mad_input, 10, &adc);
+ if ((ret < 0) || (adc > 4)) {
+ dev_err(codec->dev, "%s: Invalid ADC = %s\n", __func__,
+ pahu_conn_mad_text[pahu_mad_input]);
+ return -EINVAL;
+ }
+
+ snprintf(mad_amic_input_widget, 6, "%s%u", "AMIC", adc);
+
+ mad_input_widget = mad_amic_input_widget;
+ is_adc_input = true;
+ } else {
+ /* DMIC type input widget*/
+ mad_input_widget = pahu_conn_mad_text[pahu_mad_input];
+ }
+
+ dev_dbg(codec->dev,
+ "%s: pahu input widget = %s, adc_input = %s\n", __func__,
+ mad_input_widget, is_adc_input ? "true" : "false");
+
+ for (i = 0; i < card->num_of_dapm_routes; i++) {
+ if (!strcmp(card->of_dapm_routes[i].sink, mad_input_widget)) {
+ source_widget = card->of_dapm_routes[i].source;
+ if (!source_widget) {
+ dev_err(codec->dev,
+ "%s: invalid source widget\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ if (strnstr(source_widget,
+ "MIC BIAS1", sizeof("MIC BIAS1"))) {
+ mic_bias_found = 1;
+ break;
+ } else if (strnstr(source_widget,
+ "MIC BIAS2", sizeof("MIC BIAS2"))) {
+ mic_bias_found = 2;
+ break;
+ } else if (strnstr(source_widget,
+ "MIC BIAS3", sizeof("MIC BIAS3"))) {
+ mic_bias_found = 3;
+ break;
+ } else if (strnstr(source_widget,
+ "MIC BIAS4", sizeof("MIC BIAS4"))) {
+ mic_bias_found = 4;
+ break;
+ }
+ }
+ }
+
+ if (!mic_bias_found) {
+ dev_err(codec->dev, "%s: mic bias not found for input %s\n",
+ __func__, mad_input_widget);
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "%s: mic_bias found = %d\n", __func__,
+ mic_bias_found);
+
+ snd_soc_update_bits(codec, WCD9360_SOC_MAD_INP_SEL,
+ 0x0F, pahu_mad_input);
+ snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP,
+ 0x07, mic_bias_found);
+ /* for all adc inputs, mad should be in micbias mode with BG enabled */
+ if (is_adc_input)
+ snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP,
+ 0x88, 0x88);
+ else
+ snd_soc_update_bits(codec, WCD9360_ANA_MAD_SETUP,
+ 0x88, 0x00);
+ return 0;
+}
+
+static int pahu_ear_spkr_pa_gain_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ ucontrol->value.integer.value[0] = pahu->ear_spkr_gain;
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int pahu_ear_spkr_pa_gain_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ pahu->ear_spkr_gain = ucontrol->value.integer.value[0];
+
+ dev_dbg(codec->dev, "%s: gain = %d\n", __func__, pahu->ear_spkr_gain);
+
+ return 0;
+}
+
+static int pahu_spkr_left_boost_stage_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u8 bst_state_max = 0;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ bst_state_max = snd_soc_read(codec, WCD9360_CDC_BOOST0_BOOST_CTL);
+ bst_state_max = (bst_state_max & 0x0c) >> 2;
+ ucontrol->value.integer.value[0] = bst_state_max;
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int pahu_spkr_left_boost_stage_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u8 bst_state_max;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ bst_state_max = ucontrol->value.integer.value[0] << 2;
+ snd_soc_update_bits(codec, WCD9360_CDC_BOOST0_BOOST_CTL,
+ 0x0c, bst_state_max);
+
+ return 0;
+}
+
+static int pahu_spkr_right_boost_stage_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u8 bst_state_max = 0;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ bst_state_max = snd_soc_read(codec, WCD9360_CDC_BOOST1_BOOST_CTL);
+ bst_state_max = (bst_state_max & 0x0c) >> 2;
+ ucontrol->value.integer.value[0] = bst_state_max;
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int pahu_spkr_right_boost_stage_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ u8 bst_state_max;
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+ bst_state_max = ucontrol->value.integer.value[0] << 2;
+ snd_soc_update_bits(codec, WCD9360_CDC_BOOST1_BOOST_CTL,
+ 0x0c, bst_state_max);
+
+ return 0;
+}
+
+static const char *const pahu_anc_func_text[] = {"OFF", "ON"};
+static const struct soc_enum pahu_anc_func_enum =
+ SOC_ENUM_SINGLE_EXT(2, pahu_anc_func_text);
+
+static const char *const pahu_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
+static SOC_ENUM_SINGLE_EXT_DECL(pahu_clkmode_enum, pahu_clkmode_text);
+
+/* Cutoff frequency for high pass filter */
+static const char * const cf_text[] = {
+ "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
+};
+
+static const char * const rx_cf_text[] = {
+ "CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ",
+ "CF_NEG_3DB_0P48HZ"
+};
+
+static const char * const amic_pwr_lvl_text[] = {
+ "LOW_PWR", "DEFAULT", "HIGH_PERF", "HYBRID"
+};
+
+static const char * const pahu_ear_pa_gain_text[] = {
+ "G_6_DB", "G_4P5_DB", "G_3_DB", "G_1P5_DB",
+ "G_0_DB", "G_M2P5_DB", "UNDEFINED", "G_M12_DB"
+};
+
+static const char * const pahu_ear_spkr_pa_gain_text[] = {
+ "G_DEFAULT", "G_0_DB", "G_1_DB", "G_2_DB", "G_3_DB",
+ "G_4_DB", "G_5_DB", "G_6_DB"
+};
+
+static const char * const pahu_speaker_boost_stage_text[] = {
+ "NO_MAX_STATE", "MAX_STATE_1", "MAX_STATE_2"
+};
+
+static SOC_ENUM_SINGLE_EXT_DECL(pahu_ear_pa_gain_enum, pahu_ear_pa_gain_text);
+static SOC_ENUM_SINGLE_EXT_DECL(pahu_ear_spkr_pa_gain_enum,
+ pahu_ear_spkr_pa_gain_text);
+static SOC_ENUM_SINGLE_EXT_DECL(pahu_spkr_boost_stage_enum,
+ pahu_speaker_boost_stage_text);
+static SOC_ENUM_SINGLE_EXT_DECL(amic_pwr_lvl_enum, amic_pwr_lvl_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec0_enum, WCD9360_CDC_TX0_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec1_enum, WCD9360_CDC_TX1_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec2_enum, WCD9360_CDC_TX2_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec3_enum, WCD9360_CDC_TX3_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec4_enum, WCD9360_CDC_TX4_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec5_enum, WCD9360_CDC_TX5_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec6_enum, WCD9360_CDC_TX6_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec7_enum, WCD9360_CDC_TX7_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_dec8_enum, WCD9360_CDC_TX8_TX_PATH_CFG0, 5,
+ cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int0_1_enum, WCD9360_CDC_RX0_RX_PATH_CFG2, 0,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int0_2_enum, WCD9360_CDC_RX0_RX_PATH_MIX_CFG, 2,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int7_1_enum, WCD9360_CDC_RX7_RX_PATH_CFG2, 0,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int7_2_enum, WCD9360_CDC_RX7_RX_PATH_MIX_CFG, 2,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int8_1_enum, WCD9360_CDC_RX8_RX_PATH_CFG2, 0,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int8_2_enum, WCD9360_CDC_RX8_RX_PATH_MIX_CFG, 2,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int9_1_enum, WCD9360_CDC_RX9_RX_PATH_CFG2, 0,
+ rx_cf_text);
+static SOC_ENUM_SINGLE_DECL(cf_int9_2_enum, WCD9360_CDC_RX9_RX_PATH_MIX_CFG, 2,
+ rx_cf_text);
+
+static const struct snd_kcontrol_new pahu_snd_controls[] = {
+ SOC_ENUM_EXT("EAR SPKR PA Gain", pahu_ear_spkr_pa_gain_enum,
+ pahu_ear_spkr_pa_gain_get, pahu_ear_spkr_pa_gain_put),
+ SOC_ENUM_EXT("SPKR Left Boost Max State", pahu_spkr_boost_stage_enum,
+ pahu_spkr_left_boost_stage_get,
+ pahu_spkr_left_boost_stage_put),
+ SOC_ENUM_EXT("SPKR Right Boost Max State", pahu_spkr_boost_stage_enum,
+ pahu_spkr_right_boost_stage_get,
+ pahu_spkr_right_boost_stage_put),
+ SOC_SINGLE_TLV("ADC1 Volume", WCD9360_ANA_AMIC1, 0, 20, 0, analog_gain),
+ SOC_SINGLE_TLV("ADC2 Volume", WCD9360_ANA_AMIC2, 0, 20, 0, analog_gain),
+ SOC_SINGLE_TLV("ADC3 Volume", WCD9360_ANA_AMIC3, 0, 20, 0, analog_gain),
+ SOC_SINGLE_TLV("ADC4 Volume", WCD9360_ANA_AMIC4, 0, 20, 0, analog_gain),
+
+ SOC_SINGLE_SX_TLV("RX0 Digital Volume", WCD9360_CDC_RX0_RX_VOL_CTL,
+ 0, -84, 40, digital_gain), /* -84dB min - 40dB max */
+ SOC_SINGLE_SX_TLV("RX7 Digital Volume", WCD9360_CDC_RX7_RX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX8 Digital Volume", WCD9360_CDC_RX8_RX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX9 Digital Volume", WCD9360_CDC_RX9_RX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX0 Mix Digital Volume",
+ WCD9360_CDC_RX0_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX7 Mix Digital Volume",
+ WCD9360_CDC_RX7_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX8 Mix Digital Volume",
+ WCD9360_CDC_RX8_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("RX9 Mix Digital Volume",
+ WCD9360_CDC_RX9_RX_VOL_MIX_CTL, 0, -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("DEC0 Volume", WCD9360_CDC_TX0_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC1 Volume", WCD9360_CDC_TX1_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC2 Volume", WCD9360_CDC_TX2_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC3 Volume", WCD9360_CDC_TX3_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC4 Volume", WCD9360_CDC_TX4_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC5 Volume", WCD9360_CDC_TX5_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC6 Volume", WCD9360_CDC_TX6_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC7 Volume", WCD9360_CDC_TX7_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("DEC8 Volume", WCD9360_CDC_TX8_TX_VOL_CTL, 0,
+ -84, 40, digital_gain),
+
+ SOC_SINGLE_SX_TLV("IIR0 INP0 Volume",
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_SX_TLV("IIR0 INP1 Volume",
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_SX_TLV("IIR0 INP2 Volume",
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0, -84, 40,
+ digital_gain),
+ SOC_SINGLE_SX_TLV("IIR0 INP3 Volume",
+ WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0, -84, 40,
+ digital_gain),
+
+ SOC_SINGLE_EXT("ANC Slot", SND_SOC_NOPM, 0, 100, 0, pahu_get_anc_slot,
+ pahu_put_anc_slot),
+ SOC_ENUM_EXT("ANC Function", pahu_anc_func_enum, pahu_get_anc_func,
+ pahu_put_anc_func),
+
+ SOC_ENUM_EXT("CLK MODE", pahu_clkmode_enum, pahu_get_clkmode,
+ pahu_put_clkmode),
+
+ SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
+ SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
+ SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
+ SOC_ENUM("TX3 HPF cut off", cf_dec3_enum),
+ SOC_ENUM("TX4 HPF cut off", cf_dec4_enum),
+ SOC_ENUM("TX5 HPF cut off", cf_dec5_enum),
+ SOC_ENUM("TX6 HPF cut off", cf_dec6_enum),
+ SOC_ENUM("TX7 HPF cut off", cf_dec7_enum),
+ SOC_ENUM("TX8 HPF cut off", cf_dec8_enum),
+
+ SOC_ENUM("RX INT0_1 HPF cut off", cf_int0_1_enum),
+ SOC_ENUM("RX INT0_2 HPF cut off", cf_int0_2_enum),
+ SOC_ENUM("RX INT7_1 HPF cut off", cf_int7_1_enum),
+ SOC_ENUM("RX INT7_2 HPF cut off", cf_int7_2_enum),
+ SOC_ENUM("RX INT8_1 HPF cut off", cf_int8_1_enum),
+ SOC_ENUM("RX INT8_2 HPF cut off", cf_int8_2_enum),
+ SOC_ENUM("RX INT9_1 HPF cut off", cf_int9_1_enum),
+ SOC_ENUM("RX INT9_2 HPF cut off", cf_int9_2_enum),
+
+ SOC_SINGLE_EXT("IIR0 Enable Band1", IIR0, BAND1, 1, 0,
+ pahu_iir_enable_audio_mixer_get,
+ pahu_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("IIR0 Enable Band2", IIR0, BAND2, 1, 0,
+ pahu_iir_enable_audio_mixer_get,
+ pahu_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("IIR0 Enable Band3", IIR0, BAND3, 1, 0,
+ pahu_iir_enable_audio_mixer_get,
+ pahu_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("IIR0 Enable Band4", IIR0, BAND4, 1, 0,
+ pahu_iir_enable_audio_mixer_get,
+ pahu_iir_enable_audio_mixer_put),
+ SOC_SINGLE_EXT("IIR0 Enable Band5", IIR0, BAND5, 1, 0,
+ pahu_iir_enable_audio_mixer_get,
+ pahu_iir_enable_audio_mixer_put),
+
+ SOC_SINGLE_MULTI_EXT("IIR0 Band1", IIR0, BAND1, 255, 0, 5,
+ pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("IIR0 Band2", IIR0, BAND2, 255, 0, 5,
+ pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("IIR0 Band3", IIR0, BAND3, 255, 0, 5,
+ pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("IIR0 Band4", IIR0, BAND4, 255, 0, 5,
+ pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put),
+ SOC_SINGLE_MULTI_EXT("IIR0 Band5", IIR0, BAND5, 255, 0, 5,
+ pahu_iir_band_audio_mixer_get, pahu_iir_band_audio_mixer_put),
+
+ SOC_SINGLE_EXT("COMP0 Switch", SND_SOC_NOPM, COMPANDER_1, 1, 0,
+ pahu_compander_get, pahu_compander_put),
+ SOC_SINGLE_EXT("COMP7 Switch", SND_SOC_NOPM, COMPANDER_7, 1, 0,
+ pahu_compander_get, pahu_compander_put),
+ SOC_SINGLE_EXT("COMP8 Switch", SND_SOC_NOPM, COMPANDER_8, 1, 0,
+ pahu_compander_get, pahu_compander_put),
+
+ SOC_ENUM_EXT("MAD Input", pahu_conn_mad_enum,
+ pahu_mad_input_get, pahu_mad_input_put),
+
+ SOC_SINGLE_EXT("DMIC1_CLK_PIN_MODE", SND_SOC_NOPM, 15, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC1_DATA_PIN_MODE", SND_SOC_NOPM, 16, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC2_CLK_PIN_MODE", SND_SOC_NOPM, 17, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC2_DATA_PIN_MODE", SND_SOC_NOPM, 18, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC3_CLK_PIN_MODE", SND_SOC_NOPM, 28, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC3_DATA_PIN_MODE", SND_SOC_NOPM, 29, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC4_CLK_PIN_MODE", SND_SOC_NOPM, 30, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_SINGLE_EXT("DMIC4_DATA_PIN_MODE", SND_SOC_NOPM, 31, 1, 0,
+ pahu_dmic_pin_mode_get, pahu_dmic_pin_mode_put),
+
+ SOC_ENUM_EXT("AMIC_1_2 PWR MODE", amic_pwr_lvl_enum,
+ pahu_amic_pwr_lvl_get, pahu_amic_pwr_lvl_put),
+ SOC_ENUM_EXT("AMIC_3_4 PWR MODE", amic_pwr_lvl_enum,
+ pahu_amic_pwr_lvl_get, pahu_amic_pwr_lvl_put),
+};
+
+static int pahu_dec_enum_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int val;
+ u16 mic_sel_reg = 0;
+ u8 mic_sel;
+
+ val = ucontrol->value.enumerated.item[0];
+ if (val > e->items - 1)
+ return -EINVAL;
+
+ dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
+ widget->name, val);
+
+ switch (e->reg) {
+ case WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1:
+ if (e->shift_l == 0)
+ mic_sel_reg = WCD9360_CDC_TX0_TX_PATH_CFG0;
+ else if (e->shift_l == 2)
+ mic_sel_reg = WCD9360_CDC_TX4_TX_PATH_CFG0;
+ else if (e->shift_l == 4)
+ mic_sel_reg = WCD9360_CDC_TX8_TX_PATH_CFG0;
+ break;
+ case WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1:
+ if (e->shift_l == 0)
+ mic_sel_reg = WCD9360_CDC_TX1_TX_PATH_CFG0;
+ else if (e->shift_l == 2)
+ mic_sel_reg = WCD9360_CDC_TX5_TX_PATH_CFG0;
+ break;
+ case WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1:
+ if (e->shift_l == 0)
+ mic_sel_reg = WCD9360_CDC_TX2_TX_PATH_CFG0;
+ else if (e->shift_l == 2)
+ mic_sel_reg = WCD9360_CDC_TX6_TX_PATH_CFG0;
+ break;
+ case WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1:
+ if (e->shift_l == 0)
+ mic_sel_reg = WCD9360_CDC_TX3_TX_PATH_CFG0;
+ else if (e->shift_l == 2)
+ mic_sel_reg = WCD9360_CDC_TX7_TX_PATH_CFG0;
+ break;
+ default:
+ dev_err(codec->dev, "%s: e->reg: 0x%x not expected\n",
+ __func__, e->reg);
+ return -EINVAL;
+ }
+
+ /* ADC: 0, DMIC: 1 */
+ mic_sel = val ? 0x0 : 0x1;
+ if (mic_sel_reg)
+ snd_soc_update_bits(codec, mic_sel_reg, 1 << 7, mic_sel << 7);
+
+ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+}
+
+static int pahu_int_dem_inp_mux_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_dapm_widget *widget =
+ snd_soc_dapm_kcontrol_widget(kcontrol);
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(widget->dapm);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int val;
+ unsigned short look_ahead_dly_reg = WCD9360_CDC_RX0_RX_PATH_CFG0;
+
+ val = ucontrol->value.enumerated.item[0];
+ if (val >= e->items)
+ return -EINVAL;
+
+ dev_dbg(codec->dev, "%s: wname: %s, val: 0x%x\n", __func__,
+ widget->name, val);
+
+ if (e->reg == WCD9360_CDC_RX0_RX_PATH_SEC0)
+ look_ahead_dly_reg = WCD9360_CDC_RX0_RX_PATH_CFG0;
+ else if (e->reg == WCD9360_CDC_RX9_RX_PATH_SEC0)
+ look_ahead_dly_reg = WCD9360_CDC_RX9_RX_PATH_CFG0;
+
+ /* Set Look Ahead Delay */
+ snd_soc_update_bits(codec, look_ahead_dly_reg,
+ 0x08, (val ? 0x08 : 0x00));
+ /* Set DEM INP Select */
+ return snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
+}
+
+static const char * const rx_int0_7_mix_mux_text[] = {
+ "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
+ "RX6", "RX7", "PROXIMITY", "IIR0"
+};
+
+static const char * const rx_int_mix_mux_text[] = {
+ "ZERO", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5",
+ "RX6", "RX7", "NA", "IIR0"
+};
+
+static const char * const rx_prim_mix_text[] = {
+ "ZERO", "DEC0", "DEC1", "IIR0", "INVALID", "RX0", "RX1", "RX2",
+ "RX3", "RX4", "RX5", "RX6", "RX7"
+};
+
+static const char * const rx_sidetone_mix_text[] = {
+ "ZERO", "SRC0"
+};
+
+static const char * const cdc_if_tx0_mux_text[] = {
+ "ZERO", "RX_MIX_TX0", "DEC0", "DEC0_192"
+};
+static const char * const cdc_if_tx1_mux_text[] = {
+ "ZERO", "RX_MIX_TX1", "DEC1", "DEC1_192"
+};
+static const char * const cdc_if_tx2_mux_text[] = {
+ "ZERO", "RX_MIX_TX2", "DEC2", "DEC2_192"
+};
+static const char * const cdc_if_tx3_mux_text[] = {
+ "ZERO", "RX_MIX_TX3", "DEC3", "DEC3_192"
+};
+static const char * const cdc_if_tx4_mux_text[] = {
+ "ZERO", "RX_MIX_TX4", "DEC4", "DEC4_192"
+};
+static const char * const cdc_if_tx5_mux_text[] = {
+ "ZERO", "RX_MIX_TX5", "DEC5", "DEC5_192"
+};
+static const char * const cdc_if_tx6_mux_text[] = {
+ "ZERO", "RX_MIX_TX6", "DEC6", "DEC6_192"
+};
+static const char * const cdc_if_tx7_mux_text[] = {
+ "ZERO", "RX_MIX_TX7", "DEC7", "DEC7_192"
+};
+static const char * const cdc_if_tx8_mux_text[] = {
+ "ZERO", "RX_MIX_TX8", "DEC8", "DEC8_192"
+};
+static const char * const cdc_if_tx9_mux_text[] = {
+ "ZERO", "DEC7", "DEC7_192"
+};
+static const char * const cdc_if_tx10_mux_text[] = {
+ "ZERO", "DEC6", "DEC6_192"
+};
+static const char * const cdc_if_tx10_mux2_text[] = {
+ "TX10_MUX1", "I2SRX1_0_BRDG"
+};
+static const char * const cdc_if_tx11_mux2_text[] = {
+ "TX11_MUX1", "I2SRX1_1_BRDG", "SWR_PACKED_PDM"
+};
+static const char * const cdc_if_tx11_mux_text[] = {
+ "RDMA_TX11", "DEC_0_5", "DEC_9_12", "MAD_AUDIO", "MAD_BRDCST"
+};
+static const char * const cdc_if_tx11_inp1_mux_text[] = {
+ "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4",
+ "DEC5", "RX_MIX_TX5", "DEC9_10", "DEC11_12"
+};
+static const char * const cdc_if_tx13_mux_text[] = {
+ "CDC_DEC_5", "MAD_BRDCST"
+};
+static const char * const cdc_if_tx13_inp1_mux_text[] = {
+ "ZERO", "DEC5", "DEC5_192"
+};
+
+static const char * const iir_inp_mux_text[] = {
+ "ZERO", "DEC0", "DEC1", "DEC2", "DEC3", "DEC4", "DEC5", "DEC6",
+ "DEC7", "DEC8", "RX0", "RX1", "RX2", "RX3", "RX4", "RX5", "RX6", "RX7"
+};
+
+static const char * const rx_int_dem_inp_mux_text[] = {
+ "NORMAL_DSM_OUT", "NOT_VALID", "ADC_LOOPBACK"
+};
+
+static const char * const rx_int0_1_interp_mux_text[] = {
+ "ZERO", "RX INT0_1 MIX1",
+};
+
+static const char * const rx_int7_1_interp_mux_text[] = {
+ "ZERO", "RX INT7_1 MIX1",
+};
+
+static const char * const rx_int8_1_interp_mux_text[] = {
+ "ZERO", "RX INT8_1 MIX1",
+};
+
+static const char * const rx_int9_1_interp_mux_text[] = {
+ "ZERO", "RX INT9_1 MIX1",
+};
+
+static const char * const rx_int0_2_interp_mux_text[] = {
+ "ZERO", "RX INT0_2 MUX",
+};
+
+static const char * const rx_int7_2_interp_mux_text[] = {
+ "ZERO", "RX INT7_2 MUX",
+};
+
+static const char * const rx_int8_2_interp_mux_text[] = {
+ "ZERO", "RX INT8_2 MUX",
+};
+
+static const char * const rx_int9_2_interp_mux_text[] = {
+ "ZERO", "RX INT9_2 MUX",
+};
+
+static const char * const mad_sel_txt[] = {
+ "SPE", "MSM"
+};
+
+static const char * const mad_inp_mux_txt[] = {
+ "MAD", "DEC1"
+};
+
+static const char * const adc_mux_text[] = {
+ "DMIC", "AMIC", "ANC_FB_TUNE1"
+};
+
+static const char * const dmic_mux_text[] = {
+ "ZERO", "DMIC0", "DMIC1", "DMIC2", "DMIC3", "DMIC4", "DMIC5",
+ "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "NA", "DMIC6",
+ "DMIC7"
+};
+
+static const char * const amic_mux_text[] = {
+ "ZERO", "ADC1", "ADC2", "ADC3", "ADC4"
+};
+
+static const char * const adc2_in_text[] = {
+ "AMIC2", "AMIC1"
+};
+
+static const char * const adc4_in_text[] = {
+ "AMIC4", "AMIC3"
+};
+
+static const char * const anc0_fb_mux_text[] = {
+ "ZERO", "INVALID", "ANC_IN_EAR", "ANC_IN_EAR_SPKR",
+};
+
+static const char * const rx_echo_mux_text[] = {
+ "ZERO", "RX_MIX0", "NA", "NA", "NA", "NA", "NA", "NA",
+ "RX_MIX7", "RX_MIX8", "NA", "NA", "NA", "NA", "RX_MIX9"
+};
+
+static const char *const slim_rx_mux_text[] = {
+ "ZERO", "AIF1_PB", "AIF2_PB", "AIF3_PB", "AIF4_PB"
+};
+
+static const char *const cdc_if_rx0_mux_text[] = {
+ "SLIM RX0", "I2S RX0"
+};
+static const char *const cdc_if_rx1_mux_text[] = {
+ "SLIM RX1", "I2S RX1"
+};
+static const char *const cdc_if_rx2_mux_text[] = {
+ "SLIM RX2", "I2SRX1_0", "I2SRX0_2"
+};
+static const char *const cdc_if_rx3_mux_text[] = {
+ "SLIM RX3", "I2SRX1_1", "I2SRX0_3"
+};
+static const char *const cdc_if_rx4_mux_text[] = {
+ "SLIM RX4", "I2S RX4"
+};
+static const char *const cdc_if_rx5_mux_text[] = {
+ "SLIM RX5", "I2S RX5"
+};
+static const char *const cdc_if_rx6_mux_text[] = {
+ "SLIM RX6", "I2S RX6"
+};
+static const char *const cdc_if_rx7_mux_text[] = {
+ "SLIM RX7", "I2S RX7"
+};
+
+static const char * const asrc2_mux_text[] = {
+ "ZERO", "ASRC_IN_SPKR1",
+};
+
+static const char * const asrc3_mux_text[] = {
+ "ZERO", "ASRC_IN_SPKR2",
+};
+
+static const char * const native_mux_text[] = {
+ "OFF", "ON",
+};
+
+static const char *const wdma3_port0_text[] = {
+ "RX_MIX_TX0", "DEC0"
+};
+
+static const char *const wdma3_port1_text[] = {
+ "RX_MIX_TX1", "DEC1"
+};
+
+static const char *const wdma3_port2_text[] = {
+ "RX_MIX_TX2", "DEC2"
+};
+
+static const char *const wdma3_port3_text[] = {
+ "RX_MIX_TX3", "DEC3"
+};
+
+static const char *const wdma3_port4_text[] = {
+ "RX_MIX_TX4", "DEC4"
+};
+
+static const char *const wdma3_port5_text[] = {
+ "RX_MIX_TX5", "DEC5"
+};
+
+static const char *const wdma3_port6_text[] = {
+ "RX_MIX_TX6", "DEC6"
+};
+
+static const char *const wdma3_ch_text[] = {
+ "PORT_0", "PORT_1", "PORT_2", "PORT_3", "PORT_4",
+ "PORT_5", "PORT_6", "PORT_7", "PORT_8",
+};
+
+static const struct snd_kcontrol_new aif4_vi_mixer[] = {
+ SOC_SINGLE_EXT("SPKR_VI_1", SND_SOC_NOPM, WCD9360_TX14, 1, 0,
+ pahu_vi_feed_mixer_get, pahu_vi_feed_mixer_put),
+ SOC_SINGLE_EXT("SPKR_VI_2", SND_SOC_NOPM, WCD9360_TX15, 1, 0,
+ pahu_vi_feed_mixer_get, pahu_vi_feed_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif1_cap_mixer[] = {
+ SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif2_cap_mixer[] = {
+ SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif3_cap_mixer[] = {
+ SOC_SINGLE_EXT("SLIM TX0", SND_SOC_NOPM, WCD9360_TX0, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX1", SND_SOC_NOPM, WCD9360_TX1, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX2", SND_SOC_NOPM, WCD9360_TX2, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX3", SND_SOC_NOPM, WCD9360_TX3, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX4", SND_SOC_NOPM, WCD9360_TX4, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX5", SND_SOC_NOPM, WCD9360_TX5, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX6", SND_SOC_NOPM, WCD9360_TX6, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX7", SND_SOC_NOPM, WCD9360_TX7, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX8", SND_SOC_NOPM, WCD9360_TX8, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX9", SND_SOC_NOPM, WCD9360_TX9, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX10", SND_SOC_NOPM, WCD9360_TX10, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX11", SND_SOC_NOPM, WCD9360_TX11, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+ SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new aif4_mad_mixer[] = {
+ SOC_SINGLE_EXT("SLIM TX13", SND_SOC_NOPM, WCD9360_TX13, 1, 0,
+ slim_tx_mixer_get, slim_tx_mixer_put),
+};
+
+WCD_DAPM_ENUM_EXT(slim_rx0, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx1, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx2, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx3, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx4, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx5, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx6, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+WCD_DAPM_ENUM_EXT(slim_rx7, SND_SOC_NOPM, 0, slim_rx_mux_text,
+ slim_rx_mux_get, slim_rx_mux_put);
+
+WCD_DAPM_ENUM(cdc_if_rx0, SND_SOC_NOPM, 0, cdc_if_rx0_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx1, SND_SOC_NOPM, 0, cdc_if_rx1_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx2, SND_SOC_NOPM, 0, cdc_if_rx2_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx3, SND_SOC_NOPM, 0, cdc_if_rx3_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx4, SND_SOC_NOPM, 0, cdc_if_rx4_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx5, SND_SOC_NOPM, 0, cdc_if_rx5_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx6, SND_SOC_NOPM, 0, cdc_if_rx6_mux_text);
+WCD_DAPM_ENUM(cdc_if_rx7, SND_SOC_NOPM, 0, cdc_if_rx7_mux_text);
+
+WCD_DAPM_ENUM(rx_int0_2, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
+ rx_int0_7_mix_mux_text);
+WCD_DAPM_ENUM(rx_int7_2, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 0,
+ rx_int0_7_mix_mux_text);
+WCD_DAPM_ENUM(rx_int8_2, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 0,
+ rx_int_mix_mux_text);
+WCD_DAPM_ENUM(rx_int9_2, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 0,
+ rx_int0_7_mix_mux_text);
+
+WCD_DAPM_ENUM(rx_int0_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 0,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int0_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int0_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int7_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 0,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int7_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int7_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int8_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 0,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int8_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int8_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int9_1_mix_inp0, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 0,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int9_1_mix_inp1, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0, 4,
+ rx_prim_mix_text);
+WCD_DAPM_ENUM(rx_int9_1_mix_inp2, WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1, 4,
+ rx_prim_mix_text);
+
+WCD_DAPM_ENUM(rx_int0_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0,
+ rx_sidetone_mix_text);
+WCD_DAPM_ENUM(rx_int7_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 2,
+ rx_sidetone_mix_text);
+WCD_DAPM_ENUM(rx_int9_mix2_inp, WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1, 4,
+ rx_sidetone_mix_text);
+
+WCD_DAPM_ENUM(tx_adc_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 4,
+ adc_mux_text);
+WCD_DAPM_ENUM(tx_adc_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 4,
+ adc_mux_text);
+
+WCD_DAPM_ENUM(tx_dmic_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 3,
+ dmic_mux_text);
+WCD_DAPM_ENUM(tx_dmic_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 3,
+ dmic_mux_text);
+
+WCD_DAPM_ENUM(tx_amic_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux10, WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0, 0,
+ amic_mux_text);
+WCD_DAPM_ENUM(tx_amic_mux11, WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0, 0,
+ amic_mux_text);
+
+WCD_DAPM_ENUM(tx_adc2_in, WCD9360_ANA_AMIC_INPUT_SWITCH_CTL, 7, adc2_in_text);
+WCD_DAPM_ENUM(tx_adc4_in, WCD9360_ANA_AMIC_INPUT_SWITCH_CTL, 6, adc4_in_text);
+
+WCD_DAPM_ENUM(cdc_if_tx0, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 0,
+ cdc_if_tx0_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 2,
+ cdc_if_tx1_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx2, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 4,
+ cdc_if_tx2_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx3, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0, 6,
+ cdc_if_tx3_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx4, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 0,
+ cdc_if_tx4_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx5, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 2,
+ cdc_if_tx5_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx6, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 4,
+ cdc_if_tx6_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx7, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1, 6,
+ cdc_if_tx7_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx8, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 0,
+ cdc_if_tx8_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx9, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 2,
+ cdc_if_tx9_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx10, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2, 4,
+ cdc_if_tx10_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx10_inp2, WCD9360_DATA_HUB_SB_TX10_INP_CFG, 3,
+ cdc_if_tx10_mux2_text);
+WCD_DAPM_ENUM(cdc_if_tx11_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 0,
+ cdc_if_tx11_inp1_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx11, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0,
+ cdc_if_tx11_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx11_inp2, WCD9360_DATA_HUB_SB_TX11_INP_CFG, 3,
+ cdc_if_tx11_mux2_text);
+WCD_DAPM_ENUM(cdc_if_tx13_inp1, WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3, 4,
+ cdc_if_tx13_inp1_mux_text);
+WCD_DAPM_ENUM(cdc_if_tx13, WCD9360_DATA_HUB_SB_TX13_INP_CFG, 0,
+ cdc_if_tx13_mux_text);
+
+WCD_DAPM_ENUM(rx_mix_tx0, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 0,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx1, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0, 4,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx2, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 0,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx3, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1, 4,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx4, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 0,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx5, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2, 4,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx6, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 0,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx7, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3, 4,
+ rx_echo_mux_text);
+WCD_DAPM_ENUM(rx_mix_tx8, WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4, 0,
+ rx_echo_mux_text);
+
+WCD_DAPM_ENUM(iir0_inp0, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0, 0,
+ iir_inp_mux_text);
+WCD_DAPM_ENUM(iir0_inp1, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1, 0,
+ iir_inp_mux_text);
+WCD_DAPM_ENUM(iir0_inp2, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2, 0,
+ iir_inp_mux_text);
+WCD_DAPM_ENUM(iir0_inp3, WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3, 0,
+ iir_inp_mux_text);
+
+WCD_DAPM_ENUM(rx_int0_1_interp, SND_SOC_NOPM, 0, rx_int0_1_interp_mux_text);
+WCD_DAPM_ENUM(rx_int7_1_interp, SND_SOC_NOPM, 0, rx_int7_1_interp_mux_text);
+WCD_DAPM_ENUM(rx_int8_1_interp, SND_SOC_NOPM, 0, rx_int8_1_interp_mux_text);
+WCD_DAPM_ENUM(rx_int9_1_interp, SND_SOC_NOPM, 0, rx_int9_1_interp_mux_text);
+
+WCD_DAPM_ENUM(rx_int0_2_interp, SND_SOC_NOPM, 0, rx_int0_2_interp_mux_text);
+WCD_DAPM_ENUM(rx_int7_2_interp, SND_SOC_NOPM, 0, rx_int7_2_interp_mux_text);
+WCD_DAPM_ENUM(rx_int8_2_interp, SND_SOC_NOPM, 0, rx_int8_2_interp_mux_text);
+WCD_DAPM_ENUM(rx_int9_2_interp, SND_SOC_NOPM, 0, rx_int9_2_interp_mux_text);
+
+WCD_DAPM_ENUM(mad_sel, WCD9360_CPE_SS_SVA_CFG, 0,
+ mad_sel_txt);
+
+WCD_DAPM_ENUM(mad_inp_mux, WCD9360_CPE_SS_SVA_CFG, 2,
+ mad_inp_mux_txt);
+
+WCD_DAPM_ENUM_EXT(rx_int0_dem_inp, WCD9360_CDC_RX0_RX_PATH_SEC0, 0,
+ rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
+ pahu_int_dem_inp_mux_put);
+
+WCD_DAPM_ENUM_EXT(rx_int9_dem_inp, WCD9360_CDC_RX9_RX_PATH_SEC0, 0,
+ rx_int_dem_inp_mux_text, snd_soc_dapm_get_enum_double,
+ pahu_int_dem_inp_mux_put);
+
+WCD_DAPM_ENUM_EXT(tx_adc_mux0, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux1, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux2, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux3, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux4, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 2,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux5, WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 2,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux6, WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 2,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux7, WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 2,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+WCD_DAPM_ENUM_EXT(tx_adc_mux8, WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 4,
+ adc_mux_text, snd_soc_dapm_get_enum_double, pahu_dec_enum_put);
+
+WCD_DAPM_ENUM(asrc2, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 4,
+ asrc2_mux_text);
+WCD_DAPM_ENUM(asrc3, WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0, 6,
+ asrc3_mux_text);
+
+WCD_DAPM_ENUM(int7_2_native, SND_SOC_NOPM, 0, native_mux_text);
+WCD_DAPM_ENUM(int8_2_native, SND_SOC_NOPM, 0, native_mux_text);
+
+WCD_DAPM_ENUM(anc0_fb, WCD9360_CDC_RX_INP_MUX_ANC_CFG0, 0, anc0_fb_mux_text);
+
+WCD_DAPM_ENUM(wdma3_port0, WCD9360_DMA_WDMA3_PRT_CFG, 0, wdma3_port0_text);
+WCD_DAPM_ENUM(wdma3_port1, WCD9360_DMA_WDMA3_PRT_CFG, 1, wdma3_port1_text);
+WCD_DAPM_ENUM(wdma3_port2, WCD9360_DMA_WDMA3_PRT_CFG, 2, wdma3_port2_text);
+WCD_DAPM_ENUM(wdma3_port3, WCD9360_DMA_WDMA3_PRT_CFG, 3, wdma3_port3_text);
+WCD_DAPM_ENUM(wdma3_port4, WCD9360_DMA_WDMA3_PRT_CFG, 4, wdma3_port4_text);
+WCD_DAPM_ENUM(wdma3_port5, WCD9360_DMA_WDMA3_PRT_CFG, 5, wdma3_port5_text);
+WCD_DAPM_ENUM(wdma3_port6, WCD9360_DMA_WDMA3_PRT_CFG, 6, wdma3_port6_text);
+
+WCD_DAPM_ENUM(wdma3_ch0, WCD9360_DMA_CH_0_1_CFG_WDMA_3, 0, wdma3_ch_text);
+WCD_DAPM_ENUM(wdma3_ch1, WCD9360_DMA_CH_0_1_CFG_WDMA_3, 4, wdma3_ch_text);
+WCD_DAPM_ENUM(wdma3_ch2, WCD9360_DMA_CH_2_3_CFG_WDMA_3, 0, wdma3_ch_text);
+WCD_DAPM_ENUM(wdma3_ch3, WCD9360_DMA_CH_2_3_CFG_WDMA_3, 4, wdma3_ch_text);
+
+static const struct snd_kcontrol_new anc_ear_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new anc_ear_spkr_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new anc_spkr_pa_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new mad_cpe1_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new mad_cpe2_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new mad_brdcst_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux0_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux1_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux2_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux3_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux4_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux5_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux6_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux7_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new adc_us_mux8_switch =
+ SOC_DAPM_SINGLE("US_Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const struct snd_kcontrol_new wdma3_onoff_switch =
+ SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0);
+
+static const char *const i2s_tx1_0_txt[] = {
+ "ZERO", "SB_TX8", "SB_RX2", "SB_TX12"
+};
+
+static const char *const i2s_tx1_1_txt[] = {
+ "ZERO", "SB_RX0", "SB_RX1", "SB_RX2", "SB_RX3", "SB_TX11"
+};
+
+WCD_DAPM_ENUM(i2s_tx1_0_inp, WCD9360_DATA_HUB_I2S_TX1_0_CFG, 0, i2s_tx1_0_txt);
+WCD_DAPM_ENUM(i2s_tx1_1_inp, WCD9360_DATA_HUB_I2S_TX1_1_CFG, 0, i2s_tx1_1_txt);
+
+static const struct snd_soc_dapm_widget pahu_dapm_widgets[] = {
+ SND_SOC_DAPM_AIF_IN_E("AIF1 PB", "AIF1 Playback", 0, SND_SOC_NOPM,
+ AIF1_PB, 0, pahu_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("AIF2 PB", "AIF2 Playback", 0, SND_SOC_NOPM,
+ AIF2_PB, 0, pahu_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("AIF3 PB", "AIF3 Playback", 0, SND_SOC_NOPM,
+ AIF3_PB, 0, pahu_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("AIF4 PB", "AIF4 Playback", 0, SND_SOC_NOPM,
+ AIF4_PB, 0, pahu_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_IN_E("I2S1 PB", "I2S1 Playback", 0, SND_SOC_NOPM,
+ I2S1_PB, 0, pahu_i2s_aif_rx_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("SLIM RX0 MUX", WCD9360_RX0, slim_rx0),
+ WCD_DAPM_MUX("SLIM RX1 MUX", WCD9360_RX1, slim_rx1),
+ WCD_DAPM_MUX("SLIM RX2 MUX", WCD9360_RX2, slim_rx2),
+ WCD_DAPM_MUX("SLIM RX3 MUX", WCD9360_RX3, slim_rx3),
+ WCD_DAPM_MUX("SLIM RX4 MUX", WCD9360_RX4, slim_rx4),
+ WCD_DAPM_MUX("SLIM RX5 MUX", WCD9360_RX5, slim_rx5),
+ WCD_DAPM_MUX("SLIM RX6 MUX", WCD9360_RX6, slim_rx6),
+ WCD_DAPM_MUX("SLIM RX7 MUX", WCD9360_RX7, slim_rx7),
+
+ SND_SOC_DAPM_MIXER("SLIM RX0", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX6", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM RX7", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ WCD_DAPM_MUX("CDC_IF RX0 MUX", WCD9360_RX0, cdc_if_rx0),
+ WCD_DAPM_MUX("CDC_IF RX1 MUX", WCD9360_RX1, cdc_if_rx1),
+ WCD_DAPM_MUX("CDC_IF RX2 MUX", WCD9360_RX2, cdc_if_rx2),
+ WCD_DAPM_MUX("CDC_IF RX3 MUX", WCD9360_RX3, cdc_if_rx3),
+ WCD_DAPM_MUX("CDC_IF RX4 MUX", WCD9360_RX4, cdc_if_rx4),
+ WCD_DAPM_MUX("CDC_IF RX5 MUX", WCD9360_RX5, cdc_if_rx5),
+ WCD_DAPM_MUX("CDC_IF RX6 MUX", WCD9360_RX6, cdc_if_rx6),
+ WCD_DAPM_MUX("CDC_IF RX7 MUX", WCD9360_RX7, cdc_if_rx7),
+
+ SND_SOC_DAPM_MUX_E("RX INT0_2 MUX", SND_SOC_NOPM, INTERP_EAR, 0,
+ &rx_int0_2_mux, pahu_codec_enable_mix_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT7_2 MUX", SND_SOC_NOPM, INTERP_SPKR1, 0,
+ &rx_int7_2_mux, pahu_codec_enable_mix_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT8_2 MUX", SND_SOC_NOPM, INTERP_SPKR2, 0,
+ &rx_int8_2_mux, pahu_codec_enable_mix_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT9_2 MUX", SND_SOC_NOPM, INTERP_AUX, 0,
+ &rx_int9_2_mux, pahu_codec_enable_mix_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("RX INT0_1 MIX1 INP0", 0, rx_int0_1_mix_inp0),
+ WCD_DAPM_MUX("RX INT0_1 MIX1 INP1", 0, rx_int0_1_mix_inp1),
+ WCD_DAPM_MUX("RX INT0_1 MIX1 INP2", 0, rx_int0_1_mix_inp2),
+
+ SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
+ &rx_int7_1_mix_inp0_mux, pahu_codec_enable_swr,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx_int7_1_mix_inp1_mux, pahu_codec_enable_swr,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT7_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx_int7_1_mix_inp2_mux, pahu_codec_enable_swr,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP0", SND_SOC_NOPM, 0, 0,
+ &rx_int8_1_mix_inp0_mux, pahu_codec_enable_swr,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP1", SND_SOC_NOPM, 0, 0,
+ &rx_int8_1_mix_inp1_mux, pahu_codec_enable_swr,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT8_1 MIX1 INP2", SND_SOC_NOPM, 0, 0,
+ &rx_int8_1_mix_inp2_mux, pahu_codec_enable_swr,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("RX INT9_1 MIX1 INP0", 0, rx_int9_1_mix_inp0),
+ WCD_DAPM_MUX("RX INT9_1 MIX1 INP1", 0, rx_int9_1_mix_inp1),
+ WCD_DAPM_MUX("RX INT9_1 MIX1 INP2", 0, rx_int9_1_mix_inp2),
+
+ SND_SOC_DAPM_MIXER("RX INT0_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT0 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT7_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT7 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT8_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT8 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT9_1 MIX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT9 SEC MIX", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("RX INT0 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT7 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("RX INT9 MIX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER_E("RX INT7 CHAIN", SND_SOC_NOPM, 0, 0,
+ NULL, 0, pahu_codec_spk_boost_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MIXER_E("RX INT8 CHAIN", SND_SOC_NOPM, 0, 0,
+ NULL, 0, pahu_codec_spk_boost_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("RX INT0 MIX2 INP", SND_SOC_NOPM, INTERP_EAR,
+ 0, &rx_int0_mix2_inp_mux, pahu_codec_enable_rx_path_clk,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT7 MIX2 INP", SND_SOC_NOPM, INTERP_SPKR1,
+ 0, &rx_int7_mix2_inp_mux, pahu_codec_enable_rx_path_clk,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT9 MIX2 INP", SND_SOC_NOPM, INTERP_AUX,
+ 0, &rx_int9_mix2_inp_mux, pahu_codec_enable_rx_path_clk,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("CDC_IF TX0 MUX", WCD9360_TX0, cdc_if_tx0),
+ WCD_DAPM_MUX("CDC_IF TX1 MUX", WCD9360_TX1, cdc_if_tx1),
+ WCD_DAPM_MUX("CDC_IF TX2 MUX", WCD9360_TX2, cdc_if_tx2),
+ WCD_DAPM_MUX("CDC_IF TX3 MUX", WCD9360_TX3, cdc_if_tx3),
+ WCD_DAPM_MUX("CDC_IF TX4 MUX", WCD9360_TX4, cdc_if_tx4),
+ WCD_DAPM_MUX("CDC_IF TX5 MUX", WCD9360_TX5, cdc_if_tx5),
+ WCD_DAPM_MUX("CDC_IF TX6 MUX", WCD9360_TX6, cdc_if_tx6),
+ WCD_DAPM_MUX("CDC_IF TX7 MUX", WCD9360_TX7, cdc_if_tx7),
+ WCD_DAPM_MUX("CDC_IF TX8 MUX", WCD9360_TX8, cdc_if_tx8),
+ WCD_DAPM_MUX("CDC_IF TX9 MUX", WCD9360_TX9, cdc_if_tx9),
+ WCD_DAPM_MUX("CDC_IF TX10 MUX", WCD9360_TX10, cdc_if_tx10),
+ WCD_DAPM_MUX("CDC_IF TX11 MUX", WCD9360_TX11, cdc_if_tx11),
+ WCD_DAPM_MUX("CDC_IF TX11 INP1 MUX", WCD9360_TX11, cdc_if_tx11_inp1),
+ WCD_DAPM_MUX("CDC_IF TX13 MUX", WCD9360_TX13, cdc_if_tx13),
+ WCD_DAPM_MUX("CDC_IF TX13 INP1 MUX", WCD9360_TX13, cdc_if_tx13_inp1),
+ WCD_DAPM_MUX("CDC_IF TX10 MUX2", WCD9360_TX10, cdc_if_tx10_inp2),
+ WCD_DAPM_MUX("CDC_IF TX11 MUX2", WCD9360_TX11, cdc_if_tx11_inp2),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX0", WCD9360_CDC_TX0_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux0_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX1", WCD9360_CDC_TX1_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux1_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX2", WCD9360_CDC_TX2_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux2_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX3", WCD9360_CDC_TX3_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux3_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX4", WCD9360_CDC_TX4_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux4_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX5", WCD9360_CDC_TX5_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux5_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX6", WCD9360_CDC_TX6_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux6_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX7", WCD9360_CDC_TX7_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux7_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX8", WCD9360_CDC_TX8_TX_PATH_CTL, 5, 0,
+ &tx_adc_mux8_mux, pahu_codec_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX10", SND_SOC_NOPM, 10, 0, &tx_adc_mux10_mux,
+ pahu_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU),
+
+ SND_SOC_DAPM_MUX_E("ADC MUX11", SND_SOC_NOPM, 11, 0, &tx_adc_mux11_mux,
+ pahu_codec_tx_adc_cfg, SND_SOC_DAPM_POST_PMU),
+
+ WCD_DAPM_MUX("DMIC MUX0", 0, tx_dmic_mux0),
+ WCD_DAPM_MUX("DMIC MUX1", 0, tx_dmic_mux1),
+ WCD_DAPM_MUX("DMIC MUX2", 0, tx_dmic_mux2),
+ WCD_DAPM_MUX("DMIC MUX3", 0, tx_dmic_mux3),
+ WCD_DAPM_MUX("DMIC MUX4", 0, tx_dmic_mux4),
+ WCD_DAPM_MUX("DMIC MUX5", 0, tx_dmic_mux5),
+ WCD_DAPM_MUX("DMIC MUX6", 0, tx_dmic_mux6),
+ WCD_DAPM_MUX("DMIC MUX7", 0, tx_dmic_mux7),
+ WCD_DAPM_MUX("DMIC MUX8", 0, tx_dmic_mux8),
+ WCD_DAPM_MUX("DMIC MUX10", 0, tx_dmic_mux10),
+ WCD_DAPM_MUX("DMIC MUX11", 0, tx_dmic_mux11),
+
+ WCD_DAPM_MUX("AMIC MUX0", 0, tx_amic_mux0),
+ WCD_DAPM_MUX("AMIC MUX1", 0, tx_amic_mux1),
+ WCD_DAPM_MUX("AMIC MUX2", 0, tx_amic_mux2),
+ WCD_DAPM_MUX("AMIC MUX3", 0, tx_amic_mux3),
+ WCD_DAPM_MUX("AMIC MUX4", 0, tx_amic_mux4),
+ WCD_DAPM_MUX("AMIC MUX5", 0, tx_amic_mux5),
+ WCD_DAPM_MUX("AMIC MUX6", 0, tx_amic_mux6),
+ WCD_DAPM_MUX("AMIC MUX7", 0, tx_amic_mux7),
+ WCD_DAPM_MUX("AMIC MUX8", 0, tx_amic_mux8),
+ WCD_DAPM_MUX("AMIC MUX10", 0, tx_amic_mux10),
+ WCD_DAPM_MUX("AMIC MUX11", 0, tx_amic_mux11),
+
+ SND_SOC_DAPM_ADC_E("ADC1", NULL, WCD9360_ANA_AMIC1, 7, 0,
+ pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_ADC_E("ADC2", NULL, WCD9360_ANA_AMIC2, 7, 0,
+ pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_ADC_E("ADC3", NULL, WCD9360_ANA_AMIC3, 7, 0,
+ pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+ SND_SOC_DAPM_ADC_E("ADC4", NULL, WCD9360_ANA_AMIC4, 7, 0,
+ pahu_codec_enable_adc, SND_SOC_DAPM_PRE_PMU),
+
+ WCD_DAPM_MUX("ANC0 FB MUX", 0, anc0_fb),
+
+ WCD_DAPM_MUX("ADC2_IN", 0, tx_adc2_in),
+ WCD_DAPM_MUX("ADC4_IN", 0, tx_adc4_in),
+
+ SND_SOC_DAPM_INPUT("AMIC1"),
+ SND_SOC_DAPM_INPUT("AMIC2"),
+ SND_SOC_DAPM_INPUT("AMIC3"),
+ SND_SOC_DAPM_INPUT("AMIC4"),
+
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS1", SND_SOC_NOPM, 0, 0,
+ pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS2", SND_SOC_NOPM, 0, 0,
+ pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS3", SND_SOC_NOPM, 0, 0,
+ pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E("MIC BIAS4", SND_SOC_NOPM, 0, 0,
+ pahu_codec_enable_micbias, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS1_STANDALONE, SND_SOC_NOPM, 0, 0,
+ pahu_codec_force_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS2_STANDALONE, SND_SOC_NOPM, 0, 0,
+ pahu_codec_force_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS3_STANDALONE, SND_SOC_NOPM, 0, 0,
+ pahu_codec_force_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MICBIAS_E(DAPM_MICBIAS4_STANDALONE, SND_SOC_NOPM, 0, 0,
+ pahu_codec_force_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_OUT_E("AIF1 CAP", "AIF1 Capture", 0, SND_SOC_NOPM,
+ AIF1_CAP, 0, pahu_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_OUT_E("AIF2 CAP", "AIF2 Capture", 0, SND_SOC_NOPM,
+ AIF2_CAP, 0, pahu_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_OUT_E("AIF3 CAP", "AIF3 Capture", 0, SND_SOC_NOPM,
+ AIF3_CAP, 0, pahu_codec_enable_slimtx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("I2S TX1_0 MUX", 0, i2s_tx1_0_inp),
+ WCD_DAPM_MUX("I2S TX1_1 MUX", 0, i2s_tx1_1_inp),
+ SND_SOC_DAPM_MIXER("I2S TX1 MIXER", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_AIF_OUT_E("I2S1 CAP", "I2S1 Capture", 0,
+ SND_SOC_NOPM, I2S1_CAP, 0, pahu_i2s_aif_tx_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD |
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIXER("AIF1_CAP Mixer", SND_SOC_NOPM, AIF1_CAP, 0,
+ aif1_cap_mixer, ARRAY_SIZE(aif1_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF2_CAP Mixer", SND_SOC_NOPM, AIF2_CAP, 0,
+ aif2_cap_mixer, ARRAY_SIZE(aif2_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF3_CAP Mixer", SND_SOC_NOPM, AIF3_CAP, 0,
+ aif3_cap_mixer, ARRAY_SIZE(aif3_cap_mixer)),
+ SND_SOC_DAPM_MIXER("AIF4_MAD Mixer", SND_SOC_NOPM, AIF4_MAD_TX, 0,
+ aif4_mad_mixer, ARRAY_SIZE(aif4_mad_mixer)),
+
+ SND_SOC_DAPM_AIF_OUT_E("AIF4 VI", "VIfeed", 0, SND_SOC_NOPM,
+ AIF4_VIFEED, 0, pahu_codec_enable_slimvi_feedback,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_AIF_OUT("AIF4 MAD", "AIF4 MAD TX", 0,
+ SND_SOC_NOPM, 0, 0),
+
+ SND_SOC_DAPM_MIXER("AIF4_VI Mixer", SND_SOC_NOPM, AIF4_VIFEED, 0,
+ aif4_vi_mixer, ARRAY_SIZE(aif4_vi_mixer)),
+ SND_SOC_DAPM_INPUT("VIINPUT"),
+
+ SND_SOC_DAPM_MIXER("SLIM TX0", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX1", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX2", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX3", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX4", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX5", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX6", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX7", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX8", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX9", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX10", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX11", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("SLIM TX13", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* Digital Mic Inputs */
+ SND_SOC_DAPM_ADC_E("DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC1", NULL, SND_SOC_NOPM, 1, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC2", NULL, SND_SOC_NOPM, 2, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC3", NULL, SND_SOC_NOPM, 3, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC4", NULL, SND_SOC_NOPM, 4, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC5", NULL, SND_SOC_NOPM, 5, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC6", NULL, SND_SOC_NOPM, 6, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("DMIC7", NULL, SND_SOC_NOPM, 7, 0,
+ pahu_codec_enable_dmic,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("IIR0 INP0 MUX", 0, iir0_inp0),
+ WCD_DAPM_MUX("IIR0 INP1 MUX", 0, iir0_inp1),
+ WCD_DAPM_MUX("IIR0 INP2 MUX", 0, iir0_inp2),
+ WCD_DAPM_MUX("IIR0 INP3 MUX", 0, iir0_inp3),
+
+ SND_SOC_DAPM_MIXER_E("IIR0", WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL,
+ 4, 0, NULL, 0, pahu_codec_set_iir_gain,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_MIXER("SRC0", WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL,
+ 4, 0, NULL, 0),
+
+ WCD_DAPM_MUX("RX MIX TX0 MUX", 0, rx_mix_tx0),
+ WCD_DAPM_MUX("RX MIX TX1 MUX", 0, rx_mix_tx1),
+ WCD_DAPM_MUX("RX MIX TX2 MUX", 0, rx_mix_tx2),
+ WCD_DAPM_MUX("RX MIX TX3 MUX", 0, rx_mix_tx3),
+ WCD_DAPM_MUX("RX MIX TX4 MUX", 0, rx_mix_tx4),
+ WCD_DAPM_MUX("RX MIX TX5 MUX", 0, rx_mix_tx5),
+ WCD_DAPM_MUX("RX MIX TX6 MUX", 0, rx_mix_tx6),
+ WCD_DAPM_MUX("RX MIX TX7 MUX", 0, rx_mix_tx7),
+ WCD_DAPM_MUX("RX MIX TX8 MUX", 0, rx_mix_tx8),
+ WCD_DAPM_MUX("RX INT0 DEM MUX", 0, rx_int0_dem_inp),
+ WCD_DAPM_MUX("RX INT9 DEM MUX", 0, rx_int9_dem_inp),
+
+ SND_SOC_DAPM_MUX_E("RX INT0_1 INTERP", SND_SOC_NOPM, INTERP_EAR, 0,
+ &rx_int0_1_interp_mux, pahu_codec_enable_main_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT7_1 INTERP", SND_SOC_NOPM, INTERP_SPKR1, 0,
+ &rx_int7_1_interp_mux, pahu_codec_enable_main_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT8_1 INTERP", SND_SOC_NOPM, INTERP_SPKR2, 0,
+ &rx_int8_1_interp_mux, pahu_codec_enable_main_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("RX INT9_1 INTERP", SND_SOC_NOPM, INTERP_AUX, 0,
+ &rx_int9_1_interp_mux, pahu_codec_enable_main_path,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ WCD_DAPM_MUX("RX INT0_2 INTERP", 0, rx_int0_2_interp),
+ WCD_DAPM_MUX("RX INT7_2 INTERP", 0, rx_int7_2_interp),
+ WCD_DAPM_MUX("RX INT8_2 INTERP", 0, rx_int8_2_interp),
+ WCD_DAPM_MUX("RX INT9_2 INTERP", 0, rx_int9_2_interp),
+
+ SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9360_CDC_TX0_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux0_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX1", WCD9360_CDC_TX1_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux1_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX2", WCD9360_CDC_TX2_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux2_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX3", WCD9360_CDC_TX3_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux3_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX4", WCD9360_CDC_TX4_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux4_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX5", WCD9360_CDC_TX5_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux5_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX6", WCD9360_CDC_TX6_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux6_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX7", WCD9360_CDC_TX7_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux7_switch),
+ SND_SOC_DAPM_SWITCH("ADC US MUX8", WCD9360_CDC_TX8_TX_PATH_192_CTL, 0,
+ 0, &adc_us_mux8_switch),
+
+ /* MAD related widgets */
+ SND_SOC_DAPM_INPUT("MAD_CPE_INPUT"),
+ SND_SOC_DAPM_INPUT("MADINPUT"),
+
+ WCD_DAPM_MUX("MAD_SEL MUX", 0, mad_sel),
+ WCD_DAPM_MUX("MAD_INP MUX", 0, mad_inp_mux),
+
+ SND_SOC_DAPM_SWITCH_E("MAD_BROADCAST", SND_SOC_NOPM, 0, 0,
+ &mad_brdcst_switch, pahu_codec_ape_enable_mad,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_SWITCH_E("MAD_CPE1", SND_SOC_NOPM, 0, 0,
+ &mad_cpe1_switch, pahu_codec_cpe_mad_ctl,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SWITCH_E("MAD_CPE2", SND_SOC_NOPM, 0, 0,
+ &mad_cpe2_switch, pahu_codec_cpe_mad_ctl,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT1"),
+ SND_SOC_DAPM_OUTPUT("MAD_CPE_OUT2"),
+
+ SND_SOC_DAPM_DAC_E("RX INT0 DAC", NULL, SND_SOC_NOPM,
+ 0, 0, pahu_codec_ear_dac_event, SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_PGA_E("EAR PA", WCD9360_ANA_EAR, 7, 0, NULL, 0,
+ pahu_codec_enable_ear_pa,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("ANC EAR PA", WCD9360_ANA_EAR, 7, 0, NULL, 0,
+ pahu_codec_enable_ear_pa, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_PGA_E("ANC SPK1 PA", SND_SOC_NOPM, 0, 0, NULL, 0,
+ pahu_codec_enable_spkr_anc,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_OUTPUT("EAR"),
+ SND_SOC_DAPM_OUTPUT("SPK1 OUT"),
+ SND_SOC_DAPM_OUTPUT("SPK2 OUT"),
+ SND_SOC_DAPM_OUTPUT("ANC EAR"),
+
+ SND_SOC_DAPM_SWITCH("ANC OUT EAR Enable", SND_SOC_NOPM, 0, 0,
+ &anc_ear_switch),
+ SND_SOC_DAPM_SWITCH("ANC OUT EAR SPKR Enable", SND_SOC_NOPM, 0, 0,
+ &anc_ear_spkr_switch),
+ SND_SOC_DAPM_SWITCH("ANC SPKR PA Enable", SND_SOC_NOPM, 0, 0,
+ &anc_spkr_pa_switch),
+
+ SND_SOC_DAPM_DAC("RX INT9 DAC", NULL, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_PGA_E("AUX PA", WCD9360_AUX_ANA_EAR, 7, 0, NULL, 0,
+ pahu_codec_enable_aux_pa, SND_SOC_DAPM_POST_PMU),
+ SND_SOC_DAPM_OUTPUT("AUX"),
+
+
+ SND_SOC_DAPM_SUPPLY("LDO_RXTX", SND_SOC_NOPM, 0, 0,
+ pahu_codec_enable_ldo_rxtx,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("RX INT7 NATIVE SUPPLY", SND_SOC_NOPM,
+ INTERP_SPKR1, 0, pahu_enable_native_supply,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_SUPPLY("RX INT8 NATIVE SUPPLY", SND_SOC_NOPM,
+ INTERP_SPKR2, 0, pahu_enable_native_supply,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
+
+ WCD_DAPM_MUX("RX INT7_2 NATIVE MUX", 0, int7_2_native),
+ WCD_DAPM_MUX("RX INT8_2 NATIVE MUX", 0, int8_2_native),
+
+ SND_SOC_DAPM_MUX_E("ASRC2 MUX", SND_SOC_NOPM, ASRC2, 0,
+ &asrc2_mux, pahu_codec_enable_asrc_resampler,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_MUX_E("ASRC3 MUX", SND_SOC_NOPM, ASRC3, 0,
+ &asrc3_mux, pahu_codec_enable_asrc_resampler,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ /* WDMA3 widgets */
+ WCD_DAPM_MUX("WDMA3 PORT0 MUX", 0, wdma3_port0),
+ WCD_DAPM_MUX("WDMA3 PORT1 MUX", 1, wdma3_port1),
+ WCD_DAPM_MUX("WDMA3 PORT2 MUX", 2, wdma3_port2),
+ WCD_DAPM_MUX("WDMA3 PORT3 MUX", 3, wdma3_port3),
+ WCD_DAPM_MUX("WDMA3 PORT4 MUX", 4, wdma3_port4),
+ WCD_DAPM_MUX("WDMA3 PORT5 MUX", 5, wdma3_port5),
+ WCD_DAPM_MUX("WDMA3 PORT6 MUX", 6, wdma3_port6),
+
+ WCD_DAPM_MUX("WDMA3 CH0 MUX", 0, wdma3_ch0),
+ WCD_DAPM_MUX("WDMA3 CH1 MUX", 4, wdma3_ch1),
+ WCD_DAPM_MUX("WDMA3 CH2 MUX", 0, wdma3_ch2),
+ WCD_DAPM_MUX("WDMA3 CH3 MUX", 4, wdma3_ch3),
+
+ SND_SOC_DAPM_MIXER("WDMA3_CH_MIXER", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_SWITCH_E("WDMA3_ON_OFF", SND_SOC_NOPM, 0, 0,
+ &wdma3_onoff_switch, pahu_codec_wdma3_ctl,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_OUTPUT("WDMA3_OUT"),
+};
+
+static int pahu_get_channel_map(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec);
+ u32 i = 0;
+ struct wcd9xxx_ch *ch;
+ int ret = 0;
+
+ switch (dai->id) {
+ case AIF1_PB:
+ case AIF2_PB:
+ case AIF3_PB:
+ case AIF4_PB:
+ if (!rx_slot || !rx_num) {
+ dev_err(pahu->dev, "%s: Invalid rx_slot 0x%pK or rx_num 0x%pK\n",
+ __func__, rx_slot, rx_num);
+ ret = -EINVAL;
+ break;
+ }
+ list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list,
+ list) {
+ dev_dbg(pahu->dev, "%s: slot_num %u ch->ch_num %d\n",
+ __func__, i, ch->ch_num);
+ rx_slot[i++] = ch->ch_num;
+ }
+ *rx_num = i;
+ dev_dbg(pahu->dev, "%s: dai_name = %s dai_id = %x rx_num = %d\n",
+ __func__, dai->name, dai->id, i);
+ if (*rx_num == 0) {
+ dev_err(pahu->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n",
+ __func__, dai->name, dai->id);
+ ret = -EINVAL;
+ }
+ break;
+ case AIF1_CAP:
+ case AIF2_CAP:
+ case AIF3_CAP:
+ case AIF4_MAD_TX:
+ case AIF4_VIFEED:
+ if (!tx_slot || !tx_num) {
+ dev_err(pahu->dev, "%s: Invalid tx_slot 0x%pK or tx_num 0x%pK\n",
+ __func__, tx_slot, tx_num);
+ ret = -EINVAL;
+ break;
+ }
+ list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list,
+ list) {
+ dev_dbg(pahu->dev, "%s: slot_num %u ch->ch_num %d\n",
+ __func__, i, ch->ch_num);
+ tx_slot[i++] = ch->ch_num;
+ }
+ *tx_num = i;
+ dev_dbg(pahu->dev, "%s: dai_name = %s dai_id = %x tx_num = %d\n",
+ __func__, dai->name, dai->id, i);
+ if (*tx_num == 0) {
+ dev_err(pahu->dev, "%s: Channel list empty for dai_name = %s dai_id = %x\n",
+ __func__, dai->name, dai->id);
+ ret = -EINVAL;
+ }
+ break;
+ default:
+ dev_err(pahu->dev, "%s: Invalid DAI ID %x\n",
+ __func__, dai->id);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int pahu_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+{
+ struct pahu_priv *pahu;
+ struct wcd9xxx *core;
+ struct wcd9xxx_codec_dai_data *dai_data = NULL;
+
+ pahu = snd_soc_codec_get_drvdata(dai->codec);
+ core = dev_get_drvdata(dai->codec->dev->parent);
+
+ if (!tx_slot || !rx_slot) {
+ dev_err(pahu->dev, "%s: Invalid tx_slot 0x%pK, rx_slot 0x%pK\n",
+ __func__, tx_slot, rx_slot);
+ return -EINVAL;
+ }
+ dev_dbg(pahu->dev, "%s(): dai_name = %s DAI-ID %x tx_ch %d rx_ch %d\n",
+ __func__, dai->name, dai->id, tx_num, rx_num);
+
+ wcd9xxx_init_slimslave(core, core->slim->laddr,
+ tx_num, tx_slot, rx_num, rx_slot);
+ /* Reserve TX13 for MAD data channel */
+ dai_data = &pahu->dai[AIF4_MAD_TX];
+ if (dai_data)
+ list_add_tail(&core->tx_chs[WCD9360_TX13].list,
+ &dai_data->wcd9xxx_ch_list);
+
+ return 0;
+}
+
+static int pahu_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+
+ return 0;
+}
+
+static void pahu_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+}
+
+static int pahu_set_decimator_rate(struct snd_soc_dai *dai,
+ u32 sample_rate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ struct wcd9xxx_ch *ch;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ u32 tx_port = 0, tx_fs_rate = 0;
+ u8 shift = 0, shift_val = 0, tx_mux_sel = 0;
+ int decimator = -1;
+ u16 tx_port_reg = 0, tx_fs_reg = 0;
+
+ switch (sample_rate) {
+ case 8000:
+ tx_fs_rate = 0;
+ break;
+ case 16000:
+ tx_fs_rate = 1;
+ break;
+ case 32000:
+ tx_fs_rate = 3;
+ break;
+ case 48000:
+ tx_fs_rate = 4;
+ break;
+ case 96000:
+ tx_fs_rate = 5;
+ break;
+ case 192000:
+ tx_fs_rate = 6;
+ break;
+ default:
+ dev_err(pahu->dev, "%s: Invalid TX sample rate: %d\n",
+ __func__, sample_rate);
+ return -EINVAL;
+
+ };
+
+ list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) {
+ tx_port = ch->port;
+ dev_dbg(codec->dev, "%s: dai->id = %d, tx_port = %d",
+ __func__, dai->id, tx_port);
+
+ if ((tx_port < 0) || (tx_port == 12) || (tx_port >= 14)) {
+ dev_err(codec->dev, "%s: Invalid SLIM TX%u port. DAI ID: %d\n",
+ __func__, tx_port, dai->id);
+ return -EINVAL;
+ }
+ /* Find the SB TX MUX input - which decimator is connected */
+ if (tx_port < 4) {
+ tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0;
+ shift = (tx_port << 1);
+ shift_val = 0x03;
+ } else if ((tx_port >= 4) && (tx_port < 8)) {
+ tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1;
+ shift = ((tx_port - 4) << 1);
+ shift_val = 0x03;
+ } else if ((tx_port >= 8) && (tx_port < 11)) {
+ tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2;
+ shift = ((tx_port - 8) << 1);
+ shift_val = 0x03;
+ } else if (tx_port == 11) {
+ tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3;
+ shift = 0;
+ shift_val = 0x0F;
+ } else if (tx_port == 13) {
+ tx_port_reg = WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3;
+ shift = 4;
+ shift_val = 0x03;
+ }
+ tx_mux_sel = snd_soc_read(codec, tx_port_reg) &
+ (shift_val << shift);
+ tx_mux_sel = tx_mux_sel >> shift;
+
+ if (tx_port <= 8) {
+ if ((tx_mux_sel == 0x2) || (tx_mux_sel == 0x3))
+ decimator = tx_port;
+ } else if (tx_port <= 10) {
+ if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
+ decimator = ((tx_port == 9) ? 7 : 6);
+ } else if (tx_port == 11) {
+ if ((tx_mux_sel >= 1) && (tx_mux_sel < 7))
+ decimator = tx_mux_sel - 1;
+ } else if (tx_port == 13) {
+ if ((tx_mux_sel == 0x1) || (tx_mux_sel == 0x2))
+ decimator = 5;
+ }
+
+ if (decimator >= 0) {
+ tx_fs_reg = WCD9360_CDC_TX0_TX_PATH_CTL +
+ 16 * decimator;
+ dev_dbg(codec->dev, "%s: set DEC%u (-> SLIM_TX%u) rate to %u\n",
+ __func__, decimator, tx_port, sample_rate);
+ snd_soc_update_bits(codec, tx_fs_reg, 0x0F, tx_fs_rate);
+ } else if ((tx_port <= 8) && (tx_mux_sel == 0x01)) {
+ /* Check if the TX Mux input is RX MIX TXn */
+ dev_dbg(codec->dev, "%s: RX_MIX_TX%u going to CDC_IF TX%u\n",
+ __func__, tx_port, tx_port);
+ } else {
+ dev_err(codec->dev, "%s: ERROR: Invalid decimator: %d\n",
+ __func__, decimator);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
+static int pahu_set_mix_interpolator_rate(struct snd_soc_dai *dai,
+ u8 rate_reg_val,
+ u32 sample_rate)
+{
+ u8 int_2_inp;
+ u32 j;
+ u16 int_mux_cfg1, int_fs_reg;
+ u8 int_mux_cfg1_val;
+ struct snd_soc_codec *codec = dai->codec;
+ struct wcd9xxx_ch *ch;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) {
+ int_2_inp = INTn_2_INP_SEL_RX0 + ch->port -
+ WCD9360_RX_PORT_START_NUMBER;
+ if ((int_2_inp < INTn_2_INP_SEL_RX0) ||
+ (int_2_inp > INTn_2_INP_SEL_RX7)) {
+ dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n",
+ __func__,
+ (ch->port - WCD9360_RX_PORT_START_NUMBER),
+ dai->id);
+ return -EINVAL;
+ }
+
+ for (j = 0; j < WCD9360_NUM_INTERPOLATORS; j++) {
+ if (j == INTERP_EAR) {
+ int_mux_cfg1 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1;
+ int_fs_reg = WCD9360_CDC_RX0_RX_PATH_MIX_CTL;
+ } else if (j == INTERP_SPKR1) {
+ int_mux_cfg1 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1;
+ int_fs_reg = WCD9360_CDC_RX7_RX_PATH_MIX_CTL;
+ } else if (j == INTERP_SPKR2) {
+ int_mux_cfg1 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1;
+ int_fs_reg = WCD9360_CDC_RX8_RX_PATH_MIX_CTL;
+ } else if (j == INTERP_AUX) {
+ int_mux_cfg1 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1;
+ int_fs_reg = WCD9360_CDC_RX9_RX_PATH_MIX_CTL;
+ } else {
+ continue;
+ }
+
+ int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1) &
+ 0x0F;
+ if (int_mux_cfg1_val == int_2_inp) {
+ /*
+ * Ear mix path supports only 48, 96, 192,
+ * 384KHz only
+ */
+ if ((j == INTERP_EAR || j == INTERP_AUX) &&
+ (rate_reg_val < 0x4 || rate_reg_val > 0x7)) {
+ dev_err_ratelimited(codec->dev,
+ "%s: Invalid rate for AIF_PB DAI(%d)\n",
+ __func__, dai->id);
+ return -EINVAL;
+ }
+
+ dev_dbg(codec->dev, "%s: AIF_PB DAI(%d) connected to INT%u_2\n",
+ __func__, dai->id, j);
+ dev_dbg(codec->dev, "%s: set INT%u_2 sample rate to %u\n",
+ __func__, j, sample_rate);
+ snd_soc_update_bits(codec, int_fs_reg, 0x0F,
+ rate_reg_val);
+ }
+ }
+ }
+ return 0;
+}
+
+static int pahu_set_prim_interpolator_rate(struct snd_soc_dai *dai,
+ u8 rate_reg_val,
+ u32 sample_rate)
+{
+ u8 int_1_mix1_inp;
+ u32 j;
+ u16 int_mux_cfg0, int_mux_cfg1;
+ u16 int_fs_reg;
+ u8 int_mux_cfg0_val, int_mux_cfg1_val;
+ u8 inp0_sel, inp1_sel, inp2_sel;
+ struct snd_soc_codec *codec = dai->codec;
+ struct wcd9xxx_ch *ch;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ list_for_each_entry(ch, &pahu->dai[dai->id].wcd9xxx_ch_list, list) {
+ int_1_mix1_inp = INTn_1_INP_SEL_RX0 + ch->port -
+ WCD9360_RX_PORT_START_NUMBER;
+ if ((int_1_mix1_inp < INTn_1_INP_SEL_RX0) ||
+ (int_1_mix1_inp > INTn_1_INP_SEL_RX7)) {
+ dev_err(codec->dev, "%s: Invalid RX%u port, Dai ID is %d\n",
+ __func__,
+ (ch->port - WCD9360_RX_PORT_START_NUMBER),
+ dai->id);
+ return -EINVAL;
+ }
+
+ /*
+ * Loop through all interpolator MUX inputs and find out
+ * to which interpolator input, the slim rx port
+ * is connected
+ */
+ for (j = 0; j < WCD9360_NUM_INTERPOLATORS; j++) {
+ if (j == INTERP_EAR) {
+ int_mux_cfg0 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0;
+ int_fs_reg = WCD9360_CDC_RX0_RX_PATH_CTL;
+ } else if (j == INTERP_SPKR1) {
+ int_mux_cfg0 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0;
+ int_fs_reg = WCD9360_CDC_RX7_RX_PATH_CTL;
+ } else if (j == INTERP_SPKR2) {
+ int_mux_cfg0 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0;
+ int_fs_reg = WCD9360_CDC_RX8_RX_PATH_CTL;
+ } else if (j == INTERP_AUX) {
+ int_mux_cfg0 =
+ WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0;
+ int_fs_reg = WCD9360_CDC_RX9_RX_PATH_CTL;
+ } else {
+ continue;
+ }
+ int_mux_cfg1 = int_mux_cfg0 + 1;
+
+ int_mux_cfg0_val = snd_soc_read(codec, int_mux_cfg0);
+ int_mux_cfg1_val = snd_soc_read(codec, int_mux_cfg1);
+ inp0_sel = int_mux_cfg0_val & 0x0F;
+ inp1_sel = (int_mux_cfg0_val >> 4) & 0x0F;
+ inp2_sel = (int_mux_cfg1_val >> 4) & 0x0F;
+ if ((inp0_sel == int_1_mix1_inp) ||
+ (inp1_sel == int_1_mix1_inp) ||
+ (inp2_sel == int_1_mix1_inp)) {
+ /*
+ * Primary path does not support
+ * native sample rates
+ */
+ if (rate_reg_val > 0x7) {
+ dev_err_ratelimited(codec->dev,
+ "%s: Invalid rate for AIF_PB DAI(%d)\n",
+ __func__, dai->id);
+ return -EINVAL;
+ }
+ dev_dbg(codec->dev,
+ "%s: AIF_PB DAI(%d) connected to INT%u_1\n",
+ __func__, dai->id, j);
+ dev_dbg(codec->dev,
+ "%s: set INT%u_1 sample rate to %u\n",
+ __func__, j, sample_rate);
+ snd_soc_update_bits(codec, int_fs_reg, 0x0F,
+ rate_reg_val);
+ }
+ int_mux_cfg0 += 2;
+ }
+ }
+
+ return 0;
+}
+
+
+static int pahu_set_interpolator_rate(struct snd_soc_dai *dai,
+ u32 sample_rate)
+{
+ struct snd_soc_codec *codec = dai->codec;
+ int rate_val = 0;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(sr_val_tbl); i++) {
+ if (sample_rate == sr_val_tbl[i].sample_rate) {
+ rate_val = sr_val_tbl[i].rate_val;
+ break;
+ }
+ }
+ if ((i == ARRAY_SIZE(sr_val_tbl)) || (rate_val < 0)) {
+ dev_err(codec->dev, "%s: Unsupported sample rate: %d\n",
+ __func__, sample_rate);
+ return -EINVAL;
+ }
+
+ ret = pahu_set_prim_interpolator_rate(dai, (u8)rate_val, sample_rate);
+ if (ret)
+ return ret;
+ ret = pahu_set_mix_interpolator_rate(dai, (u8)rate_val, sample_rate);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
+static int pahu_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ return 0;
+}
+
+static int pahu_vi_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec);
+
+ dev_dbg(pahu->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n",
+ __func__, dai->name, dai->id, params_rate(params),
+ params_channels(params));
+
+ pahu->dai[dai->id].rate = params_rate(params);
+ pahu->dai[dai->id].bit_width = 32;
+
+ return 0;
+}
+
+static int pahu_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec);
+ int ret = 0;
+
+ dev_dbg(pahu->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n",
+ __func__, dai->name, dai->id, params_rate(params),
+ params_channels(params));
+
+ switch (substream->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ ret = pahu_set_interpolator_rate(dai, params_rate(params));
+ if (ret) {
+ dev_err(pahu->dev, "%s: cannot set sample rate: %u\n",
+ __func__, params_rate(params));
+ return ret;
+ }
+ switch (params_width(params)) {
+ case 16:
+ pahu->dai[dai->id].bit_width = 16;
+ break;
+ case 24:
+ pahu->dai[dai->id].bit_width = 24;
+ break;
+ case 32:
+ pahu->dai[dai->id].bit_width = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
+ pahu->dai[dai->id].rate = params_rate(params);
+ break;
+ case SNDRV_PCM_STREAM_CAPTURE:
+ if (dai->id != AIF4_MAD_TX)
+ ret = pahu_set_decimator_rate(dai,
+ params_rate(params));
+ if (ret) {
+ dev_err(pahu->dev, "%s: cannot set TX Decimator rate: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ switch (params_width(params)) {
+ case 16:
+ pahu->dai[dai->id].bit_width = 16;
+ break;
+ case 24:
+ pahu->dai[dai->id].bit_width = 24;
+ break;
+ default:
+ dev_err(pahu->dev, "%s: Invalid format 0x%x\n",
+ __func__, params_width(params));
+ return -EINVAL;
+ };
+ pahu->dai[dai->id].rate = params_rate(params);
+ break;
+ default:
+ dev_err(pahu->dev, "%s: Invalid stream type %d\n", __func__,
+ substream->stream);
+ return -EINVAL;
+ };
+
+ return 0;
+}
+
+static int pahu_i2s_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(dai->codec);
+
+ dev_dbg(dai->dev, "%s: dai_name = %s DAI-ID %x rate %d num_ch %d\n",
+ __func__, dai->name, dai->id, params_rate(params),
+ params_channels(params));
+
+ pahu->dai[dai->id].rate = params_rate(params);
+ pahu->dai[dai->id].bit_width = params_width(params);
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops pahu_dai_ops = {
+ .startup = pahu_startup,
+ .shutdown = pahu_shutdown,
+ .hw_params = pahu_hw_params,
+ .prepare = pahu_prepare,
+ .set_channel_map = pahu_set_channel_map,
+ .get_channel_map = pahu_get_channel_map,
+};
+
+static struct snd_soc_dai_ops pahu_vi_dai_ops = {
+ .hw_params = pahu_vi_hw_params,
+ .set_channel_map = pahu_set_channel_map,
+ .get_channel_map = pahu_get_channel_map,
+};
+
+static struct snd_soc_dai_ops pahu_i2s_dai_ops = {
+ .hw_params = pahu_i2s_hw_params,
+};
+
+static struct snd_soc_dai_driver pahu_dai[] = {
+ {
+ .name = "pahu_rx1",
+ .id = AIF1_PB,
+ .playback = {
+ .stream_name = "AIF1 Playback",
+ .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_tx1",
+ .id = AIF1_CAP,
+ .capture = {
+ .stream_name = "AIF1 Capture",
+ .rates = WCD9360_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+ .channels_max = 8,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_rx2",
+ .id = AIF2_PB,
+ .playback = {
+ .stream_name = "AIF2 Playback",
+ .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_tx2",
+ .id = AIF2_CAP,
+ .capture = {
+ .stream_name = "AIF2 Capture",
+ .rates = WCD9360_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+ .channels_max = 8,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_rx3",
+ .id = AIF3_PB,
+ .playback = {
+ .stream_name = "AIF3 Playback",
+ .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_tx3",
+ .id = AIF3_CAP,
+ .capture = {
+ .stream_name = "AIF3 Capture",
+ .rates = WCD9360_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+ .channels_max = 8,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_rx4",
+ .id = AIF4_PB,
+ .playback = {
+ .stream_name = "AIF4 Playback",
+ .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_vifeedback",
+ .id = AIF4_VIFEED,
+ .capture = {
+ .stream_name = "VIfeed",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_48000,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 4,
+ },
+ .ops = &pahu_vi_dai_ops,
+ },
+ {
+ .name = "pahu_mad1",
+ .id = AIF4_MAD_TX,
+ .capture = {
+ .stream_name = "AIF4 MAD TX",
+ .rates = SNDRV_PCM_RATE_16000,
+ .formats = WCD9360_FORMATS_S16_LE,
+ .rate_min = 16000,
+ .rate_max = 16000,
+ .channels_min = 1,
+ .channels_max = 1,
+ },
+ .ops = &pahu_dai_ops,
+ },
+ {
+ .name = "pahu_i2s1_rx",
+ .id = I2S1_PB,
+ .playback = {
+ .stream_name = "I2S1 Playback",
+ .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 384000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &pahu_i2s_dai_ops,
+ },
+ {
+ .name = "pahu_i2s1_tx",
+ .id = I2S1_CAP,
+ .capture = {
+ .stream_name = "I2S1 Capture",
+ .rates = WCD9360_RATES_MASK | WCD9360_FRAC_RATES_MASK,
+ .formats = WCD9360_FORMATS_S16_S24_S32_LE,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &pahu_i2s_dai_ops,
+ },
+};
+
+static void pahu_codec_power_gate_digital_core(struct pahu_priv *pahu)
+{
+ mutex_lock(&pahu->power_lock);
+ dev_dbg(pahu->dev, "%s: Entering power gating function, %d\n",
+ __func__, pahu->power_active_ref);
+
+ if (pahu->power_active_ref > 0)
+ goto exit;
+
+ wcd9xxx_set_power_state(pahu->wcd9xxx,
+ WCD_REGION_POWER_COLLAPSE_BEGIN,
+ WCD9XXX_DIG_CORE_REGION_1);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x04, 0x04);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x01, 0x00);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x02, 0x00);
+ wcd9xxx_set_power_state(pahu->wcd9xxx, WCD_REGION_POWER_DOWN,
+ WCD9XXX_DIG_CORE_REGION_1);
+exit:
+ dev_dbg(pahu->dev, "%s: Exiting power gating function, %d\n",
+ __func__, pahu->power_active_ref);
+ mutex_unlock(&pahu->power_lock);
+}
+
+static void pahu_codec_power_gate_work(struct work_struct *work)
+{
+ struct pahu_priv *pahu;
+ struct delayed_work *dwork;
+
+ dwork = to_delayed_work(work);
+ pahu = container_of(dwork, struct pahu_priv, power_gate_work);
+
+ pahu_codec_power_gate_digital_core(pahu);
+}
+
+/* called under power_lock acquisition */
+static int pahu_dig_core_remove_power_collapse(struct pahu_priv *pahu)
+{
+ regmap_write(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x05);
+ regmap_write(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x07);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_RST_CTL, 0x02, 0x00);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_RST_CTL, 0x02, 0x02);
+ regmap_write(pahu->wcd9xxx->regmap,
+ WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x03);
+
+ wcd9xxx_set_power_state(pahu->wcd9xxx,
+ WCD_REGION_POWER_COLLAPSE_REMOVE,
+ WCD9XXX_DIG_CORE_REGION_1);
+ regcache_mark_dirty(pahu->wcd9xxx->regmap);
+ regcache_sync_region(pahu->wcd9xxx->regmap,
+ WCD9360_DIG_CORE_REG_MIN,
+ WCD9360_DIG_CORE_REG_MAX);
+ return 0;
+}
+
+static int pahu_dig_core_power_collapse(struct pahu_priv *pahu,
+ int req_state)
+{
+ int cur_state;
+
+ /* Exit if feature is disabled */
+ if (!dig_core_collapse_enable)
+ return 0;
+
+ mutex_lock(&pahu->power_lock);
+ if (req_state == POWER_COLLAPSE)
+ pahu->power_active_ref--;
+ else if (req_state == POWER_RESUME)
+ pahu->power_active_ref++;
+ else
+ goto unlock_mutex;
+
+ if (pahu->power_active_ref < 0) {
+ dev_dbg(pahu->dev, "%s: power_active_ref is negative\n",
+ __func__);
+ goto unlock_mutex;
+ }
+
+ if (req_state == POWER_COLLAPSE) {
+ if (pahu->power_active_ref == 0) {
+ schedule_delayed_work(&pahu->power_gate_work,
+ msecs_to_jiffies(dig_core_collapse_timer * 1000));
+ }
+ } else if (req_state == POWER_RESUME) {
+ if (pahu->power_active_ref == 1) {
+ /*
+ * At this point, there can be two cases:
+ * 1. Core already in power collapse state
+ * 2. Timer kicked in and still did not expire or
+ * waiting for the power_lock
+ */
+ cur_state = wcd9xxx_get_current_power_state(
+ pahu->wcd9xxx,
+ WCD9XXX_DIG_CORE_REGION_1);
+ if (cur_state == WCD_REGION_POWER_DOWN) {
+ pahu_dig_core_remove_power_collapse(pahu);
+ } else {
+ mutex_unlock(&pahu->power_lock);
+ cancel_delayed_work_sync(
+ &pahu->power_gate_work);
+ mutex_lock(&pahu->power_lock);
+ }
+ }
+ }
+
+unlock_mutex:
+ mutex_unlock(&pahu->power_lock);
+
+ return 0;
+}
+
+static int pahu_cdc_req_mclk_enable(struct pahu_priv *pahu,
+ bool enable)
+{
+ int ret = 0;
+
+ if (enable) {
+ ret = clk_prepare_enable(pahu->wcd_ext_clk);
+ if (ret) {
+ dev_err(pahu->dev, "%s: ext clk enable failed\n",
+ __func__);
+ goto done;
+ }
+ /* get BG */
+ wcd_resmgr_enable_master_bias(pahu->resmgr);
+ /* get MCLK */
+ wcd_resmgr_enable_clk_block(pahu->resmgr, WCD_CLK_MCLK);
+ } else {
+ /* put MCLK */
+ wcd_resmgr_disable_clk_block(pahu->resmgr, WCD_CLK_MCLK);
+ /* put BG */
+ wcd_resmgr_disable_master_bias(pahu->resmgr);
+ clk_disable_unprepare(pahu->wcd_ext_clk);
+ }
+
+done:
+ return ret;
+}
+
+static int __pahu_cdc_mclk_enable_locked(struct pahu_priv *pahu,
+ bool enable)
+{
+ int ret = 0;
+
+ if (!pahu->wcd_ext_clk) {
+ dev_err(pahu->dev, "%s: wcd ext clock is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ dev_dbg(pahu->dev, "%s: mclk_enable = %u\n", __func__, enable);
+
+ if (enable) {
+ pahu_dig_core_power_collapse(pahu, POWER_RESUME);
+ pahu_vote_svs(pahu, true);
+ ret = pahu_cdc_req_mclk_enable(pahu, true);
+ if (ret)
+ goto done;
+ } else {
+ pahu_cdc_req_mclk_enable(pahu, false);
+ pahu_vote_svs(pahu, false);
+ pahu_dig_core_power_collapse(pahu, POWER_COLLAPSE);
+ }
+
+done:
+ return ret;
+}
+
+static int __pahu_cdc_mclk_enable(struct pahu_priv *pahu,
+ bool enable)
+{
+ int ret;
+
+ WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr);
+ ret = __pahu_cdc_mclk_enable_locked(pahu, enable);
+ if (enable)
+ wcd_resmgr_set_sido_input_src(pahu->resmgr,
+ SIDO_SOURCE_RCO_BG);
+ WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr);
+
+ return ret;
+}
+
+static ssize_t pahu_codec_version_read(struct snd_info_entry *entry,
+ void *file_private_data,
+ struct file *file,
+ char __user *buf, size_t count,
+ loff_t pos)
+{
+ struct pahu_priv *pahu;
+ struct wcd9xxx *wcd9xxx;
+ char buffer[PAHU_VERSION_ENTRY_SIZE];
+ int len = 0;
+
+ pahu = (struct pahu_priv *) entry->private_data;
+ if (!pahu) {
+ pr_err("%s: pahu priv is null\n", __func__);
+ return -EINVAL;
+ }
+
+ wcd9xxx = pahu->wcd9xxx;
+
+ switch (wcd9xxx->version) {
+ case PAHU_VERSION_1_0:
+ len = snprintf(buffer, sizeof(buffer), "WCD9360_1_0\n");
+ break;
+ default:
+ len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
+ }
+
+ return simple_read_from_buffer(buf, count, &pos, buffer, len);
+}
+
+static struct snd_info_entry_ops pahu_codec_info_ops = {
+ .read = pahu_codec_version_read,
+};
+
+/*
+ * pahu_codec_info_create_codec_entry - creates wcd9360 module
+ * @codec_root: The parent directory
+ * @codec: Codec instance
+ *
+ * Creates wcd9360 module and version entry under the given
+ * parent directory.
+ *
+ * Return: 0 on success or negative error code on failure.
+ */
+int pahu_codec_info_create_codec_entry(struct snd_info_entry *codec_root,
+ struct snd_soc_codec *codec)
+{
+ struct snd_info_entry *version_entry;
+ struct pahu_priv *pahu;
+ struct snd_soc_card *card;
+
+ if (!codec_root || !codec)
+ return -EINVAL;
+
+ pahu = snd_soc_codec_get_drvdata(codec);
+ card = codec->component.card;
+ pahu->entry = snd_info_create_subdir(codec_root->module,
+ "pahu", codec_root);
+ if (!pahu->entry) {
+ dev_dbg(codec->dev, "%s: failed to create wcd9360 entry\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ version_entry = snd_info_create_card_entry(card->snd_card,
+ "version",
+ pahu->entry);
+ if (!version_entry) {
+ dev_dbg(codec->dev, "%s: failed to create wcd9360 version entry\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ version_entry->private_data = pahu;
+ version_entry->size = PAHU_VERSION_ENTRY_SIZE;
+ version_entry->content = SNDRV_INFO_CONTENT_DATA;
+ version_entry->c.ops = &pahu_codec_info_ops;
+
+ if (snd_info_register(version_entry) < 0) {
+ snd_info_free_entry(version_entry);
+ return -ENOMEM;
+ }
+ pahu->version_entry = version_entry;
+
+ return 0;
+}
+EXPORT_SYMBOL(pahu_codec_info_create_codec_entry);
+
+/**
+ * pahu_cdc_mclk_enable - Enable/disable codec mclk
+ *
+ * @codec: codec instance
+ * @enable: Indicates clk enable or disable
+ *
+ * Returns 0 on Success and error on failure
+ */
+int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ return __pahu_cdc_mclk_enable(pahu, enable);
+}
+EXPORT_SYMBOL(pahu_cdc_mclk_enable);
+
+static int __pahu_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
+ bool enable)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ if (enable) {
+ if (wcd_resmgr_get_clk_type(pahu->resmgr) ==
+ WCD_CLK_RCO) {
+ ret = wcd_resmgr_enable_clk_block(pahu->resmgr,
+ WCD_CLK_RCO);
+ } else {
+ ret = pahu_cdc_req_mclk_enable(pahu, true);
+ if (ret) {
+ dev_err(codec->dev,
+ "%s: mclk_enable failed, err = %d\n",
+ __func__, ret);
+ goto done;
+ }
+ wcd_resmgr_set_sido_input_src(pahu->resmgr,
+ SIDO_SOURCE_RCO_BG);
+ ret = wcd_resmgr_enable_clk_block(pahu->resmgr,
+ WCD_CLK_RCO);
+ ret |= pahu_cdc_req_mclk_enable(pahu, false);
+ }
+
+ } else {
+ ret = wcd_resmgr_disable_clk_block(pahu->resmgr,
+ WCD_CLK_RCO);
+ }
+
+ if (ret) {
+ dev_err(codec->dev, "%s: Error in %s RCO\n",
+ __func__, (enable ? "enabling" : "disabling"));
+ ret = -EINVAL;
+ }
+
+done:
+ return ret;
+}
+
+/*
+ * pahu_codec_internal_rco_ctrl: Enable/Disable codec's RCO clock
+ * @codec: Handle to the codec
+ * @enable: Indicates whether clock should be enabled or disabled
+ */
+static int pahu_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
+ bool enable)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+ int ret = 0;
+
+ WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr);
+ ret = __pahu_codec_internal_rco_ctrl(codec, enable);
+ WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr);
+ return ret;
+}
+
+/*
+ * pahu_cdc_mclk_tx_enable: Enable/Disable codec's clock for TX path
+ * @codec: Handle to codec
+ * @enable: Indicates whether clock should be enabled or disabled
+ */
+int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable)
+{
+ struct pahu_priv *pahu_p;
+ int ret = 0;
+ bool clk_mode;
+ bool clk_internal;
+
+ if (!codec)
+ return -EINVAL;
+
+ pahu_p = snd_soc_codec_get_drvdata(codec);
+ clk_mode = test_bit(CLK_MODE, &pahu_p->status_mask);
+ clk_internal = test_bit(CLK_INTERNAL, &pahu_p->status_mask);
+
+ dev_dbg(codec->dev, "%s: clkmode: %d, enable: %d, clk_internal: %d\n",
+ __func__, clk_mode, enable, clk_internal);
+
+ if (clk_mode || clk_internal) {
+ if (enable) {
+ wcd_resmgr_enable_master_bias(pahu_p->resmgr);
+ pahu_dig_core_power_collapse(pahu_p, POWER_RESUME);
+ pahu_vote_svs(pahu_p, true);
+ ret = pahu_codec_internal_rco_ctrl(codec, enable);
+ set_bit(CLK_INTERNAL, &pahu_p->status_mask);
+ } else {
+ clear_bit(CLK_INTERNAL, &pahu_p->status_mask);
+ pahu_codec_internal_rco_ctrl(codec, enable);
+ pahu_vote_svs(pahu_p, false);
+ pahu_dig_core_power_collapse(pahu_p, POWER_COLLAPSE);
+ wcd_resmgr_disable_master_bias(pahu_p->resmgr);
+ }
+ } else {
+ ret = __pahu_cdc_mclk_enable(pahu_p, enable);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(pahu_cdc_mclk_tx_enable);
+
+static const struct wcd_resmgr_cb pahu_resmgr_cb = {
+ .cdc_rco_ctrl = __pahu_codec_internal_rco_ctrl,
+};
+
+static const struct pahu_reg_mask_val pahu_codec_mclk2_1_0_defaults[] = {
+ /*
+ * PLL Settings:
+ * Clock Root: MCLK2,
+ * Clock Source: EXT_CLK,
+ * Clock Destination: MCLK2
+ * Clock Freq In: 19.2MHz,
+ * Clock Freq Out: 11.2896MHz
+ */
+ {WCD9360_CLK_SYS_MCLK2_PRG1, 0x60, 0x20},
+ {WCD9360_CLK_SYS_INT_POST_DIV_REG0, 0xFF, 0x5E},
+ {WCD9360_CLK_SYS_INT_POST_DIV_REG1, 0x1F, 0x1F},
+ {WCD9360_CLK_SYS_INT_REF_DIV_REG0, 0xFF, 0x54},
+ {WCD9360_CLK_SYS_INT_REF_DIV_REG1, 0xFF, 0x01},
+ {WCD9360_CLK_SYS_INT_FILTER_REG1, 0x07, 0x04},
+ {WCD9360_CLK_SYS_INT_PLL_L_VAL, 0xFF, 0x93},
+ {WCD9360_CLK_SYS_INT_PLL_N_VAL, 0xFF, 0xFA},
+ {WCD9360_CLK_SYS_INT_TEST_REG0, 0xFF, 0x90},
+ {WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG, 0xFF, 0x7E},
+ {WCD9360_CLK_SYS_INT_VCO_PROG, 0xFF, 0xF8},
+ {WCD9360_CLK_SYS_INT_TEST_REG1, 0xFF, 0x68},
+ {WCD9360_CLK_SYS_INT_LDO_LOCK_CFG, 0xFF, 0x40},
+ {WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG, 0xFF, 0x32},
+};
+
+static const struct pahu_reg_mask_val pahu_codec_reg_defaults[] = {
+ {WCD9360_BIAS_VBG_FINE_ADJ, 0xFF, 0x75},
+ {WCD9360_CODEC_RPM_CLK_MCLK_CFG, 0x03, 0x01},
+ {WCD9360_CODEC_CPR_SVS_CX_VDD, 0xFF, 0x7C}, /* value in svs mode */
+ {WCD9360_CODEC_CPR_SVS2_CX_VDD, 0xFF, 0x58}, /* value in svs2 mode */
+ {WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
+ {WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
+ {WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
+ {WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL, 0x01, 0x01},
+ {WCD9360_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
+ {WCD9360_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
+ {WCD9360_CDC_RX0_RX_PATH_SEC0, 0x08, 0x00},
+ {WCD9360_CDC_RX9_RX_PATH_SEC0, 0x08, 0x00},
+ {WCD9360_MICB1_TEST_CTL_2, 0x07, 0x01},
+ {WCD9360_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
+ {WCD9360_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
+ {WCD9360_CDC_BOOST1_BOOST_CFG1, 0x3F, 0x12},
+ {WCD9360_CDC_BOOST1_BOOST_CFG2, 0x1C, 0x08},
+ {WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD, 0x1F, 0x09},
+ {WCD9360_CDC_TX0_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX1_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX2_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX3_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX4_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX5_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX6_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX7_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CDC_TX8_TX_PATH_CFG1, 0x01, 0x00},
+ {WCD9360_CPE_FLL_CONFIG_CTL_2, 0xFF, 0x20},
+ {WCD9360_CPE_SS_DMIC_CFG, 0x80, 0x00},
+ {WCD9360_CDC_BOOST0_BOOST_CTL, 0x70, 0x50},
+ {WCD9360_CDC_BOOST1_BOOST_CTL, 0x70, 0x50},
+ {WCD9360_CDC_RX7_RX_PATH_CFG1, 0x08, 0x08},
+ {WCD9360_CDC_RX8_RX_PATH_CFG1, 0x08, 0x08},
+ {WCD9360_CDC_TOP_TOP_CFG1, 0x02, 0x02},
+ {WCD9360_CDC_TOP_TOP_CFG1, 0x01, 0x01},
+ {WCD9360_CDC_TOP_EAR_COMP_LUT, 0x80, 0x80},
+ {WCD9360_EAR_EAR_DAC_CON, 0x06, 0x02},
+ {WCD9360_AUX_INT_AUX_DAC_CON, 0x06, 0x02},
+ {WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+ {WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+ {WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+ {WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0, 0x01, 0x01},
+ {WCD9360_DATA_HUB_SB_TX11_INP_CFG, 0x01, 0x01},
+ {WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL, 0x01, 0x01},
+ {WCD9360_CDC_COMPANDER7_CTL3, 0x80, 0x80},
+ {WCD9360_CDC_COMPANDER8_CTL3, 0x80, 0x80},
+ {WCD9360_CDC_COMPANDER7_CTL7, 0x01, 0x01},
+ {WCD9360_CDC_COMPANDER8_CTL7, 0x01, 0x01},
+ {WCD9360_CODEC_RPM_CLK_GATE, 0x08, 0x00},
+ {WCD9360_TLMM_DMIC3_CLK_PINCFG, 0xFF, 0x0a},
+ {WCD9360_TLMM_DMIC3_DATA_PINCFG, 0xFF, 0x0a},
+ {WCD9360_CPE_SS_SVA_CFG, 0x60, 0x00},
+ {WCD9360_CPE_SS_CPAR_CFG, 0x10, 0x10},
+};
+
+static const struct pahu_cpr_reg_defaults cpr_defaults[] = {
+ { 0x00000820, 0x00000094 },
+ { 0x00000fC0, 0x00000048 },
+ { 0x0000f000, 0x00000044 },
+ { 0x0000bb80, 0xC0000178 },
+ { 0x00000000, 0x00000160 },
+ { 0x10854522, 0x00000060 },
+ { 0x10854509, 0x00000064 },
+ { 0x108544dd, 0x00000068 },
+ { 0x108544ad, 0x0000006C },
+ { 0x0000077E, 0x00000070 },
+ { 0x000007da, 0x00000074 },
+ { 0x00000000, 0x00000078 },
+ { 0x00000000, 0x0000007C },
+ { 0x00042029, 0x00000080 },
+ { 0x4002002A, 0x00000090 },
+ { 0x4002002B, 0x00000090 },
+};
+
+static void pahu_update_reg_defaults(struct pahu_priv *pahu)
+{
+ u32 i;
+ struct wcd9xxx *wcd9xxx;
+
+ wcd9xxx = pahu->wcd9xxx;
+ for (i = 0; i < ARRAY_SIZE(pahu_codec_reg_defaults); i++)
+ regmap_update_bits(wcd9xxx->regmap,
+ pahu_codec_reg_defaults[i].reg,
+ pahu_codec_reg_defaults[i].mask,
+ pahu_codec_reg_defaults[i].val);
+}
+
+static void pahu_update_cpr_defaults(struct pahu_priv *pahu)
+{
+ int i;
+ struct wcd9xxx *wcd9xxx;
+
+ wcd9xxx = pahu->wcd9xxx;
+
+ __pahu_cdc_mclk_enable(pahu, true);
+
+ regmap_update_bits(wcd9xxx->regmap, WCD9360_CODEC_RPM_CLK_GATE,
+ 0x10, 0x00);
+
+ for (i = 0; i < ARRAY_SIZE(cpr_defaults); i++) {
+ regmap_bulk_write(wcd9xxx->regmap,
+ WCD9360_CODEC_CPR_WR_DATA_0,
+ (u8 *)&cpr_defaults[i].wr_data, 4);
+ regmap_bulk_write(wcd9xxx->regmap,
+ WCD9360_CODEC_CPR_WR_ADDR_0,
+ (u8 *)&cpr_defaults[i].wr_addr, 4);
+ }
+
+ __pahu_cdc_mclk_enable(pahu, false);
+}
+
+static void pahu_slim_interface_init_reg(struct snd_soc_codec *codec)
+{
+ int i;
+ struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec);
+
+ for (i = 0; i < WCD9XXX_SLIM_NUM_PORT_REG; i++)
+ wcd9xxx_interface_reg_write(priv->wcd9xxx,
+ WCD9360_SLIM_PGD_PORT_INT_RX_EN0 + i,
+ 0xFF);
+}
+
+static irqreturn_t pahu_misc_irq(int irq, void *data)
+{
+ struct pahu_priv *pahu = data;
+ int misc_val;
+
+ /* Find source of interrupt */
+ regmap_read(pahu->wcd9xxx->regmap, WCD9360_INTR_CODEC_MISC_STATUS,
+ &misc_val);
+
+ dev_dbg(pahu->dev, "%s: Codec misc irq: %d, val: 0x%x\n",
+ __func__, irq, misc_val);
+
+ /* Clear interrupt status */
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_INTR_CODEC_MISC_CLEAR, misc_val, 0x00);
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t pahu_slimbus_irq(int irq, void *data)
+{
+ struct pahu_priv *pahu = data;
+ unsigned long status = 0;
+ int i, j, port_id, k;
+ u32 bit;
+ u8 val, int_val = 0;
+ bool tx, cleared;
+ unsigned short reg = 0;
+
+ for (i = WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_0, j = 0;
+ i <= WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_1; i++, j++) {
+ val = wcd9xxx_interface_reg_read(pahu->wcd9xxx, i);
+ status |= ((u32)val << (8 * j));
+ }
+
+ for_each_set_bit(j, &status, 32) {
+ tx = (j >= 16 ? true : false);
+ port_id = (tx ? j - 16 : j);
+ val = wcd9xxx_interface_reg_read(pahu->wcd9xxx,
+ WCD9360_SLIM_PGD_PORT_INT_RX_SOURCE0 + j);
+ if (val) {
+ if (!tx)
+ reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 +
+ (port_id / 8);
+ else
+ reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 +
+ (port_id / 8);
+ int_val = wcd9xxx_interface_reg_read(
+ pahu->wcd9xxx, reg);
+ /*
+ * Ignore interrupts for ports for which the
+ * interrupts are not specifically enabled.
+ */
+ if (!(int_val & (1 << (port_id % 8))))
+ continue;
+ }
+ if (val & WCD9360_SLIM_IRQ_OVERFLOW)
+ dev_err_ratelimited(pahu->dev, "%s: overflow error on %s port %d, value %x\n",
+ __func__, (tx ? "TX" : "RX"), port_id, val);
+ if (val & WCD9360_SLIM_IRQ_UNDERFLOW)
+ dev_err_ratelimited(pahu->dev, "%s: underflow error on %s port %d, value %x\n",
+ __func__, (tx ? "TX" : "RX"), port_id, val);
+ if ((val & WCD9360_SLIM_IRQ_OVERFLOW) ||
+ (val & WCD9360_SLIM_IRQ_UNDERFLOW)) {
+ if (!tx)
+ reg = WCD9360_SLIM_PGD_PORT_INT_RX_EN0 +
+ (port_id / 8);
+ else
+ reg = WCD9360_SLIM_PGD_PORT_INT_TX_EN0 +
+ (port_id / 8);
+ int_val = wcd9xxx_interface_reg_read(
+ pahu->wcd9xxx, reg);
+ if (int_val & (1 << (port_id % 8))) {
+ int_val = int_val ^ (1 << (port_id % 8));
+ wcd9xxx_interface_reg_write(pahu->wcd9xxx,
+ reg, int_val);
+ }
+ }
+ if (val & WCD9360_SLIM_IRQ_PORT_CLOSED) {
+ /*
+ * INT SOURCE register starts from RX to TX
+ * but port number in the ch_mask is in opposite way
+ */
+ bit = (tx ? j - 16 : j + 16);
+ dev_dbg(pahu->dev, "%s: %s port %d closed value %x, bit %u\n",
+ __func__, (tx ? "TX" : "RX"), port_id, val,
+ bit);
+ for (k = 0, cleared = false; k < NUM_CODEC_DAIS; k++) {
+ dev_dbg(pahu->dev, "%s: pahu->dai[%d].ch_mask = 0x%lx\n",
+ __func__, k, pahu->dai[k].ch_mask);
+ if (test_and_clear_bit(bit,
+ &pahu->dai[k].ch_mask)) {
+ cleared = true;
+ if (!pahu->dai[k].ch_mask)
+ wake_up(
+ &pahu->dai[k].dai_wait);
+ /*
+ * There are cases when multiple DAIs
+ * might be using the same slimbus
+ * channel. Hence don't break here.
+ */
+ }
+ }
+ }
+ wcd9xxx_interface_reg_write(pahu->wcd9xxx,
+ WCD9360_SLIM_PGD_PORT_INT_CLR_RX_0 +
+ (j / 8),
+ 1 << (j % 8));
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int pahu_setup_irqs(struct pahu_priv *pahu)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = pahu->codec;
+ struct wcd9xxx *wcd9xxx = pahu->wcd9xxx;
+ struct wcd9xxx_core_resource *core_res =
+ &wcd9xxx->core_res;
+
+ ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_SLIMBUS,
+ pahu_slimbus_irq, "SLIMBUS Slave", pahu);
+ if (ret)
+ dev_err(codec->dev, "%s: Failed to request irq %d\n", __func__,
+ WCD9XXX_IRQ_SLIMBUS);
+ else
+ pahu_slim_interface_init_reg(codec);
+
+ /* Register for misc interrupts as well */
+ ret = wcd9xxx_request_irq(core_res, WCD9360_IRQ_MISC,
+ pahu_misc_irq, "CDC MISC Irq", pahu);
+ if (ret)
+ dev_err(codec->dev, "%s: Failed to request cdc misc irq\n",
+ __func__);
+
+ return ret;
+}
+
+static void pahu_init_slim_slave_cfg(struct snd_soc_codec *codec)
+{
+ struct pahu_priv *priv = snd_soc_codec_get_drvdata(codec);
+ struct afe_param_cdc_slimbus_slave_cfg *cfg;
+ struct wcd9xxx *wcd9xxx = priv->wcd9xxx;
+ uint64_t eaddr = 0;
+
+ cfg = &priv->slimbus_slave_cfg;
+ cfg->minor_version = 1;
+ cfg->tx_slave_port_offset = 0;
+ cfg->rx_slave_port_offset = 16;
+
+ memcpy(&eaddr, &wcd9xxx->slim->e_addr, sizeof(wcd9xxx->slim->e_addr));
+ WARN_ON(sizeof(wcd9xxx->slim->e_addr) != 6);
+ cfg->device_enum_addr_lsw = eaddr & 0xFFFFFFFF;
+ cfg->device_enum_addr_msw = eaddr >> 32;
+
+ dev_dbg(codec->dev, "%s: slimbus logical address 0x%llx\n",
+ __func__, eaddr);
+}
+
+static void pahu_cleanup_irqs(struct pahu_priv *pahu)
+{
+ struct wcd9xxx *wcd9xxx = pahu->wcd9xxx;
+ struct wcd9xxx_core_resource *core_res =
+ &wcd9xxx->core_res;
+
+ wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_SLIMBUS, pahu);
+ wcd9xxx_free_irq(core_res, WCD9360_IRQ_MISC, pahu);
+}
+
+/*
+ * wcd9360_get_micb_vout_ctl_val: converts micbias from volts to register value
+ * @micb_mv: micbias in mv
+ *
+ * return register value converted
+ */
+int wcd9360_get_micb_vout_ctl_val(u32 micb_mv)
+{
+ /* min micbias voltage is 1V and maximum is 2.85V */
+ if (micb_mv < 1000 || micb_mv > 2850) {
+ pr_err("%s: unsupported micbias voltage\n", __func__);
+ return -EINVAL;
+ }
+
+ return (micb_mv - 1000) / 50;
+}
+EXPORT_SYMBOL(wcd9360_get_micb_vout_ctl_val);
+
+static int pahu_handle_pdata(struct pahu_priv *pahu,
+ struct wcd9xxx_pdata *pdata)
+{
+ struct snd_soc_codec *codec = pahu->codec;
+ u8 mad_dmic_ctl_val;
+ u8 anc_ctl_value;
+ u32 dmic_clk_drv;
+ int vout_ctl_1, vout_ctl_2, vout_ctl_3, vout_ctl_4;
+ int rc = 0;
+
+ if (!pdata) {
+ dev_err(codec->dev, "%s: NULL pdata\n", __func__);
+ return -ENODEV;
+ }
+
+ /* set micbias voltage */
+ vout_ctl_1 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb1_mv);
+ vout_ctl_2 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb2_mv);
+ vout_ctl_3 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb3_mv);
+ vout_ctl_4 = wcd9360_get_micb_vout_ctl_val(pdata->micbias.micb4_mv);
+ if (vout_ctl_1 < 0 || vout_ctl_2 < 0 ||
+ vout_ctl_3 < 0 || vout_ctl_4 < 0) {
+ rc = -EINVAL;
+ goto done;
+ }
+ snd_soc_update_bits(codec, WCD9360_ANA_MICB1, 0x3F, vout_ctl_1);
+ snd_soc_update_bits(codec, WCD9360_ANA_MICB2, 0x3F, vout_ctl_2);
+ snd_soc_update_bits(codec, WCD9360_ANA_MICB3, 0x3F, vout_ctl_3);
+ snd_soc_update_bits(codec, WCD9360_ANA_MICB4, 0x3F, vout_ctl_4);
+
+ if (pdata->dmic_sample_rate ==
+ WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
+ dev_info(codec->dev, "%s: dmic_rate invalid default = %d\n",
+ __func__, WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ);
+ pdata->dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ;
+ }
+ if (pdata->mad_dmic_sample_rate ==
+ WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED) {
+ dev_info(codec->dev, "%s: mad_dmic_rate invalid default = %d\n",
+ __func__, WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ);
+ /*
+ * use dmic_sample_rate as the default for MAD
+ * if mad dmic sample rate is undefined
+ */
+ pdata->mad_dmic_sample_rate = pdata->dmic_sample_rate;
+ }
+
+ if (pdata->dmic_clk_drv ==
+ WCD9XXX_DMIC_CLK_DRIVE_UNDEFINED) {
+ pdata->dmic_clk_drv = WCD9360_DMIC_CLK_DRIVE_DEFAULT;
+ dev_dbg(codec->dev,
+ "%s: dmic_clk_strength invalid, default = %d\n",
+ __func__, pdata->dmic_clk_drv);
+ }
+
+ switch (pdata->dmic_clk_drv) {
+ case 2:
+ dmic_clk_drv = 0;
+ break;
+ case 4:
+ dmic_clk_drv = 1;
+ break;
+ case 8:
+ dmic_clk_drv = 2;
+ break;
+ case 16:
+ dmic_clk_drv = 3;
+ break;
+ default:
+ dev_err(codec->dev,
+ "%s: invalid dmic_clk_drv %d, using default\n",
+ __func__, pdata->dmic_clk_drv);
+ dmic_clk_drv = 0;
+ break;
+ }
+
+ snd_soc_update_bits(codec, WCD9360_TEST_DEBUG_PAD_DRVCTL_0,
+ 0x0C, dmic_clk_drv << 2);
+
+ /*
+ * Default the DMIC clk rates to mad_dmic_sample_rate,
+ * whereas, the anc/txfe dmic rates to dmic_sample_rate
+ * since the anc/txfe are independent of mad block.
+ */
+ mad_dmic_ctl_val = pahu_get_dmic_clk_val(pahu->codec,
+ pdata->mad_dmic_sample_rate);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC0_CTL,
+ 0x0E, mad_dmic_ctl_val << 1);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC1_CTL,
+ 0x0E, mad_dmic_ctl_val << 1);
+ snd_soc_update_bits(codec, WCD9360_CPE_SS_DMIC2_CTL,
+ 0x0E, mad_dmic_ctl_val << 1);
+
+ if (dmic_clk_drv == WCD9360_DMIC_CLK_DIV_2)
+ anc_ctl_value = WCD9360_ANC_DMIC_X2_FULL_RATE;
+ else
+ anc_ctl_value = WCD9360_ANC_DMIC_X2_HALF_RATE;
+
+ snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_2_CTL,
+ 0x40, anc_ctl_value << 6);
+ snd_soc_update_bits(codec, WCD9360_CDC_ANC0_MODE_2_CTL,
+ 0x20, anc_ctl_value << 5);
+
+done:
+ return rc;
+}
+
+static void pahu_cdc_vote_svs(struct snd_soc_codec *codec, bool vote)
+{
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ return pahu_vote_svs(pahu, vote);
+}
+
+struct wcd_dsp_cdc_cb cdc_cb = {
+ .cdc_clk_en = pahu_codec_internal_rco_ctrl,
+ .cdc_vote_svs = pahu_cdc_vote_svs,
+};
+
+static int pahu_wdsp_initialize(struct snd_soc_codec *codec)
+{
+ struct wcd9xxx *control;
+ struct pahu_priv *pahu;
+ struct wcd_dsp_params params;
+ int ret = 0;
+
+ control = dev_get_drvdata(codec->dev->parent);
+ pahu = snd_soc_codec_get_drvdata(codec);
+
+ params.cb = &cdc_cb;
+ params.irqs.cpe_ipc1_irq = WCD9360_IRQ_CPE1_INTR;
+ params.irqs.cpe_err_irq = WCD9360_IRQ_CPE_ERROR;
+ params.irqs.fatal_irqs = CPE_FATAL_IRQS;
+ params.clk_rate = control->mclk_rate;
+ params.dsp_instance = 0;
+
+ wcd9360_dsp_cntl_init(codec, ¶ms, &pahu->wdsp_cntl);
+ if (!pahu->wdsp_cntl) {
+ dev_err(pahu->dev, "%s: wcd-dsp-control init failed\n",
+ __func__);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static void pahu_mclk2_reg_defaults(struct pahu_priv *pahu)
+{
+ int i;
+ struct snd_soc_codec *codec = pahu->codec;
+
+ /* MCLK2 configuration */
+ for (i = 0; i < ARRAY_SIZE(pahu_codec_mclk2_1_0_defaults); i++)
+ snd_soc_update_bits(codec,
+ pahu_codec_mclk2_1_0_defaults[i].reg,
+ pahu_codec_mclk2_1_0_defaults[i].mask,
+ pahu_codec_mclk2_1_0_defaults[i].val);
+}
+
+static int pahu_device_down(struct wcd9xxx *wcd9xxx)
+{
+ struct snd_soc_codec *codec;
+ struct pahu_priv *priv;
+ int count;
+
+ codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+ priv = snd_soc_codec_get_drvdata(codec);
+ if (priv->swr.ctrl_data)
+ swrm_wcd_notify(priv->swr.ctrl_data[0].swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ snd_soc_card_change_online_state(codec->component.card, 0);
+ for (count = 0; count < NUM_CODEC_DAIS; count++)
+ priv->dai[count].bus_down_in_recovery = true;
+ wcd9360_dsp_ssr_event(priv->wdsp_cntl, WCD_CDC_DOWN_EVENT);
+ wcd_resmgr_set_sido_input_src_locked(priv->resmgr,
+ SIDO_SOURCE_INTERNAL);
+
+ return 0;
+}
+
+static int pahu_post_reset_cb(struct wcd9xxx *wcd9xxx)
+{
+ int i, ret = 0;
+ struct wcd9xxx *control;
+ struct snd_soc_codec *codec;
+ struct pahu_priv *pahu;
+ struct wcd9xxx_pdata *pdata;
+
+ codec = (struct snd_soc_codec *)(wcd9xxx->ssr_priv);
+ pahu = snd_soc_codec_get_drvdata(codec);
+ control = dev_get_drvdata(codec->dev->parent);
+
+ wcd9xxx_set_power_state(pahu->wcd9xxx,
+ WCD_REGION_POWER_COLLAPSE_REMOVE,
+ WCD9XXX_DIG_CORE_REGION_1);
+
+ mutex_lock(&pahu->codec_mutex);
+
+ pahu_vote_svs(pahu, true);
+ pahu_slimbus_slave_port_cfg.slave_dev_intfdev_la =
+ control->slim_slave->laddr;
+ pahu_slimbus_slave_port_cfg.slave_dev_pgd_la =
+ control->slim->laddr;
+ pahu_init_slim_slave_cfg(codec);
+ snd_soc_card_change_online_state(codec->component.card, 1);
+
+ for (i = 0; i < PAHU_MAX_MICBIAS; i++)
+ pahu->micb_ref[i] = 0;
+
+ dev_dbg(codec->dev, "%s: MCLK Rate = %x\n",
+ __func__, control->mclk_rate);
+
+ pahu_update_reg_defaults(pahu);
+ wcd_resmgr_post_ssr_v2(pahu->resmgr);
+ __pahu_enable_efuse_sensing(pahu);
+ pahu_mclk2_reg_defaults(pahu);
+
+ __pahu_cdc_mclk_enable(pahu, true);
+ regcache_mark_dirty(codec->component.regmap);
+ regcache_sync(codec->component.regmap);
+ __pahu_cdc_mclk_enable(pahu, false);
+
+ pahu_update_cpr_defaults(pahu);
+
+ pdata = dev_get_platdata(codec->dev->parent);
+ ret = pahu_handle_pdata(pahu, pdata);
+ if (ret < 0)
+ dev_err(codec->dev, "%s: invalid pdata\n", __func__);
+
+ pahu_cleanup_irqs(pahu);
+ ret = pahu_setup_irqs(pahu);
+ if (ret) {
+ dev_err(codec->dev, "%s: pahu irq setup failed %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ pahu_set_spkr_mode(codec, pahu->swr.spkr_mode);
+ /*
+ * Once the codec initialization is completed, the svs vote
+ * can be released allowing the codec to go to SVS2.
+ */
+ pahu_vote_svs(pahu, false);
+ wcd9360_dsp_ssr_event(pahu->wdsp_cntl, WCD_CDC_UP_EVENT);
+
+done:
+ mutex_unlock(&pahu->codec_mutex);
+ return ret;
+}
+
+static int pahu_soc_codec_probe(struct snd_soc_codec *codec)
+{
+ struct wcd9xxx *control;
+ struct pahu_priv *pahu;
+ struct wcd9xxx_pdata *pdata;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ int i, ret;
+ void *ptr = NULL;
+
+ control = dev_get_drvdata(codec->dev->parent);
+
+ dev_info(codec->dev, "%s()\n", __func__);
+ pahu = snd_soc_codec_get_drvdata(codec);
+ pahu->intf_type = wcd9xxx_get_intf_type();
+
+ control->dev_down = pahu_device_down;
+ control->post_reset = pahu_post_reset_cb;
+ control->ssr_priv = (void *)codec;
+
+ /* Resource Manager post Init */
+ ret = wcd_resmgr_post_init(pahu->resmgr, &pahu_resmgr_cb, codec);
+ if (ret) {
+ dev_err(codec->dev, "%s: wcd resmgr post init failed\n",
+ __func__);
+ goto err;
+ }
+
+ pahu->fw_data = devm_kzalloc(codec->dev, sizeof(*(pahu->fw_data)),
+ GFP_KERNEL);
+ if (!pahu->fw_data)
+ goto err;
+
+ set_bit(WCD9XXX_ANC_CAL, pahu->fw_data->cal_bit);
+ set_bit(WCD9XXX_MAD_CAL, pahu->fw_data->cal_bit);
+
+ ret = wcd_cal_create_hwdep(pahu->fw_data,
+ WCD9XXX_CODEC_HWDEP_NODE, codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s hwdep failed %d\n", __func__, ret);
+ goto err_hwdep;
+ }
+
+ pahu->codec = codec;
+ for (i = 0; i < COMPANDER_MAX; i++)
+ pahu->comp_enabled[i] = 0;
+
+ pdata = dev_get_platdata(codec->dev->parent);
+ ret = pahu_handle_pdata(pahu, pdata);
+ if (ret < 0) {
+ dev_err(codec->dev, "%s: bad pdata\n", __func__);
+ goto err_hwdep;
+ }
+
+ ptr = devm_kzalloc(codec->dev, (sizeof(pahu_rx_chs) +
+ sizeof(pahu_tx_chs)), GFP_KERNEL);
+ if (!ptr) {
+ ret = -ENOMEM;
+ goto err_hwdep;
+ }
+
+ snd_soc_dapm_add_routes(dapm, pahu_slim_audio_map,
+ ARRAY_SIZE(pahu_slim_audio_map));
+ for (i = 0; i < NUM_CODEC_DAIS; i++) {
+ INIT_LIST_HEAD(&pahu->dai[i].wcd9xxx_ch_list);
+ init_waitqueue_head(&pahu->dai[i].dai_wait);
+ }
+ pahu_slimbus_slave_port_cfg.slave_dev_intfdev_la =
+ control->slim_slave->laddr;
+ pahu_slimbus_slave_port_cfg.slave_dev_pgd_la =
+ control->slim->laddr;
+ pahu_slimbus_slave_port_cfg.slave_port_mapping[0] =
+ WCD9360_TX13;
+ pahu_init_slim_slave_cfg(codec);
+
+ control->num_rx_port = WCD9360_RX_MAX;
+ control->rx_chs = ptr;
+ memcpy(control->rx_chs, pahu_rx_chs, sizeof(pahu_rx_chs));
+ control->num_tx_port = WCD9360_TX_MAX;
+ control->tx_chs = ptr + sizeof(pahu_rx_chs);
+ memcpy(control->tx_chs, pahu_tx_chs, sizeof(pahu_tx_chs));
+
+ ret = pahu_setup_irqs(pahu);
+ if (ret) {
+ dev_err(pahu->dev, "%s: pahu irq setup failed %d\n",
+ __func__, ret);
+ goto err_pdata;
+ }
+
+ for (i = 0; i < WCD9360_NUM_DECIMATORS; i++) {
+ pahu->tx_hpf_work[i].pahu = pahu;
+ pahu->tx_hpf_work[i].decimator = i;
+ INIT_DELAYED_WORK(&pahu->tx_hpf_work[i].dwork,
+ pahu_tx_hpf_corner_freq_callback);
+
+ pahu->tx_mute_dwork[i].pahu = pahu;
+ pahu->tx_mute_dwork[i].decimator = i;
+ INIT_DELAYED_WORK(&pahu->tx_mute_dwork[i].dwork,
+ pahu_tx_mute_update_callback);
+ }
+
+ pahu->spk_anc_dwork.pahu = pahu;
+ INIT_DELAYED_WORK(&pahu->spk_anc_dwork.dwork,
+ pahu_spk_anc_update_callback);
+
+ pahu_mclk2_reg_defaults(pahu);
+
+ mutex_lock(&pahu->codec_mutex);
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR PA");
+ snd_soc_dapm_disable_pin(dapm, "ANC EAR");
+ snd_soc_dapm_enable_pin(dapm, "ANC SPK1 PA");
+ mutex_unlock(&pahu->codec_mutex);
+
+ snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF2 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF2 Capture");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF3 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF3 Capture");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 MAD TX");
+ snd_soc_dapm_ignore_suspend(dapm, "VIfeed");
+ snd_soc_dapm_ignore_suspend(dapm, "I2S1 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "I2S1 Capture");
+
+ snd_soc_dapm_sync(dapm);
+
+ pahu_wdsp_initialize(codec);
+
+ /*
+ * Once the codec initialization is completed, the svs vote
+ * can be released allowing the codec to go to SVS2.
+ */
+ pahu_vote_svs(pahu, false);
+
+ return ret;
+
+err_pdata:
+ devm_kfree(codec->dev, ptr);
+ control->rx_chs = NULL;
+ control->tx_chs = NULL;
+err_hwdep:
+ devm_kfree(codec->dev, pahu->fw_data);
+ pahu->fw_data = NULL;
+err:
+ return ret;
+}
+
+static int pahu_soc_codec_remove(struct snd_soc_codec *codec)
+{
+ struct wcd9xxx *control;
+ struct pahu_priv *pahu = snd_soc_codec_get_drvdata(codec);
+
+ control = dev_get_drvdata(codec->dev->parent);
+ devm_kfree(codec->dev, control->rx_chs);
+ /* slimslave deinit in wcd core looks for this value */
+ control->num_rx_port = 0;
+ control->num_tx_port = 0;
+ control->rx_chs = NULL;
+ control->tx_chs = NULL;
+ pahu_cleanup_irqs(pahu);
+
+ if (pahu->wdsp_cntl)
+ wcd9360_dsp_cntl_deinit(&pahu->wdsp_cntl);
+
+ return 0;
+}
+
+static struct regmap *pahu_get_regmap(struct device *dev)
+{
+ struct wcd9xxx *control = dev_get_drvdata(dev->parent);
+
+ return control->regmap;
+}
+
+static struct snd_soc_codec_driver soc_codec_dev_pahu = {
+ .probe = pahu_soc_codec_probe,
+ .remove = pahu_soc_codec_remove,
+ .get_regmap = pahu_get_regmap,
+ .component_driver = {
+ .controls = pahu_snd_controls,
+ .num_controls = ARRAY_SIZE(pahu_snd_controls),
+ .dapm_widgets = pahu_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(pahu_dapm_widgets),
+ .dapm_routes = pahu_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(pahu_audio_map),
+ },
+};
+
+#ifdef CONFIG_PM
+static int pahu_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pahu_priv *pahu = platform_get_drvdata(pdev);
+
+ if (!pahu) {
+ dev_err(dev, "%s: pahu private data is NULL\n", __func__);
+ return -EINVAL;
+ }
+ dev_dbg(dev, "%s: system suspend\n", __func__);
+ if (delayed_work_pending(&pahu->power_gate_work) &&
+ cancel_delayed_work_sync(&pahu->power_gate_work))
+ pahu_codec_power_gate_digital_core(pahu);
+ return 0;
+}
+
+static int pahu_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct pahu_priv *pahu = platform_get_drvdata(pdev);
+
+ if (!pahu) {
+ dev_err(dev, "%s: pahu private data is NULL\n", __func__);
+ return -EINVAL;
+ }
+ dev_dbg(dev, "%s: system resume\n", __func__);
+ return 0;
+}
+
+static const struct dev_pm_ops pahu_pm_ops = {
+ .suspend = pahu_suspend,
+ .resume = pahu_resume,
+};
+#endif
+
+static int pahu_swrm_read(void *handle, int reg)
+{
+ struct pahu_priv *pahu;
+ struct wcd9xxx *wcd9xxx;
+ unsigned short swr_rd_addr_base;
+ unsigned short swr_rd_data_base;
+ int val, ret;
+
+ if (!handle) {
+ pr_err("%s: NULL handle\n", __func__);
+ return -EINVAL;
+ }
+ pahu = (struct pahu_priv *)handle;
+ wcd9xxx = pahu->wcd9xxx;
+
+ dev_dbg(pahu->dev, "%s: Reading soundwire register, 0x%x\n",
+ __func__, reg);
+ swr_rd_addr_base = WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0;
+ swr_rd_data_base = WCD9360_SWR_AHB_BRIDGE_RD_DATA_0;
+
+ mutex_lock(&pahu->swr.read_mutex);
+ ret = regmap_bulk_write(wcd9xxx->regmap, swr_rd_addr_base,
+ (u8 *)®, 4);
+ if (ret < 0) {
+ dev_err(pahu->dev, "%s: RD Addr Failure\n", __func__);
+ goto done;
+ }
+ ret = regmap_bulk_read(wcd9xxx->regmap, swr_rd_data_base,
+ (u8 *)&val, 4);
+ if (ret < 0) {
+ dev_err(pahu->dev, "%s: RD Data Failure\n", __func__);
+ goto done;
+ }
+ ret = val;
+done:
+ mutex_unlock(&pahu->swr.read_mutex);
+
+ return ret;
+}
+
+static int pahu_swrm_bulk_write(void *handle, u32 *reg, u32 *val, size_t len)
+{
+ struct pahu_priv *pahu;
+ struct wcd9xxx *wcd9xxx;
+ struct wcd9xxx_reg_val *bulk_reg;
+ unsigned short swr_wr_addr_base;
+ unsigned short swr_wr_data_base;
+ int i, j, ret;
+
+ if (!handle || !reg || !val) {
+ pr_err("%s: NULL parameter\n", __func__);
+ return -EINVAL;
+ }
+ if (len <= 0) {
+ pr_err("%s: Invalid size: %zu\n", __func__, len);
+ return -EINVAL;
+ }
+ pahu = (struct pahu_priv *)handle;
+ wcd9xxx = pahu->wcd9xxx;
+
+ swr_wr_addr_base = WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0;
+ swr_wr_data_base = WCD9360_SWR_AHB_BRIDGE_WR_DATA_0;
+
+ bulk_reg = kzalloc((2 * len * sizeof(struct wcd9xxx_reg_val)),
+ GFP_KERNEL);
+ if (!bulk_reg)
+ return -ENOMEM;
+
+ for (i = 0, j = 0; i < (len * 2); i += 2, j++) {
+ bulk_reg[i].reg = swr_wr_data_base;
+ bulk_reg[i].buf = (u8 *)(&val[j]);
+ bulk_reg[i].bytes = 4;
+ bulk_reg[i+1].reg = swr_wr_addr_base;
+ bulk_reg[i+1].buf = (u8 *)(®[j]);
+ bulk_reg[i+1].bytes = 4;
+ }
+
+ mutex_lock(&pahu->swr.write_mutex);
+ ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg,
+ (len * 2), false);
+ if (ret) {
+ dev_err(pahu->dev, "%s: swrm bulk write failed, ret: %d\n",
+ __func__, ret);
+ }
+ mutex_unlock(&pahu->swr.write_mutex);
+
+ kfree(bulk_reg);
+ return ret;
+}
+
+static int pahu_swrm_write(void *handle, int reg, int val)
+{
+ struct pahu_priv *pahu;
+ struct wcd9xxx *wcd9xxx;
+ unsigned short swr_wr_addr_base;
+ unsigned short swr_wr_data_base;
+ struct wcd9xxx_reg_val bulk_reg[2];
+ int ret;
+
+ if (!handle) {
+ pr_err("%s: NULL handle\n", __func__);
+ return -EINVAL;
+ }
+ pahu = (struct pahu_priv *)handle;
+ wcd9xxx = pahu->wcd9xxx;
+
+ swr_wr_addr_base = WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0;
+ swr_wr_data_base = WCD9360_SWR_AHB_BRIDGE_WR_DATA_0;
+
+ /* First Write the Data to register */
+ bulk_reg[0].reg = swr_wr_data_base;
+ bulk_reg[0].buf = (u8 *)(&val);
+ bulk_reg[0].bytes = 4;
+ bulk_reg[1].reg = swr_wr_addr_base;
+ bulk_reg[1].buf = (u8 *)(®);
+ bulk_reg[1].bytes = 4;
+
+ mutex_lock(&pahu->swr.write_mutex);
+ ret = wcd9xxx_slim_bulk_write(wcd9xxx, bulk_reg, 2, false);
+ if (ret < 0)
+ dev_err(pahu->dev, "%s: WR Data Failure\n", __func__);
+ mutex_unlock(&pahu->swr.write_mutex);
+
+ return ret;
+}
+
+static int pahu_swrm_clock(void *handle, bool enable)
+{
+ struct pahu_priv *pahu;
+
+ if (!handle) {
+ pr_err("%s: NULL handle\n", __func__);
+ return -EINVAL;
+ }
+ pahu = (struct pahu_priv *)handle;
+
+ mutex_lock(&pahu->swr.clk_mutex);
+ dev_dbg(pahu->dev, "%s: swrm clock %s\n",
+ __func__, (enable?"enable" : "disable"));
+ if (enable) {
+ pahu->swr.clk_users++;
+ if (pahu->swr.clk_users == 1) {
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_TEST_DEBUG_NPL_DLY_TEST_1,
+ 0x10, 0x00);
+ __pahu_cdc_mclk_enable(pahu, true);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL,
+ 0x01, 0x01);
+ }
+ } else {
+ pahu->swr.clk_users--;
+ if (pahu->swr.clk_users == 0) {
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL,
+ 0x01, 0x00);
+ __pahu_cdc_mclk_enable(pahu, false);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_TEST_DEBUG_NPL_DLY_TEST_1,
+ 0x10, 0x10);
+ }
+ }
+ dev_dbg(pahu->dev, "%s: swrm clock users %d\n",
+ __func__, pahu->swr.clk_users);
+ mutex_unlock(&pahu->swr.clk_mutex);
+
+ return 0;
+}
+
+static int pahu_swrm_handle_irq(void *handle,
+ irqreturn_t (*swrm_irq_handler)(int irq,
+ void *data),
+ void *swrm_handle,
+ int action)
+{
+ struct pahu_priv *pahu;
+ int ret = 0;
+ struct wcd9xxx *wcd9xxx;
+
+ if (!handle) {
+ pr_err("%s: NULL handle\n", __func__);
+ return -EINVAL;
+ }
+ pahu = (struct pahu_priv *) handle;
+ wcd9xxx = pahu->wcd9xxx;
+
+ if (action) {
+ ret = wcd9xxx_request_irq(&wcd9xxx->core_res,
+ WCD9360_IRQ_SOUNDWIRE,
+ swrm_irq_handler,
+ "Pahu SWR Master", swrm_handle);
+ if (ret)
+ dev_err(pahu->dev, "%s: Failed to request irq %d\n",
+ __func__, WCD9360_IRQ_SOUNDWIRE);
+ } else
+ wcd9xxx_free_irq(&wcd9xxx->core_res, WCD9360_IRQ_SOUNDWIRE,
+ swrm_handle);
+
+ return ret;
+}
+
+static void pahu_codec_add_spi_device(struct pahu_priv *pahu,
+ struct device_node *node)
+{
+ struct spi_master *master;
+ struct spi_device *spi;
+ u32 prop_value;
+ int rc;
+
+ /* Read the master bus num from DT node */
+ rc = of_property_read_u32(node, "qcom,master-bus-num",
+ &prop_value);
+ if (rc < 0) {
+ dev_err(pahu->dev, "%s: prop %s not found in node %s",
+ __func__, "qcom,master-bus-num", node->full_name);
+ goto done;
+ }
+
+ /* Get the reference to SPI master */
+ master = spi_busnum_to_master(prop_value);
+ if (!master) {
+ dev_err(pahu->dev, "%s: Invalid spi_master for bus_num %u\n",
+ __func__, prop_value);
+ goto done;
+ }
+
+ /* Allocate the spi device */
+ spi = spi_alloc_device(master);
+ if (!spi) {
+ dev_err(pahu->dev, "%s: spi_alloc_device failed\n",
+ __func__);
+ goto err_spi_alloc_dev;
+ }
+
+ /* Initialize device properties */
+ if (of_modalias_node(node, spi->modalias,
+ sizeof(spi->modalias)) < 0) {
+ dev_err(pahu->dev, "%s: cannot find modalias for %s\n",
+ __func__, node->full_name);
+ goto err_dt_parse;
+ }
+
+ rc = of_property_read_u32(node, "qcom,chip-select",
+ &prop_value);
+ if (rc < 0) {
+ dev_err(pahu->dev, "%s: prop %s not found in node %s",
+ __func__, "qcom,chip-select", node->full_name);
+ goto err_dt_parse;
+ }
+ spi->chip_select = prop_value;
+
+ rc = of_property_read_u32(node, "qcom,max-frequency",
+ &prop_value);
+ if (rc < 0) {
+ dev_err(pahu->dev, "%s: prop %s not found in node %s",
+ __func__, "qcom,max-frequency", node->full_name);
+ goto err_dt_parse;
+ }
+ spi->max_speed_hz = prop_value;
+
+ spi->dev.of_node = node;
+
+ rc = spi_add_device(spi);
+ if (rc < 0) {
+ dev_err(pahu->dev, "%s: spi_add_device failed\n", __func__);
+ goto err_dt_parse;
+ }
+
+ pahu->spi = spi;
+ /* Put the reference to SPI master */
+ put_device(&master->dev);
+
+ return;
+
+err_dt_parse:
+ spi_dev_put(spi);
+
+err_spi_alloc_dev:
+ /* Put the reference to SPI master */
+ put_device(&master->dev);
+done:
+ return;
+}
+
+static void pahu_add_child_devices(struct work_struct *work)
+{
+ struct pahu_priv *pahu;
+ struct platform_device *pdev;
+ struct device_node *node;
+ struct wcd9xxx *wcd9xxx;
+ struct pahu_swr_ctrl_data *swr_ctrl_data = NULL, *temp;
+ int ret, ctrl_num = 0;
+ struct wcd_swr_ctrl_platform_data *platdata;
+ char plat_dev_name[WCD9360_STRING_LEN];
+
+ pahu = container_of(work, struct pahu_priv,
+ pahu_add_child_devices_work);
+ if (!pahu) {
+ pr_err("%s: Memory for wcd9360 does not exist\n",
+ __func__);
+ return;
+ }
+ wcd9xxx = pahu->wcd9xxx;
+ if (!wcd9xxx) {
+ pr_err("%s: Memory for WCD9XXX does not exist\n",
+ __func__);
+ return;
+ }
+ if (!wcd9xxx->dev->of_node) {
+ dev_err(wcd9xxx->dev, "%s: DT node for wcd9xxx does not exist\n",
+ __func__);
+ return;
+ }
+
+ platdata = &pahu->swr.plat_data;
+ pahu->child_count = 0;
+
+ for_each_child_of_node(wcd9xxx->dev->of_node, node) {
+
+ /* Parse and add the SPI device node */
+ if (!strcmp(node->name, "wcd_spi")) {
+ pahu_codec_add_spi_device(pahu, node);
+ continue;
+ }
+
+ /* Parse other child device nodes and add platform device */
+ if (!strcmp(node->name, "swr_master"))
+ strlcpy(plat_dev_name, "pahu_swr_ctrl",
+ (WCD9360_STRING_LEN - 1));
+ else if (strnstr(node->name, "msm_cdc_pinctrl",
+ strlen("msm_cdc_pinctrl")) != NULL)
+ strlcpy(plat_dev_name, node->name,
+ (WCD9360_STRING_LEN - 1));
+ else
+ continue;
+
+ pdev = platform_device_alloc(plat_dev_name, -1);
+ if (!pdev) {
+ dev_err(wcd9xxx->dev, "%s: pdev memory alloc failed\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err_mem;
+ }
+ pdev->dev.parent = pahu->dev;
+ pdev->dev.of_node = node;
+
+ if (strcmp(node->name, "swr_master") == 0) {
+ ret = platform_device_add_data(pdev, platdata,
+ sizeof(*platdata));
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: cannot add plat data ctrl:%d\n",
+ __func__, ctrl_num);
+ goto err_pdev_add;
+ }
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: Cannot add platform device\n",
+ __func__);
+ goto err_pdev_add;
+ }
+
+ if (strcmp(node->name, "swr_master") == 0) {
+ temp = krealloc(swr_ctrl_data,
+ (ctrl_num + 1) * sizeof(
+ struct pahu_swr_ctrl_data),
+ GFP_KERNEL);
+ if (!temp) {
+ dev_err(wcd9xxx->dev, "out of memory\n");
+ ret = -ENOMEM;
+ goto err_pdev_add;
+ }
+ swr_ctrl_data = temp;
+ swr_ctrl_data[ctrl_num].swr_pdev = pdev;
+ ctrl_num++;
+ dev_dbg(&pdev->dev,
+ "%s: Added soundwire ctrl device(s)\n",
+ __func__);
+ pahu->swr.ctrl_data = swr_ctrl_data;
+ }
+ if (pahu->child_count < WCD9360_CHILD_DEVICES_MAX)
+ pahu->pdev_child_devices[pahu->child_count++] = pdev;
+ else
+ goto err_mem;
+ }
+
+ return;
+
+err_pdev_add:
+ platform_device_put(pdev);
+err_mem:
+ return;
+}
+
+static int __pahu_enable_efuse_sensing(struct pahu_priv *pahu)
+{
+ int val, rc;
+
+ WCD9XXX_V2_BG_CLK_LOCK(pahu->resmgr);
+ __pahu_cdc_mclk_enable_locked(pahu, true);
+
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x1E, 0x10);
+ regmap_update_bits(pahu->wcd9xxx->regmap,
+ WCD9360_CHIP_TIER_CTRL_EFUSE_CTL, 0x01, 0x01);
+ /*
+ * 5ms sleep required after enabling efuse control
+ * before checking the status.
+ */
+ usleep_range(5000, 5500);
+ wcd_resmgr_set_sido_input_src(pahu->resmgr,
+ SIDO_SOURCE_RCO_BG);
+
+ WCD9XXX_V2_BG_CLK_UNLOCK(pahu->resmgr);
+
+ rc = regmap_read(pahu->wcd9xxx->regmap,
+ WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS, &val);
+ if (rc || (!(val & 0x01)))
+ WARN(1, "%s: Efuse sense is not complete val=%x, ret=%d\n",
+ __func__, val, rc);
+
+ __pahu_cdc_mclk_enable(pahu, false);
+
+ return rc;
+}
+
+/*
+ * pahu_get_wcd_dsp_cntl: Get the reference to wcd_dsp_cntl
+ * @dev: Device pointer for codec device
+ *
+ * This API gets the reference to codec's struct wcd_dsp_cntl
+ */
+void *pahu_get_wcd_dsp_cntl(struct device *dev)
+{
+ struct platform_device *pdev;
+ struct pahu_priv *pahu;
+
+ if (!dev) {
+ pr_err("%s: Invalid device\n", __func__);
+ return NULL;
+ }
+
+ pdev = to_platform_device(dev);
+ pahu = platform_get_drvdata(pdev);
+
+ return pahu->wdsp_cntl;
+}
+EXPORT_SYMBOL(pahu_get_wcd_dsp_cntl);
+
+static int pahu_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct pahu_priv *pahu;
+ struct clk *wcd_ext_clk;
+ struct wcd9xxx_resmgr_v2 *resmgr;
+ struct wcd9xxx_power_region *cdc_pwr;
+
+ pahu = devm_kzalloc(&pdev->dev, sizeof(struct pahu_priv),
+ GFP_KERNEL);
+ if (!pahu)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pahu);
+
+ pahu->wcd9xxx = dev_get_drvdata(pdev->dev.parent);
+ pahu->dev = &pdev->dev;
+ INIT_DELAYED_WORK(&pahu->power_gate_work, pahu_codec_power_gate_work);
+ mutex_init(&pahu->power_lock);
+ INIT_WORK(&pahu->pahu_add_child_devices_work,
+ pahu_add_child_devices);
+ mutex_init(&pahu->micb_lock);
+ mutex_init(&pahu->swr.read_mutex);
+ mutex_init(&pahu->swr.write_mutex);
+ mutex_init(&pahu->swr.clk_mutex);
+ mutex_init(&pahu->codec_mutex);
+ mutex_init(&pahu->svs_mutex);
+
+ /*
+ * Codec hardware by default comes up in SVS mode.
+ * Initialize the svs_ref_cnt to 1 to reflect the hardware
+ * state in the driver.
+ */
+ pahu->svs_ref_cnt = 1;
+
+ cdc_pwr = devm_kzalloc(&pdev->dev, sizeof(struct wcd9xxx_power_region),
+ GFP_KERNEL);
+ if (!cdc_pwr) {
+ ret = -ENOMEM;
+ goto err_resmgr;
+ }
+ pahu->wcd9xxx->wcd9xxx_pwr[WCD9XXX_DIG_CORE_REGION_1] = cdc_pwr;
+ cdc_pwr->pwr_collapse_reg_min = WCD9360_DIG_CORE_REG_MIN;
+ cdc_pwr->pwr_collapse_reg_max = WCD9360_DIG_CORE_REG_MAX;
+ wcd9xxx_set_power_state(pahu->wcd9xxx,
+ WCD_REGION_POWER_COLLAPSE_REMOVE,
+ WCD9XXX_DIG_CORE_REGION_1);
+ /*
+ * Init resource manager so that if child nodes such as SoundWire
+ * requests for clock, resource manager can honor the request
+ */
+ resmgr = wcd_resmgr_init(&pahu->wcd9xxx->core_res, NULL);
+ if (IS_ERR(resmgr)) {
+ ret = PTR_ERR(resmgr);
+ dev_err(&pdev->dev, "%s: Failed to initialize wcd resmgr\n",
+ __func__);
+ goto err_resmgr;
+ }
+ pahu->resmgr = resmgr;
+ pahu->swr.plat_data.handle = (void *) pahu;
+ pahu->swr.plat_data.read = pahu_swrm_read;
+ pahu->swr.plat_data.write = pahu_swrm_write;
+ pahu->swr.plat_data.bulk_write = pahu_swrm_bulk_write;
+ pahu->swr.plat_data.clk = pahu_swrm_clock;
+ pahu->swr.plat_data.handle_irq = pahu_swrm_handle_irq;
+ pahu->swr.spkr_gain_offset = WCD9360_RX_GAIN_OFFSET_0_DB;
+
+ /* Register for Clock */
+ wcd_ext_clk = clk_get(pahu->wcd9xxx->dev, "wcd_clk");
+ if (IS_ERR(wcd_ext_clk)) {
+ dev_err(pahu->wcd9xxx->dev, "%s: clk get %s failed\n",
+ __func__, "wcd_ext_clk");
+ goto err_clk;
+ }
+ pahu->wcd_ext_clk = wcd_ext_clk;
+ dev_dbg(&pdev->dev, "%s: MCLK Rate = %x\n", __func__,
+ pahu->wcd9xxx->mclk_rate);
+ /* Update codec register default values */
+ pahu_update_reg_defaults(pahu);
+ __pahu_enable_efuse_sensing(pahu);
+ pahu_update_cpr_defaults(pahu);
+
+ /* Register with soc framework */
+ ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_pahu,
+ pahu_dai, ARRAY_SIZE(pahu_dai));
+ if (ret) {
+ dev_err(&pdev->dev, "%s: Codec registration failed\n",
+ __func__);
+ goto err_cdc_reg;
+ }
+ schedule_work(&pahu->pahu_add_child_devices_work);
+
+ return ret;
+
+err_cdc_reg:
+ clk_put(pahu->wcd_ext_clk);
+err_clk:
+ wcd_resmgr_remove(pahu->resmgr);
+err_resmgr:
+ mutex_destroy(&pahu->micb_lock);
+ mutex_destroy(&pahu->svs_mutex);
+ mutex_destroy(&pahu->codec_mutex);
+ mutex_destroy(&pahu->swr.read_mutex);
+ mutex_destroy(&pahu->swr.write_mutex);
+ mutex_destroy(&pahu->swr.clk_mutex);
+ devm_kfree(&pdev->dev, pahu);
+
+ return ret;
+}
+
+static int pahu_remove(struct platform_device *pdev)
+{
+ struct pahu_priv *pahu;
+ int count = 0;
+
+ pahu = platform_get_drvdata(pdev);
+ if (!pahu)
+ return -EINVAL;
+
+ if (pahu->spi)
+ spi_unregister_device(pahu->spi);
+ for (count = 0; count < pahu->child_count &&
+ count < WCD9360_CHILD_DEVICES_MAX; count++)
+ platform_device_unregister(pahu->pdev_child_devices[count]);
+
+ mutex_destroy(&pahu->micb_lock);
+ mutex_destroy(&pahu->svs_mutex);
+ mutex_destroy(&pahu->codec_mutex);
+ mutex_destroy(&pahu->swr.read_mutex);
+ mutex_destroy(&pahu->swr.write_mutex);
+ mutex_destroy(&pahu->swr.clk_mutex);
+
+ snd_soc_unregister_codec(&pdev->dev);
+ clk_put(pahu->wcd_ext_clk);
+ wcd_resmgr_remove(pahu->resmgr);
+ devm_kfree(&pdev->dev, pahu);
+ return 0;
+}
+
+static struct platform_driver pahu_codec_driver = {
+ .probe = pahu_probe,
+ .remove = pahu_remove,
+ .driver = {
+ .name = "pahu_codec",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &pahu_pm_ops,
+#endif
+ },
+};
+
+module_platform_driver(pahu_codec_driver);
+
+MODULE_DESCRIPTION("Pahu Codec driver");
+MODULE_LICENSE("GPL v2");
diff --git a/asoc/codecs/wcd9360/wcd9360.h b/asoc/codecs/wcd9360/wcd9360.h
new file mode 100644
index 0000000..2c70a68
--- /dev/null
+++ b/asoc/codecs/wcd9360/wcd9360.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __WCD9360_H__
+#define __WCD9360_H__
+
+#include <dsp/apr_audio-v2.h>
+#include "../wcd9xxx-slimslave.h"
+#include "../wcd9xxx-common-v2.h"
+
+#define WCD9360_REGISTER_START_OFFSET 0x800
+#define WCD9360_SB_PGD_PORT_RX_BASE 0x40
+#define WCD9360_SB_PGD_PORT_TX_BASE 0x50
+#define WCD9360_RX_PORT_START_NUMBER 16
+
+#define WCD9360_DMIC_CLK_DIV_2 0x0
+#define WCD9360_DMIC_CLK_DIV_3 0x1
+#define WCD9360_DMIC_CLK_DIV_4 0x2
+#define WCD9360_DMIC_CLK_DIV_6 0x3
+#define WCD9360_DMIC_CLK_DIV_8 0x4
+#define WCD9360_DMIC_CLK_DIV_16 0x5
+#define WCD9360_DMIC_CLK_DRIVE_DEFAULT 0x02
+
+#define WCD9360_ANC_DMIC_X2_FULL_RATE 1
+#define WCD9360_ANC_DMIC_X2_HALF_RATE 0
+
+#define PAHU_MAX_MICBIAS 4
+#define PAHU_NUM_INTERPOLATORS 10
+#define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64
+
+/* Convert from vout ctl to micbias voltage in mV */
+#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
+
+
+/* Number of input and output Slimbus port */
+enum {
+ WCD9360_RX0 = 0,
+ WCD9360_RX1,
+ WCD9360_RX2,
+ WCD9360_RX3,
+ WCD9360_RX4,
+ WCD9360_RX5,
+ WCD9360_RX6,
+ WCD9360_RX7,
+ WCD9360_RX_MAX,
+};
+
+enum {
+ WCD9360_TX0 = 0,
+ WCD9360_TX1,
+ WCD9360_TX2,
+ WCD9360_TX3,
+ WCD9360_TX4,
+ WCD9360_TX5,
+ WCD9360_TX6,
+ WCD9360_TX7,
+ WCD9360_TX8,
+ WCD9360_TX9,
+ WCD9360_TX10,
+ WCD9360_TX11,
+ WCD9360_TX12,
+ WCD9360_TX13,
+ WCD9360_TX14,
+ WCD9360_TX15,
+ WCD9360_TX_MAX,
+};
+
+/*
+ * Selects compander and smart boost settings
+ * for a given speaker mode
+ */
+enum {
+ WCD9360_SPKR_MODE_DEFAULT,
+ WCD9360_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */
+};
+
+/*
+ * Rx path gain offsets
+ */
+enum {
+ WCD9360_RX_GAIN_OFFSET_M1P5_DB,
+ WCD9360_RX_GAIN_OFFSET_0_DB,
+};
+
+enum {
+ WCD9360_MIC_BIAS_1 = 1,
+ WCD9360_MIC_BIAS_2,
+ WCD9360_MIC_BIAS_3,
+ WCD9360_MIC_BIAS_4
+};
+
+enum {
+ WCD9360_MICB_PULLUP_ENABLE,
+ WCD9360_MICB_PULLUP_DISABLE,
+ WCD9360_MICB_ENABLE,
+ WCD9360_MICB_DISABLE,
+};
+
+/*
+ * Dai data structure holds the
+ * dai specific info like rate,
+ * channel number etc.
+ */
+struct pahu_codec_dai_data {
+ u32 rate;
+ u32 *ch_num;
+ u32 ch_act;
+ u32 ch_tot;
+};
+
+/*
+ * Structure used to update codec
+ * register defaults after reset
+ */
+struct pahu_reg_mask_val {
+ u16 reg;
+ u8 mask;
+ u8 val;
+};
+
+extern void *pahu_get_afe_config(struct snd_soc_codec *codec,
+ enum afe_config_type config_type);
+extern int pahu_cdc_mclk_enable(struct snd_soc_codec *codec, bool enable);
+extern int pahu_cdc_mclk_tx_enable(struct snd_soc_codec *codec, bool enable);
+extern int pahu_set_spkr_mode(struct snd_soc_codec *codec, int mode);
+extern int pahu_set_spkr_gain_offset(struct snd_soc_codec *codec, int offset);
+extern void *pahu_get_wcd_dsp_cntl(struct device *dev);
+extern int wcd9360_get_micb_vout_ctl_val(u32 micb_mv);
+extern int pahu_codec_info_create_codec_entry(
+ struct snd_info_entry *codec_root,
+ struct snd_soc_codec *codec);
+#endif
diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c
index 49be43a..7cb7f68 100644
--- a/asoc/codecs/wcd9xxx-core.c
+++ b/asoc/codecs/wcd9xxx-core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -51,7 +51,7 @@
* Number of return values needs to be checked for each
* registration of Slimbus of I2C bus for each codec
*/
-#define NUM_WCD9XXX_REG_RET 4
+#define NUM_WCD9XXX_REG_RET 5
#define SLIM_USR_MC_REPEAT_CHANGE_VALUE 0x0
#define SLIM_REPEAT_WRITE_MAX_SLICE 16
@@ -88,9 +88,12 @@
[WCD9330] = WCD9330,
[WCD9335] = WCD9335,
[WCD934X] = WCD934X,
+ [WCD9360] = WCD9360,
};
static const struct of_device_id wcd9xxx_of_match[] = {
+ { .compatible = "qcom,tavil-i2c",
+ .data = (void *)&wcd9xxx_cdc_types[WCD934X]},
{ .compatible = "qcom,tasha-i2c-pgd",
.data = (void *)&wcd9xxx_cdc_types[WCD9335]},
{ .compatible = "qcom,wcd9xxx-i2c",
@@ -327,7 +330,8 @@
struct slim_ele_access slim_msg;
mutex_lock(&wcd9xxx->io_lock);
- if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X) {
+ if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X ||
+ wcd9xxx->type == WCD9360) {
ret = wcd9xxx_page_write(wcd9xxx, ®);
if (ret)
goto done;
@@ -1346,7 +1350,8 @@
* Vout_D to be ready after BUCK_SIDO is powered up.
* SYS_RST_N shouldn't be pulled high during this time
*/
- if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X)
+ if (wcd9xxx->type == WCD9335 || wcd9xxx->type == WCD934X ||
+ wcd9xxx->type == WCD9360)
usleep_range(600, 650);
else
usleep_range(5, 10);
@@ -1592,6 +1597,7 @@
{"tomtom-slim-pgd", WCD9330},
{"tasha-slim-pgd", WCD9335},
{"tavil-slim-pgd", WCD934X},
+ {"pahu-slim-pgd", WCD9360},
{}
};
@@ -1623,6 +1629,11 @@
{}
};
+static struct i2c_device_id tavil_id_table[] = {
+ {"tavil-i2c", WCD9XXX_I2C_TOP_LEVEL},
+ {}
+};
+
static struct i2c_device_id tabla_id_table[] = {
{"tabla top level", WCD9XXX_I2C_TOP_LEVEL},
{"tabla analog", WCD9XXX_I2C_ANALOG},
@@ -1670,6 +1681,17 @@
.remove = wcd9xxx_i2c_remove,
};
+static struct i2c_driver wcd934x_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "tavil-i2c-core",
+ .pm = &wcd9xxx_i2c_pm_ops,
+ },
+ .id_table = tavil_id_table,
+ .probe = wcd9xxx_i2c_probe,
+ .remove = wcd9xxx_i2c_remove,
+};
+
int wcd9xxx_init(void)
{
int ret[NUM_WCD9XXX_REG_RET] = {0};
@@ -1697,6 +1719,11 @@
pr_err("%s: Failed to register wcd SB driver: %d\n",
__func__, ret[3]);
+ ret[4] = i2c_add_driver(&wcd934x_i2c_driver);
+ if (ret[4])
+ pr_err("%s: Failed to add the wcd934x I2C driver: %d\n",
+ __func__, ret[4]);
+
for (i = 0; i < NUM_WCD9XXX_REG_RET; i++) {
if (ret[i])
return ret[i];
@@ -1712,6 +1739,7 @@
i2c_del_driver(&tabla_i2c_driver);
i2c_del_driver(&wcd9xxx_i2c_driver);
i2c_del_driver(&wcd9335_i2c_driver);
+ i2c_del_driver(&wcd934x_i2c_driver);
slim_driver_unregister(&wcd_slim_driver);
}
diff --git a/asoc/codecs/wcd9xxx-regmap.h b/asoc/codecs/wcd9xxx-regmap.h
index b7604ff..18e0e58 100644
--- a/asoc/codecs/wcd9xxx-regmap.h
+++ b/asoc/codecs/wcd9xxx-regmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -19,6 +19,8 @@
typedef int (*regmap_patch_fptr)(struct regmap *, int);
+extern struct regmap_config wcd9360_regmap_config;
+
extern struct regmap_config wcd934x_regmap_config;
extern int wcd934x_regmap_register_patch(struct regmap *regmap,
int version);
@@ -32,6 +34,9 @@
struct regmap_config *regmap_config;
switch (type) {
+ case WCD9360:
+ regmap_config = &wcd9360_regmap_config;
+ break;
case WCD934X:
regmap_config = &wcd934x_regmap_config;
break;
diff --git a/asoc/codecs/wcd9xxx-resmgr-v2.c b/asoc/codecs/wcd9xxx-resmgr-v2.c
index 1b7610f..d390558 100644
--- a/asoc/codecs/wcd9xxx-resmgr-v2.c
+++ b/asoc/codecs/wcd9xxx-resmgr-v2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,14 +17,18 @@
#include <sound/soc.h>
#include "wcd9xxx-resmgr-v2.h"
#include "core.h"
-#include "wcd9335_registers.h"
-#include <asoc/wcd934x_registers.h>
#define WCD9XXX_RCO_CALIBRATION_DELAY_INC_US 5000
+/* This register is valid only for WCD9335 */
+#define WCD93XX_ANA_CLK_TOP 0x0602
+
#define WCD93XX_ANA_BIAS 0x0601
#define WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL 0x0d41
#define WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL 0x0d42
-
+#define WCD93XX_CLK_SYS_MCLK_PRG 0x711
+#define WCD93XX_CODEC_RPM_CLK_GATE 0x002
+#define WCD93XX_ANA_RCO 0x603
+#define WCD93XX_ANA_BUCK_CTL 0x606
static const char *wcd_resmgr_clk_type_to_str(enum wcd_clock_type clk_type)
{
@@ -44,13 +48,13 @@
bool change;
int ret;
- if (resmgr->codec_type == WCD934X) {
- /* Tavil does not support ANA_CLK_TOP register */
- if (reg == WCD9335_ANA_CLK_TOP)
+ if (resmgr->codec_type != WCD9335) {
+ /* Tavil and Pahu does not support ANA_CLK_TOP register */
+ if (reg == WCD93XX_ANA_CLK_TOP)
return 0;
} else {
/* Tasha does not support CLK_SYS_MCLK_PRG register */
- if (reg == WCD934X_CLK_SYS_MCLK_PRG)
+ if (reg == WCD93XX_CLK_SYS_MCLK_PRG)
return 0;
}
if (resmgr->codec) {
@@ -74,11 +78,11 @@
{
int val, ret;
- if (resmgr->codec_type == WCD934X) {
- if (reg == WCD9335_ANA_CLK_TOP)
+ if (resmgr->codec_type != WCD9335) {
+ if (reg == WCD93XX_ANA_CLK_TOP)
return 0;
} else {
- if (reg == WCD934X_CLK_SYS_MCLK_PRG)
+ if (reg == WCD93XX_CLK_SYS_MCLK_PRG)
return 0;
}
if (resmgr->codec) {
@@ -242,26 +246,26 @@
if (++resmgr->clk_mclk_users == 1) {
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_CLK_TOP, 0x80, 0x80);
+ WCD93XX_ANA_CLK_TOP, 0x80, 0x80);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_CLK_TOP, 0x08, 0x00);
+ WCD93XX_ANA_CLK_TOP, 0x08, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_CLK_TOP, 0x04, 0x04);
- if (resmgr->codec_type == WCD934X) {
+ WCD93XX_ANA_CLK_TOP, 0x04, 0x04);
+ if (resmgr->codec_type != WCD9335) {
/*
* In tavil clock contrl register is changed
* to CLK_SYS_MCLK_PRG
*/
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x80);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x80);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x30, 0x10);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x30, 0x10);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x01, 0x01);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x01, 0x01);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x00);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x01);
@@ -269,10 +273,7 @@
WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x01);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL,
- 0x01, 0x01);
- wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CODEC_RPM_CLK_GATE, 0x03, 0x00);
+ WCD93XX_CODEC_RPM_CLK_GATE, 0x03, 0x00);
} else {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
@@ -308,28 +309,28 @@
if (resmgr->clk_rco_users > 0) {
/* MCLK to RCO switch */
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_CLK_TOP,
+ WCD93XX_ANA_CLK_TOP,
0x08, 0x08);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x02, 0x02);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x02);
/* Disable clock buffer */
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x80, 0x00);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x00);
resmgr->clk_type = WCD_CLK_RCO;
} else {
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_CLK_TOP,
+ WCD93XX_ANA_CLK_TOP,
0x04, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG, 0x81, 0x00);
+ WCD93XX_CLK_SYS_MCLK_PRG, 0x81, 0x00);
resmgr->clk_type = WCD_CLK_OFF;
}
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
0x80, 0x00);
}
- if ((resmgr->codec_type == WCD934X) &&
+ if ((resmgr->codec_type != WCD9335) &&
(resmgr->clk_type == WCD_CLK_OFF))
wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
@@ -342,15 +343,15 @@
static void wcd_resmgr_set_buck_accuracy(struct wcd9xxx_resmgr_v2 *resmgr)
{
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x02, 0x02);
/* 100us sleep needed after HIGH_ACCURACY_PRE_EN1 */
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x01, 0x01);
/* 100us sleep needed after HIGH_ACCURACY_PRE_EN2 */
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x04, 0x04);
/* 100us sleep needed after HIGH_ACCURACY_EN */
usleep_range(100, 110);
@@ -373,9 +374,9 @@
/* RCO Enable */
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) {
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_RCO,
- 0x80, 0x80);
- if (resmgr->codec_type == WCD934X)
+ WCD93XX_ANA_RCO,
+ 0x80, 0x80);
+ if (resmgr->codec_type != WCD9335)
wcd_resmgr_set_buck_accuracy(resmgr);
}
@@ -384,7 +385,7 @@
* requirements
*/
usleep_range(20, 25);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x40, 0x40);
/*
* 20us required after RCO is enabled as per HW
@@ -392,20 +393,20 @@
*/
usleep_range(20, 25);
/* RCO Calibration */
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x04, 0x04);
- if (resmgr->codec_type == WCD934X)
+ if (resmgr->codec_type != WCD9335)
/*
- * For wcd934x codec, 20us sleep is needed
+ * For wcd934x and wcd936x codecs, 20us sleep is needed
* after enabling RCO calibration
*/
usleep_range(20, 25);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x04, 0x00);
- if (resmgr->codec_type == WCD934X)
+ if (resmgr->codec_type != WCD9335)
/*
- * For wcd934x codec, 20us sleep is needed
+ * For wcd934x and wcd936x codecs, 20us sleep is needed
* after disabling RCO calibration
*/
usleep_range(20, 25);
@@ -413,7 +414,7 @@
/* RCO calibration takes app. 5ms to complete */
usleep_range(WCD9XXX_RCO_CALIBRATION_DELAY_INC_US,
WCD9XXX_RCO_CALIBRATION_DELAY_INC_US + 100);
- if (wcd_resmgr_codec_reg_read(resmgr, WCD9335_ANA_RCO) & 0x02)
+ if (wcd_resmgr_codec_reg_read(resmgr, WCD93XX_ANA_RCO) & 0x02)
rco_cal_done = false;
WARN((!rco_cal_done), "RCO Calibration failed\n");
@@ -421,10 +422,10 @@
/* Switch MUX to RCO */
if (resmgr->clk_mclk_users == 1) {
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_CLK_TOP,
+ WCD93XX_ANA_CLK_TOP,
0x08, 0x08);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG,
+ WCD93XX_CLK_SYS_MCLK_PRG,
0x02, 0x02);
resmgr->clk_type = WCD_CLK_RCO;
}
@@ -449,35 +450,35 @@
if ((resmgr->clk_rco_users == 0) &&
(resmgr->clk_type == WCD_CLK_RCO)) {
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
0x08, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG,
+ WCD93XX_CLK_SYS_MCLK_PRG,
0x02, 0x00);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_CLK_TOP,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
0x04, 0x00);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x40, 0x00);
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL)
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_RCO,
+ WCD93XX_ANA_RCO,
0x80, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD934X_CLK_SYS_MCLK_PRG,
+ WCD93XX_CLK_SYS_MCLK_PRG,
0x01, 0x00);
resmgr->clk_type = WCD_CLK_OFF;
} else if ((resmgr->clk_rco_users == 0) &&
(resmgr->clk_mclk_users)) {
/* Disable RCO while MCLK is ON */
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD9335_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x40, 0x00);
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL)
wcd_resmgr_codec_reg_update_bits(resmgr,
- WCD9335_ANA_RCO,
+ WCD93XX_ANA_RCO,
0x80, 0x00);
}
- if ((resmgr->codec_type == WCD934X) &&
+ if ((resmgr->codec_type != WCD9335) &&
(resmgr->clk_type == WCD_CLK_OFF))
wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
@@ -530,28 +531,28 @@
return;
if (sido_src == SIDO_SOURCE_INTERNAL) {
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x04, 0x00);
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x03, 0x00);
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x80, 0x00);
usleep_range(100, 110);
resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
pr_debug("%s: sido input src to internal\n", __func__);
} else if (sido_src == SIDO_SOURCE_RCO_BG) {
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_RCO,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x80, 0x80);
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x02, 0x02);
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x01, 0x01);
usleep_range(100, 110);
- wcd_resmgr_codec_reg_update_bits(resmgr, WCD934X_ANA_BUCK_CTL,
+ wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x04, 0x04);
usleep_range(100, 110);
resmgr->sido_input_src = SIDO_SOURCE_RCO_BG;
diff --git a/asoc/codecs/wcd9xxx-rst.c b/asoc/codecs/wcd9xxx-rst.c
index 3df95d5..563dd78 100644
--- a/asoc/codecs/wcd9xxx-rst.c
+++ b/asoc/codecs/wcd9xxx-rst.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -22,6 +22,8 @@
#include "wcd9335_irq.h"
#include <asoc/wcd934x_registers.h>
#include "wcd934x/wcd934x_irq.h"
+#include <asoc/wcd9360-registers.h>
+#include "wcd9360/wcd9360-irq.h"
/* wcd9335 interrupt table */
static const struct intr_data wcd9335_intr_table[] = {
@@ -86,6 +88,25 @@
{WCD934X_IRQ_VBAT_RESTORE, false},
};
+static const struct intr_data wcd9360_intr_table[] = {
+ {WCD9XXX_IRQ_SLIMBUS, false},
+ {WCD9360_IRQ_MISC, false},
+ {WCD9360_IRQ_LDO_RXTX_SCD, false},
+ {WCD9360_IRQ_EAR_PA_SCD, false},
+ {WCD9360_IRQ_AUX_PA_SCD, false},
+ {WCD9360_IRQ_EAR_PA_CNP_COMPLETE, false},
+ {WCD9360_IRQ_AUX_PA_CNP_COMPLETE, false},
+ {WCD9360_IRQ_RESERVED_3, false},
+ {WCD9360_IRQ_SOUNDWIRE, false},
+ {WCD9360_IRQ_RCO_ERROR, false},
+ {WCD9360_IRQ_CPE_ERROR, false},
+ {WCD9360_IRQ_MAD_AUDIO, false},
+ {WCD9360_IRQ_MAD_BEACON, false},
+ {WCD9360_IRQ_CPE1_INTR, true},
+ {WCD9360_IRQ_RESERVED_4, false},
+ {WCD9360_IRQ_MAD_ULTRASOUND, false},
+};
+
/*
* wcd9335_bring_down: Bringdown WCD Codec
*
@@ -384,11 +405,143 @@
return rc;
}
+/*
+ * wcd9360_bring_down: Bringdown WCD Codec
+ *
+ * @wcd9xxx: Pointer to wcd9xxx structure
+ *
+ * Returns 0 for success or negative error code for failure
+ */
+static int wcd9360_bring_down(struct wcd9xxx *wcd9xxx)
+{
+ if (!wcd9xxx || !wcd9xxx->regmap)
+ return -EINVAL;
+
+ regmap_write(wcd9xxx->regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
+ 0x04);
+
+ return 0;
+}
+
+/*
+ * wcd9360_bring_up: Bringup WCD Codec
+ *
+ * @wcd9xxx: Pointer to the wcd9xxx structure
+ *
+ * Returns 0 for success or negative error code for failure
+ */
+static int wcd9360_bring_up(struct wcd9xxx *wcd9xxx)
+{
+ struct regmap *wcd_regmap;
+
+ if (!wcd9xxx)
+ return -EINVAL;
+
+ if (!wcd9xxx->regmap) {
+ dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null!\n",
+ __func__);
+ return -EINVAL;
+ }
+ wcd_regmap = wcd9xxx->regmap;
+
+ regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x01);
+ regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_A_STARTUP, 0x19);
+ regmap_write(wcd_regmap, WCD9360_SIDO_NEW_VOUT_D_STARTUP, 0x15);
+ /* Add 1msec delay for VOUT to settle */
+ usleep_range(1000, 1100);
+ regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
+ regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
+ regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x3);
+ regmap_write(wcd_regmap, WCD9360_CODEC_RPM_RST_CTL, 0x7);
+ regmap_write(wcd_regmap, WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
+
+ return 0;
+}
+
+/*
+ * wcd9360_get_cdc_info: Get codec specific information
+ *
+ * @wcd9xxx: pointer to wcd9xxx structure
+ * @wcd_type: pointer to wcd9xxx_codec_type structure
+ *
+ * Returns 0 for success or negative error code for failure
+ */
+static int wcd9360_get_cdc_info(struct wcd9xxx *wcd9xxx,
+ struct wcd9xxx_codec_type *wcd_type)
+{
+ u16 id_minor, id_major;
+ struct regmap *wcd_regmap;
+ int rc, version = -1;
+
+ if (!wcd9xxx || !wcd_type)
+ return -EINVAL;
+
+ if (!wcd9xxx->regmap) {
+ dev_err(wcd9xxx->dev, "%s: wcd9xxx regmap is null\n", __func__);
+ return -EINVAL;
+ }
+ wcd_regmap = wcd9xxx->regmap;
+
+ rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
+ (u8 *)&id_minor, sizeof(u16));
+ if (rc)
+ return -EINVAL;
+
+ rc = regmap_bulk_read(wcd_regmap, WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
+ (u8 *)&id_major, sizeof(u16));
+ if (rc)
+ return -EINVAL;
+
+ dev_info(wcd9xxx->dev, "%s: wcd9xxx chip id major 0x%x, minor 0x%x\n",
+ __func__, id_major, id_minor);
+
+ if (id_major != PAHU_MAJOR)
+ goto version_unknown;
+
+ /*
+ * As fine version info cannot be retrieved before pahu probe.
+ * Assign coarse versions for possible future use before Pahu probe.
+ */
+ if (id_minor == cpu_to_le16(0))
+ version = PAHU_VERSION_1_0;
+
+version_unknown:
+ if (version < 0)
+ dev_err(wcd9xxx->dev, "%s: wcd934x version unknown\n",
+ __func__);
+
+ /* Fill codec type info */
+ wcd_type->id_major = id_major;
+ wcd_type->id_minor = id_minor;
+ wcd_type->num_irqs = WCD9360_NUM_IRQS;
+ wcd_type->version = version;
+ wcd_type->slim_slave_type = WCD9XXX_SLIM_SLAVE_ADDR_TYPE_1;
+ wcd_type->i2c_chip_status = 0x01;
+ wcd_type->intr_tbl = wcd9360_intr_table;
+ wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9360_intr_table);
+
+ wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] =
+ WCD9360_INTR_PIN1_STATUS0;
+ wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] =
+ WCD9360_INTR_PIN1_CLEAR0;
+ wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] =
+ WCD9360_INTR_PIN1_MASK0;
+ wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] =
+ WCD9360_INTR_LEVEL0;
+ wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] =
+ WCD9360_INTR_CLR_COMMIT;
+
+ return rc;
+}
+
codec_bringdown_fn wcd9xxx_bringdown_fn(int type)
{
codec_bringdown_fn cdc_bdown_fn;
switch (type) {
+ case WCD9360:
+ cdc_bdown_fn = wcd9360_bring_down;
+ break;
case WCD934X:
cdc_bdown_fn = wcd934x_bring_down;
break;
@@ -408,6 +561,9 @@
codec_bringup_fn cdc_bup_fn;
switch (type) {
+ case WCD9360:
+ cdc_bup_fn = wcd9360_bring_up;
+ break;
case WCD934X:
cdc_bup_fn = wcd934x_bring_up;
break;
@@ -427,6 +583,9 @@
codec_type_fn cdc_type_fn;
switch (type) {
+ case WCD9360:
+ cdc_type_fn = wcd9360_get_cdc_info;
+ break;
case WCD934X:
cdc_type_fn = wcd934x_get_cdc_info;
break;
diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c
index eee90a2..1f521bc 100644
--- a/asoc/codecs/wcd9xxx-utils.c
+++ b/asoc/codecs/wcd9xxx-utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,6 +38,16 @@
static enum wcd9xxx_intf_status wcd9xxx_intf = -1;
+static struct mfd_cell pahu_devs[] = {
+ {
+ .name = "qcom-wcd-pinctrl",
+ .of_compatible = "qcom,wcd-pinctrl",
+ },
+ {
+ .name = "pahu_codec",
+ },
+};
+
static struct mfd_cell tavil_devs[] = {
{
.name = "qcom-wcd-pinctrl",
@@ -467,7 +477,8 @@
unsigned short c_reg, reg_addr;
u8 pg_num, prev_pg_num;
- if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X)
+ if (wcd9xxx->type != WCD9335 && wcd9xxx->type != WCD934X &&
+ wcd9xxx->type != WCD9360)
return ret;
c_reg = *reg;
@@ -864,6 +875,10 @@
}
switch (wcd9xxx->type) {
+ case WCD9360:
+ cinfo->dev = pahu_devs;
+ cinfo->size = ARRAY_SIZE(pahu_devs);
+ break;
case WCD934X:
cinfo->dev = tavil_devs;
cinfo->size = ARRAY_SIZE(tavil_devs);
diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c
index a7fcce3..2e154e7 100644
--- a/asoc/codecs/wcd_cpe_core.c
+++ b/asoc/codecs/wcd_cpe_core.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -329,6 +329,14 @@
goto done;
}
+ if (phdr->p_filesz != split_fw->size) {
+ dev_err(core->dev,
+ "%s: %s size mismatch, phdr_size: 0x%x fw_size: 0x%zx",
+ __func__, split_fname, phdr->p_filesz, split_fw->size);
+ ret = -EINVAL;
+ goto done;
+ }
+
segment->cpe_addr = phdr->p_paddr;
segment->size = phdr->p_filesz;
segment->data = (u8 *) split_fw->data;
@@ -1936,6 +1944,7 @@
init_completion(&core->online_compl);
init_waitqueue_head(&core->ssr_entry.offline_poll_wait);
mutex_init(&core->ssr_lock);
+ mutex_init(&core->session_lock);
core->cpe_users = 0;
core->cpe_clk_ref = 0;
@@ -3387,6 +3396,7 @@
* If this is the first session to be allocated,
* only then register the afe service.
*/
+ WCD_CPE_GRAB_LOCK(&core->session_lock, "session_lock");
if (!wcd_cpe_lsm_session_active())
afe_register_service = true;
@@ -3401,6 +3411,7 @@
dev_err(core->dev,
"%s: max allowed sessions already allocated\n",
__func__);
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return NULL;
}
@@ -3409,6 +3420,7 @@
dev_err(core->dev,
"%s: Failed to enable cpe, err = %d\n",
__func__, ret);
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return NULL;
}
@@ -3451,6 +3463,8 @@
init_completion(&session->cmd_comp);
lsm_sessions[session_id] = session;
+
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return session;
err_afe_mode_cmd:
@@ -3465,6 +3479,7 @@
err_session_alloc:
wcd_cpe_vote(core, false);
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return NULL;
}
@@ -3615,9 +3630,11 @@
struct wcd_cpe_core *core = core_handle;
int ret = 0;
+ WCD_CPE_GRAB_LOCK(&core->session_lock, "session_lock");
if (!session) {
dev_err(core->dev,
"%s: Invalid lsm session\n", __func__);
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return -EINVAL;
}
@@ -3628,6 +3645,7 @@
"%s: Wrong session id %d max allowed = %d\n",
__func__, session->id,
WCD_CPE_LSM_MAX_SESSIONS);
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return -EINVAL;
}
@@ -3648,6 +3666,7 @@
"%s: Failed to un-vote cpe, err = %d\n",
__func__, ret);
+ WCD_CPE_REL_LOCK(&core->session_lock, "session_lock");
return ret;
}
diff --git a/asoc/codecs/wcd_cpe_core.h b/asoc/codecs/wcd_cpe_core.h
index 3d672b8..5884a52 100644
--- a/asoc/codecs/wcd_cpe_core.h
+++ b/asoc/codecs/wcd_cpe_core.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -172,6 +172,9 @@
/* mutex to protect cpe ssr status variables */
struct mutex ssr_lock;
+ /* mutex to protect cpe session status variables */
+ struct mutex session_lock;
+
/* Store the calibration data needed for cpe */
struct cal_type_data *cal_data[WCD_CPE_LSM_CAL_MAX];
diff --git a/asoc/codecs/wcd_cpe_services.c b/asoc/codecs/wcd_cpe_services.c
index 522ce7a..fc8242a 100644
--- a/asoc/codecs/wcd_cpe_services.c
+++ b/asoc/codecs/wcd_cpe_services.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -606,8 +606,10 @@
return CPE_SVC_INVALID_HANDLE;
}
+ CPE_SVC_GRAB_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc");
list_del(&(n->list));
kfree(reg_handle);
+ CPE_SVC_REL_LOCK(&cpe_d.cpe_svc_lock, "cpe_svc");
return CPE_SVC_SUCCESS;
}
diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c
index 5bab856..8b2ca31 100644
--- a/asoc/msm-audio-effects-q6-v2.c
+++ b/asoc/msm-audio-effects-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -16,6 +16,7 @@
#include <dsp/apr_audio-v2.h>
#include <dsp/q6asm-v2.h>
#include <dsp/msm-audio-effects-q6-v2.h>
+#include <dsp/q6common.h>
#define MAX_ENABLE_CMD_SIZE 32
@@ -67,44 +68,36 @@
struct msm_nt_eff_all_config *effects,
bool flag)
{
- uint32_t updt_params[MAX_ENABLE_CMD_SIZE] = {0};
- uint32_t params_length;
+ u32 flag_param = flag ? 1 : 0;
+ struct param_hdr_v3 param_hdr;
int rc = 0;
pr_debug("%s\n", __func__);
- if (!ac) {
- pr_err("%s: cannot set audio effects\n", __func__);
- return -EINVAL;
- }
- params_length = 0;
- updt_params[0] = AUDPROC_MODULE_ID_VIRTUALIZER;
- updt_params[1] = AUDPROC_PARAM_ID_ENABLE;
- updt_params[2] = VIRTUALIZER_ENABLE_PARAM_SZ;
- updt_params[3] = flag;
- params_length += COMMAND_PAYLOAD_SZ + VIRTUALIZER_ENABLE_PARAM_SZ;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
+ param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ;
if (effects->virtualizer.enable_flag)
- q6asm_send_audio_effects_params(ac, (char *)&updt_params[0],
- params_length);
- memset(updt_params, 0, MAX_ENABLE_CMD_SIZE);
- params_length = 0;
- updt_params[0] = AUDPROC_MODULE_ID_BASS_BOOST;
- updt_params[1] = AUDPROC_PARAM_ID_ENABLE;
- updt_params[2] = BASS_BOOST_ENABLE_PARAM_SZ;
- updt_params[3] = flag;
- params_length += COMMAND_PAYLOAD_SZ + BASS_BOOST_ENABLE_PARAM_SZ;
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr,
+ (u8 *) &flag_param);
+
+ param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
+ param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ;
if (effects->bass_boost.enable_flag)
- q6asm_send_audio_effects_params(ac, (char *)&updt_params[0],
- params_length);
- memset(updt_params, 0, MAX_ENABLE_CMD_SIZE);
- params_length = 0;
- updt_params[0] = AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
- updt_params[1] = AUDPROC_PARAM_ID_ENABLE;
- updt_params[2] = EQ_ENABLE_PARAM_SZ;
- updt_params[3] = flag;
- params_length += COMMAND_PAYLOAD_SZ + EQ_ENABLE_PARAM_SZ;
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr,
+ (u8 *) &flag_param);
+
+ param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
+ param_hdr.param_size = EQ_ENABLE_PARAM_SZ;
if (effects->equalizer.enable_flag)
- q6asm_send_audio_effects_params(ac, (char *)&updt_params[0],
- params_length);
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr,
+ (u8 *) &flag_param);
+
return rc;
}
@@ -124,24 +117,32 @@
{
long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
char *params = NULL;
+ u8 *updt_params;
int rc = 0;
int devices = GET_NEXT(values, param_max_offset, rc);
int num_commands = GET_NEXT(values, param_max_offset, rc);
- int *updt_params, i, prev_enable_flag;
- uint32_t params_length = (MAX_INBAND_PARAM_SZ);
+ int i, prev_enable_flag;
+ uint32_t max_params_length = 0;
+ uint32_t params_length = 0;
+ struct param_hdr_v3 param_hdr;
+ u8 *param_data = NULL;
+ u32 packed_data_size = 0;
pr_debug("%s\n", __func__);
if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL;
}
- params = kzalloc(params_length, GFP_KERNEL);
- if (!params)
+ params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
+ if (!params) {
+ pr_err("%s, params memory alloc failed\n", __func__);
return -ENOMEM;
-
+ }
pr_debug("%s: device: %d\n", __func__, devices);
- updt_params = (int *)params;
- params_length = 0;
+ updt_params = (u8 *) params;
+ /* Set MID and IID once at top and only update param specific fields*/
+ param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER;
+ param_hdr.instance_id = INSTANCE_ID_0;
for (i = 0; i < num_commands; i++) {
uint32_t command_id =
GET_NEXT(values, param_max_offset, rc);
@@ -163,23 +164,19 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__,
prev_enable_flag, virtualizer->enable_flag);
- if (prev_enable_flag != virtualizer->enable_flag) {
- params_length += COMMAND_PAYLOAD_SZ +
- VIRTUALIZER_ENABLE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "VIRT ENABLE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_VIRTUALIZER;
- *updt_params++ =
+ if (prev_enable_flag == virtualizer->enable_flag)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ VIRTUALIZER_ENABLE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "VIRT ENABLE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE;
- *updt_params++ =
- VIRTUALIZER_ENABLE_PARAM_SZ;
- *updt_params++ =
- virtualizer->enable_flag;
- }
+ param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ;
+ param_data = (u8 *) &virtualizer->enable_flag;
break;
case VIRTUALIZER_STRENGTH:
if (length != 1 || index_offset != 0) {
@@ -191,23 +188,19 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: VIRT STRENGTH val: %d\n",
__func__, virtualizer->strength);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- VIRTUALIZER_STRENGTH_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "VIRT STRENGTH", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_VIRTUALIZER;
- *updt_params++ =
- AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH;
- *updt_params++ =
- VIRTUALIZER_STRENGTH_PARAM_SZ;
- *updt_params++ =
- virtualizer->strength;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ VIRTUALIZER_STRENGTH_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "VIRT STRENGTH", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH;
+ param_hdr.param_size = VIRTUALIZER_STRENGTH_PARAM_SZ;
+ param_data = (u8 *) &virtualizer->strength;
break;
case VIRTUALIZER_OUT_TYPE:
if (length != 1 || index_offset != 0) {
@@ -219,23 +212,19 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: VIRT OUT_TYPE val:%d\n",
__func__, virtualizer->out_type);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- VIRTUALIZER_OUT_TYPE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "VIRT OUT_TYPE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_VIRTUALIZER;
- *updt_params++ =
- AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE;
- *updt_params++ =
- VIRTUALIZER_OUT_TYPE_PARAM_SZ;
- *updt_params++ =
- virtualizer->out_type;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ VIRTUALIZER_OUT_TYPE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "VIRT OUT_TYPE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE;
+ param_hdr.param_size = VIRTUALIZER_OUT_TYPE_PARAM_SZ;
+ param_data = (u8 *) &virtualizer->out_type;
break;
case VIRTUALIZER_GAIN_ADJUST:
if (length != 1 || index_offset != 0) {
@@ -247,32 +236,40 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: VIRT GAIN_ADJUST val:%d\n",
__func__, virtualizer->gain_adjust);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "VIRT GAIN_ADJUST", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_VIRTUALIZER;
- *updt_params++ =
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "VIRT GAIN_ADJUST", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST;
- *updt_params++ =
- VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
- *updt_params++ =
- virtualizer->gain_adjust;
- }
+ param_hdr.param_size = VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
+ param_data = (u8 *) &virtualizer->gain_adjust;
break;
default:
pr_err("%s: Invalid command to set config\n", __func__);
- break;
+ continue;
}
+ if (rc)
+ goto invalid_config;
+
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ param_data, &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
}
if (params_length && (rc == 0))
- q6asm_send_audio_effects_params(ac, params,
- params_length);
+ q6asm_set_pp_params(ac, NULL, params, params_length);
else
pr_debug("%s: did not send pp params\n", __func__);
invalid_config:
@@ -297,24 +294,33 @@
{
long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
char *params = NULL;
+ u8 *updt_params;
int rc = 0;
int devices = GET_NEXT(values, param_max_offset, rc);
int num_commands = GET_NEXT(values, param_max_offset, rc);
- int *updt_params, i, prev_enable_flag;
- uint32_t params_length = (MAX_INBAND_PARAM_SZ);
+ int i, prev_enable_flag;
+ uint32_t max_params_length = 0;
+ uint32_t params_length = 0;
+ struct param_hdr_v3 param_hdr;
+ u8 *param_data = NULL;
+ u32 packed_data_size = 0;
pr_debug("%s\n", __func__);
if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL;
}
- params = kzalloc(params_length, GFP_KERNEL);
- if (!params)
+ params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
+ if (!params) {
+ pr_err("%s, params memory alloc failed\n", __func__);
return -ENOMEM;
-
+ }
pr_debug("%s: device: %d\n", __func__, devices);
- updt_params = (int *)params;
- params_length = 0;
+ updt_params = (u8 *) params;
+ /* Set MID and IID once at top and only update param specific fields*/
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_REVERB;
+ param_hdr.instance_id = INSTANCE_ID_0;
for (i = 0; i < num_commands; i++) {
uint32_t command_id =
GET_NEXT(values, param_max_offset, rc);
@@ -336,23 +342,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__,
prev_enable_flag, reverb->enable_flag);
- if (prev_enable_flag != reverb->enable_flag) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_ENABLE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_ENABLE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_ENABLE;
- *updt_params++ =
- REVERB_ENABLE_PARAM_SZ;
- *updt_params++ =
- reverb->enable_flag;
- }
+ if (prev_enable_flag == reverb->enable_flag)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_ENABLE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_ENABLE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ENABLE;
+ param_hdr.param_size = REVERB_ENABLE_PARAM_SZ;
+ param_data = (u8 *) &reverb->enable_flag;
break;
case REVERB_MODE:
if (length != 1 || index_offset != 0) {
@@ -364,23 +365,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_MODE val:%d\n",
__func__, reverb->mode);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_MODE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_MODE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_MODE;
- *updt_params++ =
- REVERB_MODE_PARAM_SZ;
- *updt_params++ =
- reverb->mode;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_MODE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_MODE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_MODE;
+ param_hdr.param_size = REVERB_MODE_PARAM_SZ;
+ param_data = (u8 *) &reverb->mode;
break;
case REVERB_PRESET:
if (length != 1 || index_offset != 0) {
@@ -392,23 +388,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_PRESET val:%d\n",
__func__, reverb->preset);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_PRESET_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_PRESET", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_PRESET;
- *updt_params++ =
- REVERB_PRESET_PARAM_SZ;
- *updt_params++ =
- reverb->preset;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_PRESET_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_PRESET", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_PRESET;
+ param_hdr.param_size = REVERB_PRESET_PARAM_SZ;
+ param_data = (u8 *) &reverb->preset;
break;
case REVERB_WET_MIX:
if (length != 1 || index_offset != 0) {
@@ -420,23 +411,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_WET_MIX val:%d\n",
__func__, reverb->wet_mix);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_WET_MIX_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_WET_MIX", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_WET_MIX;
- *updt_params++ =
- REVERB_WET_MIX_PARAM_SZ;
- *updt_params++ =
- reverb->wet_mix;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_WET_MIX_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_WET_MIX", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_WET_MIX;
+ param_hdr.param_size = REVERB_WET_MIX_PARAM_SZ;
+ param_data = (u8 *) &reverb->wet_mix;
break;
case REVERB_GAIN_ADJUST:
if (length != 1 || index_offset != 0) {
@@ -448,23 +434,19 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n",
__func__, reverb->gain_adjust);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_GAIN_ADJUST_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_GAIN_ADJUST", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST;
- *updt_params++ =
- REVERB_GAIN_ADJUST_PARAM_SZ;
- *updt_params++ =
- reverb->gain_adjust;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_GAIN_ADJUST_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_GAIN_ADJUST", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST;
+ param_hdr.param_size = REVERB_GAIN_ADJUST_PARAM_SZ;
+ param_data = (u8 *) &reverb->gain_adjust;
break;
case REVERB_ROOM_LEVEL:
if (length != 1 || index_offset != 0) {
@@ -476,23 +458,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n",
__func__, reverb->room_level);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_ROOM_LEVEL_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_ROOM_LEVEL", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL;
- *updt_params++ =
- REVERB_ROOM_LEVEL_PARAM_SZ;
- *updt_params++ =
- reverb->room_level;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_ROOM_LEVEL_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_ROOM_LEVEL", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL;
+ param_hdr.param_size = REVERB_ROOM_LEVEL_PARAM_SZ;
+ param_data = (u8 *) &reverb->room_level;
break;
case REVERB_ROOM_HF_LEVEL:
if (length != 1 || index_offset != 0) {
@@ -504,23 +481,19 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n",
__func__, reverb->room_hf_level);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_ROOM_HF_LEVEL_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_ROOM_HF_LEVEL", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL;
- *updt_params++ =
- REVERB_ROOM_HF_LEVEL_PARAM_SZ;
- *updt_params++ =
- reverb->room_hf_level;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_ROOM_HF_LEVEL_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_ROOM_HF_LEVEL", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL;
+ param_hdr.param_size = REVERB_ROOM_HF_LEVEL_PARAM_SZ;
+ param_data = (u8 *) &reverb->room_hf_level;
break;
case REVERB_DECAY_TIME:
if (length != 1 || index_offset != 0) {
@@ -532,23 +505,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_DECAY_TIME val:%d\n",
__func__, reverb->decay_time);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_DECAY_TIME_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_DECAY_TIME", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_DECAY_TIME;
- *updt_params++ =
- REVERB_DECAY_TIME_PARAM_SZ;
- *updt_params++ =
- reverb->decay_time;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_DECAY_TIME_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_DECAY_TIME", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DECAY_TIME;
+ param_hdr.param_size = REVERB_DECAY_TIME_PARAM_SZ;
+ param_data = (u8 *) &reverb->decay_time;
break;
case REVERB_DECAY_HF_RATIO:
if (length != 1 || index_offset != 0) {
@@ -560,23 +528,19 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n",
__func__, reverb->decay_hf_ratio);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_DECAY_HF_RATIO_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_DECAY_HF_RATIO", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO;
- *updt_params++ =
- REVERB_DECAY_HF_RATIO_PARAM_SZ;
- *updt_params++ =
- reverb->decay_hf_ratio;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_DECAY_HF_RATIO_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_DECAY_HF_RATIO", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO;
+ param_hdr.param_size = REVERB_DECAY_HF_RATIO_PARAM_SZ;
+ param_data = (u8 *) &reverb->decay_hf_ratio;
break;
case REVERB_REFLECTIONS_LEVEL:
if (length != 1 || index_offset != 0) {
@@ -588,23 +552,20 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n",
__func__, reverb->reflections_level);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_REFLECTIONS_LEVEL", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_REFLECTIONS_LEVEL", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL;
- *updt_params++ =
+ param_hdr.param_size =
REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
- *updt_params++ =
- reverb->reflections_level;
- }
+ param_data = (u8 *) &reverb->reflections_level;
break;
case REVERB_REFLECTIONS_DELAY:
if (length != 1 || index_offset != 0) {
@@ -616,23 +577,20 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n",
__func__, reverb->reflections_delay);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_REFLECTIONS_DELAY_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_REFLECTIONS_DELAY", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_REFLECTIONS_DELAY_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_REFLECTIONS_DELAY", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY;
- *updt_params++ =
+ param_hdr.param_size =
REVERB_REFLECTIONS_DELAY_PARAM_SZ;
- *updt_params++ =
- reverb->reflections_delay;
- }
+ param_data = (u8 *) &reverb->reflections_delay;
break;
case REVERB_LEVEL:
if (length != 1 || index_offset != 0) {
@@ -644,23 +602,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_LEVEL val:%d\n",
__func__, reverb->level);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_LEVEL_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_LEVEL", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_LEVEL;
- *updt_params++ =
- REVERB_LEVEL_PARAM_SZ;
- *updt_params++ =
- reverb->level;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_LEVEL_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_LEVEL", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_LEVEL;
+ param_hdr.param_size = REVERB_LEVEL_PARAM_SZ;
+ param_data = (u8 *) &reverb->level;
break;
case REVERB_DELAY:
if (length != 1 || index_offset != 0) {
@@ -672,23 +625,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s:REVERB_DELAY val:%d\n",
__func__, reverb->delay);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_DELAY_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_DELAY", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_DELAY;
- *updt_params++ =
- REVERB_DELAY_PARAM_SZ;
- *updt_params++ =
- reverb->delay;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_DELAY_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_DELAY", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DELAY;
+ param_hdr.param_size = REVERB_DELAY_PARAM_SZ;
+ param_data = (u8 *) &reverb->delay;
break;
case REVERB_DIFFUSION:
if (length != 1 || index_offset != 0) {
@@ -700,23 +648,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_DIFFUSION val:%d\n",
__func__, reverb->diffusion);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_DIFFUSION_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_DIFFUSION", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_DIFFUSION;
- *updt_params++ =
- REVERB_DIFFUSION_PARAM_SZ;
- *updt_params++ =
- reverb->diffusion;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_DIFFUSION_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_DIFFUSION", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DIFFUSION;
+ param_hdr.param_size = REVERB_DIFFUSION_PARAM_SZ;
+ param_data = (u8 *) &reverb->diffusion;
break;
case REVERB_DENSITY:
if (length != 1 || index_offset != 0) {
@@ -728,32 +671,39 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: REVERB_DENSITY val:%d\n",
__func__, reverb->density);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- REVERB_DENSITY_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "REVERB_DENSITY", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_REVERB;
- *updt_params++ =
- AUDPROC_PARAM_ID_REVERB_DENSITY;
- *updt_params++ =
- REVERB_DENSITY_PARAM_SZ;
- *updt_params++ =
- reverb->density;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ REVERB_DENSITY_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "REVERB_DENSITY", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DENSITY;
+ param_hdr.param_size = REVERB_DENSITY_PARAM_SZ;
+ param_data = (u8 *) &reverb->density;
break;
default:
pr_err("%s: Invalid command to set config\n", __func__);
- break;
+ continue;
}
+ if (rc)
+ goto invalid_config;
+
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ param_data, &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
}
if (params_length && (rc == 0))
- q6asm_send_audio_effects_params(ac, params,
- params_length);
+ q6asm_set_pp_params(ac, NULL, params, params_length);
else
pr_debug("%s: did not send pp params\n", __func__);
invalid_config:
@@ -778,24 +728,33 @@
{
long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
char *params = NULL;
+ u8 *updt_params;
int rc = 0;
int devices = GET_NEXT(values, param_max_offset, rc);
int num_commands = GET_NEXT(values, param_max_offset, rc);
- int *updt_params, i, prev_enable_flag;
- uint32_t params_length = (MAX_INBAND_PARAM_SZ);
+ int i, prev_enable_flag;
+ uint32_t max_params_length = 0;
+ uint32_t params_length = 0;
+ struct param_hdr_v3 param_hdr;
+ u8 *param_data = NULL;
+ u32 packed_data_size = 0;
pr_debug("%s\n", __func__);
if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL;
}
- params = kzalloc(params_length, GFP_KERNEL);
- if (!params)
+ params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
+ if (!params) {
+ pr_err("%s, params memory alloc failed\n", __func__);
return -ENOMEM;
-
+ }
pr_debug("%s: device: %d\n", __func__, devices);
- updt_params = (int *)params;
- params_length = 0;
+ updt_params = (u8 *) params;
+ /* Set MID and IID once at top and only update param specific fields*/
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST;
+ param_hdr.instance_id = INSTANCE_ID_0;
for (i = 0; i < num_commands; i++) {
uint32_t command_id =
GET_NEXT(values, param_max_offset, rc);
@@ -818,23 +777,18 @@
pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n",
__func__, prev_enable_flag,
bass_boost->enable_flag);
- if (prev_enable_flag != bass_boost->enable_flag) {
- params_length += COMMAND_PAYLOAD_SZ +
- BASS_BOOST_ENABLE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "BASS_BOOST_ENABLE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_BASS_BOOST;
- *updt_params++ =
- AUDPROC_PARAM_ID_BASS_BOOST_ENABLE;
- *updt_params++ =
- BASS_BOOST_ENABLE_PARAM_SZ;
- *updt_params++ =
- bass_boost->enable_flag;
- }
+ if (prev_enable_flag == bass_boost->enable_flag)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ BASS_BOOST_ENABLE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "BASS_BOOST_ENABLE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_ENABLE;
+ param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ;
+ param_data = (u8 *) &bass_boost->enable_flag;
break;
case BASS_BOOST_MODE:
if (length != 1 || index_offset != 0) {
@@ -846,23 +800,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: BASS_BOOST_MODE val:%d\n",
__func__, bass_boost->mode);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- BASS_BOOST_MODE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "BASS_BOOST_MODE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_BASS_BOOST;
- *updt_params++ =
- AUDPROC_PARAM_ID_BASS_BOOST_MODE;
- *updt_params++ =
- BASS_BOOST_MODE_PARAM_SZ;
- *updt_params++ =
- bass_boost->mode;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ BASS_BOOST_MODE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "BASS_BOOST_MODE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_MODE;
+ param_hdr.param_size = BASS_BOOST_MODE_PARAM_SZ;
+ param_data = (u8 *) &bass_boost->mode;
break;
case BASS_BOOST_STRENGTH:
if (length != 1 || index_offset != 0) {
@@ -874,32 +823,40 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n",
__func__, bass_boost->strength);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- BASS_BOOST_STRENGTH_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "BASS_BOOST_STRENGTH", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_BASS_BOOST;
- *updt_params++ =
- AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH;
- *updt_params++ =
- BASS_BOOST_STRENGTH_PARAM_SZ;
- *updt_params++ =
- bass_boost->strength;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ BASS_BOOST_STRENGTH_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "BASS_BOOST_STRENGTH", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH;
+ param_hdr.param_size = BASS_BOOST_STRENGTH_PARAM_SZ;
+ param_data = (u8 *) &bass_boost->strength;
break;
default:
pr_err("%s: Invalid command to set config\n", __func__);
- break;
+ continue;
}
+ if (rc)
+ goto invalid_config;
+
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ param_data, &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
}
if (params_length && (rc == 0))
- q6asm_send_audio_effects_params(ac, params,
- params_length);
+ q6asm_set_pp_params(ac, NULL, params, params_length);
else
pr_debug("%s: did not send pp params\n", __func__);
invalid_config:
@@ -924,24 +881,33 @@
{
long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
char *params = NULL;
+ u8 *updt_params;
int rc = 0;
int devices = GET_NEXT(values, param_max_offset, rc);
int num_commands = GET_NEXT(values, param_max_offset, rc);
- int *updt_params, i, j, prev_enable_flag;
- uint32_t params_length = (MAX_INBAND_PARAM_SZ);
+ int i, prev_enable_flag;
+ uint32_t max_params_length = 0;
+ uint32_t params_length = 0;
+ struct param_hdr_v3 param_hdr;
+ u8 *param_data = NULL;
+ u32 packed_data_size = 0;
pr_debug("%s\n", __func__);
if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL;
}
- params = kzalloc(params_length, GFP_KERNEL);
- if (!params)
+ params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
+ if (!params) {
+ pr_err("%s, params memory alloc failed\n", __func__);
return -ENOMEM;
-
+ }
pr_debug("%s: device: %d\n", __func__, devices);
- updt_params = (int *)params;
- params_length = 0;
+ updt_params = (u8 *) params;
+ /* Set MID and IID once at top and only update param specific fields*/
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_PBE;
+ param_hdr.instance_id = INSTANCE_ID_0;
for (i = 0; i < num_commands; i++) {
uint32_t command_id =
GET_NEXT(values, param_max_offset, rc);
@@ -962,23 +928,18 @@
prev_enable_flag = pbe->enable_flag;
pbe->enable_flag =
GET_NEXT(values, param_max_offset, rc);
- if (prev_enable_flag != pbe->enable_flag) {
- params_length += COMMAND_PAYLOAD_SZ +
- PBE_ENABLE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "PBE_ENABLE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_PBE;
- *updt_params++ =
- AUDPROC_PARAM_ID_PBE_ENABLE;
- *updt_params++ =
- PBE_ENABLE_PARAM_SZ;
- *updt_params++ =
- pbe->enable_flag;
- }
+ if (prev_enable_flag == pbe->enable_flag)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ PBE_ENABLE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "PBE_ENABLE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_PBE_ENABLE;
+ param_hdr.param_size = PBE_ENABLE_PARAM_SZ;
+ param_data = (u8 *) &pbe->enable_flag;
break;
case PBE_CONFIG:
pr_debug("%s: PBE_PARAM length %u\n", __func__, length);
@@ -989,37 +950,38 @@
rc = -EINVAL;
goto invalid_config;
}
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ + length;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "PBE_PARAM", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_PBE;
- *updt_params++ =
- AUDPROC_PARAM_ID_PBE_PARAM_CONFIG;
- *updt_params++ =
- length;
- for (j = 0; j < length; ) {
- j += sizeof(*updt_params);
- *updt_params++ =
- GET_NEXT(
- values,
- param_max_offset,
- rc);
- }
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length =
+ params_length + COMMAND_IID_PAYLOAD_SZ + length;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "PBE_PARAM", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_PBE_PARAM_CONFIG;
+ param_hdr.param_size = length;
+ param_data = (u8 *) values;
break;
default:
pr_err("%s: Invalid command to set config\n", __func__);
- break;
+ continue;
}
+ if (rc)
+ goto invalid_config;
+
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ param_data, &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
}
if (params_length && (rc == 0))
- q6asm_send_audio_effects_params(ac, params,
- params_length);
+ q6asm_set_pp_params(ac, NULL, params, params_length);
invalid_config:
kfree(params);
return rc;
@@ -1042,24 +1004,36 @@
{
long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
char *params = NULL;
+ u8 *updt_params = NULL;
int rc = 0;
int devices = GET_NEXT(values, param_max_offset, rc);
int num_commands = GET_NEXT(values, param_max_offset, rc);
- int *updt_params, i, prev_enable_flag;
- uint32_t params_length = (MAX_INBAND_PARAM_SZ);
+ int i, prev_enable_flag;
+ uint32_t max_params_length = 0;
+ uint32_t params_length = 0;
+ struct param_hdr_v3 param_hdr;
+ u8 *param_data = NULL;
+ u32 packed_data_size = 0;
+ u8 *eq_config_data = NULL;
+ u32 *updt_config_data = NULL;
+ int config_param_length;
pr_debug("%s\n", __func__);
if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL;
}
- params = kzalloc(params_length, GFP_KERNEL);
- if (!params)
+ params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
+ if (!params) {
+ pr_err("%s, params memory alloc failed\n", __func__);
return -ENOMEM;
-
+ }
pr_debug("%s: device: %d\n", __func__, devices);
- updt_params = (int *)params;
- params_length = 0;
+ updt_params = (u8 *) params;
+ /* Set MID and IID once at top and only update param specific fields*/
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
+ param_hdr.instance_id = INSTANCE_ID_0;
for (i = 0; i < num_commands; i++) {
uint32_t command_id =
GET_NEXT(values, param_max_offset, rc);
@@ -1084,23 +1058,18 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__,
prev_enable_flag, eq->enable_flag);
- if (prev_enable_flag != eq->enable_flag) {
- params_length += COMMAND_PAYLOAD_SZ +
- EQ_ENABLE_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "EQ_ENABLE", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
- *updt_params++ =
- AUDPROC_PARAM_ID_EQ_ENABLE;
- *updt_params++ =
- EQ_ENABLE_PARAM_SZ;
- *updt_params++ =
- eq->enable_flag;
- }
+ if (prev_enable_flag == eq->enable_flag)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ EQ_ENABLE_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "EQ_ENABLE", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_EQ_ENABLE;
+ param_hdr.param_size = EQ_ENABLE_PARAM_SZ;
+ param_data = (u8 *) &eq->enable_flag;
break;
case EQ_CONFIG:
if (length < EQ_CONFIG_PARAM_LEN || index_offset != 0) {
@@ -1149,43 +1118,50 @@
eq->per_band_cfg[idx].quality_factor =
GET_NEXT(values, param_max_offset, rc);
}
- if (command_config_state == CONFIG_SET) {
- int config_param_length = EQ_CONFIG_PARAM_SZ +
- (EQ_CONFIG_PER_BAND_PARAM_SZ*
- eq->config.num_bands);
- params_length += COMMAND_PAYLOAD_SZ +
- config_param_length;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "EQ_CONFIG", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
- *updt_params++ =
- AUDPROC_PARAM_ID_EQ_CONFIG;
- *updt_params++ =
- config_param_length;
- *updt_params++ =
- eq->config.eq_pregain;
- *updt_params++ =
- eq->config.preset_id;
- *updt_params++ =
- eq->config.num_bands;
- for (idx = 0; idx < MAX_EQ_BANDS; idx++) {
- if (eq->per_band_cfg[idx].band_idx < 0)
- continue;
- *updt_params++ =
+ if (command_config_state != CONFIG_SET)
+ break;
+ config_param_length = EQ_CONFIG_PARAM_SZ +
+ (EQ_CONFIG_PER_BAND_PARAM_SZ *
+ eq->config.num_bands);
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ config_param_length;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "EQ_CONFIG", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_EQ_CONFIG;
+ param_hdr.param_size = config_param_length;
+
+ if (!eq_config_data)
+ eq_config_data = kzalloc(config_param_length,
+ GFP_KERNEL);
+ else
+ memset(eq_config_data, 0, config_param_length);
+ if (!eq_config_data) {
+ pr_err("%s, EQ_CONFIG:memory alloc failed\n",
+ __func__);
+ rc = -ENOMEM;
+ goto invalid_config;
+ }
+ param_data = eq_config_data;
+ updt_config_data = (u32 *) eq_config_data;
+ *updt_config_data++ = eq->config.eq_pregain;
+ *updt_config_data++ = eq->config.preset_id;
+ *updt_config_data++ = eq->config.num_bands;
+ for (idx = 0; idx < MAX_EQ_BANDS; idx++) {
+ if (eq->per_band_cfg[idx].band_idx < 0)
+ continue;
+ *updt_config_data++ =
eq->per_band_cfg[idx].filter_type;
- *updt_params++ =
+ *updt_config_data++ =
eq->per_band_cfg[idx].freq_millihertz;
- *updt_params++ =
+ *updt_config_data++ =
eq->per_band_cfg[idx].gain_millibels;
- *updt_params++ =
+ *updt_config_data++ =
eq->per_band_cfg[idx].quality_factor;
- *updt_params++ =
+ *updt_config_data++ =
eq->per_band_cfg[idx].band_idx;
- }
}
break;
case EQ_BAND_INDEX:
@@ -1203,23 +1179,18 @@
eq->band_index = idx;
pr_debug("%s: EQ_BAND_INDEX val:%d\n",
__func__, eq->band_index);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- EQ_BAND_INDEX_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "EQ_BAND_INDEX", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
- *updt_params++ =
- AUDPROC_PARAM_ID_EQ_BAND_INDEX;
- *updt_params++ =
- EQ_BAND_INDEX_PARAM_SZ;
- *updt_params++ =
- eq->band_index;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ EQ_BAND_INDEX_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "EQ_BAND_INDEX", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id = AUDPROC_PARAM_ID_EQ_BAND_INDEX;
+ param_hdr.param_size = EQ_BAND_INDEX_PARAM_SZ;
+ param_data = (u8 *) &eq->band_index;
break;
case EQ_SINGLE_BAND_FREQ:
if (length != 1 || index_offset != 0) {
@@ -1235,36 +1206,45 @@
GET_NEXT(values, param_max_offset, rc);
pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n",
__func__, eq->band_index, eq->freq_millihertz);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- EQ_SINGLE_BAND_FREQ_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "EQ_SINGLE_BAND_FREQ", rc);
- if (rc != 0)
- goto invalid_config;
- *updt_params++ =
- AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
- *updt_params++ =
- AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ;
- *updt_params++ =
- EQ_SINGLE_BAND_FREQ_PARAM_SZ;
- *updt_params++ =
- eq->freq_millihertz;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ EQ_SINGLE_BAND_FREQ_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "EQ_SINGLE_BAND_FREQ", rc);
+ if (rc != 0)
+ break;
+ param_hdr.param_id =
+ AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ;
+ param_hdr.param_size = EQ_SINGLE_BAND_FREQ_PARAM_SZ;
+ param_data = (u8 *) &eq->freq_millihertz;
break;
default:
pr_err("%s: Invalid command to set config\n", __func__);
- break;
+ continue;
}
+ if (rc)
+ goto invalid_config;
+
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ param_data, &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
}
if (params_length && (rc == 0))
- q6asm_send_audio_effects_params(ac, params,
- params_length);
+ q6asm_set_pp_params(ac, NULL, params, params_length);
else
pr_debug("%s: did not send pp params\n", __func__);
invalid_config:
kfree(params);
+ kfree(eq_config_data);
return rc;
}
EXPORT_SYMBOL(msm_audio_effects_popless_eq_handler);
@@ -1277,8 +1257,13 @@
int devices;
int num_commands;
char *params = NULL;
- int *updt_params, i;
- uint32_t params_length = (MAX_INBAND_PARAM_SZ);
+ u8 *updt_params;
+ int i;
+ uint32_t vol_gain_2ch = 0;
+ uint32_t max_params_length = 0;
+ uint32_t params_length = 0;
+ struct param_hdr_v3 param_hdr;
+ u32 packed_data_size = 0;
long *param_max_offset;
int rc = 0;
@@ -1295,12 +1280,15 @@
pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL;
}
- params = kzalloc(params_length, GFP_KERNEL);
- if (!params)
+ params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
+ if (!params) {
+ pr_err("%s, params memory alloc failed\n", __func__);
return -ENOMEM;
-
- updt_params = (int *)params;
- params_length = 0;
+ }
+ updt_params = (u8 *) params;
+ /* Set MID and IID once at top and only update param specific fields*/
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ q6asm_set_soft_volume_module_instance_ids(instance, ¶m_hdr);
for (i = 0; i < num_commands; i++) {
uint32_t command_id =
GET_NEXT(values, param_max_offset, rc);
@@ -1322,43 +1310,15 @@
vol->right_gain =
GET_NEXT(values, param_max_offset, rc);
vol->master_gain = 0x2000;
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
- params_length += COMMAND_PAYLOAD_SZ +
- SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "VOLUME/VOLUME2_GAIN_2CH",
- rc);
- if (rc != 0)
- goto invalid_config;
- if (instance == SOFT_VOLUME_INSTANCE_2)
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL2;
- else
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL;
- *updt_params++ =
- ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN;
- *updt_params++ =
- SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
- *updt_params++ =
- (vol->left_gain << 16) |
- vol->right_gain;
- if (instance == SOFT_VOLUME_INSTANCE_2)
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL2;
- else
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL;
- *updt_params++ =
- ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
- *updt_params++ =
- SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
- *updt_params++ =
- vol->master_gain;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ SOFT_VOLUME_GAIN_2CH_PARAM_SZ +
+ COMMAND_IID_PAYLOAD_SZ +
+ SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "VOLUME/VOLUME2_GAIN_2CH", rc);
break;
case SOFT_VOLUME_GAIN_MASTER:
case SOFT_VOLUME2_GAIN_MASTER:
@@ -1371,53 +1331,57 @@
vol->right_gain = 0x2000;
vol->master_gain =
GET_NEXT(values, param_max_offset, rc);
- if (command_config_state == CONFIG_SET) {
- params_length += COMMAND_PAYLOAD_SZ +
- SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
- params_length += COMMAND_PAYLOAD_SZ +
- SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
- CHECK_PARAM_LEN(params_length,
- MAX_INBAND_PARAM_SZ,
- "VOLUME/VOLUME2_GAIN_MASTER",
- rc);
- if (rc != 0)
- goto invalid_config;
- if (instance == SOFT_VOLUME_INSTANCE_2)
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL2;
- else
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL;
- *updt_params++ =
- ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN;
- *updt_params++ =
- SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
- *updt_params++ =
- (vol->left_gain << 16) |
- vol->right_gain;
- if (instance == SOFT_VOLUME_INSTANCE_2)
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL2;
- else
- *updt_params++ =
- ASM_MODULE_ID_VOL_CTRL;
- *updt_params++ =
- ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
- *updt_params++ =
- SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
- *updt_params++ =
- vol->master_gain;
- }
+ if (command_config_state != CONFIG_SET)
+ break;
+ max_params_length = params_length +
+ COMMAND_IID_PAYLOAD_SZ +
+ SOFT_VOLUME_GAIN_2CH_PARAM_SZ +
+ COMMAND_IID_PAYLOAD_SZ +
+ SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
+ CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
+ "VOLUME/VOLUME2_GAIN_MASTER", rc);
break;
default:
pr_err("%s: Invalid command id: %d to set config\n",
__func__, command_id);
- break;
+ continue;
}
+ if (rc)
+ continue;
+
+ /* Set Volume Control for Left/Right */
+ param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN;
+ param_hdr.param_size = SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
+ vol_gain_2ch = (vol->left_gain << 16) | vol->right_gain;
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ (u8 *) &vol_gain_2ch,
+ &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
+
+ /* Set Master Volume Control */
+ param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
+ param_hdr.param_size = SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
+ rc = q6common_pack_pp_params(updt_params, ¶m_hdr,
+ (u8 *) &vol->master_gain,
+ &packed_data_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, rc);
+ goto invalid_config;
+ }
+
+ updt_params += packed_data_size;
+ params_length += packed_data_size;
}
if (params_length && (rc == 0))
- q6asm_send_audio_effects_params(ac, params,
- params_length);
+ q6asm_set_pp_params(ac, NULL, params, params_length);
invalid_config:
kfree(params);
return rc;
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index 3a3774a..b644df7 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1521,9 +1521,10 @@
pr_debug("%s: sample_rate = %d channels = %d bps = %d sample_word_size = %d\n",
__func__, prtd->sample_rate, prtd->num_channels,
bits_per_sample, sample_word_size);
- ret = q6asm_enc_cfg_blk_pcm_format_support_v3(prtd->audio_client,
+ ret = q6asm_enc_cfg_blk_pcm_format_support_v4(prtd->audio_client,
prtd->sample_rate, prtd->num_channels,
- bits_per_sample, sample_word_size);
+ bits_per_sample, sample_word_size,
+ ASM_LITTLE_ENDIAN, DEFAULT_QF);
return ret;
}
diff --git a/asoc/msm-cpe-lsm.c b/asoc/msm-cpe-lsm.c
index 6377784..4094c1e 100644
--- a/asoc/msm-cpe-lsm.c
+++ b/asoc/msm-cpe-lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -478,18 +478,21 @@
lab_d->pcm_buf = pcm_buf;
dma_alloc = bufsz * bufcnt;
pcm_buf->mem = NULL;
- pcm_buf->mem = dma_alloc_coherent(dma_data->sdev->dev.parent,
- dma_alloc,
- &(pcm_buf->phys),
- GFP_KERNEL);
+ pcm_buf->mem = kzalloc(dma_alloc, GFP_DMA);
if (!pcm_buf->mem) {
- dev_err(rtd->dev,
- "%s:DMA alloc failed size = %x\n",
- __func__, dma_alloc);
rc = -ENOMEM;
goto fail;
}
+ pcm_buf->phys = dma_map_single(dma_data->sdev->dev.parent,
+ pcm_buf->mem, dma_alloc, DMA_BIDIRECTIONAL);
+ if (dma_mapping_error(dma_data->sdev->dev.parent, pcm_buf->phys)) {
+ dev_err(rtd->dev, "%s Error mapping DMA buffers\n", __func__);
+ pcm_buf->phys = (phys_addr_t)NULL;
+ rc = -EFAULT;
+ goto fail;
+ }
+
count = 0;
while (count < bufcnt) {
pcm_buf[count].mem = pcm_buf[0].mem + (count * bufsz);
@@ -504,13 +507,10 @@
return 0;
fail:
- if (pcm_buf) {
- if (pcm_buf->mem)
- dma_free_coherent(dma_data->sdev->dev.parent, dma_alloc,
- pcm_buf->mem, pcm_buf->phys);
- kfree(pcm_buf);
- lab_d->pcm_buf = NULL;
- }
+ if (pcm_buf && pcm_buf->mem)
+ kfree(pcm_buf->mem);
+ kfree(pcm_buf);
+ lab_d->pcm_buf = NULL;
exit:
return rc;
}
@@ -544,8 +544,12 @@
pcm_buf = lab_d->pcm_buf;
dma_alloc = bufsz * bufcnt;
if (dma_data && pcm_buf)
- dma_free_coherent(dma_data->sdev->dev.parent, dma_alloc,
- pcm_buf->mem, pcm_buf->phys);
+ if (pcm_buf->phys)
+ dma_unmap_single(dma_data->sdev->dev.parent,
+ pcm_buf->phys, dma_alloc, DMA_BIDIRECTIONAL);
+ if (pcm_buf)
+ kfree(pcm_buf->mem);
+
kfree(pcm_buf);
lab_d->pcm_buf = NULL;
return rc;
@@ -633,7 +637,7 @@
memset(lab_d->pcm_buf[0].mem, 0, lab_d->pcm_size);
rc = slim_port_xfer(dma_data->sdev, dma_data->ph,
- lab_d->pcm_buf[0].phys,
+ lab_d->pcm_buf[0].mem,
hw_params->buf_sz, &lab_d->comp);
if (rc) {
dev_err(rtd->dev,
@@ -643,7 +647,7 @@
}
rc = slim_port_xfer(dma_data->sdev, dma_data->ph,
- lab_d->pcm_buf[1].phys,
+ lab_d->pcm_buf[1].mem,
hw_params->buf_sz, &lab_d->comp);
if (rc) {
dev_err(rtd->dev,
@@ -678,7 +682,7 @@
lab_d->thread_status != MSM_LSM_LAB_THREAD_ERROR) {
rc = slim_port_xfer(dma_data->sdev, dma_data->ph,
- next_buf->phys,
+ next_buf->mem,
hw_params->buf_sz, &lab_d->comp);
if (rc) {
dev_err(rtd->dev,
@@ -3132,7 +3136,7 @@
}
static int msm_cpe_lsm_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
struct cpe_lsm_data *lsm_d = cpe_get_lsm_data(substream);
struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -3140,10 +3144,8 @@
struct cpe_lsm_session *session;
struct cpe_lsm_lab *lab_d = &lsm_d->lab;
char *pcm_buf;
- int fbytes = 0;
int rc = 0;
- fbytes = frames_to_bytes(runtime, frames);
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_PREPARED) {
pr_err("%s: XRUN ignore for now\n", __func__);
@@ -3286,7 +3288,7 @@
.prepare = msm_cpe_lsm_prepare,
.trigger = msm_cpe_lsm_trigger,
.pointer = msm_cpe_lsm_pointer,
- .copy = msm_cpe_lsm_copy,
+ .copy_user = msm_cpe_lsm_copy,
.hw_params = msm_cpe_lsm_hwparams,
.compat_ioctl = msm_cpe_lsm_ioctl_compat,
};
diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c
index 72883eb..3de797f 100644
--- a/asoc/msm-dai-fe.c
+++ b/asoc/msm-dai-fe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -698,6 +698,36 @@
},
{
.playback = {
+ .stream_name = "SEC_AUXPCM_HOSTLESS Playback",
+ .aif_name = "SEC_AUXPCM_DL_HL",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 1,
+ .rate_min = 8000,
+ .rate_max = 16000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "SEC_AUXPCM_RX_HOSTLESS",
+ .probe = fe_dai_probe,
+ },
+ {
+ .capture = {
+ .stream_name = "SEC_AUXPCM_HOSTLESS Capture",
+ .aif_name = "SEC_AUXPCM_UL_HL",
+ .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 1,
+ .rate_min = 8000,
+ .rate_max = 16000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "SEC_AUXPCM_TX_HOSTLESS",
+ .probe = fe_dai_probe,
+ },
+ {
+ .playback = {
.stream_name = "VOICE_STUB Playback",
.aif_name = "VOICE_STUB_DL",
.rates = SNDRV_PCM_RATE_8000_48000,
@@ -2453,7 +2483,7 @@
.capture = {
.stream_name = "MultiMedia17 Capture",
.aif_name = "MM_UL17",
- .rates = (SNDRV_PCM_RATE_8000_48000|
+ .rates = (SNDRV_PCM_RATE_8000_192000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
@@ -2461,7 +2491,7 @@
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.compress_new = snd_soc_new_compress,
@@ -2472,7 +2502,7 @@
.capture = {
.stream_name = "MultiMedia18 Capture",
.aif_name = "MM_UL18",
- .rates = (SNDRV_PCM_RATE_8000_48000|
+ .rates = (SNDRV_PCM_RATE_8000_192000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
@@ -2491,7 +2521,7 @@
.capture = {
.stream_name = "MultiMedia19 Capture",
.aif_name = "MM_UL19",
- .rates = (SNDRV_PCM_RATE_8000_48000|
+ .rates = (SNDRV_PCM_RATE_8000_192000|
SNDRV_PCM_RATE_KNOT),
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
@@ -2499,7 +2529,7 @@
.channels_min = 1,
.channels_max = 8,
.rate_min = 8000,
- .rate_max = 48000,
+ .rate_max = 192000,
},
.ops = &msm_fe_Multimedia_dai_ops,
.compress_new = snd_soc_new_compress,
@@ -2539,6 +2569,44 @@
.name = "MultiMedia20",
.probe = fe_dai_probe,
},
+ {
+ .capture = {
+ .stream_name = "MultiMedia28 Capture",
+ .aif_name = "MM_UL28",
+ .rates = (SNDRV_PCM_RATE_8000_192000|
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .compress_new = snd_soc_new_compress,
+ .name = "MultiMedia28",
+ .probe = fe_dai_probe,
+ },
+ {
+ .capture = {
+ .stream_name = "MultiMedia29 Capture",
+ .aif_name = "MM_UL29",
+ .rates = (SNDRV_PCM_RATE_8000_192000|
+ SNDRV_PCM_RATE_KNOT),
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S24_3LE),
+ .channels_min = 1,
+ .channels_max = 8,
+ .rate_min = 8000,
+ .rate_max = 192000,
+ },
+ .ops = &msm_fe_Multimedia_dai_ops,
+ .compress_new = snd_soc_new_compress,
+ .name = "MultiMedia29",
+ .probe = fe_dai_probe,
+ },
};
static int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index bec7fcf..d0df70c 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -8978,6 +8978,7 @@
void msm_dai_q6_exit(void)
{
+ platform_driver_unregister(&msm_dai_tdm_q6);
platform_driver_unregister(&msm_dai_q6_tdm_driver);
platform_driver_unregister(&msm_dai_q6_spdif_driver);
platform_driver_unregister(&msm_dai_mi2s_q6);
diff --git a/asoc/msm-ds2-dap-config.c b/asoc/msm-ds2-dap-config.c
index 645ecf5..ad7a3c6 100644
--- a/asoc/msm-ds2-dap-config.c
+++ b/asoc/msm-ds2-dap-config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,6 +17,7 @@
#include <sound/control.h>
#include <dsp/q6adm-v2.h>
#include <dsp/q6core.h>
+#include <dsp/q6common.h>
#include "msm-ds2-dap-config.h"
#include "msm-pcm-routing-v2.h"
@@ -196,18 +197,23 @@
int32_t *update_params_value = NULL;
uint32_t params_length = SOFT_VOLUME_PARAM_SIZE * sizeof(uint32_t);
uint32_t param_payload_len = PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
+ struct param_hdr_v3 param_hdr;
int rc = 0;
update_params_value = kzalloc(params_length + param_payload_len,
GFP_KERNEL);
- if (!update_params_value)
+ if (!update_params_value) {
+ pr_err("%s: params memory alloc failed\n", __func__);
goto end;
+ }
- rc = adm_get_params(port_id, copp_idx,
- AUDPROC_MODULE_ID_VOL_CTRL,
- AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS,
- params_length + param_payload_len,
- (char *) update_params_value);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS;
+ param_hdr.param_size = params_length + param_payload_len;
+ rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL,
+ ¶m_hdr, (char *) update_params_value);
if (rc == 0) {
pr_debug("%s: params_value [0x%x, 0x%x, 0x%x]\n",
__func__, update_params_value[0],
@@ -227,12 +233,13 @@
static int msm_ds2_dap_set_vspe_vdhe(int dev_map_idx,
bool is_custom_stereo_enabled)
{
- int32_t *update_params_value = NULL;
- int32_t *param_val = NULL;
- int idx, i, j, rc = 0, cdev;
- uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM +
- 2 * DOLBY_PARAM_PAYLOAD_SIZE) *
- sizeof(uint32_t);
+ u8 *packed_param_data = NULL;
+ u8 *param_data = NULL;
+ struct param_hdr_v3 param_hdr;
+ u32 packed_param_size = 0;
+ u32 param_size = 0;
+ int cdev;
+ int rc = 0;
if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) {
pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx);
@@ -260,74 +267,95 @@
goto end;
}
- update_params_value = kzalloc(params_length, GFP_KERNEL);
- if (!update_params_value) {
- rc = -ENOMEM;
+ /* Allocate the max space needed */
+ packed_param_size = (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t)) +
+ (2 * sizeof(union param_hdrs));
+ packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
+ if (!packed_param_data)
+ return -ENOMEM;
+
+ packed_param_size = 0;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ /* Set common values */
+ cdev = dev_map[dev_map_idx].cache_dev;
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+
+ /* Pack VDHE header + data */
+ param_hdr.param_id = DOLBY_PARAM_ID_VDHE;
+ param_size = DOLBY_PARAM_VDHE_LENGTH * sizeof(uint32_t);
+ param_hdr.param_size = param_size;
+
+ if (is_custom_stereo_enabled)
+ param_data = NULL;
+ else
+ param_data = (u8 *) &ds2_dap_params[cdev]
+ .params_val[DOLBY_PARAM_VDHE_OFFSET];
+
+ rc = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data,
+ ¶m_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params for dolby vdhe, error %d\n",
+ __func__, rc);
goto end;
}
- params_length = 0;
- param_val = update_params_value;
- cdev = dev_map[dev_map_idx].cache_dev;
- /* for VDHE and VSPE DAP params at index 0 and 1 in table */
- for (i = 0; i < 2; i++) {
- *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
- *update_params_value++ = ds2_dap_params_id[i];
- *update_params_value++ = ds2_dap_params_length[i] *
- sizeof(uint32_t);
- idx = ds2_dap_params_offset[i];
- for (j = 0; j < ds2_dap_params_length[i]; j++) {
- if (is_custom_stereo_enabled)
- *update_params_value++ = 0;
- else
- *update_params_value++ =
- ds2_dap_params[cdev].params_val[idx+j];
- }
- params_length += (DOLBY_PARAM_PAYLOAD_SIZE +
- ds2_dap_params_length[i]) *
- sizeof(uint32_t);
- }
+ packed_param_size += param_size;
- pr_debug("%s: valid param length: %d\n", __func__, params_length);
- if (params_length) {
- rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id,
- dev_map[dev_map_idx].copp_idx,
- (char *)param_val,
- params_length);
- if (rc) {
- pr_err("%s: send vdhe/vspe params failed with rc=%d\n",
- __func__, rc);
- rc = -EINVAL;
- goto end;
- }
+ /* Pack VSPE header + data */
+ param_hdr.param_id = DOLBY_PARAM_ID_VSPE;
+ param_size = DOLBY_PARAM_VSPE_LENGTH * sizeof(uint32_t);
+ param_hdr.param_size = param_size;
+
+ if (is_custom_stereo_enabled)
+ param_data = NULL;
+ else
+ param_data = (u8 *) &ds2_dap_params[cdev]
+ .params_val[DOLBY_PARAM_VSPE_OFFSET];
+
+ rc = q6common_pack_pp_params(packed_param_data + packed_param_size,
+ ¶m_hdr, param_data, ¶m_size);
+ if (rc) {
+ pr_err("%s: Failed to pack params for dolby vspe, error %d\n",
+ __func__, rc);
+ goto end;
+ }
+ packed_param_size += param_size;
+
+ rc = adm_set_pp_params(dev_map[dev_map_idx].port_id,
+ dev_map[dev_map_idx].copp_idx, NULL,
+ packed_param_data, packed_param_size);
+ if (rc) {
+ pr_err("%s: send vdhe/vspe params failed with rc=%d\n",
+ __func__, rc);
+ rc = -EINVAL;
+ goto end;
}
end:
- kfree(param_val);
+ kfree(packed_param_data);
return rc;
}
int qti_set_custom_stereo_on(int port_id, int copp_idx,
bool is_custom_stereo_on)
{
-
+ struct custom_stereo_param custom_stereo;
+ struct param_hdr_v3 param_hdr;
uint16_t op_FL_ip_FL_weight;
uint16_t op_FL_ip_FR_weight;
uint16_t op_FR_ip_FL_weight;
uint16_t op_FR_ip_FR_weight;
-
- int32_t *update_params_value32 = NULL, rc = 0;
- int32_t *param_val = NULL;
- int16_t *update_params_value16 = 0;
- uint32_t params_length_bytes = CUSTOM_STEREO_PAYLOAD_SIZE *
- sizeof(uint32_t);
- uint32_t avail_length = params_length_bytes;
+ int rc = 0;
if ((port_id != SLIMBUS_0_RX) &&
(port_id != RT_PROXY_PORT_001_RX)) {
pr_debug("%s:No Custom stereo for port:0x%x\n",
__func__, port_id);
- goto skip_send_cmd;
+ return 0;
}
+ memset(&custom_stereo, 0, sizeof(custom_stereo));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
pr_debug("%s: port 0x%x, copp_idx %d, is_custom_stereo_on %d\n",
__func__, port_id, copp_idx, is_custom_stereo_on);
if (is_custom_stereo_on) {
@@ -346,76 +374,50 @@
op_FR_ip_FR_weight = Q14_GAIN_UNITY;
}
- update_params_value32 = kzalloc(params_length_bytes, GFP_KERNEL);
- if (!update_params_value32) {
- rc = -ENOMEM;
- goto skip_send_cmd;
- }
- param_val = update_params_value32;
- if (avail_length < 2 * sizeof(uint32_t))
- goto skip_send_cmd;
- *update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER;
- *update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF;
- avail_length = avail_length - (2 * sizeof(uint32_t));
+ param_hdr.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF;
+ param_hdr.param_size = sizeof(struct custom_stereo_param);
- update_params_value16 = (int16_t *)update_params_value32;
- if (avail_length < 10 * sizeof(uint16_t))
- goto skip_send_cmd;
- *update_params_value16++ = CUSTOM_STEREO_CMD_PARAM_SIZE;
- /* for alignment only*/
- *update_params_value16++ = 0;
/* index is 32-bit param in little endian*/
- *update_params_value16++ = CUSTOM_STEREO_INDEX_PARAM;
- *update_params_value16++ = 0;
+ custom_stereo.index = CUSTOM_STEREO_INDEX_PARAM;
+ custom_stereo.reserved = 0;
/* for stereo mixing num out ch*/
- *update_params_value16++ = CUSTOM_STEREO_NUM_OUT_CH;
+ custom_stereo.num_out_ch = CUSTOM_STEREO_NUM_OUT_CH;
/* for stereo mixing num in ch*/
- *update_params_value16++ = CUSTOM_STEREO_NUM_IN_CH;
+ custom_stereo.num_in_ch = CUSTOM_STEREO_NUM_IN_CH;
/* Out ch map FL/FR*/
- *update_params_value16++ = PCM_CHANNEL_FL;
- *update_params_value16++ = PCM_CHANNEL_FR;
+ custom_stereo.out_fl = PCM_CHANNEL_FL;
+ custom_stereo.out_fr = PCM_CHANNEL_FR;
/* In ch map FL/FR*/
- *update_params_value16++ = PCM_CHANNEL_FL;
- *update_params_value16++ = PCM_CHANNEL_FR;
- avail_length = avail_length - (10 * sizeof(uint16_t));
+ custom_stereo.in_fl = PCM_CHANNEL_FL;
+ custom_stereo.in_fr = PCM_CHANNEL_FR;
+
/* weighting coefficients as name suggests,
* mixing will be done according to these coefficients
*/
- if (avail_length < 4 * sizeof(uint16_t))
- goto skip_send_cmd;
- *update_params_value16++ = op_FL_ip_FL_weight;
- *update_params_value16++ = op_FL_ip_FR_weight;
- *update_params_value16++ = op_FR_ip_FL_weight;
- *update_params_value16++ = op_FR_ip_FR_weight;
- avail_length = avail_length - (4 * sizeof(uint16_t));
- if (params_length_bytes != 0) {
- rc = adm_dolby_dap_send_params(port_id, copp_idx,
- (char *)param_val,
- params_length_bytes);
- if (rc) {
- pr_err("%s: send params failed rc=%d\n", __func__, rc);
- rc = -EINVAL;
- goto skip_send_cmd;
- }
+ custom_stereo.op_FL_ip_FL_weight = op_FL_ip_FL_weight;
+ custom_stereo.op_FL_ip_FR_weight = op_FL_ip_FR_weight;
+ custom_stereo.op_FR_ip_FL_weight = op_FR_ip_FL_weight;
+ custom_stereo.op_FR_ip_FR_weight = op_FR_ip_FR_weight;
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (u8 *) &custom_stereo);
+ if (rc) {
+ pr_err("%s: send params failed rc=%d\n", __func__, rc);
+ return -EINVAL;
}
- kfree(param_val);
+
return 0;
-skip_send_cmd:
- pr_err("%s: insufficient memory, send cmd failed\n",
- __func__);
- kfree(param_val);
- return rc;
}
static int dap_set_custom_stereo_onoff(int dev_map_idx,
bool is_custom_stereo_enabled)
{
+ uint32_t enable = is_custom_stereo_enabled ? 1 : 0;
+ struct param_hdr_v3 param_hdr;
+ int rc = 0;
- int32_t *update_params_value = NULL, rc = 0;
- int32_t *param_val = NULL;
- uint32_t params_length_bytes = (TOTAL_LENGTH_DOLBY_PARAM +
- DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t);
if ((dev_map[dev_map_idx].port_id != SLIMBUS_0_RX) &&
(dev_map[dev_map_idx].port_id != RT_PROXY_PORT_001_RX)) {
pr_debug("%s:No Custom stereo for port:0x%x\n",
@@ -429,41 +431,25 @@
goto end;
}
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
/* DAP custom stereo */
msm_ds2_dap_set_vspe_vdhe(dev_map_idx,
is_custom_stereo_enabled);
- update_params_value = kzalloc(params_length_bytes, GFP_KERNEL);
- if (!update_params_value) {
- pr_err("%s: params memory alloc failed\n", __func__);
- rc = -ENOMEM;
- goto end;
- }
- params_length_bytes = 0;
- param_val = update_params_value;
- *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
- *update_params_value++ = DOLBY_ENABLE_CUSTOM_STEREO;
- *update_params_value++ = sizeof(uint32_t);
- if (is_custom_stereo_enabled)
- *update_params_value++ = 1;
- else
- *update_params_value++ = 0;
- params_length_bytes += (DOLBY_PARAM_PAYLOAD_SIZE + 1) *
- sizeof(uint32_t);
- pr_debug("%s: valid param length: %d\n", __func__, params_length_bytes);
- if (params_length_bytes) {
- rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id,
- dev_map[dev_map_idx].copp_idx,
- (char *)param_val,
- params_length_bytes);
- if (rc) {
- pr_err("%s: custom stereo param failed with rc=%d\n",
- __func__, rc);
- rc = -EINVAL;
- goto end;
- }
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = DOLBY_ENABLE_CUSTOM_STEREO;
+ param_hdr.param_size = sizeof(enable);
+
+ rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id,
+ dev_map[dev_map_idx].copp_idx,
+ param_hdr, (u8 *) &enable);
+ if (rc) {
+ pr_err("%s: set custom stereo enable failed with rc=%d\n",
+ __func__, rc);
+ rc = -EINVAL;
}
end:
- kfree(param_val);
return rc;
}
@@ -652,8 +638,11 @@
{
int rc = 0, i = 0, port_id, copp_idx;
/* Account for 32 bit integer allocation */
- int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t));
+ int32_t param_sz =
+ (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t));
int32_t *update_param_val = NULL;
+ struct module_instance_info mod_inst_info;
+ int mod_inst_info_sz = 0;
if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) {
pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx);
@@ -661,10 +650,12 @@
goto end;
}
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
port_id = dev_map[dev_map_idx].port_id;
copp_idx = dev_map[dev_map_idx].copp_idx;
pr_debug("%s: port_id 0x%x copp_idx %d\n", __func__, port_id, copp_idx);
- update_param_val = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL);
+ update_param_val =
+ kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL);
if (!update_param_val) {
pr_err("%s, param memory alloc failed\n", __func__);
rc = -ENOMEM;
@@ -673,9 +664,10 @@
if (!ds2_dap_params_states.dap_bypass) {
/* get modules from dsp */
- rc = adm_get_pp_topo_module_list(port_id, copp_idx,
- ADM_GET_TOPO_MODULE_LIST_LENGTH,
- (char *)update_param_val);
+ rc = adm_get_pp_topo_module_list_v2(
+ port_id, copp_idx,
+ ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH,
+ update_param_val);
if (rc < 0) {
pr_err("%s:topo list port %d, err %d,copp_idx %d\n",
__func__, port_id, copp_idx, rc);
@@ -689,11 +681,15 @@
rc = -EINVAL;
goto end;
}
+
+ mod_inst_info_sz = sizeof(struct module_instance_info) /
+ sizeof(uint32_t);
/* Turn off modules */
- for (i = 1; i < update_param_val[0]; i++) {
+ for (i = 1; i < update_param_val[0] * mod_inst_info_sz;
+ i += mod_inst_info_sz) {
if (!msm_ds2_dap_can_enable_module(
- update_param_val[i]) ||
- (update_param_val[i] == DS2_MODULE_ID)) {
+ update_param_val[i]) ||
+ (update_param_val[i] == DS2_MODULE_ID)) {
pr_debug("%s: Do not enable/disable %d\n",
__func__, update_param_val[i]);
continue;
@@ -701,15 +697,21 @@
pr_debug("%s: param disable %d\n",
__func__, update_param_val[i]);
- adm_param_enable(port_id, copp_idx, update_param_val[i],
- MODULE_DISABLE);
+ memcpy(&mod_inst_info, &update_param_val[i],
+ sizeof(mod_inst_info));
+ adm_param_enable_v2(port_id, copp_idx,
+ mod_inst_info,
+ MODULE_DISABLE);
}
} else {
msm_ds2_dap_send_cal_data(dev_map_idx);
}
- adm_param_enable(port_id, copp_idx, DS2_MODULE_ID,
- !ds2_dap_params_states.dap_bypass);
+
+ mod_inst_info.module_id = DS2_MODULE_ID;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+ adm_param_enable_v2(port_id, copp_idx, mod_inst_info,
+ !ds2_dap_params_states.dap_bypass);
end:
kfree(update_param_val);
return rc;
@@ -885,17 +887,22 @@
{
int rc = 0, i = 0, j = 0;
/*Account for 32 bit integer allocation */
- int32_t param_sz = (ADM_GET_TOPO_MODULE_LIST_LENGTH / sizeof(uint32_t));
+ int32_t param_sz =
+ (ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH / sizeof(uint32_t));
int32_t *mod_list = NULL;
int port_id = 0, copp_idx = -1;
bool cs_onoff = ds2_dap_params_states.custom_stereo_onoff;
int ramp_wait = DOLBY_SOFT_VOLUME_PERIOD;
+ struct module_instance_info mod_inst_info;
+ int mod_inst_info_sz = 0;
pr_debug("%s: bypass type %d bypass %d custom stereo %d\n", __func__,
ds2_dap_params_states.dap_bypass_type,
ds2_dap_params_states.dap_bypass,
ds2_dap_params_states.custom_stereo_onoff);
- mod_list = kzalloc(ADM_GET_TOPO_MODULE_LIST_LENGTH, GFP_KERNEL);
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
+ mod_list =
+ kzalloc(ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH, GFP_KERNEL);
if (!mod_list) {
pr_err("%s: param memory alloc failed\n", __func__);
rc = -ENOMEM;
@@ -922,9 +929,10 @@
}
/* getmodules from dsp */
- rc = adm_get_pp_topo_module_list(port_id, copp_idx,
- ADM_GET_TOPO_MODULE_LIST_LENGTH,
- (char *)mod_list);
+ rc = adm_get_pp_topo_module_list_v2(
+ port_id, copp_idx,
+ ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH,
+ mod_list);
if (rc < 0) {
pr_err("%s:adm get topo list port %d",
__func__, port_id);
@@ -976,8 +984,11 @@
/* if dap bypass is set */
if (ds2_dap_params_states.dap_bypass) {
/* Turn off dap module */
- adm_param_enable(port_id, copp_idx,
- DS2_MODULE_ID, MODULE_DISABLE);
+ mod_inst_info.module_id = DS2_MODULE_ID;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+ adm_param_enable_v2(port_id, copp_idx,
+ mod_inst_info,
+ MODULE_DISABLE);
/*
* If custom stereo is on at the time of bypass,
* switch off custom stereo on dap and turn on
@@ -1000,8 +1011,13 @@
copp_idx, rc);
}
}
+
+ mod_inst_info_sz =
+ sizeof(struct module_instance_info) /
+ sizeof(uint32_t);
/* Turn on qti modules */
- for (j = 1; j < mod_list[0]; j++) {
+ for (j = 1; j < mod_list[0] * mod_inst_info_sz;
+ j += mod_inst_info_sz) {
if (!msm_ds2_dap_can_enable_module(
mod_list[j]) ||
mod_list[j] ==
@@ -1009,9 +1025,11 @@
continue;
pr_debug("%s: param enable %d\n",
__func__, mod_list[j]);
- adm_param_enable(port_id, copp_idx,
- mod_list[j],
- MODULE_ENABLE);
+ memcpy(&mod_inst_info, &mod_list[j],
+ sizeof(mod_inst_info));
+ adm_param_enable_v2(port_id, copp_idx,
+ mod_inst_info,
+ MODULE_ENABLE);
}
/* Add adm api to resend calibration on port */
@@ -1026,7 +1044,8 @@
}
} else {
/* Turn off qti modules */
- for (j = 1; j < mod_list[0]; j++) {
+ for (j = 1; j < mod_list[0] * mod_inst_info_sz;
+ j += mod_inst_info_sz) {
if (!msm_ds2_dap_can_enable_module(
mod_list[j]) ||
mod_list[j] ==
@@ -1034,15 +1053,20 @@
continue;
pr_debug("%s: param disable %d\n",
__func__, mod_list[j]);
- adm_param_enable(port_id, copp_idx,
- mod_list[j],
- MODULE_DISABLE);
+ memcpy(&mod_inst_info, &mod_list[j],
+ sizeof(mod_inst_info));
+ adm_param_enable_v2(port_id, copp_idx,
+ mod_inst_info,
+ MODULE_DISABLE);
}
/* Enable DAP modules */
pr_debug("%s:DS2 param enable\n", __func__);
- adm_param_enable(port_id, copp_idx,
- DS2_MODULE_ID, MODULE_ENABLE);
+ mod_inst_info.module_id = DS2_MODULE_ID;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+ adm_param_enable_v2(port_id, copp_idx,
+ mod_inst_info,
+ MODULE_ENABLE);
/*
* If custom stereo is on at the time of dap on,
* switch off custom stereo on qti channel mixer
@@ -1101,19 +1125,19 @@
static int msm_ds2_dap_send_end_point(int dev_map_idx, int endp_idx)
{
- int rc = 0;
- int32_t *update_params_value = NULL, *params_value = NULL;
- uint32_t params_length = (DOLBY_PARAM_INT_ENDP_LENGTH +
- DOLBY_PARAM_PAYLOAD_SIZE) * sizeof(uint32_t);
+ uint32_t offset = 0;
+ struct param_hdr_v3 param_hdr;
int cache_device = 0;
struct ds2_dap_params_s *ds2_ap_params_obj = NULL;
int32_t *modified_param = NULL;
+ int rc = 0;
if (dev_map_idx < 0 || dev_map_idx >= DS2_DEVICES_ALL) {
pr_err("%s: invalid dev map index %d\n", __func__, dev_map_idx);
rc = -EINVAL;
goto end;
}
+ memset(¶m_hdr, 0, sizeof(param_hdr));
cache_device = dev_map[dev_map_idx].cache_dev;
ds2_ap_params_obj = &ds2_dap_params[cache_device];
@@ -1122,12 +1146,6 @@
pr_debug("%s: endp - %pK %pK\n", __func__,
&ds2_dap_params[cache_device], ds2_ap_params_obj);
- params_value = kzalloc(params_length, GFP_KERNEL);
- if (!params_value) {
- rc = -ENOMEM;
- goto end;
- }
-
if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) {
pr_err("%s: invalid port\n", __func__);
rc = -EINVAL;
@@ -1141,21 +1159,20 @@
goto end;
}
- update_params_value = params_value;
- *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
- *update_params_value++ = DOLBY_PARAM_ID_INIT_ENDP;
- *update_params_value++ = DOLBY_PARAM_INT_ENDP_LENGTH * sizeof(uint32_t);
- *update_params_value++ = ds2_ap_params_obj->params_val[
- ds2_dap_params_offset[endp_idx]];
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = DOLBY_PARAM_ID_INIT_ENDP;
+ param_hdr.param_size = sizeof(offset);
+ offset = ds2_ap_params_obj->params_val[ds2_dap_params_offset[endp_idx]];
pr_debug("%s: off %d, length %d\n", __func__,
ds2_dap_params_offset[endp_idx],
ds2_dap_params_length[endp_idx]);
pr_debug("%s: param 0x%x, param val %d\n", __func__,
ds2_dap_params_id[endp_idx], ds2_ap_params_obj->
params_val[ds2_dap_params_offset[endp_idx]]);
- rc = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id,
- dev_map[dev_map_idx].copp_idx,
- (char *)params_value, params_length);
+ rc = adm_pack_and_set_one_pp_param(dev_map[dev_map_idx].port_id,
+ dev_map[dev_map_idx].copp_idx,
+ param_hdr, (u8 *) &offset);
if (rc) {
pr_err("%s: send dolby params failed rc %d\n", __func__, rc);
rc = -EINVAL;
@@ -1172,19 +1189,17 @@
ds2_ap_params_obj->dap_params_modified[endp_idx] = 0x00010001;
end:
- kfree(params_value);
return rc;
}
static int msm_ds2_dap_send_cached_params(int dev_map_idx,
int commit)
{
- int32_t *update_params_value = NULL, *params_value = NULL;
- uint32_t idx, i, j, ret = 0;
- uint32_t params_length = (TOTAL_LENGTH_DOLBY_PARAM +
- (MAX_DS2_PARAMS - 1) *
- DOLBY_PARAM_PAYLOAD_SIZE) *
- sizeof(uint32_t);
+ uint8_t *packed_params = NULL;
+ uint32_t packed_params_size = 0;
+ uint32_t param_size = 0;
+ struct param_hdr_v3 param_hdr;
+ uint32_t idx, i, ret = 0;
int cache_device = 0;
struct ds2_dap_params_s *ds2_ap_params_obj = NULL;
int32_t *modified_param = NULL;
@@ -1194,6 +1209,7 @@
ret = -EINVAL;
goto end;
}
+ memset(¶m_hdr, 0, sizeof(param_hdr));
cache_device = dev_map[dev_map_idx].cache_dev;
/* Use off profile cache in only for soft bypass */
@@ -1207,12 +1223,16 @@
pr_debug("%s: cached param - %pK %pK, cache_device %d\n", __func__,
&ds2_dap_params[cache_device], ds2_ap_params_obj,
cache_device);
- params_value = kzalloc(params_length, GFP_KERNEL);
- if (!params_value) {
- pr_err("%s: params memory alloc failed\n", __func__);
- ret = -ENOMEM;
- goto end;
- }
+
+ /*
+ * Allocate the max space needed. This is enough space to hold the
+ * header for each param plus the total size of all the params.
+ */
+ packed_params_size = (sizeof(param_hdr) * (MAX_DS2_PARAMS - 1)) +
+ (TOTAL_LENGTH_DOLBY_PARAM * sizeof(uint32_t));
+ packed_params = kzalloc(packed_params_size, GFP_KERNEL);
+ if (!packed_params)
+ return -ENOMEM;
if (dev_map[dev_map_idx].port_id == DOLBY_INVALID_PORT_ID) {
pr_err("%s: invalid port id\n", __func__);
@@ -1227,8 +1247,7 @@
goto end;
}
- update_params_value = params_value;
- params_length = 0;
+ packed_params_size = 0;
for (i = 0; i < (MAX_DS2_PARAMS-1); i++) {
/*get the pointer to the param modified array in the cache*/
modified_param = ds2_ap_params_obj->dap_params_modified;
@@ -1241,28 +1260,33 @@
if (!msm_ds2_dap_check_is_param_modified(modified_param, i,
commit))
continue;
- *update_params_value++ = DOLBY_BUNDLE_MODULE_ID;
- *update_params_value++ = ds2_dap_params_id[i];
- *update_params_value++ = ds2_dap_params_length[i] *
- sizeof(uint32_t);
+
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = ds2_dap_params_id[i];
+ param_hdr.param_size =
+ ds2_dap_params_length[i] * sizeof(uint32_t);
+
idx = ds2_dap_params_offset[i];
- for (j = 0; j < ds2_dap_params_length[i]; j++) {
- *update_params_value++ =
- ds2_ap_params_obj->params_val[idx+j];
- pr_debug("%s: id 0x%x,val %d\n", __func__,
- ds2_dap_params_id[i],
- ds2_ap_params_obj->params_val[idx+j]);
+ ret = q6common_pack_pp_params(
+ packed_params + packed_params_size, ¶m_hdr,
+ (u8 *) &ds2_ap_params_obj->params_val[idx],
+ ¶m_size);
+ if (ret) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, ret);
+ goto end;
}
- params_length += (DOLBY_PARAM_PAYLOAD_SIZE +
- ds2_dap_params_length[i]) * sizeof(uint32_t);
+
+ packed_params_size += param_size;
}
- pr_debug("%s: valid param length: %d\n", __func__, params_length);
- if (params_length) {
- ret = adm_dolby_dap_send_params(dev_map[dev_map_idx].port_id,
- dev_map[dev_map_idx].copp_idx,
- (char *)params_value,
- params_length);
+ pr_debug("%s: total packed param length: %d\n", __func__,
+ packed_params_size);
+ if (packed_params_size) {
+ ret = adm_set_pp_params(dev_map[dev_map_idx].port_id,
+ dev_map[dev_map_idx].copp_idx, NULL,
+ packed_params, packed_params_size);
if (ret) {
pr_err("%s: send dolby params failed ret %d\n",
__func__, ret);
@@ -1285,7 +1309,7 @@
}
}
end:
- kfree(params_value);
+ kfree(packed_params);
return ret;
}
@@ -1523,11 +1547,12 @@
{
int rc = 0, i, port_id = 0, copp_idx = -1;
struct dolby_param_data *dolby_data = (struct dolby_param_data *)arg;
- int32_t *update_params_value = NULL, *params_value = NULL;
+ int32_t *params_value = NULL;
uint32_t params_length = DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM *
sizeof(uint32_t);
uint32_t param_payload_len =
DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
+ struct param_hdr_v3 param_hdr;
/* Return error on get param in soft or hard bypass */
if (ds2_dap_params_states.dap_bypass == true) {
@@ -1573,17 +1598,15 @@
params_value = kzalloc(params_length + param_payload_len,
GFP_KERNEL);
- if (!params_value) {
- rc = -ENOMEM;
- goto end;
- }
+ if (!params_value)
+ return -ENOMEM;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
if (dolby_data->param_id == DOLBY_PARAM_ID_VER) {
- rc = adm_get_params(port_id, copp_idx,
- DOLBY_BUNDLE_MODULE_ID,
- DOLBY_PARAM_ID_VER,
- params_length + param_payload_len,
- (char *)params_value);
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = DOLBY_PARAM_ID_VER;
+ param_hdr.param_size = params_length + param_payload_len;
} else {
for (i = 0; i < MAX_DS2_PARAMS; i++)
if (ds2_dap_params_id[i] ==
@@ -1596,25 +1619,25 @@
goto end;
} else {
params_length =
- ds2_dap_params_length[i] * sizeof(uint32_t);
+ ds2_dap_params_length[i] * sizeof(uint32_t);
- rc = adm_get_params(port_id, copp_idx,
- DOLBY_BUNDLE_MODULE_ID,
- ds2_dap_params_id[i],
- params_length +
- param_payload_len,
- (char *)params_value);
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = ds2_dap_params_id[i];
+ param_hdr.param_size =
+ params_length + param_payload_len;
}
}
+ rc = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL,
+ ¶m_hdr, (u8 *) params_value);
if (rc) {
pr_err("%s: get parameters failed rc %d\n", __func__, rc);
rc = -EINVAL;
goto end;
}
- update_params_value = params_value;
- if (copy_to_user((void *)dolby_data->data,
- &update_params_value[DOLBY_PARAM_PAYLOAD_SIZE],
- (dolby_data->length * sizeof(uint32_t)))) {
+ if (copy_to_user((void __user *) dolby_data->data,
+ ¶ms_value[DOLBY_PARAM_PAYLOAD_SIZE],
+ (dolby_data->length * sizeof(uint32_t)))) {
pr_err("%s: error getting param\n", __func__);
rc = -EFAULT;
goto end;
@@ -1633,6 +1656,7 @@
uint32_t offset, length, params_length;
uint32_t param_payload_len =
DOLBY_PARAM_PAYLOAD_SIZE * sizeof(uint32_t);
+ struct param_hdr_v3 param_hdr;
for (i = 0; i < DS2_DEVICES_ALL; i++) {
if ((dev_map[i].active)) {
@@ -1651,6 +1675,7 @@
goto end;
}
+ memset(¶m_hdr, 0, sizeof(param_hdr));
length = ds2_dap_params[cache_dev].params_val[DOLBY_PARAM_VCNB_OFFSET];
if (length > DOLBY_PARAM_VCNB_MAX_LENGTH || length <= 0) {
@@ -1665,6 +1690,7 @@
visualizer_data = kzalloc(params_length, GFP_KERNEL);
if (!visualizer_data) {
+ pr_err("%s: params memory alloc failed\n", __func__);
ret = -ENOMEM;
dolby_data->length = 0;
goto end;
@@ -1682,11 +1708,13 @@
offset = 0;
params_length = length * sizeof(uint32_t);
- ret = adm_get_params(port_id, copp_idx,
- DOLBY_BUNDLE_MODULE_ID,
- DOLBY_PARAM_ID_VCBG,
- params_length + param_payload_len,
- (((char *)(visualizer_data)) + offset));
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = DOLBY_PARAM_ID_VCBG;
+ param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len;
+ ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL,
+ ¶m_hdr,
+ (((char *) (visualizer_data)) + offset));
if (ret) {
pr_err("%s: get parameters failed ret %d\n", __func__, ret);
ret = -EINVAL;
@@ -1694,11 +1722,13 @@
goto end;
}
offset = length * sizeof(uint32_t);
- ret = adm_get_params(port_id, copp_idx,
- DOLBY_BUNDLE_MODULE_ID,
- DOLBY_PARAM_ID_VCBE,
- params_length + param_payload_len,
- (((char *)(visualizer_data)) + offset));
+ param_hdr.module_id = DOLBY_BUNDLE_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = DOLBY_PARAM_ID_VCBE;
+ param_hdr.param_size = length * sizeof(uint32_t) + param_payload_len;
+ ret = adm_get_pp_params(port_id, copp_idx, ADM_CLIENT_ID_DEFAULT, NULL,
+ ¶m_hdr,
+ (((char *) (visualizer_data)) + offset));
if (ret) {
pr_err("%s: get parameters failed ret %d\n", __func__, ret);
ret = -EINVAL;
diff --git a/asoc/msm-ds2-dap-config.h b/asoc/msm-ds2-dap-config.h
index c90bd8f..4d6b5eb 100644
--- a/asoc/msm-ds2-dap-config.h
+++ b/asoc/msm-ds2-dap-config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved.
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
@@ -33,7 +33,6 @@
compat_uptr_t license_key;
};
-
#define SNDRV_DEVDEP_DAP_IOCTL_SET_PARAM32\
_IOWR('U', 0x10, struct dolby_param_data32)
#define SNDRV_DEVDEP_DAP_IOCTL_GET_PARAM32\
@@ -63,6 +62,34 @@
DAP_CMD_SET_BYPASS_TYPE = 5,
};
+struct custom_stereo_param {
+ /* Index is 32-bit param in little endian */
+ u16 index;
+ u16 reserved;
+
+ /* For stereo mixing, the number of out channels */
+ u16 num_out_ch;
+ /* For stereo mixing, the number of in channels */
+ u16 num_in_ch;
+
+ /* Out channel map FL/FR*/
+ u16 out_fl;
+ u16 out_fr;
+
+ /* In channel map FL/FR*/
+ u16 in_fl;
+ u16 in_fr;
+
+ /*
+ * Weighting coefficients. Mixing will be done according to
+ * these coefficients.
+ */
+ u16 op_FL_ip_FL_weight;
+ u16 op_FL_ip_FR_weight;
+ u16 op_FR_ip_FL_weight;
+ u16 op_FR_ip_FR_weight;
+};
+
#define DOLBY_PARAM_INT_ENDP_LENGTH 1
#define DOLBY_PARAM_INT_ENDP_OFFSET (DOLBY_PARAM_PSTG_OFFSET + \
DOLBY_PARAM_PSTG_LENGTH)
diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c
index f6a5698..666ad08 100644
--- a/asoc/msm-lsm-client.c
+++ b/asoc/msm-lsm-client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2176,12 +2176,12 @@
}
static int msm_lsm_pcm_copy(struct snd_pcm_substream *substream, int ch,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct lsm_priv *prtd = runtime->private_data;
char *pcm_buf = NULL;
- int fbytes = 0, rc = 0;
+ int rc = 0;
struct snd_soc_pcm_runtime *rtd;
if (!substream->private_data) {
@@ -2196,7 +2196,6 @@
return -EINVAL;
}
- fbytes = frames_to_bytes(runtime, frames);
if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
runtime->status->state == SNDRV_PCM_STATE_PREPARED) {
dev_err(rtd->dev,
@@ -2221,12 +2220,12 @@
prtd->lsm_client->hw_params.period_count;
pcm_buf = prtd->lsm_client->lab_buffer[prtd->appl_cnt].data;
dev_dbg(rtd->dev,
- "%s: copy the pcm data size %d\n",
+ "%s: copy the pcm data size %lu\n",
__func__, fbytes);
if (pcm_buf) {
if (copy_to_user(buf, pcm_buf, fbytes)) {
dev_err(rtd->dev,
- "%s: failed to copy bytes %d\n",
+ "%s: failed to copy bytes %lu\n",
__func__, fbytes);
return -EINVAL;
}
@@ -2341,7 +2340,7 @@
.prepare = msm_lsm_prepare,
.compat_ioctl = msm_lsm_ioctl_compat,
.hw_params = msm_lsm_hw_params,
- .copy = msm_lsm_pcm_copy,
+ .copy_user = msm_lsm_pcm_copy,
.pointer = msm_lsm_pcm_pointer,
};
diff --git a/asoc/msm-pcm-afe-v2.c b/asoc/msm-pcm-afe-v2.c
index 77eecb2..3a65fe5 100644
--- a/asoc/msm-pcm-afe-v2.c
+++ b/asoc/msm-pcm-afe-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -489,20 +489,20 @@
}
static int msm_afe_playback_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t hwoff,
- void __user *buf, snd_pcm_uframes_t frames)
+ int channel, unsigned long hwoff,
+ void __user *buf, unsigned long fbytes)
{
int ret = 0;
struct snd_pcm_runtime *runtime = substream->runtime;
struct pcm_afe_info *prtd = runtime->private_data;
- char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
+ char *hwbuf = runtime->dma_area + hwoff;
u32 mem_map_handle = 0;
pr_debug("%s : appl_ptr 0x%lx hw_ptr 0x%lx dest_to_copy 0x%pK\n",
__func__,
runtime->control->appl_ptr, runtime->status->hw_ptr, hwbuf);
- if (copy_from_user(hwbuf, buf, frames_to_bytes(runtime, frames))) {
+ if (copy_from_user(hwbuf, buf, fbytes)) {
pr_err("%s :Failed to copy audio from user buffer\n",
__func__);
@@ -542,13 +542,13 @@
}
static int msm_afe_capture_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t hwoff,
- void __user *buf, snd_pcm_uframes_t frames)
+ int channel, unsigned long hwoff,
+ void __user *buf, unsigned long fbytes)
{
int ret = 0;
struct snd_pcm_runtime *runtime = substream->runtime;
struct pcm_afe_info *prtd = runtime->private_data;
- char *hwbuf = runtime->dma_area + frames_to_bytes(runtime, hwoff);
+ char *hwbuf = runtime->dma_area + hwoff;
u32 mem_map_handle = 0;
if (!prtd->mmap_flag) {
@@ -590,7 +590,7 @@
__func__, runtime->control->appl_ptr,
runtime->status->hw_ptr, hwbuf);
- if (copy_to_user(buf, hwbuf, frames_to_bytes(runtime, frames))) {
+ if (copy_to_user(buf, hwbuf, fbytes)) {
pr_err("%s: copy to user failed\n", __func__);
goto fail;
@@ -602,8 +602,8 @@
}
static int msm_afe_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t hwoff, void __user *buf,
- snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf,
+ unsigned long fbytes)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct pcm_afe_info *prtd = runtime->private_data;
@@ -618,10 +618,10 @@
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = msm_afe_playback_copy(substream, channel, hwoff,
- buf, frames);
+ buf, fbytes);
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
ret = msm_afe_capture_copy(substream, channel, hwoff,
- buf, frames);
+ buf, fbytes);
return ret;
}
@@ -841,7 +841,7 @@
static const struct snd_pcm_ops msm_afe_ops = {
.open = msm_afe_open,
- .copy = msm_afe_copy,
+ .copy_user = msm_afe_copy,
.hw_params = msm_afe_hw_params,
.trigger = msm_afe_trigger,
.close = msm_afe_close,
diff --git a/asoc/msm-pcm-dtmf-v2.c b/asoc/msm-pcm-dtmf-v2.c
index 9953eeb..77dc81c 100644
--- a/asoc/msm-pcm-dtmf-v2.c
+++ b/asoc/msm-pcm-dtmf-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -217,24 +217,21 @@
}
static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t hwoff,
- void __user *buf, snd_pcm_uframes_t frames)
+ int channel, unsigned long hwoff,
+ void __user *buf, unsigned long fbytes)
{
int ret = 0;
- int count = 0;
struct dtmf_buf_node *buf_node = NULL;
struct snd_pcm_runtime *runtime = substream->runtime;
struct dtmf_drv_info *prtd = runtime->private_data;
unsigned long dsp_flags;
- count = frames_to_bytes(runtime, frames);
-
ret = wait_event_interruptible_timeout(prtd->out_wait,
(!list_empty(&prtd->out_queue)),
1 * HZ);
if (ret > 0) {
- if (count <= DTMF_PKT_SIZE) {
+ if (fbytes <= DTMF_PKT_SIZE) {
spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
buf_node = list_first_entry(&prtd->out_queue,
struct dtmf_buf_node, list);
@@ -242,7 +239,7 @@
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
ret = copy_to_user(buf,
&buf_node->dtmf_det_pkt,
- count);
+ fbytes);
if (ret) {
pr_err("%s: Copy to user returned %d\n",
__func__, ret);
@@ -254,8 +251,8 @@
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
} else {
- pr_err("%s: Read count %d > DTMF_PKT_SIZE\n",
- __func__, count);
+ pr_err("%s: Read count %lu > DTMF_PKT_SIZE\n",
+ __func__, fbytes);
ret = -ENOMEM;
}
} else if (ret == 0) {
@@ -269,14 +266,14 @@
}
static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
int ret = 0;
pr_debug("%s() DTMF\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames);
+ ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes);
return ret;
}
@@ -524,7 +521,7 @@
static const struct snd_pcm_ops msm_pcm_ops = {
.open = msm_pcm_open,
- .copy = msm_pcm_copy,
+ .copy_user = msm_pcm_copy,
.hw_params = msm_pcm_hw_params,
.close = msm_pcm_close,
.prepare = msm_pcm_prepare,
diff --git a/asoc/msm-pcm-host-voice-v2.c b/asoc/msm-pcm-host-voice-v2.c
index fd771df..7486ad7 100644
--- a/asoc/msm-pcm-host-voice-v2.c
+++ b/asoc/msm-pcm-host-voice-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -119,7 +119,7 @@
struct tap_point rx_tap_point;
phys_addr_t sess_paddr;
void *sess_kvaddr;
- struct ion_handle *ion_handle;
+ struct dma_buf *dma_buf;
struct mem_map_table tp_mem_table;
};
@@ -145,7 +145,6 @@
struct mutex lock;
struct session session[MAX_SESSION];
struct mixer_conf mixer_conf;
- struct ion_client *ion_client;
struct start_cmd start_cmd;
};
@@ -452,19 +451,12 @@
paddr = sess->sess_paddr;
if (paddr) {
- msm_audio_ion_free(prtd->ion_client, sess->ion_handle);
- prtd->ion_client = NULL;
- sess->ion_handle = NULL;
- msm_audio_ion_free(sess->tp_mem_table.client,
- sess->tp_mem_table.handle);
- sess->tp_mem_table.client = NULL;
- sess->tp_mem_table.handle = NULL;
+ msm_audio_ion_free(sess->dma_buf);
+ sess->dma_buf = NULL;
+ msm_audio_ion_free(sess->tp_mem_table.dma_buf);
+ sess->tp_mem_table.dma_buf = NULL;
sess->sess_paddr = 0;
sess->sess_kvaddr = 0;
- sess->ion_handle = 0;
- prtd->ion_client = 0;
- sess->tp_mem_table.client = 0;
- sess->tp_mem_table.handle = 0;
txtp->capture_dai_data.vocpcm_ion_buffer.paddr = 0;
txtp->capture_dai_data.vocpcm_ion_buffer.kvaddr = 0;
@@ -531,9 +523,7 @@
txtp = &sess->tx_tap_point;
rxtp = &sess->rx_tap_point;
- result = msm_audio_ion_alloc("host_pcm_buffer",
- &prtd->ion_client,
- &sess->ion_handle,
+ result = msm_audio_ion_alloc(&sess->dma_buf,
VHPCM_BLOCK_SIZE,
&sess->sess_paddr,
&mem_len,
@@ -549,9 +539,7 @@
pr_debug("%s: Host PCM memory block allocated\n", __func__);
/* Allocate mem_map_table for tap point */
- result = msm_audio_ion_alloc("host_pcm_table",
- &sess->tp_mem_table.client,
- &sess->tp_mem_table.handle,
+ result = msm_audio_ion_alloc(&sess->tp_mem_table.dma_buf,
sizeof(struct vss_imemory_table_t),
&sess->tp_mem_table.phys,
&len,
@@ -560,9 +548,8 @@
if (result) {
pr_err("%s: msm_audio_ion_alloc error, rc = %d\n",
__func__, result);
- msm_audio_ion_free(prtd->ion_client, sess->ion_handle);
- prtd->ion_client = NULL;
- sess->ion_handle = NULL;
+ msm_audio_ion_free(sess->dma_buf);
+ sess->dma_buf = NULL;
sess->sess_paddr = 0;
sess->sess_kvaddr = 0;
ret = -ENOMEM;
@@ -1088,8 +1075,8 @@
}
static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf,
- snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf,
+ unsigned long fbytes)
{
int ret = 0;
struct hpcm_buf_node *buf_node = NULL;
@@ -1098,8 +1085,6 @@
struct dai_data *dai_data = hpcm_get_dai_data(substream->pcm->id, prtd);
unsigned long dsp_flags;
- int count = frames_to_bytes(runtime, frames);
-
if (dai_data == NULL) {
pr_err("%s, dai_data is null\n", __func__);
@@ -1112,7 +1097,7 @@
dai_data->state == HPCM_STOPPED),
1 * HZ);
if (ret > 0) {
- if (count <= HPCM_MAX_VOC_PKT_SIZE) {
+ if (fbytes <= HPCM_MAX_VOC_PKT_SIZE) {
spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
buf_node =
list_first_entry(&dai_data->free_queue,
@@ -1120,14 +1105,14 @@
list_del(&buf_node->list);
spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
ret = copy_from_user(&buf_node->frame.voc_pkt, buf,
- count);
- buf_node->frame.len = count;
+ fbytes);
+ buf_node->frame.len = fbytes;
spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
list_add_tail(&buf_node->list, &dai_data->filled_queue);
spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
} else {
- pr_err("%s: Write cnt %d is > HPCM_MAX_VOC_PKT_SIZE\n",
- __func__, count);
+ pr_err("%s: Write cnt %lu is > HPCM_MAX_VOC_PKT_SIZE\n",
+ __func__, fbytes);
ret = -ENOMEM;
}
} else if (ret == 0) {
@@ -1142,11 +1127,10 @@
}
static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t hwoff,
- void __user *buf, snd_pcm_uframes_t frames)
+ int channel, unsigned long hwoff,
+ void __user *buf, unsigned long fbytes)
{
int ret = 0;
- int count = 0;
struct hpcm_buf_node *buf_node = NULL;
struct snd_pcm_runtime *runtime = substream->runtime;
struct hpcm_drv *prtd = runtime->private_data;
@@ -1160,15 +1144,13 @@
goto done;
}
- count = frames_to_bytes(runtime, frames);
-
ret = wait_event_interruptible_timeout(dai_data->queue_wait,
(!list_empty(&dai_data->filled_queue) ||
dai_data->state == HPCM_STOPPED),
1 * HZ);
if (ret > 0) {
- if (count <= HPCM_MAX_VOC_PKT_SIZE) {
+ if (fbytes <= HPCM_MAX_VOC_PKT_SIZE) {
spin_lock_irqsave(&dai_data->dsp_lock, dsp_flags);
buf_node = list_first_entry(&dai_data->filled_queue,
struct hpcm_buf_node, list);
@@ -1186,8 +1168,8 @@
spin_unlock_irqrestore(&dai_data->dsp_lock, dsp_flags);
} else {
- pr_err("%s: Read count %d > HPCM_MAX_VOC_PKT_SIZE\n",
- __func__, count);
+ pr_err("%s: Read count %lu > HPCM_MAX_VOC_PKT_SIZE\n",
+ __func__, fbytes);
ret = -ENOMEM;
}
@@ -1204,17 +1186,17 @@
}
static int msm_pcm_copy(struct snd_pcm_substream *substream, int channel,
- snd_pcm_uframes_t hwoff, void __user *buf,
- snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf,
+ unsigned long fbytes)
{
int ret = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
ret = msm_pcm_playback_copy(substream, channel,
- hwoff, buf, frames);
+ hwoff, buf, fbytes);
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
ret = msm_pcm_capture_copy(substream, channel,
- hwoff, buf, frames);
+ hwoff, buf, fbytes);
return ret;
}
@@ -1446,7 +1428,7 @@
.prepare = msm_pcm_prepare,
.trigger = msm_pcm_trigger,
.pointer = msm_pcm_pointer,
- .copy = msm_pcm_copy,
+ .copy_user = msm_pcm_copy,
.close = msm_pcm_close,
};
diff --git a/asoc/msm-pcm-q6-noirq.c b/asoc/msm-pcm-q6-noirq.c
index dbc6d33..249f8a5 100644
--- a/asoc/msm-pcm-q6-noirq.c
+++ b/asoc/msm-pcm-q6-noirq.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -20,6 +20,7 @@
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/dma-mapping.h>
+#include <linux/dma-buf.h>
#include <sound/core.h>
#include <sound/soc.h>
@@ -451,7 +452,13 @@
apd = prtd->audio_client->port;
ab = &(apd[dir].buf[0]);
- mmap_fd->fd = ion_share_dma_buf_fd(ab->client, ab->handle);
+ /*
+ * Passing O_CLOEXEC as flag passed to fd, to be in sync with
+ * previous implimentation.
+ * This was the flag used by previous internal wrapper API, which
+ * used to call dma_buf_fd internally.
+ */
+ mmap_fd->fd = dma_buf_fd(ab->dma_buf, O_CLOEXEC);
if (mmap_fd->fd >= 0) {
mmap_fd->dir = dir;
mmap_fd->actual_size = ab->actual_size;
@@ -530,7 +537,7 @@
}
static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
return -EINVAL;
}
@@ -1182,7 +1189,7 @@
static const struct snd_pcm_ops msm_pcm_ops = {
.open = msm_pcm_open,
.prepare = msm_pcm_prepare,
- .copy = msm_pcm_copy,
+ .copy_user = msm_pcm_copy,
.hw_params = msm_pcm_hw_params,
.ioctl = msm_pcm_ioctl,
#ifdef CONFIG_COMPAT
diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c
index bb6ce73..bbcbab3 100644
--- a/asoc/msm-pcm-q6-v2.c
+++ b/asoc/msm-pcm-q6-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -714,10 +714,9 @@
}
static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
int ret = 0;
- int fbytes = 0;
int xfer = 0;
char *bufptr = NULL;
void *data = NULL;
@@ -728,7 +727,6 @@
struct snd_pcm_runtime *runtime = substream->runtime;
struct msm_audio *prtd = runtime->private_data;
- fbytes = frames_to_bytes(runtime, frames);
pr_debug("%s: prtd->out_count = %d\n",
__func__, atomic_read(&prtd->out_count));
@@ -775,8 +773,8 @@
bufptr = data;
if (bufptr) {
- pr_debug("%s:fbytes =%d: xfer=%d size=%d\n",
- __func__, fbytes, xfer, size);
+ pr_debug("%s:fbytes =%lu: xfer=%d size=%d\n",
+ __func__, fbytes, xfer, size);
if (copy_from_user(bufptr, buf, xfer)) {
ret = -EFAULT;
pr_err("%s: copy_from_user failed\n",
@@ -786,8 +784,8 @@
}
buf += xfer;
fbytes -= xfer;
- pr_debug("%s:fbytes = %d: xfer=%d\n", __func__, fbytes,
- xfer);
+ pr_debug("%s:fbytes = %lu: xfer=%d\n", __func__,
+ fbytes, xfer);
if (atomic_read(&prtd->start)) {
pr_debug("%s:writing %d bytes of buffer to dsp\n",
__func__, xfer);
@@ -870,11 +868,10 @@
}
static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t hwoff, void __user *buf,
- snd_pcm_uframes_t frames)
+ int channel, unsigned long hwoff, void __user *buf,
+ unsigned long fbytes)
{
int ret = 0;
- int fbytes = 0;
int xfer;
char *bufptr;
void *data = NULL;
@@ -886,7 +883,6 @@
pr_debug("%s\n", __func__);
- fbytes = frames_to_bytes(runtime, frames);
pr_debug("appl_ptr %d\n", (int)runtime->control->appl_ptr);
pr_debug("hw_ptr %d\n", (int)runtime->status->hw_ptr);
@@ -915,7 +911,7 @@
data = q6asm_is_cpu_buf_avail(OUT, prtd->audio_client, &size, &idx);
bufptr = data;
pr_debug("Size = %d\n", size);
- pr_debug("fbytes = %d\n", fbytes);
+ pr_debug("fbytes = %lu\n", fbytes);
pr_debug("idx = %d\n", idx);
if (bufptr) {
xfer = fbytes;
@@ -932,7 +928,7 @@
fbytes -= xfer;
size -= xfer;
prtd->in_frame_info[idx].offset += xfer;
- pr_debug("%s:fbytes = %d: size=%d: xfer=%d\n",
+ pr_debug("%s:fbytes = %lu: size=%d: xfer=%d\n",
__func__, fbytes, size, xfer);
pr_debug(" Sending next buffer to dsp\n");
memset(&prtd->in_frame_info[idx], 0,
@@ -977,14 +973,14 @@
}
static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
int ret = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames);
+ ret = msm_pcm_playback_copy(substream, a, hwoff, buf, fbytes);
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames);
+ ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes);
return ret;
}
@@ -1086,7 +1082,7 @@
static const struct snd_pcm_ops msm_pcm_ops = {
.open = msm_pcm_open,
- .copy = msm_pcm_copy,
+ .copy_user = msm_pcm_copy,
.hw_params = msm_pcm_hw_params,
.close = msm_pcm_close,
.ioctl = snd_pcm_lib_ioctl,
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 1ff7c41..0096688 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,7 @@
#include <dsp/q6afe-v2.h>
#include <dsp/q6lsm.h>
#include <dsp/q6core.h>
+#include <dsp/q6common.h>
#include <dsp/audio_cal_utils.h>
#include "msm-pcm-routing-v2.h"
@@ -645,6 +646,12 @@
/* MULTIMEDIA20 */
{{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA28 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
+ /* MULTIMEDIA29 */
+ {{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
+ {0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
/* VOIP */
{{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} },
{0, INVALID_SESSION, LEGACY_PCM_MODE, {NULL, NULL} } },
@@ -896,6 +903,9 @@
cal_block = list_entry(ptr,
struct cal_block_data, list);
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
+
if (((struct audio_cal_info_adm_top *)cal_block
->cal_info)->path == path) {
return cal_block;
@@ -922,6 +932,9 @@
cal_block = list_entry(ptr,
struct cal_block_data, list);
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
+
cal_info = (struct audio_cal_info_adm_top *)
cal_block->cal_info;
if ((cal_info->path == path) &&
@@ -932,9 +945,14 @@
}
pr_debug("%s: Can't find topology for path %d, app %d, acdb_id %d defaulting to search by path\n",
__func__, path, app_type, acdb_id);
- return msm_routing_find_topology_by_path(cal_index, path);
+ return msm_routing_find_topology_by_path(path, cal_index);
}
+/*
+ * Retrieving cal_block will mark cal_block as stale.
+ * Hence it cannot be reused or resent unless the flag
+ * is reset.
+ */
static int msm_routing_get_adm_topology(int fedai_id, int session_type,
int be_id)
{
@@ -956,20 +974,24 @@
cal_block = msm_routing_find_topology(session_type, app_type,
acdb_dev_id,
ADM_TOPOLOGY_CAL_TYPE_IDX);
- if (cal_block != NULL)
+ if (cal_block != NULL) {
topology = ((struct audio_cal_info_adm_top *)
cal_block->cal_info)->topology;
- mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock);
+ cal_utils_mark_cal_used(cal_block);
+ mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock);
+ } else {
+ mutex_unlock(&cal_data[ADM_TOPOLOGY_CAL_TYPE_IDX]->lock);
- if (cal_block == NULL) {
pr_debug("%s: Check for LSM topology\n", __func__);
mutex_lock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock);
cal_block = msm_routing_find_topology(session_type, app_type,
acdb_dev_id,
ADM_LSM_TOPOLOGY_CAL_TYPE_IDX);
- if (cal_block != NULL)
+ if (cal_block != NULL) {
topology = ((struct audio_cal_info_adm_top *)
cal_block->cal_info)->topology;
+ cal_utils_mark_cal_used(cal_block);
+ }
mutex_unlock(&cal_data[ADM_LSM_TOPOLOGY_CAL_TYPE_IDX]->lock);
}
@@ -1427,7 +1449,7 @@
if ((copp_idx < 0) ||
(copp_idx >= MAX_COPPS_PER_PORT)) {
pr_err("%s: adm open failed copp_idx:%d\n",
- __func__, copp_idx);
+ __func__, copp_idx);
mutex_unlock(&routing_lock);
return -EINVAL;
}
@@ -2572,7 +2594,6 @@
pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
mad_type);
- adm_set_lsm_port_id(port_id);
return afe_port_set_mad_type(port_id, mad_type);
}
@@ -3728,6 +3749,16 @@
msm_route_ec_ref_rx_enum[0],
msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put);
+static const struct snd_kcontrol_new ext_ec_ref_mux_ul28 =
+ SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL28 MUX Mux",
+ msm_route_ec_ref_rx_enum[0],
+ msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put);
+
+static const struct snd_kcontrol_new ext_ec_ref_mux_ul29 =
+ SOC_DAPM_ENUM_EXT("AUDIO_REF_EC_UL29 MUX Mux",
+ msm_route_ec_ref_rx_enum[0],
+ msm_routing_ec_ref_rx_get, msm_routing_ec_ref_rx_put);
+
static int msm_routing_ext_ec_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -3871,6 +3902,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_PRI_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
@@ -3931,6 +3968,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SEC_I2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = {
@@ -3991,7 +4034,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SPDIF_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
-
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SPDIF_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SPDIF_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = {
@@ -4103,6 +4151,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_5_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
@@ -4163,6 +4217,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SLIMBUS_0_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new mi2s_rx_mixer_controls[] = {
@@ -4223,6 +4283,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_MI2S_RX,
+ 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_mixer_controls[] = {
@@ -4283,6 +4349,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ 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,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new quinary_mi2s_rx_mixer_controls[] = {
@@ -4343,6 +4415,13 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_QUINARY_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_QUINARY_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_QUINARY_MI2S_RX,
+ 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_mixer_controls[] = {
@@ -4397,6 +4476,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
+ 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,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new secondary_mi2s_rx2_mixer_controls[] = {
@@ -4463,6 +4548,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ 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,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
@@ -4523,6 +4614,13 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_PRI_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+
};
static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = {
@@ -4685,6 +4783,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_HDMI_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_HDMI_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new display_port_mixer_controls[] = {
@@ -4995,6 +5099,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_BT_SCO_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_INT_BT_SCO_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new int_bt_a2dp_rx_mixer_controls[] = {
@@ -5106,6 +5216,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_INT_FM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_INT_FM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new afe_pcm_rx_mixer_controls[] = {
@@ -5166,6 +5282,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AFE_PCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_AFE_PCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new auxpcm_rx_mixer_controls[] = {
@@ -5226,6 +5348,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new sec_auxpcm_rx_mixer_controls[] = {
@@ -5286,6 +5414,12 @@
SOC_SINGLE_EXT("MultiMedia19", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia28", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia29", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new tert_auxpcm_rx_mixer_controls[] = {
@@ -7831,6 +7965,9 @@
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -7855,6 +7992,9 @@
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -7882,6 +8022,9 @@
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
@@ -7977,6 +8120,60 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new mmul28_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new mmul29_mixer_controls[] = {
+ SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INT3_MI2S_TX", MSM_BACKEND_DAI_INT3_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_PRI_I2S_RX,
MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer,
@@ -8950,6 +9147,9 @@
SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_AUXPCM_RX,
MSM_BACKEND_DAI_QUAT_TDM_TX_0, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_MI2S_TX", MSM_BACKEND_DAI_AUXPCM_RX,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
};
static const struct snd_kcontrol_new sec_auxpcm_rx_port_mixer_controls[] = {
@@ -8962,6 +9162,9 @@
SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ MSM_BACKEND_DAI_PRI_MI2S_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
};
static const struct snd_kcontrol_new tert_auxpcm_rx_port_mixer_controls[] = {
@@ -9152,6 +9355,9 @@
SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_PRI_MI2S_RX,
MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("SEC_AUX_PCM_UL_TX", MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_BACKEND_DAI_SEC_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
};
static const struct snd_kcontrol_new usb_rx_port_mixer_controls[] = {
@@ -10923,6 +11129,9 @@
SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
MSM_BACKEND_DAI_SLIMBUS_8_TX, 1, 0, msm_routing_get_port_mixer,
msm_routing_put_port_mixer),
+ SOC_SINGLE_EXT("AUX_PCM_UL_TX", MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ MSM_BACKEND_DAI_AUXPCM_TX, 1, 0, msm_routing_get_port_mixer,
+ msm_routing_put_port_mixer),
};
static const struct snd_kcontrol_new lsm1_mixer_controls[] = {
@@ -11505,10 +11714,11 @@
int ret = 0;
unsigned long copp;
struct msm_pcm_routing_bdai_data *bedai;
- char *param_data = NULL;
- uint32_t *update_param_data = NULL;
- uint32_t param_size = sizeof(uint32_t) +
- sizeof(struct adm_param_data_v5);
+ u8 *packed_params = NULL;
+ struct param_hdr_v3 param_hdr;
+ u32 packed_param_size = (sizeof(struct param_hdr_v3) +
+ sizeof(uint32_t));
+
int dir = ucontrol->value.integer.value[0] ? SESSION_TYPE_TX :
SESSION_TYPE_RX;
int app_type = ucontrol->value.integer.value[1];
@@ -11523,15 +11733,17 @@
__func__, app_type, module_id,
instance_id, param_id, param_value);
- param_data = kzalloc(param_size, GFP_KERNEL);
- if (!param_data)
+ packed_params = kzalloc(packed_param_size, GFP_KERNEL);
+ if (!packed_params)
return -ENOMEM;
- update_param_data = (uint32_t *)param_data;
- *update_param_data++ = module_id;
- *update_param_data++ = param_id;
- *update_param_data++ = sizeof(uint32_t);
- *update_param_data++ = param_value;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = module_id;
+ param_hdr.instance_id = instance_id;
+ param_hdr.param_id = param_id;
+ param_hdr.param_size = sizeof(uint32_t);
+
+ packed_param_size = 0;
mutex_lock(&routing_lock);
for (be_id = 0; be_id < MSM_BACKEND_DAI_MAX; be_id++) {
@@ -11559,10 +11771,20 @@
if (!test_bit(copp_idx, &copp))
continue;
- ret = adm_send_params_v5(bedai->port_id,
- copp_idx,
- param_data,
- param_size);
+ ret = q6common_pack_pp_params(packed_params,
+ ¶m_hdr,
+ (u8 *) ¶m_value,
+ &packed_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack params, error %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = adm_set_pp_params(bedai->port_id,
+ copp_idx, NULL,
+ packed_params,
+ packed_param_size);
if (ret) {
pr_err("%s: Setting param failed with err=%d\n",
__func__, ret);
@@ -11574,7 +11796,7 @@
}
done:
mutex_unlock(&routing_lock);
- kfree(param_data);
+ kfree(packed_params);
return ret;
}
@@ -11650,22 +11872,24 @@
int be_idx = 0;
char *param_value;
int *update_param_value;
- uint32_t param_length = sizeof(uint32_t);
- uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t);
+ uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t);
+ struct param_hdr_v3 param_hdr;
- param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL);
+ param_value = kzalloc(param_size, GFP_KERNEL);
if (!param_value)
return -ENOMEM;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++)
if (msm_bedais[be_idx].port_id == SLIMBUS_0_TX)
break;
if ((be_idx < MSM_BACKEND_DAI_MAX) && msm_bedais[be_idx].active) {
- rc = adm_get_params(SLIMBUS_0_TX, 0,
- RMS_MODULEID_APPI_PASSTHRU,
- RMS_PARAM_FIRST_SAMPLE,
- param_length + param_payload_len,
- param_value);
+ param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE;
+ param_hdr.param_size = param_size;
+ rc = adm_get_pp_params(SLIMBUS_0_TX, 0, ADM_CLIENT_ID_DEFAULT,
+ NULL, ¶m_hdr, (u8 *) param_value);
if (rc) {
pr_err("%s: get parameters failed:%d\n", __func__, rc);
kfree(param_value);
@@ -11768,24 +11992,7 @@
static int msm_voice_source_tracking_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- int ret = 0;
- struct source_tracking_param sourceTrackingData;
-
- memset(&sourceTrackingData, 0, sizeof(struct source_tracking_param));
-
- ret = voc_get_source_tracking(&sourceTrackingData);
- if (ret) {
- pr_err("%s: Error getting Source Tracking Params, err=%d\n",
- __func__, ret);
-
- ret = -EINVAL;
- goto done;
- }
- memcpy(ucontrol->value.bytes.data, (void *)&sourceTrackingData,
- sizeof(struct source_tracking_param));
-
-done:
- return ret;
+ return -EINVAL;
}
static int msm_audio_get_copp_idx_from_port_id(int port_id, int session_type,
@@ -12400,6 +12607,10 @@
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("AUXPCM_UL_HL", "AUXPCM_HOSTLESS Capture",
0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("SEC_AUXPCM_DL_HL", "SEC_AUXPCM_HOSTLESS Playback",
+ 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SEC_AUXPCM_UL_HL", "SEC_AUXPCM_HOSTLESS Capture",
+ 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("MI2S_UL_HL", "MI2S_TX_HOSTLESS Capture",
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("INT3_MI2S_UL_HL",
@@ -13172,6 +13383,10 @@
mmul19_mixer_controls, ARRAY_SIZE(mmul19_mixer_controls)),
SND_SOC_DAPM_MIXER("MultiMedia20 Mixer", SND_SOC_NOPM, 0, 0,
mmul20_mixer_controls, ARRAY_SIZE(mmul20_mixer_controls)),
+ SND_SOC_DAPM_MIXER("MultiMedia28 Mixer", SND_SOC_NOPM, 0, 0,
+ mmul28_mixer_controls, ARRAY_SIZE(mmul28_mixer_controls)),
+ SND_SOC_DAPM_MIXER("MultiMedia29 Mixer", SND_SOC_NOPM, 0, 0,
+ mmul29_mixer_controls, ARRAY_SIZE(mmul29_mixer_controls)),
SND_SOC_DAPM_MIXER("AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
auxpcm_rx_mixer_controls, ARRAY_SIZE(auxpcm_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SEC_AUX_PCM_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -13754,14 +13969,27 @@
{"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia18 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia19 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia28 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia29 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"MultiMedia17 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia18 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"MultiMedia19 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"MultiMedia28 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
@@ -14452,6 +14680,11 @@
{"MultiMedia5 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia10 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia16 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia17 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia18 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia19 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
@@ -14759,6 +14992,8 @@
{"MultiMedia17 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia18 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia19 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"MultiMedia28 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
+ {"MultiMedia29 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia5 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia8 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"MultiMedia16 Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
@@ -14768,6 +15003,8 @@
{"MultiMedia17 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia18 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia19 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"MultiMedia28 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
+ {"MultiMedia29 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia5 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia6 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"MultiMedia8 Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
@@ -14779,6 +15016,8 @@
{"MultiMedia17 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia18 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia19 Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"MultiMedia28 Mixer", "AFE_PCM_TX", "PCM_TX"},
+ {"MultiMedia29 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia5 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia8 Mixer", "AFE_PCM_TX", "PCM_TX"},
{"MultiMedia16 Mixer", "AFE_PCM_TX", "PCM_TX"},
@@ -14797,6 +15036,8 @@
{"MM_UL18", NULL, "MultiMedia18 Mixer"},
{"MM_UL19", NULL, "MultiMedia19 Mixer"},
{"MM_UL20", NULL, "MultiMedia20 Mixer"},
+ {"MM_UL28", NULL, "MultiMedia28 Mixer"},
+ {"MM_UL29", NULL, "MultiMedia29 Mixer"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"AUX_PCM_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -15129,6 +15370,15 @@
{"AUDIO_REF_EC_UL19 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"AUDIO_REF_EC_UL19 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+ {"AUDIO_REF_EC_UL28 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"AUDIO_REF_EC_UL28 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"AUDIO_REF_EC_UL28 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"AUDIO_REF_EC_UL28 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+
+ {"AUDIO_REF_EC_UL29 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+ {"AUDIO_REF_EC_UL29 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"AUDIO_REF_EC_UL29 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
+ {"AUDIO_REF_EC_UL29 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"LSM1_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"},
{"LSM2_UL_HL", NULL, "AUDIO_REF_EC_UL1 MUX"},
@@ -15152,6 +15402,8 @@
{"MM_UL17", NULL, "AUDIO_REF_EC_UL17 MUX"},
{"MM_UL18", NULL, "AUDIO_REF_EC_UL18 MUX"},
{"MM_UL19", NULL, "AUDIO_REF_EC_UL19 MUX"},
+ {"MM_UL28", NULL, "AUDIO_REF_EC_UL28 MUX"},
+ {"MM_UL29", NULL, "AUDIO_REF_EC_UL29 MUX"},
{"VoiceMMode1_Tx Mixer", "PRI_TX_MMode1", "PRI_I2S_TX"},
{"VoiceMMode1_Tx Mixer", "PRI_MI2S_TX_MMode1", "PRI_MI2S_TX"},
@@ -15332,7 +15584,9 @@
{"HFP_SLIM7_UL_HL", "Switch", "SLIMBUS_7_TX"},
{"AUX_PCM_RX", NULL, "AUXPCM_DL_HL"},
{"AUX_PCM_RX", NULL, "INTHFP_DL_HL"},
+ {"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_DL_HL"},
{"AUXPCM_UL_HL", NULL, "AUX_PCM_TX"},
+ {"SEC_AUXPCM_UL_HL", NULL, "SEC_AUX_PCM_TX"},
{"MI2S_RX", NULL, "MI2S_DL_HL"},
{"MI2S_UL_HL", NULL, "MI2S_TX"},
{"PCM_RX_DL_HL", "Switch", "SLIM0_DL_HL"},
@@ -15903,11 +16157,13 @@
{"AUX_PCM_RX Port Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"AUX_PCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
{"AUX_PCM_RX Port Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
+ {"AUX_PCM_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"AUX_PCM_RX", NULL, "AUX_PCM_RX Port Mixer"},
{"SEC_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"SEC_AUXPCM_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
{"SEC_AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"SEC_AUXPCM_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"SEC_AUX_PCM_RX", NULL, "SEC_AUXPCM_RX Port Mixer"},
{"TERT_AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
@@ -16048,6 +16304,7 @@
{"PRI_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"PRI_MI2S_RX Port Mixer", "INTERNAL_BT_SCO_TX", "INT_BT_SCO_TX"},
{"PRI_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"},
+ {"PRI_MI2S_RX Port Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Port Mixer"},
{"SEC_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
@@ -16058,6 +16315,7 @@
{"SEC_MI2S_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"SEC_MI2S_RX Port Mixer", "INTERNAL_FM_TX", "INT_FM_TX"},
{"SEC_MI2S_RX Port Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"},
+ {"SEC_MI2S_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"SEC_MI2S_RX", NULL, "SEC_MI2S_RX Port Mixer"},
{"TERT_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
@@ -16825,6 +17083,46 @@
msm_routing_stereo_channel_reverse_control_put),
};
+static int msm_routing_instance_id_support_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ return 0;
+}
+
+static int msm_routing_instance_id_support_put(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ bool supported = ucontrol->value.integer.value[0] ? true : false;
+
+ q6common_update_instance_id_support(supported);
+ return 0;
+}
+
+static int msm_routing_instance_id_support_get(
+ struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
+{
+ bool supported = false;
+
+ supported = q6common_is_instance_id_supported();
+ ucontrol->value.integer.value[0] = supported ? 1 : 0;
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new
+ msm_routing_feature_support_mixer_controls[] = {
+ {
+ .access = SNDRV_CTL_ELEM_ACCESS_READ |
+ SNDRV_CTL_ELEM_ACCESS_WRITE,
+ .info = msm_routing_instance_id_support_info,
+ .name = "Instance ID Support",
+ .put = msm_routing_instance_id_support_put,
+ .get = msm_routing_instance_id_support_get,
+ },
+};
+
static const struct snd_pcm_ops msm_routing_pcm_ops = {
.hw_params = msm_pcm_routing_hw_params,
.close = msm_pcm_routing_close,
@@ -16896,6 +17194,10 @@
ARRAY_SIZE(aptx_dec_license_controls));
snd_soc_add_platform_controls(platform, stereo_channel_reverse_control,
ARRAY_SIZE(stereo_channel_reverse_control));
+ snd_soc_add_platform_controls(
+ platform, msm_routing_feature_support_mixer_controls,
+ ARRAY_SIZE(msm_routing_feature_support_mixer_controls));
+
return 0;
}
diff --git a/asoc/msm-pcm-routing-v2.h b/asoc/msm-pcm-routing-v2.h
index a1977b4..19c710c 100644
--- a/asoc/msm-pcm-routing-v2.h
+++ b/asoc/msm-pcm-routing-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -211,6 +211,8 @@
MSM_FRONTEND_DAI_MULTIMEDIA18,
MSM_FRONTEND_DAI_MULTIMEDIA19,
MSM_FRONTEND_DAI_MULTIMEDIA20,
+ MSM_FRONTEND_DAI_MULTIMEDIA28,
+ MSM_FRONTEND_DAI_MULTIMEDIA29,
MSM_FRONTEND_DAI_VOIP,
MSM_FRONTEND_DAI_AFE_RX,
MSM_FRONTEND_DAI_AFE_TX,
@@ -232,8 +234,8 @@
MSM_FRONTEND_DAI_MAX,
};
-#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA20 + 1)
-#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA20
+#define MSM_FRONTEND_DAI_MM_SIZE (MSM_FRONTEND_DAI_MULTIMEDIA29 + 1)
+#define MSM_FRONTEND_DAI_MM_MAX_ID MSM_FRONTEND_DAI_MULTIMEDIA29
enum {
MSM_BACKEND_DAI_PRI_I2S_RX = 0,
diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c
index b82c587..0a4aa05 100644
--- a/asoc/msm-pcm-voice-v2.c
+++ b/asoc/msm-pcm-voice-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -556,12 +556,15 @@
{
int st_enable = ucontrol->value.integer.value[0];
uint32_t session_id = ucontrol->value.integer.value[1];
+ struct module_instance_info mod_inst_info;
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
pr_debug("%s: st enable=%d session_id=%#x\n", __func__, st_enable,
session_id);
- voc_set_pp_enable(session_id,
- MODULE_ID_VOICE_MODULE_ST, st_enable);
+ mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+ voc_set_pp_enable(session_id, mod_inst_info, st_enable);
return 0;
}
diff --git a/asoc/msm-pcm-voip-v2.c b/asoc/msm-pcm-voip-v2.c
index 02cee29..b8d7390 100644
--- a/asoc/msm-pcm-voip-v2.c
+++ b/asoc/msm-pcm-voip-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -778,7 +778,7 @@
}
static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
int ret = 0;
struct voip_buf_node *buf_node = NULL;
@@ -786,9 +786,7 @@
struct voip_drv_info *prtd = runtime->private_data;
unsigned long dsp_flags;
- int count = frames_to_bytes(runtime, frames);
-
- pr_debug("%s: count = %d, frames=%d\n", __func__, count, (int)frames);
+ pr_debug("%s: fbytes=%lu\n", __func__, fbytes);
if (prtd->voip_reset) {
pr_debug("%s: RESET event happened during VoIP\n", __func__);
@@ -805,7 +803,7 @@
}
if (ret > 0) {
- if (count <= VOIP_MAX_VOC_PKT_SIZE) {
+ if (fbytes <= VOIP_MAX_VOC_PKT_SIZE) {
spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
buf_node =
list_first_entry(&prtd->free_in_queue,
@@ -814,23 +812,23 @@
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
if (prtd->mode == MODE_PCM) {
ret = copy_from_user(&buf_node->frame.voc_pkt,
- buf, count);
+ buf, fbytes);
if (ret) {
pr_err("%s: copy from user failed %d\n",
__func__, ret);
return -EFAULT;
}
- buf_node->frame.pktlen = count;
+ buf_node->frame.pktlen = fbytes;
} else {
ret = copy_from_user(&buf_node->frame,
- buf, count);
+ buf, fbytes);
if (ret) {
pr_err("%s: copy from user failed %d\n",
__func__, ret);
return -EFAULT;
}
- if (buf_node->frame.pktlen >= count)
- buf_node->frame.pktlen = count -
+ if (buf_node->frame.pktlen >= fbytes)
+ buf_node->frame.pktlen = fbytes -
(sizeof(buf_node->frame.frm_hdr) +
sizeof(buf_node->frame.pktlen));
}
@@ -838,8 +836,8 @@
list_add_tail(&buf_node->list, &prtd->in_queue);
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);
} else {
- pr_err("%s: Write cnt %d is > VOIP_MAX_VOC_PKT_SIZE\n",
- __func__, count);
+ pr_err("%s: Write cnt %lu is > VOIP_MAX_VOC_PKT_SIZE\n",
+ __func__, fbytes);
ret = -ENOMEM;
}
@@ -853,20 +851,17 @@
return ret;
}
static int msm_pcm_capture_copy(struct snd_pcm_substream *substream,
- int channel, snd_pcm_uframes_t hwoff, void __user *buf,
- snd_pcm_uframes_t frames)
+ int channel, unsigned long hwoff, void __user *buf,
+ unsigned long fbytes)
{
int ret = 0;
- int count = 0;
struct voip_buf_node *buf_node = NULL;
struct snd_pcm_runtime *runtime = substream->runtime;
struct voip_drv_info *prtd = runtime->private_data;
unsigned long dsp_flags;
int size;
- count = frames_to_bytes(runtime, frames);
-
- pr_debug("%s: count = %d\n", __func__, count);
+ pr_debug("%s: fbytes = %lu\n", __func__, fbytes);
if (prtd->voip_reset) {
pr_debug("%s: RESET event happened during VoIP\n", __func__);
@@ -885,7 +880,7 @@
if (ret > 0) {
- if (count <= VOIP_MAX_VOC_PKT_SIZE) {
+ if (fbytes <= VOIP_MAX_VOC_PKT_SIZE) {
spin_lock_irqsave(&prtd->dsp_ul_lock, dsp_flags);
buf_node = list_first_entry(&prtd->out_queue,
struct voip_buf_node, list);
@@ -914,8 +909,8 @@
&prtd->free_out_queue);
spin_unlock_irqrestore(&prtd->dsp_ul_lock, dsp_flags);
} else {
- pr_err("%s: Read count %d > VOIP_MAX_VOC_PKT_SIZE\n",
- __func__, count);
+ pr_err("%s: Read fbytes %lu > VOIP_MAX_VOC_PKT_SIZE\n",
+ __func__, fbytes);
ret = -ENOMEM;
}
@@ -930,14 +925,14 @@
return ret;
}
static int msm_pcm_copy(struct snd_pcm_substream *substream, int a,
- snd_pcm_uframes_t hwoff, void __user *buf, snd_pcm_uframes_t frames)
+ unsigned long hwoff, void __user *buf, unsigned long fbytes)
{
int ret = 0;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
- ret = msm_pcm_playback_copy(substream, a, hwoff, buf, frames);
+ ret = msm_pcm_playback_copy(substream, a, hwoff, buf, fbytes);
else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- ret = msm_pcm_capture_copy(substream, a, hwoff, buf, frames);
+ ret = msm_pcm_capture_copy(substream, a, hwoff, buf, fbytes);
return ret;
}
@@ -1598,7 +1593,7 @@
static const struct snd_pcm_ops msm_pcm_ops = {
.open = msm_pcm_open,
- .copy = msm_pcm_copy,
+ .copy_user = msm_pcm_copy,
.hw_params = msm_pcm_hw_params,
.close = msm_pcm_close,
.prepare = msm_pcm_prepare,
diff --git a/asoc/msm-qti-pp-config.c b/asoc/msm-qti-pp-config.c
index 00a29d7..f210745 100644
--- a/asoc/msm-qti-pp-config.c
+++ b/asoc/msm-qti-pp-config.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,6 +21,7 @@
#include <dsp/q6asm-v2.h>
#include <dsp/q6afe-v2.h>
#include <dsp/q6audio-v2.h>
+#include <dsp/q6common.h>
#include "msm-qti-pp-config.h"
#include "msm-pcm-routing-v2.h"
@@ -263,6 +264,11 @@
update_params_value32 = (int *)params_value;
if (avail_length < 2 * sizeof(uint32_t))
goto skip_send_cmd;
+
+ /*
+ * This module is internal to ADSP and cannot be configured with
+ * an instance id
+ */
*update_params_value32++ = MTMX_MODULE_ID_DEFAULT_CHMIXER;
*update_params_value32++ = DEFAULT_CHMIXER_PARAM_ID_COEFF;
avail_length = avail_length - (2 * sizeof(uint32_t));
@@ -329,14 +335,13 @@
int be_idx = 0, copp_idx;
char *param_value;
int *update_param_value;
- uint32_t param_length = sizeof(uint32_t);
- uint32_t param_payload_len = RMS_PAYLOAD_LEN * sizeof(uint32_t);
+ uint32_t param_size = (RMS_PAYLOAD_LEN + 1) * sizeof(uint32_t);
struct msm_pcm_routing_bdai_data msm_bedai;
+ struct param_hdr_v3 param_hdr;
- param_value = kzalloc(param_length + param_payload_len, GFP_KERNEL);
+ param_value = kzalloc(param_size, GFP_KERNEL);
if (!param_value)
return -ENOMEM;
-
msm_pcm_routing_acquire_lock();
for (be_idx = 0; be_idx < MSM_BACKEND_DAI_MAX; be_idx++) {
msm_pcm_routing_get_bedai_info(be_idx, &msm_bedai);
@@ -356,11 +361,13 @@
rc = -EINVAL;
goto get_rms_value_err;
}
- rc = adm_get_params(SLIMBUS_0_TX, copp_idx,
- RMS_MODULEID_APPI_PASSTHRU,
- RMS_PARAM_FIRST_SAMPLE,
- param_length + param_payload_len,
- param_value);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = RMS_MODULEID_APPI_PASSTHRU;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = RMS_PARAM_FIRST_SAMPLE;
+ param_hdr.param_size = param_size;
+ rc = adm_get_pp_params(SLIMBUS_0_TX, copp_idx, ADM_CLIENT_ID_DEFAULT,
+ NULL, ¶m_hdr, param_value);
if (rc) {
pr_err("%s: get parameters failed rc=%d\n", __func__, rc);
rc = -EINVAL;
@@ -692,64 +699,83 @@
static int msm_qti_pp_asphere_send_params(int port_id, int copp_idx, bool force)
{
- char *params_value = NULL;
- uint32_t *update_params_value = NULL;
- uint32_t param_size = sizeof(uint32_t) +
- sizeof(struct adm_param_data_v5);
- int params_length = 0, param_count = 0, ret = 0;
+ u8 *packed_params = NULL;
+ u32 packed_params_size = 0;
+ u32 param_size = 0;
+ struct param_hdr_v3 param_hdr;
bool set_enable = force ||
(asphere_state.enabled != asphere_state.enabled_prev);
bool set_strength = asphere_state.enabled == 1 && (set_enable ||
(asphere_state.strength != asphere_state.strength_prev));
+ int param_count = 0;
+ int ret = 0;
if (set_enable)
param_count++;
if (set_strength)
param_count++;
- params_length = param_count * param_size;
+
+ if (param_count == 0) {
+ pr_debug("%s: Nothing to send, exiting\n", __func__);
+ return 0;
+ }
pr_debug("%s: port_id %d, copp_id %d, forced %d, param_count %d\n",
- __func__, port_id, copp_idx, force, param_count);
+ __func__, port_id, copp_idx, force, param_count);
pr_debug("%s: enable prev:%u cur:%u, strength prev:%u cur:%u\n",
__func__, asphere_state.enabled_prev, asphere_state.enabled,
asphere_state.strength_prev, asphere_state.strength);
- if (params_length > 0)
- params_value = kzalloc(params_length, GFP_KERNEL);
- if (!params_value) {
- pr_err("%s, params memory alloc failed\n", __func__);
+ packed_params_size =
+ param_count * (sizeof(struct param_hdr_v3) + sizeof(uint32_t));
+ packed_params = kzalloc(packed_params_size, GFP_KERNEL);
+ if (!packed_params)
return -ENOMEM;
- }
- update_params_value = (uint32_t *)params_value;
- params_length = 0;
+
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ packed_params_size = 0;
+ param_hdr.module_id = AUDPROC_MODULE_ID_AUDIOSPHERE;
+ param_hdr.instance_id = INSTANCE_ID_0;
if (set_strength) {
/* add strength command */
- *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE;
- *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH;
- *update_params_value++ = sizeof(uint32_t);
- *update_params_value++ = asphere_state.strength;
- params_length += param_size;
+ param_hdr.param_id = AUDPROC_PARAM_ID_AUDIOSPHERE_STRENGTH;
+ param_hdr.param_size = sizeof(asphere_state.strength);
+ ret = q6common_pack_pp_params(packed_params +
+ packed_params_size,
+ ¶m_hdr,
+ (u8 *) &asphere_state.strength,
+ ¶m_size);
+ if (ret) {
+ pr_err("%s: Failed to pack params for audio sphere"
+ " strength, error %d\n", __func__, ret);
+ goto done;
+ }
+ packed_params_size += param_size;
}
if (set_enable) {
/* add enable command */
- *update_params_value++ = AUDPROC_MODULE_ID_AUDIOSPHERE;
- *update_params_value++ = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE;
- *update_params_value++ = sizeof(uint32_t);
- *update_params_value++ = asphere_state.enabled;
- params_length += param_size;
- }
- pr_debug("%s, param length: %d\n", __func__, params_length);
- if (params_length) {
- ret = adm_send_params_v5(port_id, copp_idx,
- params_value, params_length);
+ param_hdr.param_id = AUDPROC_PARAM_ID_AUDIOSPHERE_ENABLE;
+ param_hdr.param_size = sizeof(asphere_state.enabled);
+ q6common_pack_pp_params(packed_params + packed_params_size,
+ ¶m_hdr,
+ (u8 *) &asphere_state.enabled,
+ ¶m_size);
if (ret) {
- pr_err("%s: setting param failed with err=%d\n",
- __func__, ret);
- kfree(params_value);
- return -EINVAL;
+ pr_err("%s: Failed to pack params for audio sphere"
+ " enable, error %d\n", __func__, ret);
+ goto done;
}
+ packed_params_size += param_size;
}
- kfree(params_value);
+
+ pr_debug("%s: packed data size: %d\n", __func__, packed_params_size);
+ ret = adm_set_pp_params(port_id, copp_idx, NULL, packed_params,
+ packed_params_size);
+ if (ret)
+ pr_err("%s: set param failed with err=%d\n", __func__, ret);
+
+done:
+ kfree(packed_params);
return 0;
}
diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c
index ccfe528..f2376b4 100644
--- a/asoc/sdm660-common.c
+++ b/asoc/sdm660-common.c
@@ -2824,27 +2824,123 @@
return ret;
}
+
+static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
+{
+ int value = 0;
+ bool ret = false;
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct pinctrl_state *en2_pinctrl_active;
+ struct pinctrl_state *en2_pinctrl_sleep;
+
+ if (!pdata->usbc_en2_gpio_p) {
+ if (active) {
+ /* if active and usbc_en2_gpio undefined, get pin */
+ pdata->usbc_en2_gpio_p = devm_pinctrl_get(card->dev);
+ if (IS_ERR_OR_NULL(pdata->usbc_en2_gpio_p)) {
+ dev_err(card->dev,
+ "%s: Can't get EN2 gpio pinctrl:%ld\n",
+ __func__,
+ PTR_ERR(pdata->usbc_en2_gpio_p));
+ pdata->usbc_en2_gpio_p = NULL;
+ return false;
+ }
+ } else {
+ /* if not active and usbc_en2_gpio undefined, return */
+ return false;
+ }
+ }
+
+ pdata->usbc_en2_gpio = of_get_named_gpio(card->dev->of_node,
+ "qcom,usbc-analog-en2-gpio", 0);
+ if (!gpio_is_valid(pdata->usbc_en2_gpio)) {
+ dev_err(card->dev, "%s, property %s not in node %s\n",
+ __func__, "qcom,usbc-analog-en2-gpio",
+ card->dev->of_node->full_name);
+ return false;
+ }
+
+ en2_pinctrl_active = pinctrl_lookup_state(
+ pdata->usbc_en2_gpio_p, "aud_active");
+ if (IS_ERR_OR_NULL(en2_pinctrl_active)) {
+ dev_err(card->dev,
+ "%s: Cannot get aud_active pinctrl state:%ld\n",
+ __func__, PTR_ERR(en2_pinctrl_active));
+ ret = false;
+ goto err_lookup_state;
+ }
+
+ en2_pinctrl_sleep = pinctrl_lookup_state(
+ pdata->usbc_en2_gpio_p, "aud_sleep");
+ if (IS_ERR_OR_NULL(en2_pinctrl_sleep)) {
+ dev_err(card->dev,
+ "%s: Cannot get aud_sleep pinctrl state:%ld\n",
+ __func__, PTR_ERR(en2_pinctrl_sleep));
+ ret = false;
+ goto err_lookup_state;
+ }
+
+ /* if active and usbc_en2_gpio_p defined, swap using usbc_en2_gpio_p */
+ if (active) {
+ dev_dbg(codec->dev, "%s: enter\n", __func__);
+ if (pdata->usbc_en2_gpio_p) {
+ value = gpio_get_value_cansleep(pdata->usbc_en2_gpio);
+ if (value)
+ pinctrl_select_state(pdata->usbc_en2_gpio_p,
+ en2_pinctrl_sleep);
+ else
+ pinctrl_select_state(pdata->usbc_en2_gpio_p,
+ en2_pinctrl_active);
+ } else if (pdata->usbc_en2_gpio >= 0) {
+ value = gpio_get_value_cansleep(pdata->usbc_en2_gpio);
+ gpio_set_value_cansleep(pdata->usbc_en2_gpio, !value);
+ }
+ pr_debug("%s: swap select switch %d to %d\n", __func__,
+ value, !value);
+ ret = true;
+ } else {
+ /* if not active, release usbc_en2_gpio_p pin */
+ pinctrl_select_state(pdata->usbc_en2_gpio_p,
+ en2_pinctrl_sleep);
+ }
+
+err_lookup_state:
+ devm_pinctrl_put(pdata->usbc_en2_gpio_p);
+ pdata->usbc_en2_gpio_p = NULL;
+ return ret;
+}
+
static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
{
struct snd_soc_card *card = codec->component.card;
struct msm_asoc_mach_data *pdata =
snd_soc_card_get_drvdata(card);
int value = 0;
+ bool ret = 0;
- if (pdata->us_euro_gpio_p) {
- value = msm_cdc_pinctrl_get_state(pdata->us_euro_gpio_p);
- if (value)
- msm_cdc_pinctrl_select_sleep_state(
+ if (!mbhc_cfg.enable_usbc_analog) {
+ if (pdata->us_euro_gpio_p) {
+ value = msm_cdc_pinctrl_get_state(
+ pdata->us_euro_gpio_p);
+ if (value)
+ msm_cdc_pinctrl_select_sleep_state(
pdata->us_euro_gpio_p);
- else
- msm_cdc_pinctrl_select_active_state(
+ else
+ msm_cdc_pinctrl_select_active_state(
pdata->us_euro_gpio_p);
- } else if (pdata->us_euro_gpio >= 0) {
- value = gpio_get_value_cansleep(pdata->us_euro_gpio);
- gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
+ } else if (pdata->us_euro_gpio >= 0) {
+ value = gpio_get_value_cansleep(pdata->us_euro_gpio);
+ gpio_set_value_cansleep(pdata->us_euro_gpio, !value);
+ }
+ pr_debug("%s: swap select switch %d to %d\n",
+ __func__, value, !value);
+ ret = true;
+ } else {
+ /* if usbc is defined, swap using usbc_en2 */
+ ret = msm_usbc_swap_gnd_mic(codec, active);
}
- pr_debug("%s: swap select switch %d to %d\n", __func__, value, !value);
- return true;
+ return ret;
}
static int msm_populate_dai_link_component_of_node(
@@ -3256,6 +3352,7 @@
const char *mclk = "qcom,msm-mclk-freq";
int ret = -EINVAL, id;
const struct of_device_id *match;
+ const char *usb_c_dt = "qcom,msm-mbhc-usbc-audio-supported";
pdata = devm_kzalloc(&pdev->dev,
sizeof(struct msm_asoc_mach_data),
@@ -3340,6 +3437,9 @@
mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
}
+ if (of_find_property(pdev->dev.of_node, usb_c_dt, NULL))
+ mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
+
ret = msm_prepare_us_euro(card);
if (ret)
dev_dbg(&pdev->dev, "msm_prepare_us_euro failed (%d)\n",
diff --git a/asoc/sdm660-common.h b/asoc/sdm660-common.h
index 030f521..6c3eefa 100644
--- a/asoc/sdm660-common.h
+++ b/asoc/sdm660-common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -93,9 +93,11 @@
struct msm_asoc_mach_data {
int us_euro_gpio; /* used by gpio driver API */
+ int usbc_en2_gpio; /* used by gpio driver API */
int hph_en1_gpio;
int hph_en0_gpio;
struct device_node *us_euro_gpio_p; /* used by pinctrl API */
+ struct pinctrl *usbc_en2_gpio_p; /* used by pinctrl API */
struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
struct device_node *pdm_gpio_p; /* used by pinctrl API */
diff --git a/asoc/sdm660-ext-dai-links.c b/asoc/sdm660-ext-dai-links.c
index 02d35a9..5f5a60e 100644
--- a/asoc/sdm660-ext-dai-links.c
+++ b/asoc/sdm660-ext-dai-links.c
@@ -2052,8 +2052,13 @@
if (strnstr(card->name, "tasha", strlen(card->name))) {
codec_ver = tasha_codec_ver();
- if (codec_ver == WCD9326)
- card->name = "sdm660-tashalite-snd-card";
+ if (codec_ver == WCD9326) {
+ card->name = "sdm670-tashalite-snd-card";
+ } else if (codec_ver == WCD9XXX) {
+ dev_err(dev, "%s: Invalid codec version %d\n",
+ __func__, codec_ver);
+ return NULL;
+ }
len1 = ARRAY_SIZE(msm_ext_common_fe_dai);
len2 = len1 + ARRAY_SIZE(msm_ext_tasha_fe_dai);
diff --git a/asoc/sdm660-internal.c b/asoc/sdm660-internal.c
index 7e02e21..fc141e3 100644
--- a/asoc/sdm660-internal.c
+++ b/asoc/sdm660-internal.c
@@ -2360,6 +2360,79 @@
},
};
+static struct snd_soc_dai_link msm_int_compress_capture_dai[] = {
+ {/* hw:x,41 */
+ .name = "Compress9",
+ .stream_name = "Compress9",
+ .cpu_dai_name = "MultiMedia17",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA17,
+ },
+ {/* hw:x,42 */
+ .name = "Compress10",
+ .stream_name = "Compress10",
+ .cpu_dai_name = "MultiMedia18",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA18,
+ },
+ {/* hw:x,43 */
+ .name = "Compress11",
+ .stream_name = "Compress11",
+ .cpu_dai_name = "MultiMedia19",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA19,
+ },
+ {/* hw:x,44 */
+ .name = "Compress12",
+ .stream_name = "Compress12",
+ .cpu_dai_name = "MultiMedia28",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA28,
+ },
+ {/* hw:x,45 */
+ .name = "Compress13",
+ .stream_name = "Compress13",
+ .cpu_dai_name = "MultiMedia29",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA29,
+ },
+};
+
static struct snd_soc_dai_link msm_int_be_dai[] = {
/* Backend I2S DAI Links */
{
@@ -3064,6 +3137,7 @@
static struct snd_soc_dai_link msm_int_dai_links[
ARRAY_SIZE(msm_int_dai) +
ARRAY_SIZE(msm_int_wsa_dai) +
+ARRAY_SIZE(msm_int_compress_capture_dai) +
ARRAY_SIZE(msm_int_be_dai) +
ARRAY_SIZE(msm_mi2s_be_dai_links) +
ARRAY_SIZE(msm_auxpcm_be_dai_links)+
@@ -3142,6 +3216,10 @@
sizeof(msm_int_wsa_dai));
len1 += ARRAY_SIZE(msm_int_wsa_dai);
}
+ memcpy(dailink + len1, msm_int_compress_capture_dai,
+ sizeof(msm_int_compress_capture_dai));
+ len1 += ARRAY_SIZE(msm_int_compress_capture_dai);
+
memcpy(dailink + len1, msm_int_be_dai, sizeof(msm_int_be_dai));
len1 += ARRAY_SIZE(msm_int_be_dai);
diff --git a/asoc/sdm855.c b/asoc/sdm855.c
new file mode 100644
index 0000000..79642d4
--- /dev/null
+++ b/asoc/sdm855.c
@@ -0,0 +1,7361 @@
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/input.h>
+#include <linux/of_device.h>
+#include <linux/pm_qos.h>
+#include <linux/soc/qcom/fsa4480-i2c.h>
+#include <sound/core.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/info.h>
+#include <dsp/audio_notifier.h>
+#include <dsp/q6afe-v2.h>
+#include <dsp/q6core.h>
+#include "device_event.h"
+#include "msm-pcm-routing-v2.h"
+#include "codecs/msm-cdc-pinctrl.h"
+#include "codecs/wcd934x/wcd934x.h"
+#include "codecs/wcd934x/wcd934x-mbhc.h"
+#include "codecs/wcd9360/wcd9360.h"
+#include "codecs/wsa881x.h"
+#include "codecs/wcd-mbhc-v2.h"
+
+#define DRV_NAME "sdm855-asoc-snd"
+
+#define __CHIPSET__ "SDM855 "
+#define MSM_DAILINK_NAME(name) (__CHIPSET__#name)
+
+#define DEV_NAME_STR_LEN 32
+
+#define SAMPLING_RATE_8KHZ 8000
+#define SAMPLING_RATE_11P025KHZ 11025
+#define SAMPLING_RATE_16KHZ 16000
+#define SAMPLING_RATE_22P05KHZ 22050
+#define SAMPLING_RATE_32KHZ 32000
+#define SAMPLING_RATE_44P1KHZ 44100
+#define SAMPLING_RATE_48KHZ 48000
+#define SAMPLING_RATE_88P2KHZ 88200
+#define SAMPLING_RATE_96KHZ 96000
+#define SAMPLING_RATE_176P4KHZ 176400
+#define SAMPLING_RATE_192KHZ 192000
+#define SAMPLING_RATE_352P8KHZ 352800
+#define SAMPLING_RATE_384KHZ 384000
+
+#define WCD9XXX_MBHC_DEF_RLOADS 5
+
+#define WSA8810_NAME_1 "wsa881x.20170211"
+#define WSA8810_NAME_2 "wsa881x.20170212"
+#define WCN_CDC_SLIM_RX_CH_MAX 2
+#define WCN_CDC_SLIM_TX_CH_MAX 3
+#define TDM_CHANNEL_MAX 8
+
+#define ADSP_STATE_READY_TIMEOUT_MS 3000
+#define MSM_LL_QOS_VALUE 300 /* time in us to ensure LPM doesn't go in C3/C4 */
+#define MSM_HIFI_ON 1
+
+enum {
+ SLIM_RX_0 = 0,
+ SLIM_RX_1,
+ SLIM_RX_2,
+ SLIM_RX_3,
+ SLIM_RX_4,
+ SLIM_RX_5,
+ SLIM_RX_6,
+ SLIM_RX_7,
+ SLIM_RX_MAX,
+};
+enum {
+ SLIM_TX_0 = 0,
+ SLIM_TX_1,
+ SLIM_TX_2,
+ SLIM_TX_3,
+ SLIM_TX_4,
+ SLIM_TX_5,
+ SLIM_TX_6,
+ SLIM_TX_7,
+ SLIM_TX_8,
+ SLIM_TX_MAX,
+};
+
+enum {
+ PRIM_MI2S = 0,
+ SEC_MI2S,
+ TERT_MI2S,
+ QUAT_MI2S,
+ QUIN_MI2S,
+ MI2S_MAX,
+};
+
+enum {
+ PRIM_AUX_PCM = 0,
+ SEC_AUX_PCM,
+ TERT_AUX_PCM,
+ QUAT_AUX_PCM,
+ QUIN_AUX_PCM,
+ AUX_PCM_MAX,
+};
+
+struct mi2s_conf {
+ struct mutex lock;
+ u32 ref_cnt;
+ u32 msm_is_mi2s_master;
+};
+
+static u32 mi2s_ebit_clk[MI2S_MAX] = {
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_EBIT,
+ Q6AFE_LPASS_CLK_ID_SEC_MI2S_EBIT,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_EBIT,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_EBIT,
+ Q6AFE_LPASS_CLK_ID_QUI_MI2S_EBIT
+};
+
+struct dev_config {
+ u32 sample_rate;
+ u32 bit_format;
+ u32 channels;
+};
+
+enum {
+ DP_RX_IDX = 0,
+ EXT_DISP_RX_IDX_MAX,
+};
+
+struct msm_wsa881x_dev_info {
+ struct device_node *of_node;
+ u32 index;
+};
+
+enum pinctrl_pin_state {
+ STATE_DISABLE = 0, /* All pins are in sleep state */
+ STATE_MI2S_ACTIVE, /* IS2 = active, TDM = sleep */
+ STATE_TDM_ACTIVE, /* IS2 = sleep, TDM = active */
+};
+
+struct msm_pinctrl_info {
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *mi2s_disable;
+ struct pinctrl_state *tdm_disable;
+ struct pinctrl_state *mi2s_active;
+ struct pinctrl_state *tdm_active;
+ enum pinctrl_pin_state curr_state;
+};
+
+struct msm_asoc_mach_data {
+ struct snd_info_entry *codec_root;
+ struct msm_pinctrl_info pinctrl_info;
+ struct device_node *us_euro_gpio_p; /* used by pinctrl API */
+ struct device_node *hph_en1_gpio_p; /* used by pinctrl API */
+ struct device_node *hph_en0_gpio_p; /* used by pinctrl API */
+ struct device_node *fsa_handle;
+};
+
+struct msm_asoc_wcd93xx_codec {
+ void* (*get_afe_config_fn)(struct snd_soc_codec *codec,
+ enum afe_config_type config_type);
+};
+
+static const char *const pin_states[] = {"sleep", "i2s-active",
+ "tdm-active"};
+
+enum {
+ TDM_0 = 0,
+ TDM_1,
+ TDM_2,
+ TDM_3,
+ TDM_4,
+ TDM_5,
+ TDM_6,
+ TDM_7,
+ TDM_PORT_MAX,
+};
+
+enum {
+ TDM_PRI = 0,
+ TDM_SEC,
+ TDM_TERT,
+ TDM_QUAT,
+ TDM_QUIN,
+ TDM_INTERFACE_MAX,
+};
+
+struct tdm_port {
+ u32 mode;
+ u32 channel;
+};
+
+/* TDM default config */
+static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
+ { /* PRI TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* SEC TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* TERT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* QUAT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ },
+ { /* QUIN TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
+ }
+
+};
+
+/* TDM default config */
+static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
+ { /* PRI TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* SEC TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* TERT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* QUAT TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ },
+ { /* QUIN TDM */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_6 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
+ }
+
+};
+
+/* Default configuration of slimbus channels */
+static struct dev_config slim_rx_cfg[] = {
+ [SLIM_RX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_RX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static struct dev_config slim_tx_cfg[] = {
+ [SLIM_TX_0] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_1] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_2] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_3] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_4] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_5] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_6] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+/* Default configuration of external display BE */
+static struct dev_config ext_disp_rx_cfg[] = {
+ [DP_RX_IDX] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+static struct dev_config usb_rx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 2,
+};
+
+static struct dev_config usb_tx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 1,
+};
+
+static struct dev_config proxy_rx_cfg = {
+ .sample_rate = SAMPLING_RATE_48KHZ,
+ .bit_format = SNDRV_PCM_FORMAT_S16_LE,
+ .channels = 2,
+};
+
+/* Default configuration of MI2S channels */
+static struct dev_config mi2s_rx_cfg[] = {
+ [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+ [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
+};
+
+static struct dev_config mi2s_tx_cfg[] = {
+ [PRIM_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SEC_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static struct dev_config aux_pcm_rx_cfg[] = {
+ [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+
+static struct dev_config aux_pcm_tx_cfg[] = {
+ [PRIM_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [SEC_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [TERT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUAT_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+ [QUIN_AUX_PCM] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+};
+static int msm_vi_feed_tx_ch = 2;
+static const char *const slim_rx_ch_text[] = {"One", "Two"};
+static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven",
+ "Eight"};
+static const char *const vi_feed_ch_text[] = {"One", "Two"};
+static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
+ "S32_LE"};
+static char const *ext_disp_bit_format_text[] = {"S16_LE", "S24_LE",
+ "S24_3LE"};
+static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_32", "KHZ_44P1", "KHZ_48",
+ "KHZ_88P2", "KHZ_96", "KHZ_176P4",
+ "KHZ_192", "KHZ_352P8", "KHZ_384"};
+static char const *bt_sample_rate_text[] = {"KHZ_8", "KHZ_16",
+ "KHZ_44P1", "KHZ_48",
+ "KHZ_88P2", "KHZ_96"};
+static const char *const usb_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven",
+ "Eight"};
+static char const *ch_text[] = {"Two", "Three", "Four", "Five",
+ "Six", "Seven", "Eight"};
+static char const *usb_sample_rate_text[] = {"KHZ_8", "KHZ_11P025",
+ "KHZ_16", "KHZ_22P05",
+ "KHZ_32", "KHZ_44P1", "KHZ_48",
+ "KHZ_88P2", "KHZ_96", "KHZ_176P4",
+ "KHZ_192", "KHZ_352P8", "KHZ_384"};
+static char const *ext_disp_sample_rate_text[] = {"KHZ_48", "KHZ_96",
+ "KHZ_192", "KHZ_32", "KHZ_44P1",
+ "KHZ_88P2", "KHZ_176P4" };
+static char const *tdm_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven", "Eight"};
+static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
+static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
+ "KHZ_48", "KHZ_176P4",
+ "KHZ_352P8"};
+static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
+static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_11P025", "KHZ_16",
+ "KHZ_22P05", "KHZ_32", "KHZ_44P1",
+ "KHZ_48", "KHZ_96", "KHZ_192"};
+static const char *const mi2s_ch_text[] = {"One", "Two", "Three", "Four",
+ "Five", "Six", "Seven",
+ "Eight"};
+static const char *const hifi_text[] = {"Off", "On"};
+static const char *const qos_text[] = {"Disable", "Enable"};
+
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_chs, slim_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_1_tx_chs, slim_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_chs, slim_rx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_chs, usb_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_chs, usb_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(vi_feed_tx_chs, vi_feed_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_chs, ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(proxy_rx_chs, ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_format, ext_disp_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_2_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_0_tx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_5_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(slim_6_rx_sample_rate, slim_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(bt_sample_rate, bt_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_rx_sample_rate, usb_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(usb_tx_sample_rate, usb_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(ext_disp_rx_sample_rate,
+ ext_disp_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_chs, tdm_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_format, tdm_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_tx_sample_rate, tdm_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_chs, tdm_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_format, tdm_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tdm_rx_sample_rate, tdm_sample_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_rx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quin_aux_pcm_tx_sample_rate, auxpcm_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_sample_rate, mi2s_rate_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(prim_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(sec_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(tert_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quat_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_rx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(quin_mi2s_tx_chs, mi2s_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(hifi_function, hifi_text);
+
+static struct platform_device *spdev;
+
+static int msm_hifi_control;
+static bool is_initial_boot;
+static bool codec_reg_done;
+static struct snd_soc_aux_dev *msm_aux_dev;
+static struct snd_soc_codec_conf *msm_codec_conf;
+static struct msm_asoc_wcd93xx_codec msm_codec_fn;
+
+static void *def_wcd_mbhc_cal(void);
+static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec,
+ int enable, bool dapm);
+static int msm_wsa881x_init(struct snd_soc_component *component);
+
+/*
+ * Need to report LINEIN
+ * if R/L channel impedance is larger than 5K ohm
+ */
+static struct wcd_mbhc_config wcd_mbhc_cfg = {
+ .read_fw_bin = false,
+ .calibration = NULL,
+ .detect_extn_cable = true,
+ .mono_stero_detection = false,
+ .swap_gnd_mic = NULL,
+ .hs_ext_micbias = true,
+ .key_code[0] = KEY_MEDIA,
+ .key_code[1] = KEY_VOICECOMMAND,
+ .key_code[2] = KEY_VOLUMEUP,
+ .key_code[3] = KEY_VOLUMEDOWN,
+ .key_code[4] = 0,
+ .key_code[5] = 0,
+ .key_code[6] = 0,
+ .key_code[7] = 0,
+ .linein_th = 5000,
+ .moisture_en = true,
+ .mbhc_micbias = MIC_BIAS_2,
+ .anc_micbias = MIC_BIAS_2,
+ .enable_anc_mic_detect = false,
+};
+
+static struct snd_soc_dapm_route wcd_audio_paths[] = {
+ {"MIC BIAS1", NULL, "MCLK TX"},
+ {"MIC BIAS3", NULL, "MCLK TX"},
+ {"MIC BIAS4", NULL, "MCLK TX"},
+};
+
+static struct snd_soc_dapm_route wcd_audio_paths_tavil[] = {
+ {"MIC BIAS1", NULL, "MCLK TX"},
+ {"MIC BIAS2", NULL, "MCLK TX"},
+ {"MIC BIAS3", NULL, "MCLK TX"},
+ {"MIC BIAS4", NULL, "MCLK TX"},
+};
+
+static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_PRI_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_SEC_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_TER_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_QUAD_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ },
+ {
+ AFE_API_VERSION_I2S_CONFIG,
+ Q6AFE_LPASS_CLK_ID_QUI_MI2S_IBIT,
+ Q6AFE_LPASS_IBIT_CLK_1_P536_MHZ,
+ Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
+ Q6AFE_LPASS_CLK_ROOT_DEFAULT,
+ 0,
+ }
+
+};
+
+static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
+
+static int slim_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val = 0;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 10;
+ break;
+ default:
+ sample_rate_val = 4;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int slim_get_sample_rate(int value)
+{
+ int sample_rate = 0;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 6:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 8:
+ sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 9:
+ sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ case 10:
+ sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int slim_get_bit_format_val(int bit_format)
+{
+ int val = 0;
+
+ switch (bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ val = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ val = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ val = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ val = 0;
+ break;
+ }
+ return val;
+}
+
+static int slim_get_bit_format(int val)
+{
+ int bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+
+ switch (val) {
+ case 0:
+ bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ case 1:
+ bit_fmt = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 2:
+ bit_fmt = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 3:
+ bit_fmt = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ bit_fmt = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ return bit_fmt;
+}
+
+static int slim_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int port_id = 0;
+
+ if (strnstr(kcontrol->id.name, "SLIM_0_RX", sizeof("SLIM_0_RX"))) {
+ port_id = SLIM_RX_0;
+ } else if (strnstr(kcontrol->id.name,
+ "SLIM_2_RX", sizeof("SLIM_2_RX"))) {
+ port_id = SLIM_RX_2;
+ } else if (strnstr(kcontrol->id.name,
+ "SLIM_5_RX", sizeof("SLIM_5_RX"))) {
+ port_id = SLIM_RX_5;
+ } else if (strnstr(kcontrol->id.name,
+ "SLIM_6_RX", sizeof("SLIM_6_RX"))) {
+ port_id = SLIM_RX_6;
+ } else if (strnstr(kcontrol->id.name,
+ "SLIM_0_TX", sizeof("SLIM_0_TX"))) {
+ port_id = SLIM_TX_0;
+ } else if (strnstr(kcontrol->id.name,
+ "SLIM_1_TX", sizeof("SLIM_1_TX"))) {
+ port_id = SLIM_TX_1;
+ } else {
+ pr_err("%s: unsupported channel: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+
+ return port_id;
+}
+
+static int slim_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_sample_rate_val(slim_rx_cfg[ch_num].sample_rate);
+
+ pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_rx_cfg[ch_num].sample_rate =
+ slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: slim[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_sample_rate_val(slim_tx_cfg[ch_num].sample_rate);
+
+ pr_debug("%s: slim[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate = 0;
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ sample_rate = slim_get_sample_rate(ucontrol->value.enumerated.item[0]);
+ if (sample_rate == SAMPLING_RATE_44P1KHZ) {
+ pr_err("%s: Unsupported sample rate %d: for Tx path\n",
+ __func__, sample_rate);
+ return -EINVAL;
+ }
+ slim_tx_cfg[ch_num].sample_rate = sample_rate;
+
+ pr_debug("%s: slim[%d]_tx_sample_rate = %d, value = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_bit_format_val(slim_rx_cfg[ch_num].bit_format);
+
+ pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_rx_cfg[ch_num].bit_format =
+ slim_get_bit_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: slim[%d]_rx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_rx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_bit_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ ucontrol->value.enumerated.item[0] =
+ slim_get_bit_format_val(slim_tx_cfg[ch_num].bit_format);
+
+ pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_tx_bit_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_tx_cfg[ch_num].bit_format =
+ slim_get_bit_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: slim[%d]_tx_bit_format = %d, ucontrol value = %d\n",
+ __func__, ch_num, slim_tx_cfg[ch_num].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int slim_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].channels);
+ ucontrol->value.enumerated.item[0] = slim_rx_cfg[ch_num].channels - 1;
+
+ return 0;
+}
+
+static int slim_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_rx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_slim_[%d]_rx_ch = %d\n", __func__,
+ ch_num, slim_rx_cfg[ch_num].channels);
+
+ return 1;
+}
+
+static int slim_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].channels);
+ ucontrol->value.enumerated.item[0] = slim_tx_cfg[ch_num].channels - 1;
+
+ return 0;
+}
+
+static int slim_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ch_num = slim_get_port_idx(kcontrol);
+
+ if (ch_num < 0)
+ return ch_num;
+
+ slim_tx_cfg[ch_num].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_slim_[%d]_tx_ch = %d\n", __func__,
+ ch_num, slim_tx_cfg[ch_num].channels);
+
+ return 1;
+}
+
+static int msm_vi_feed_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = msm_vi_feed_tx_ch - 1;
+ pr_debug("%s: msm_vi_feed_tx_ch = %ld\n", __func__,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int msm_vi_feed_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ msm_vi_feed_tx_ch = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: msm_vi_feed_tx_ch = %d\n", __func__, msm_vi_feed_tx_ch);
+ return 1;
+}
+
+static int msm_bt_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ /*
+ * Slimbus_7_Rx/Tx sample rate values should always be in sync (same)
+ * when used for BT_SCO use case. Return either Rx or Tx sample rate
+ * value.
+ */
+ switch (slim_rx_cfg[SLIM_RX_7].sample_rate) {
+ case SAMPLING_RATE_96KHZ:
+ ucontrol->value.integer.value[0] = 5;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ ucontrol->value.integer.value[0] = 4;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+ pr_debug("%s: sample rate = %d", __func__,
+ slim_rx_cfg[SLIM_RX_7].sample_rate);
+
+ return 0;
+}
+
+static int msm_bt_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 1:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_16KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 3:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_48KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 4:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 5:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_96KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 0:
+ default:
+ slim_rx_cfg[SLIM_RX_7].sample_rate = SAMPLING_RATE_8KHZ;
+ slim_tx_cfg[SLIM_TX_7].sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ pr_debug("%s: sample rates: slim7_rx = %d, slim7_tx = %d, value = %d\n",
+ __func__,
+ slim_rx_cfg[SLIM_RX_7].sample_rate,
+ slim_tx_cfg[SLIM_TX_7].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int usb_audio_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: usb_audio_rx_ch = %d\n", __func__,
+ usb_rx_cfg.channels);
+ ucontrol->value.integer.value[0] = usb_rx_cfg.channels - 1;
+ return 0;
+}
+
+static int usb_audio_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ usb_rx_cfg.channels = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: usb_audio_rx_ch = %d\n", __func__, usb_rx_cfg.channels);
+ return 1;
+}
+
+static int usb_audio_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val;
+
+ switch (usb_rx_cfg.sample_rate) {
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 12;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 11;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 10;
+ break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_22P05KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_11P025KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ sample_rate_val = 0;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: usb_audio_rx_sample_rate = %d\n", __func__,
+ usb_rx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 12:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ case 11:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ case 10:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 9:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 8:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 6:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
+ break;
+ case 2:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
+ break;
+ case 0:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ default:
+ usb_rx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+ pr_debug("%s: control value = %ld, usb_audio_rx_sample_rate = %d\n",
+ __func__, ucontrol->value.integer.value[0],
+ usb_rx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (usb_rx_cfg.bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_rx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int usb_audio_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int rc = 0;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ usb_rx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: usb_audio_rx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_rx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return rc;
+}
+
+static int usb_audio_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: usb_audio_tx_ch = %d\n", __func__,
+ usb_tx_cfg.channels);
+ ucontrol->value.integer.value[0] = usb_tx_cfg.channels - 1;
+ return 0;
+}
+
+static int usb_audio_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ usb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
+
+ pr_debug("%s: usb_audio_tx_ch = %d\n", __func__, usb_tx_cfg.channels);
+ return 1;
+}
+
+static int usb_audio_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val;
+
+ switch (usb_tx_cfg.sample_rate) {
+ case SAMPLING_RATE_384KHZ:
+ sample_rate_val = 12;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 11;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 10;
+ break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 9;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 8;
+ break;
+ case SAMPLING_RATE_88P2KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_22P05KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_11P025KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ default:
+ sample_rate_val = 6;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: usb_audio_tx_sample_rate = %d\n", __func__,
+ usb_tx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (ucontrol->value.integer.value[0]) {
+ case 12:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
+ break;
+ case 11:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ case 10:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 9:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 8:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 7:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 6:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 5:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 4:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
+ break;
+ case 2:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 1:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
+ break;
+ case 0:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ default:
+ usb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+ pr_debug("%s: control value = %ld, usb_audio_tx_sample_rate = %d\n",
+ __func__, ucontrol->value.integer.value[0],
+ usb_tx_cfg.sample_rate);
+ return 0;
+}
+
+static int usb_audio_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ switch (usb_tx_cfg.bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ ucontrol->value.integer.value[0] = 3;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_tx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int usb_audio_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int rc = 0;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 3:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ case 2:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ usb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: usb_audio_tx_format = %d, ucontrol value = %ld\n",
+ __func__, usb_tx_cfg.bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return rc;
+}
+
+static int ext_disp_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int idx;
+
+ if (strnstr(kcontrol->id.name, "Display Port RX",
+ sizeof("Display Port RX"))) {
+ idx = DP_RX_IDX;
+ } else {
+ pr_err("%s: unsupported BE: %s",
+ __func__, kcontrol->id.name);
+ idx = -EINVAL;
+ }
+
+ return idx;
+}
+
+static int ext_disp_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = ext_disp_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ switch (ext_disp_rx_cfg[idx].bit_format) {
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ ucontrol->value.integer.value[0] = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ ucontrol->value.integer.value[0] = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ ucontrol->value.integer.value[0] = 0;
+ break;
+ }
+
+ pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
+ __func__, idx, ext_disp_rx_cfg[idx].bit_format,
+ ucontrol->value.integer.value[0]);
+ return 0;
+}
+
+static int ext_disp_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = ext_disp_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 2:
+ ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 1:
+ ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 0:
+ default:
+ ext_disp_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ pr_debug("%s: ext_disp_rx[%d].format = %d, ucontrol value = %ld\n",
+ __func__, idx, ext_disp_rx_cfg[idx].bit_format,
+ ucontrol->value.integer.value[0]);
+
+ return 0;
+}
+
+static int ext_disp_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = ext_disp_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.integer.value[0] =
+ ext_disp_rx_cfg[idx].channels - 2;
+
+ pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
+ idx, ext_disp_rx_cfg[idx].channels);
+
+ return 0;
+}
+
+static int ext_disp_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = ext_disp_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ext_disp_rx_cfg[idx].channels =
+ ucontrol->value.integer.value[0] + 2;
+
+ pr_debug("%s: ext_disp_rx[%d].ch = %d\n", __func__,
+ idx, ext_disp_rx_cfg[idx].channels);
+ return 1;
+}
+
+static int ext_disp_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int sample_rate_val;
+ int idx = ext_disp_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ switch (ext_disp_rx_cfg[idx].sample_rate) {
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 6;
+ break;
+
+ case SAMPLING_RATE_88P2KHZ:
+ sample_rate_val = 5;
+ break;
+
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 4;
+ break;
+
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 3;
+ break;
+
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 2;
+ break;
+
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 1;
+ break;
+
+ case SAMPLING_RATE_48KHZ:
+ default:
+ sample_rate_val = 0;
+ break;
+ }
+
+ ucontrol->value.integer.value[0] = sample_rate_val;
+ pr_debug("%s: ext_disp_rx[%d].sample_rate = %d\n", __func__,
+ idx, ext_disp_rx_cfg[idx].sample_rate);
+
+ return 0;
+}
+
+static int ext_disp_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = ext_disp_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ switch (ucontrol->value.integer.value[0]) {
+ case 6:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 5:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_88P2KHZ;
+ break;
+ case 4:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 3:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 2:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ case 1:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 0:
+ default:
+ ext_disp_rx_cfg[idx].sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+ pr_debug("%s: control value = %ld, ext_disp_rx[%d].sample_rate = %d\n",
+ __func__, ucontrol->value.integer.value[0], idx,
+ ext_disp_rx_cfg[idx].sample_rate);
+ return 0;
+}
+
+static int proxy_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: proxy_rx channels = %d\n",
+ __func__, proxy_rx_cfg.channels);
+ ucontrol->value.integer.value[0] = proxy_rx_cfg.channels - 2;
+
+ return 0;
+}
+
+static int proxy_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ proxy_rx_cfg.channels = ucontrol->value.integer.value[0] + 2;
+ pr_debug("%s: proxy_rx channels = %d\n",
+ __func__, proxy_rx_cfg.channels);
+
+ return 1;
+}
+
+static int tdm_get_sample_rate(int value)
+{
+ int sample_rate = 0;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_176P4KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_352P8KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int aux_pcm_get_sample_rate(int value)
+{
+ int sample_rate;
+
+ switch (value) {
+ case 1:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 0:
+ default:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int tdm_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val = 0;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_176P4KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_352P8KHZ:
+ sample_rate_val = 5;
+ break;
+ default:
+ sample_rate_val = 3;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int aux_pcm_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_8KHZ:
+ default:
+ sample_rate_val = 0;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int tdm_get_port_idx(struct snd_kcontrol *kcontrol,
+ struct tdm_port *port)
+{
+ if (port) {
+ if (strnstr(kcontrol->id.name, "PRI",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_PRI;
+ } else if (strnstr(kcontrol->id.name, "SEC",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_SEC;
+ } else if (strnstr(kcontrol->id.name, "TERT",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_TERT;
+ } else if (strnstr(kcontrol->id.name, "QUAT",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_QUAT;
+ } else if (strnstr(kcontrol->id.name, "QUIN",
+ sizeof(kcontrol->id.name))) {
+ port->mode = TDM_QUIN;
+ } else {
+ pr_err("%s: unsupported mode in: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+
+ if (strnstr(kcontrol->id.name, "RX_0",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_0",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_0;
+ } else if (strnstr(kcontrol->id.name, "RX_1",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_1",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_1;
+ } else if (strnstr(kcontrol->id.name, "RX_2",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_2",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_2;
+ } else if (strnstr(kcontrol->id.name, "RX_3",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_3",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_3;
+ } else if (strnstr(kcontrol->id.name, "RX_4",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_4",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_4;
+ } else if (strnstr(kcontrol->id.name, "RX_5",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_5",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_5;
+ } else if (strnstr(kcontrol->id.name, "RX_6",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_6",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_6;
+ } else if (strnstr(kcontrol->id.name, "RX_7",
+ sizeof(kcontrol->id.name)) ||
+ strnstr(kcontrol->id.name, "TX_7",
+ sizeof(kcontrol->id.name))) {
+ port->channel = TDM_7;
+ } else {
+ pr_err("%s: unsupported channel in: %s",
+ __func__, kcontrol->id.name);
+ return -EINVAL;
+ }
+ } else
+ return -EINVAL;
+ return 0;
+}
+
+static int tdm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
+ tdm_rx_cfg[port.mode][port.channel].sample_rate);
+
+ pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_rx_cfg[port.mode][port.channel].sample_rate =
+ tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_rx_sample_rate = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_sample_rate_val(
+ tdm_tx_cfg[port.mode][port.channel].sample_rate);
+
+ pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_tx_cfg[port.mode][port.channel].sample_rate =
+ tdm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_tx_sample_rate = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_get_format(int value)
+{
+ int format = 0;
+
+ switch (value) {
+ case 0:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ case 1:
+ format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 2:
+ format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ return format;
+}
+
+static int tdm_get_format_val(int format)
+{
+ int value = 0;
+
+ switch (format) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ value = 0;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ value = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ value = 2;
+ break;
+ default:
+ value = 0;
+ break;
+ }
+ return value;
+}
+
+static int tdm_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_format_val(
+ tdm_rx_cfg[port.mode][port.channel].bit_format);
+
+ pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_rx_cfg[port.mode][port.channel].bit_format =
+ tdm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_rx_bit_format = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] = tdm_get_format_val(
+ tdm_tx_cfg[port.mode][port.channel].bit_format);
+
+ pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_tx_cfg[port.mode][port.channel].bit_format =
+ tdm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: tdm_tx_bit_format = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].bit_format,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+
+ ucontrol->value.enumerated.item[0] =
+ tdm_rx_cfg[port.mode][port.channel].channels - 1;
+
+ pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].channels - 1,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_rx_cfg[port.mode][port.channel].channels =
+ ucontrol->value.enumerated.item[0] + 1;
+
+ pr_debug("%s: tdm_rx_ch = %d, item = %d\n", __func__,
+ tdm_rx_cfg[port.mode][port.channel].channels,
+ ucontrol->value.enumerated.item[0] + 1);
+ }
+ return ret;
+}
+
+static int tdm_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ ucontrol->value.enumerated.item[0] =
+ tdm_tx_cfg[port.mode][port.channel].channels - 1;
+
+ pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].channels - 1,
+ ucontrol->value.enumerated.item[0]);
+ }
+ return ret;
+}
+
+static int tdm_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct tdm_port port;
+ int ret = tdm_get_port_idx(kcontrol, &port);
+
+ if (ret) {
+ pr_err("%s: unsupported control: %s",
+ __func__, kcontrol->id.name);
+ } else {
+ tdm_tx_cfg[port.mode][port.channel].channels =
+ ucontrol->value.enumerated.item[0] + 1;
+
+ pr_debug("%s: tdm_tx_ch = %d, item = %d\n", __func__,
+ tdm_tx_cfg[port.mode][port.channel].channels,
+ ucontrol->value.enumerated.item[0] + 1);
+ }
+ return ret;
+}
+
+static int aux_pcm_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int idx;
+
+ if (strnstr(kcontrol->id.name, "PRIM_AUX_PCM",
+ sizeof("PRIM_AUX_PCM")))
+ idx = PRIM_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "SEC_AUX_PCM",
+ sizeof("SEC_AUX_PCM")))
+ idx = SEC_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "TERT_AUX_PCM",
+ sizeof("TERT_AUX_PCM")))
+ idx = TERT_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "QUAT_AUX_PCM",
+ sizeof("QUAT_AUX_PCM")))
+ idx = QUAT_AUX_PCM;
+ else if (strnstr(kcontrol->id.name, "QUIN_AUX_PCM",
+ sizeof("QUIN_AUX_PCM")))
+ idx = QUIN_AUX_PCM;
+ else {
+ pr_err("%s: unsupported port: %s",
+ __func__, kcontrol->id.name);
+ idx = -EINVAL;
+ }
+
+ return idx;
+}
+
+static int aux_pcm_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_rx_cfg[idx].sample_rate =
+ aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int aux_pcm_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ aux_pcm_get_sample_rate_val(aux_pcm_rx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int aux_pcm_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_tx_cfg[idx].sample_rate =
+ aux_pcm_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int aux_pcm_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ aux_pcm_get_sample_rate_val(aux_pcm_tx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
+{
+ int idx;
+
+ if (strnstr(kcontrol->id.name, "PRIM_MI2S_RX",
+ sizeof("PRIM_MI2S_RX")))
+ idx = PRIM_MI2S;
+ else if (strnstr(kcontrol->id.name, "SEC_MI2S_RX",
+ sizeof("SEC_MI2S_RX")))
+ idx = SEC_MI2S;
+ else if (strnstr(kcontrol->id.name, "TERT_MI2S_RX",
+ sizeof("TERT_MI2S_RX")))
+ idx = TERT_MI2S;
+ else if (strnstr(kcontrol->id.name, "QUAT_MI2S_RX",
+ sizeof("QUAT_MI2S_RX")))
+ idx = QUAT_MI2S;
+ else if (strnstr(kcontrol->id.name, "QUIN_MI2S_RX",
+ sizeof("QUIN_MI2S_RX")))
+ idx = QUIN_MI2S;
+ else if (strnstr(kcontrol->id.name, "PRIM_MI2S_TX",
+ sizeof("PRIM_MI2S_TX")))
+ idx = PRIM_MI2S;
+ else if (strnstr(kcontrol->id.name, "SEC_MI2S_TX",
+ sizeof("SEC_MI2S_TX")))
+ idx = SEC_MI2S;
+ else if (strnstr(kcontrol->id.name, "TERT_MI2S_TX",
+ sizeof("TERT_MI2S_TX")))
+ idx = TERT_MI2S;
+ else if (strnstr(kcontrol->id.name, "QUAT_MI2S_TX",
+ sizeof("QUAT_MI2S_TX")))
+ idx = QUAT_MI2S;
+ else if (strnstr(kcontrol->id.name, "QUIN_MI2S_TX",
+ sizeof("QUIN_MI2S_TX")))
+ idx = QUIN_MI2S;
+ else {
+ pr_err("%s: unsupported channel: %s",
+ __func__, kcontrol->id.name);
+ idx = -EINVAL;
+ }
+
+ return idx;
+}
+
+static int mi2s_get_sample_rate_val(int sample_rate)
+{
+ int sample_rate_val;
+
+ switch (sample_rate) {
+ case SAMPLING_RATE_8KHZ:
+ sample_rate_val = 0;
+ break;
+ case SAMPLING_RATE_11P025KHZ:
+ sample_rate_val = 1;
+ break;
+ case SAMPLING_RATE_16KHZ:
+ sample_rate_val = 2;
+ break;
+ case SAMPLING_RATE_22P05KHZ:
+ sample_rate_val = 3;
+ break;
+ case SAMPLING_RATE_32KHZ:
+ sample_rate_val = 4;
+ break;
+ case SAMPLING_RATE_44P1KHZ:
+ sample_rate_val = 5;
+ break;
+ case SAMPLING_RATE_48KHZ:
+ sample_rate_val = 6;
+ break;
+ case SAMPLING_RATE_96KHZ:
+ sample_rate_val = 7;
+ break;
+ case SAMPLING_RATE_192KHZ:
+ sample_rate_val = 8;
+ break;
+ default:
+ sample_rate_val = 6;
+ break;
+ }
+ return sample_rate_val;
+}
+
+static int mi2s_get_sample_rate(int value)
+{
+ int sample_rate;
+
+ switch (value) {
+ case 0:
+ sample_rate = SAMPLING_RATE_8KHZ;
+ break;
+ case 1:
+ sample_rate = SAMPLING_RATE_11P025KHZ;
+ break;
+ case 2:
+ sample_rate = SAMPLING_RATE_16KHZ;
+ break;
+ case 3:
+ sample_rate = SAMPLING_RATE_22P05KHZ;
+ break;
+ case 4:
+ sample_rate = SAMPLING_RATE_32KHZ;
+ break;
+ case 5:
+ sample_rate = SAMPLING_RATE_44P1KHZ;
+ break;
+ case 6:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ case 7:
+ sample_rate = SAMPLING_RATE_96KHZ;
+ break;
+ case 8:
+ sample_rate = SAMPLING_RATE_192KHZ;
+ break;
+ default:
+ sample_rate = SAMPLING_RATE_48KHZ;
+ break;
+ }
+ return sample_rate;
+}
+
+static int mi2s_auxpcm_get_format(int value)
+{
+ int format;
+
+ switch (value) {
+ case 0:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ case 1:
+ format = SNDRV_PCM_FORMAT_S24_LE;
+ break;
+ case 2:
+ format = SNDRV_PCM_FORMAT_S24_3LE;
+ break;
+ case 3:
+ format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ return format;
+}
+
+static int mi2s_auxpcm_get_format_value(int format)
+{
+ int value;
+
+ switch (format) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ value = 0;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ value = 1;
+ break;
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ value = 2;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ value = 3;
+ break;
+ default:
+ value = 0;
+ break;
+ }
+ return value;
+}
+
+static int mi2s_rx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_rx_cfg[idx].sample_rate =
+ mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_get_sample_rate_val(mi2s_rx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_rx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_tx_cfg[idx].sample_rate =
+ mi2s_get_sample_rate(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int mi2s_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_get_sample_rate_val(mi2s_tx_cfg[idx].sample_rate);
+
+ pr_debug("%s: idx[%d]_tx_sample_rate = %d, item = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].sample_rate,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_mi2s_rx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].channels);
+ ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].channels - 1;
+
+ return 0;
+}
+
+static int msm_mi2s_rx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_rx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_mi2s_[%d]_rx_ch = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].channels);
+
+ return 1;
+}
+
+static int msm_mi2s_tx_ch_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].channels);
+ ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].channels - 1;
+
+ return 0;
+}
+
+static int msm_mi2s_tx_ch_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_tx_cfg[idx].channels = ucontrol->value.enumerated.item[0] + 1;
+ pr_debug("%s: msm_mi2s_[%d]_tx_ch = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].channels);
+
+ return 1;
+}
+
+static int msm_mi2s_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_auxpcm_get_format_value(mi2s_rx_cfg[idx].bit_format);
+
+ pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_rx_cfg[idx].bit_format =
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+ idx, mi2s_rx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_mi2s_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_auxpcm_get_format_value(mi2s_tx_cfg[idx].bit_format);
+
+ pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = mi2s_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ mi2s_tx_cfg[idx].bit_format =
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+ idx, mi2s_tx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_rx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_auxpcm_get_format_value(aux_pcm_rx_cfg[idx].bit_format);
+
+ pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_rx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_rx_cfg[idx].bit_format =
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_rx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_tx_format_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ ucontrol->value.enumerated.item[0] =
+ mi2s_auxpcm_get_format_value(aux_pcm_tx_cfg[idx].bit_format);
+
+ pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_aux_pcm_tx_format_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int idx = aux_pcm_get_port_idx(kcontrol);
+
+ if (idx < 0)
+ return idx;
+
+ aux_pcm_tx_cfg[idx].bit_format =
+ mi2s_auxpcm_get_format(ucontrol->value.enumerated.item[0]);
+
+ pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+ idx, aux_pcm_tx_cfg[idx].bit_format,
+ ucontrol->value.enumerated.item[0]);
+
+ return 0;
+}
+
+static int msm_hifi_ctrl(struct snd_soc_codec *codec)
+{
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+
+ dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n", __func__,
+ msm_hifi_control);
+
+ if (!pdata || !pdata->hph_en1_gpio_p) {
+ dev_err(codec->dev, "%s: hph_en1_gpio is invalid\n", __func__);
+ return -EINVAL;
+ }
+ if (msm_hifi_control == MSM_HIFI_ON) {
+ msm_cdc_pinctrl_select_active_state(pdata->hph_en1_gpio_p);
+ /* 5msec delay needed as per HW requirement */
+ usleep_range(5000, 5010);
+ } else {
+ msm_cdc_pinctrl_select_sleep_state(pdata->hph_en1_gpio_p);
+ }
+ snd_soc_dapm_sync(dapm);
+
+ return 0;
+}
+
+static int msm_hifi_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ pr_debug("%s: msm_hifi_control = %d\n",
+ __func__, msm_hifi_control);
+ ucontrol->value.integer.value[0] = msm_hifi_control;
+
+ return 0;
+}
+
+static int msm_hifi_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+
+ dev_dbg(codec->dev, "%s: ucontrol->value.integer.value[0] = %ld\n",
+ __func__, ucontrol->value.integer.value[0]);
+
+ msm_hifi_control = ucontrol->value.integer.value[0];
+ msm_hifi_ctrl(codec);
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new msm_snd_controls[] = {
+ SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
+ slim_rx_ch_get, slim_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs,
+ slim_rx_ch_get, slim_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_0_TX Channels", slim_0_tx_chs,
+ slim_tx_ch_get, slim_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_1_TX Channels", slim_1_tx_chs,
+ slim_tx_ch_get, slim_tx_ch_put),
+ SOC_ENUM_EXT("SLIM_5_RX Channels", slim_5_rx_chs,
+ slim_rx_ch_get, slim_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_6_RX Channels", slim_6_rx_chs,
+ slim_rx_ch_get, slim_rx_ch_put),
+ SOC_ENUM_EXT("VI_FEED_TX Channels", vi_feed_tx_chs,
+ msm_vi_feed_tx_ch_get, msm_vi_feed_tx_ch_put),
+ SOC_ENUM_EXT("USB_AUDIO_RX Channels", usb_rx_chs,
+ usb_audio_rx_ch_get, usb_audio_rx_ch_put),
+ SOC_ENUM_EXT("USB_AUDIO_TX Channels", usb_tx_chs,
+ usb_audio_tx_ch_get, usb_audio_tx_ch_put),
+ SOC_ENUM_EXT("Display Port RX Channels", ext_disp_rx_chs,
+ ext_disp_rx_ch_get, ext_disp_rx_ch_put),
+ SOC_ENUM_EXT("PROXY_RX Channels", proxy_rx_chs,
+ proxy_rx_ch_get, proxy_rx_ch_put),
+ SOC_ENUM_EXT("SLIM_0_RX Format", slim_0_rx_format,
+ slim_rx_bit_format_get, slim_rx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_5_RX Format", slim_5_rx_format,
+ slim_rx_bit_format_get, slim_rx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_6_RX Format", slim_6_rx_format,
+ slim_rx_bit_format_get, slim_rx_bit_format_put),
+ SOC_ENUM_EXT("SLIM_0_TX Format", slim_0_tx_format,
+ slim_tx_bit_format_get, slim_tx_bit_format_put),
+ SOC_ENUM_EXT("USB_AUDIO_RX Format", usb_rx_format,
+ usb_audio_rx_format_get, usb_audio_rx_format_put),
+ SOC_ENUM_EXT("USB_AUDIO_TX Format", usb_tx_format,
+ usb_audio_tx_format_get, usb_audio_tx_format_put),
+ SOC_ENUM_EXT("Display Port RX Bit Format", ext_disp_rx_format,
+ ext_disp_rx_format_get, ext_disp_rx_format_put),
+ SOC_ENUM_EXT("SLIM_0_RX SampleRate", slim_0_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_2_RX SampleRate", slim_2_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_0_TX SampleRate", slim_0_tx_sample_rate,
+ slim_tx_sample_rate_get, slim_tx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_5_RX SampleRate", slim_5_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("SLIM_6_RX SampleRate", slim_6_rx_sample_rate,
+ slim_rx_sample_rate_get, slim_rx_sample_rate_put),
+ SOC_ENUM_EXT("BT SampleRate", bt_sample_rate,
+ msm_bt_sample_rate_get,
+ msm_bt_sample_rate_put),
+ SOC_ENUM_EXT("USB_AUDIO_RX SampleRate", usb_rx_sample_rate,
+ usb_audio_rx_sample_rate_get,
+ usb_audio_rx_sample_rate_put),
+ SOC_ENUM_EXT("USB_AUDIO_TX SampleRate", usb_tx_sample_rate,
+ usb_audio_tx_sample_rate_get,
+ usb_audio_tx_sample_rate_put),
+ SOC_ENUM_EXT("Display Port RX SampleRate", ext_disp_rx_sample_rate,
+ ext_disp_rx_sample_rate_get,
+ ext_disp_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("SEC_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("SEC_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("TERT_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("TERT_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("QUAT_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("QUAT_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("QUIN_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
+ tdm_rx_sample_rate_get,
+ tdm_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUIN_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
+ tdm_tx_sample_rate_get,
+ tdm_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUIN_TDM_RX_0 Format", tdm_rx_format,
+ tdm_rx_format_get,
+ tdm_rx_format_put),
+ SOC_ENUM_EXT("QUIN_TDM_TX_0 Format", tdm_tx_format,
+ tdm_tx_format_get,
+ tdm_tx_format_put),
+ SOC_ENUM_EXT("QUIN_TDM_RX_0 Channels", tdm_rx_chs,
+ tdm_rx_ch_get,
+ tdm_rx_ch_put),
+ SOC_ENUM_EXT("QUIN_TDM_TX_0 Channels", tdm_tx_chs,
+ tdm_tx_ch_get,
+ tdm_tx_ch_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_RX SampleRate", prim_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_RX SampleRate", sec_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_RX SampleRate", tert_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_RX SampleRate", quat_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUIN_AUX_PCM_RX SampleRate", quin_aux_pcm_rx_sample_rate,
+ aux_pcm_rx_sample_rate_get,
+ aux_pcm_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_TX SampleRate", prim_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_TX SampleRate", sec_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_TX SampleRate", tert_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_TX SampleRate", quat_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUIN_AUX_PCM_TX SampleRate", quin_aux_pcm_tx_sample_rate,
+ aux_pcm_tx_sample_rate_get,
+ aux_pcm_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_MI2S_RX SampleRate", prim_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_MI2S_RX SampleRate", sec_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_MI2S_RX SampleRate", tert_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_MI2S_RX SampleRate", quat_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("QUIN_MI2S_RX SampleRate", quin_mi2s_rx_sample_rate,
+ mi2s_rx_sample_rate_get,
+ mi2s_rx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_MI2S_TX SampleRate", prim_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("SEC_MI2S_TX SampleRate", sec_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("TERT_MI2S_TX SampleRate", tert_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUAT_MI2S_TX SampleRate", quat_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("QUIN_MI2S_TX SampleRate", quin_mi2s_tx_sample_rate,
+ mi2s_tx_sample_rate_get,
+ mi2s_tx_sample_rate_put),
+ SOC_ENUM_EXT("PRIM_MI2S_RX Channels", prim_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("PRIM_MI2S_TX Channels", prim_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("SEC_MI2S_RX Channels", sec_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("SEC_MI2S_TX Channels", sec_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("TERT_MI2S_RX Channels", tert_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("TERT_MI2S_TX Channels", tert_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("QUAT_MI2S_RX Channels", quat_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("QUAT_MI2S_TX Channels", quat_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("QUIN_MI2S_RX Channels", quin_mi2s_rx_chs,
+ msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
+ SOC_ENUM_EXT("QUIN_MI2S_TX Channels", quin_mi2s_tx_chs,
+ msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+ SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format,
+ msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
+ SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format,
+ msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
+ SOC_ENUM_EXT("SEC_MI2S_RX Format", mi2s_rx_format,
+ msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
+ SOC_ENUM_EXT("SEC_MI2S_TX Format", mi2s_tx_format,
+ msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
+ SOC_ENUM_EXT("TERT_MI2S_RX Format", mi2s_rx_format,
+ msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
+ SOC_ENUM_EXT("TERT_MI2S_TX Format", mi2s_tx_format,
+ msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
+ SOC_ENUM_EXT("QUAT_MI2S_RX Format", mi2s_rx_format,
+ msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
+ SOC_ENUM_EXT("QUAT_MI2S_TX Format", mi2s_tx_format,
+ msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
+ SOC_ENUM_EXT("QUIN_MI2S_RX Format", mi2s_rx_format,
+ msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
+ SOC_ENUM_EXT("QUIN_MI2S_TX Format", mi2s_tx_format,
+ msm_mi2s_tx_format_get, msm_mi2s_tx_format_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("PRIM_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("SEC_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("TERT_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("QUAT_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("QUIN_AUX_PCM_RX Format", aux_pcm_rx_format,
+ msm_aux_pcm_rx_format_get, msm_aux_pcm_rx_format_put),
+ SOC_ENUM_EXT("QUIN_AUX_PCM_TX Format", aux_pcm_tx_format,
+ msm_aux_pcm_tx_format_get, msm_aux_pcm_tx_format_put),
+ SOC_ENUM_EXT("HiFi Function", hifi_function, msm_hifi_get,
+ msm_hifi_put),
+
+};
+
+static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec,
+ int enable, bool dapm)
+{
+ int ret = 0;
+
+ if (!strcmp(dev_name(codec->dev), "pahu_codec")) {
+ ret = pahu_cdc_mclk_enable(codec, enable);
+ } else if (!strcmp(dev_name(codec->dev), "tavil_codec")) {
+ ret = tavil_cdc_mclk_enable(codec, enable);
+ } else {
+ dev_err(codec->dev, "%s: unknown codec to enable ext clk\n",
+ __func__);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int msm_snd_enable_codec_ext_tx_clk(struct snd_soc_codec *codec,
+ int enable, bool dapm)
+{
+ int ret = 0;
+
+ if (!strcmp(dev_name(codec->dev), "pahu_codec")) {
+ ret = pahu_cdc_mclk_tx_enable(codec, enable);
+ } else if (!strcmp(dev_name(codec->dev), "tavil_codec")) {
+ ret = tavil_cdc_mclk_tx_enable(codec, enable);
+ } else {
+ dev_err(codec->dev, "%s: unknown codec to enable TX ext clk\n",
+ __func__);
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int msm_mclk_tx_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ return msm_snd_enable_codec_ext_tx_clk(codec, 1, true);
+ case SND_SOC_DAPM_POST_PMD:
+ return msm_snd_enable_codec_ext_tx_clk(codec, 0, true);
+ }
+ return 0;
+}
+
+static int msm_mclk_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+
+ pr_debug("%s: event = %d\n", __func__, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ return msm_snd_enable_codec_ext_clk(codec, 1, true);
+ case SND_SOC_DAPM_POST_PMD:
+ return msm_snd_enable_codec_ext_clk(codec, 0, true);
+ }
+ return 0;
+}
+
+static int msm_hifi_ctrl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+
+ dev_dbg(codec->dev, "%s: msm_hifi_control = %d\n",
+ __func__, msm_hifi_control);
+
+ if (!pdata || !pdata->hph_en0_gpio_p) {
+ dev_err(codec->dev, "%s: hph_en0_gpio is invalid\n", __func__);
+ return -EINVAL;
+ }
+
+ if (msm_hifi_control != MSM_HIFI_ON) {
+ dev_dbg(codec->dev, "%s: HiFi mixer control is not set\n",
+ __func__);
+ return 0;
+ }
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ msm_cdc_pinctrl_select_active_state(pdata->hph_en0_gpio_p);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ msm_cdc_pinctrl_select_sleep_state(pdata->hph_en0_gpio_p);
+ break;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
+
+ SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
+ msm_mclk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0,
+ msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MIC("Handset Mic", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+
+ SND_SOC_DAPM_MIC("Digital Mic0", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic2", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic3", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic4", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic5", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic6", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic7", NULL),
+};
+
+static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = {
+
+ SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
+ msm_mclk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0,
+ msm_mclk_tx_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
+ SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
+ SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event),
+ SND_SOC_DAPM_MIC("Handset Mic", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic5", NULL),
+
+ SND_SOC_DAPM_MIC("Digital Mic0", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic1", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic2", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic3", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic4", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic5", NULL),
+};
+
+static inline int param_is_mask(int p)
+{
+ return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
+ (p <= SNDRV_PCM_HW_PARAM_LAST_MASK);
+}
+
+static inline struct snd_mask *param_to_mask(struct snd_pcm_hw_params *p,
+ int n)
+{
+ return &(p->masks[n - SNDRV_PCM_HW_PARAM_FIRST_MASK]);
+}
+
+static void param_set_mask(struct snd_pcm_hw_params *p, int n,
+ unsigned int bit)
+{
+ if (bit >= SNDRV_MASK_MAX)
+ return;
+ if (param_is_mask(n)) {
+ struct snd_mask *m = param_to_mask(p, n);
+
+ m->bits[0] = 0;
+ m->bits[1] = 0;
+ m->bits[bit >> 5] |= (1 << (bit & 31));
+ }
+}
+
+static int msm_slim_get_ch_from_beid(int32_t be_id)
+{
+ int ch_id = 0;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_SLIMBUS_0_RX:
+ ch_id = SLIM_RX_0;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_1_RX:
+ ch_id = SLIM_RX_1;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_2_RX:
+ ch_id = SLIM_RX_2;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_3_RX:
+ ch_id = SLIM_RX_3;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_4_RX:
+ ch_id = SLIM_RX_4;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_6_RX:
+ ch_id = SLIM_RX_6;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_0_TX:
+ ch_id = SLIM_TX_0;
+ break;
+ case MSM_BACKEND_DAI_SLIMBUS_3_TX:
+ ch_id = SLIM_TX_3;
+ break;
+ default:
+ ch_id = SLIM_RX_0;
+ break;
+ }
+
+ return ch_id;
+}
+
+static int msm_ext_disp_get_idx_from_beid(int32_t be_id)
+{
+ int idx;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
+ idx = DP_RX_IDX;
+ break;
+ default:
+ pr_err("%s: Incorrect ext_disp BE id %d\n", __func__, be_id);
+ idx = -EINVAL;
+ break;
+ }
+
+ return idx;
+}
+
+static int msm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ 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);
+ int rc = 0;
+ int idx;
+ void *config = NULL;
+ struct snd_soc_codec *codec = NULL;
+
+ pr_debug("%s: format = %d, rate = %d\n",
+ __func__, params_format(params), params_rate(params));
+
+ switch (dai_link->id) {
+ case MSM_BACKEND_DAI_SLIMBUS_0_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_1_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_2_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_3_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_4_RX:
+ case MSM_BACKEND_DAI_SLIMBUS_6_RX:
+ idx = msm_slim_get_ch_from_beid(dai_link->id);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_rx_cfg[idx].bit_format);
+ rate->min = rate->max = slim_rx_cfg[idx].sample_rate;
+ channels->min = channels->max = slim_rx_cfg[idx].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_0_TX:
+ case MSM_BACKEND_DAI_SLIMBUS_3_TX:
+ idx = msm_slim_get_ch_from_beid(dai_link->id);
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_tx_cfg[idx].bit_format);
+ rate->min = rate->max = slim_tx_cfg[idx].sample_rate;
+ channels->min = channels->max = slim_tx_cfg[idx].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_1_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_tx_cfg[1].bit_format);
+ rate->min = rate->max = slim_tx_cfg[1].sample_rate;
+ channels->min = channels->max = slim_tx_cfg[1].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_4_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ SNDRV_PCM_FORMAT_S32_LE);
+ rate->min = rate->max = SAMPLING_RATE_8KHZ;
+ channels->min = channels->max = msm_vi_feed_tx_ch;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_5_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_rx_cfg[5].bit_format);
+ rate->min = rate->max = slim_rx_cfg[5].sample_rate;
+ channels->min = channels->max = slim_rx_cfg[5].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_5_TX:
+ codec = rtd->codec;
+ rate->min = rate->max = SAMPLING_RATE_16KHZ;
+ channels->min = channels->max = 1;
+
+ config = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_SLIMBUS_SLAVE_PORT_CONFIG);
+ if (config) {
+ rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG,
+ config, SLIMBUS_5_TX);
+ if (rc)
+ pr_err("%s: Failed to set slimbus slave port config %d\n",
+ __func__, rc);
+ }
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_7_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_rx_cfg[SLIM_RX_7].bit_format);
+ rate->min = rate->max = slim_rx_cfg[SLIM_RX_7].sample_rate;
+ channels->min = channels->max =
+ slim_rx_cfg[SLIM_RX_7].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_7_TX:
+ rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
+ channels->min = channels->max =
+ slim_tx_cfg[SLIM_TX_7].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SLIMBUS_8_TX:
+ rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
+ channels->min = channels->max =
+ slim_tx_cfg[SLIM_TX_8].channels;
+ break;
+
+ case MSM_BACKEND_DAI_USB_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ usb_rx_cfg.bit_format);
+ rate->min = rate->max = usb_rx_cfg.sample_rate;
+ channels->min = channels->max = usb_rx_cfg.channels;
+ break;
+
+ case MSM_BACKEND_DAI_USB_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ usb_tx_cfg.bit_format);
+ rate->min = rate->max = usb_tx_cfg.sample_rate;
+ channels->min = channels->max = usb_tx_cfg.channels;
+ break;
+
+ case MSM_BACKEND_DAI_DISPLAY_PORT_RX:
+ idx = msm_ext_disp_get_idx_from_beid(dai_link->id);
+ if (idx < 0) {
+ pr_err("%s: Incorrect ext disp idx %d\n",
+ __func__, idx);
+ rc = idx;
+ goto done;
+ }
+
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ ext_disp_rx_cfg[idx].bit_format);
+ rate->min = rate->max = ext_disp_rx_cfg[idx].sample_rate;
+ channels->min = channels->max = ext_disp_rx_cfg[idx].channels;
+ break;
+
+ case MSM_BACKEND_DAI_AFE_PCM_RX:
+ channels->min = channels->max = proxy_rx_cfg.channels;
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_PRI][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_PRI][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_PRI][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_PRI][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_PRI][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_PRI][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_SEC][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_TERT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_TERT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_TERT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_TERT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_TERT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_TERT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_QUIN_TDM_RX_0:
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate;
+ break;
+
+ case MSM_BACKEND_DAI_QUIN_TDM_TX_0:
+ channels->min = channels->max =
+ tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_tx_cfg[TDM_QUIN][TDM_0].bit_format);
+ rate->min = rate->max = tdm_tx_cfg[TDM_QUIN][TDM_0].sample_rate;
+ break;
+
+
+ case MSM_BACKEND_DAI_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[PRIM_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[PRIM_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[PRIM_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[PRIM_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[PRIM_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[PRIM_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[SEC_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[SEC_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[SEC_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SEC_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[SEC_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[SEC_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[SEC_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[TERT_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[TERT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[TERT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERT_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[TERT_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[TERT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[TERT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[QUAT_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[QUAT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[QUAT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUAT_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[QUAT_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[QUAT_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[QUAT_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUIN_AUXPCM_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_rx_cfg[QUIN_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_rx_cfg[QUIN_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_rx_cfg[QUIN_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUIN_AUXPCM_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ aux_pcm_tx_cfg[QUIN_AUX_PCM].bit_format);
+ rate->min = rate->max =
+ aux_pcm_tx_cfg[QUIN_AUX_PCM].sample_rate;
+ channels->min = channels->max =
+ aux_pcm_tx_cfg[QUIN_AUX_PCM].channels;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_MI2S_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_rx_cfg[PRIM_MI2S].bit_format);
+ rate->min = rate->max = mi2s_rx_cfg[PRIM_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[PRIM_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_PRI_MI2S_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_tx_cfg[PRIM_MI2S].bit_format);
+ rate->min = rate->max = mi2s_tx_cfg[PRIM_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[PRIM_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_rx_cfg[SEC_MI2S].bit_format);
+ rate->min = rate->max = mi2s_rx_cfg[SEC_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[SEC_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_tx_cfg[SEC_MI2S].bit_format);
+ rate->min = rate->max = mi2s_tx_cfg[SEC_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[SEC_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_rx_cfg[TERT_MI2S].bit_format);
+ rate->min = rate->max = mi2s_rx_cfg[TERT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[TERT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_tx_cfg[TERT_MI2S].bit_format);
+ rate->min = rate->max = mi2s_tx_cfg[TERT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[TERT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_rx_cfg[QUAT_MI2S].bit_format);
+ rate->min = rate->max = mi2s_rx_cfg[QUAT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[QUAT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_tx_cfg[QUAT_MI2S].bit_format);
+ rate->min = rate->max = mi2s_tx_cfg[QUAT_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[QUAT_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUINARY_MI2S_RX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_rx_cfg[QUIN_MI2S].bit_format);
+ rate->min = rate->max = mi2s_rx_cfg[QUIN_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_rx_cfg[QUIN_MI2S].channels;
+ break;
+
+ case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ mi2s_tx_cfg[QUIN_MI2S].bit_format);
+ rate->min = rate->max = mi2s_tx_cfg[QUIN_MI2S].sample_rate;
+ channels->min = channels->max =
+ mi2s_tx_cfg[QUIN_MI2S].channels;
+ break;
+
+ default:
+ rate->min = rate->max = SAMPLING_RATE_48KHZ;
+ break;
+ }
+
+done:
+ return rc;
+}
+
+static bool msm_usbc_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
+{
+ struct snd_soc_card *card = codec->component.card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+
+ if (!pdata->fsa_handle)
+ return false;
+
+ return fsa4480_switch_event(pdata->fsa_handle, FSA_MIC_GND_SWAP);
+}
+
+static bool msm_swap_gnd_mic(struct snd_soc_codec *codec, bool active)
+{
+ int value = 0;
+ bool ret = false;
+ struct snd_soc_card *card;
+ struct msm_asoc_mach_data *pdata;
+
+ if (!codec) {
+ pr_err("%s codec is NULL\n", __func__);
+ return false;
+ }
+ card = codec->component.card;
+ pdata = snd_soc_card_get_drvdata(card);
+
+ if (!pdata)
+ return false;
+
+ if (wcd_mbhc_cfg.enable_usbc_analog)
+ return msm_usbc_swap_gnd_mic(codec, active);
+
+ /* if usbc is not defined, swap using us_euro_gpio_p */
+ if (pdata->us_euro_gpio_p) {
+ value = msm_cdc_pinctrl_get_state(
+ pdata->us_euro_gpio_p);
+ if (value)
+ msm_cdc_pinctrl_select_sleep_state(
+ pdata->us_euro_gpio_p);
+ else
+ msm_cdc_pinctrl_select_active_state(
+ pdata->us_euro_gpio_p);
+ dev_dbg(codec->dev, "%s: swap select switch %d to %d\n",
+ __func__, value, !value);
+ ret = true;
+ }
+
+ return ret;
+}
+
+static int msm_afe_set_config(struct snd_soc_codec *codec)
+{
+ int ret = 0;
+ void *config_data = NULL;
+
+ if (!msm_codec_fn.get_afe_config_fn) {
+ dev_err(codec->dev, "%s: codec get afe config not init'ed\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_REGISTERS_CONFIG);
+ if (config_data) {
+ ret = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
+ if (ret) {
+ dev_err(codec->dev,
+ "%s: Failed to set codec registers config %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_CDC_REGISTER_PAGE_CONFIG);
+ if (config_data) {
+ ret = afe_set_config(AFE_CDC_REGISTER_PAGE_CONFIG, config_data,
+ 0);
+ if (ret)
+ dev_err(codec->dev,
+ "%s: Failed to set cdc register page config\n",
+ __func__);
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_SLIMBUS_SLAVE_CONFIG);
+ if (config_data) {
+ ret = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
+ if (ret) {
+ dev_err(codec->dev,
+ "%s: Failed to set slimbus slave config %d\n",
+ __func__, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void msm_afe_clear_config(void)
+{
+ afe_clear_config(AFE_CDC_REGISTERS_CONFIG);
+ afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
+}
+
+static int msm_adsp_power_up_config(struct snd_soc_codec *codec,
+ struct snd_card *card)
+{
+ int ret = 0;
+ unsigned long timeout;
+ int adsp_ready = 0;
+ bool snd_card_online = 0;
+
+ timeout = jiffies +
+ msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+
+ do {
+ if (!snd_card_online) {
+ snd_card_online = snd_card_is_online_state(card);
+ pr_debug("%s: Sound card is %s\n", __func__,
+ snd_card_online ? "Online" : "Offline");
+ }
+ if (!adsp_ready) {
+ adsp_ready = q6core_is_adsp_ready();
+ pr_debug("%s: ADSP Audio is %s\n", __func__,
+ adsp_ready ? "ready" : "not ready");
+ }
+ if (snd_card_online && adsp_ready)
+ break;
+
+ /*
+ * Sound card/ADSP will be coming up after subsystem restart and
+ * it might not be fully up when the control reaches
+ * here. So, wait for 50msec before checking ADSP state
+ */
+ msleep(50);
+ } while (time_after(timeout, jiffies));
+
+ if (!snd_card_online || !adsp_ready) {
+ pr_err("%s: Timeout. Sound card is %s, ADSP Audio is %s\n",
+ __func__,
+ snd_card_online ? "Online" : "Offline",
+ adsp_ready ? "ready" : "not ready");
+ ret = -ETIMEDOUT;
+ goto err;
+ }
+
+ ret = msm_afe_set_config(codec);
+ if (ret)
+ pr_err("%s: Failed to set AFE config. err %d\n",
+ __func__, ret);
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static int sdm855_notifier_service_cb(struct notifier_block *this,
+ unsigned long opcode, void *ptr)
+{
+ int ret;
+ struct snd_soc_card *card = NULL;
+ const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_soc_codec *codec;
+
+ pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
+
+ switch (opcode) {
+ case AUDIO_NOTIFIER_SERVICE_DOWN:
+ /*
+ * Use flag to ignore initial boot notifications
+ * On initial boot msm_adsp_power_up_config is
+ * called on init. There is no need to clear
+ * and set the config again on initial boot.
+ */
+ if (is_initial_boot)
+ break;
+ msm_afe_clear_config();
+ break;
+ case AUDIO_NOTIFIER_SERVICE_UP:
+ if (is_initial_boot) {
+ is_initial_boot = false;
+ break;
+ }
+ if (!spdev)
+ return -EINVAL;
+
+ card = platform_get_drvdata(spdev);
+ rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
+ if (!rtd) {
+ dev_err(card->dev,
+ "%s: snd_soc_get_pcm_runtime for %s failed!\n",
+ __func__, be_dl_name);
+ ret = -EINVAL;
+ goto err;
+ }
+ codec = rtd->codec;
+
+ ret = msm_adsp_power_up_config(codec, card->snd_card);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "%s: msm_adsp_power_up_config failed ret = %d!\n",
+ __func__, ret);
+ goto err;
+ }
+ break;
+ default:
+ break;
+ }
+err:
+ return NOTIFY_OK;
+}
+
+static struct notifier_block service_nb = {
+ .notifier_call = sdm855_notifier_service_cb,
+ .priority = -INT_MAX,
+};
+
+static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret = 0;
+ void *config_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_component *aux_comp;
+ struct snd_card *card;
+ struct snd_info_entry *entry;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(rtd->card);
+
+ /*
+ * Codec SLIMBUS configuration
+ * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8
+ * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
+ * TX14, TX15, TX16
+ */
+ unsigned int rx_ch[WCD9360_RX_MAX] = {144, 145, 146, 147, 148, 149,
+ 150, 151};
+ unsigned int tx_ch[WCD9360_TX_MAX] = {128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143};
+
+ pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev));
+
+ rtd->pmdown_time = 0;
+
+ ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+ if (ret < 0) {
+ pr_err("%s: add_codec_controls failed, err %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
+ snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil,
+ ARRAY_SIZE(msm_dapm_widgets_tavil));
+ snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil,
+ ARRAY_SIZE(wcd_audio_paths_tavil));
+ } else {
+ snd_soc_dapm_new_controls(dapm, msm_dapm_widgets,
+ ARRAY_SIZE(msm_dapm_widgets));
+ snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
+ ARRAY_SIZE(wcd_audio_paths));
+ }
+
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
+ snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_OUT2");
+ snd_soc_dapm_ignore_suspend(dapm, "EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
+ snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
+
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
+ snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic5");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
+ snd_soc_dapm_ignore_suspend(dapm, "HPHL");
+ snd_soc_dapm_ignore_suspend(dapm, "HPHR");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
+ } else {
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic6");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic7");
+ }
+
+ snd_soc_dapm_sync(dapm);
+
+ snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec"))
+ msm_codec_fn.get_afe_config_fn = tavil_get_afe_config;
+ else
+ msm_codec_fn.get_afe_config_fn = pahu_get_afe_config;
+
+ ret = msm_adsp_power_up_config(codec, rtd->card->snd_card);
+ if (ret) {
+ pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
+ goto err;
+ }
+
+ config_data = msm_codec_fn.get_afe_config_fn(codec,
+ AFE_AANC_VERSION);
+ if (config_data) {
+ ret = afe_set_config(AFE_AANC_VERSION, config_data, 0);
+ if (ret) {
+ pr_err("%s: Failed to set aanc version %d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+
+ /*
+ * Send speaker configuration only for WSA8810.
+ * Default configuration is for WSA8815.
+ */
+ pr_debug("%s: Number of aux devices: %d\n",
+ __func__, rtd->card->num_aux_devs);
+ if (!strcmp(dev_name(codec_dai->dev), "tavil_codec")) {
+ if (rtd->card->num_aux_devs &&
+ !list_empty(&rtd->card->component_dev_list)) {
+ aux_comp = list_first_entry(
+ &rtd->card->component_dev_list,
+ struct snd_soc_component,
+ card_aux_list);
+ if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
+ !strcmp(aux_comp->name, WSA8810_NAME_2)) {
+ tavil_set_spkr_mode(rtd->codec,
+ WCD934X_SPKR_MODE_1);
+ tavil_set_spkr_gain_offset(rtd->codec,
+ WCD934X_RX_GAIN_OFFSET_M1P5_DB);
+ }
+ }
+ card = rtd->card->snd_card;
+ entry = snd_info_create_subdir(card->module, "codecs",
+ card->proc_root);
+ if (!entry) {
+ pr_debug("%s: Cannot create codecs module entry\n",
+ __func__);
+ pdata->codec_root = NULL;
+ goto done;
+ }
+ pdata->codec_root = entry;
+ tavil_codec_info_create_codec_entry(pdata->codec_root, codec);
+ } else {
+ if (rtd->card->num_aux_devs &&
+ !list_empty(&rtd->card->component_dev_list)) {
+ aux_comp = list_first_entry(&rtd->card->component_dev_list,
+ struct snd_soc_component, card_aux_list);
+ if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
+ !strcmp(aux_comp->name, WSA8810_NAME_2)) {
+ pahu_set_spkr_mode(rtd->codec, WCD9360_SPKR_MODE_1);
+ pahu_set_spkr_gain_offset(rtd->codec,
+ WCD9360_RX_GAIN_OFFSET_M1P5_DB);
+ }
+ }
+ card = rtd->card->snd_card;
+ entry = snd_info_create_subdir(card->module, "codecs",
+ card->proc_root);
+ if (!entry) {
+ pr_debug("%s: Cannot create codecs module entry\n",
+ __func__);
+ pdata->codec_root = NULL;
+ goto done;
+ }
+ pdata->codec_root = entry;
+ pahu_codec_info_create_codec_entry(pdata->codec_root, codec);
+ }
+done:
+ codec_reg_done = true;
+ return 0;
+
+err:
+ return ret;
+}
+
+static int msm_wcn_init(struct snd_soc_pcm_runtime *rtd)
+{
+ unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
+ unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX] = {159, 160, 161};
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+ return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+}
+
+static void *def_wcd_mbhc_cal(void)
+{
+ void *wcd_mbhc_cal;
+ struct wcd_mbhc_btn_detect_cfg *btn_cfg;
+ u16 *btn_high;
+
+ wcd_mbhc_cal = kzalloc(WCD_MBHC_CAL_SIZE(WCD_MBHC_DEF_BUTTONS,
+ WCD9XXX_MBHC_DEF_RLOADS), GFP_KERNEL);
+ if (!wcd_mbhc_cal)
+ return NULL;
+
+#define S(X, Y) ((WCD_MBHC_CAL_PLUG_TYPE_PTR(wcd_mbhc_cal)->X) = (Y))
+ S(v_hs_max, 1600);
+#undef S
+#define S(X, Y) ((WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal)->X) = (Y))
+ S(num_btn, WCD_MBHC_DEF_BUTTONS);
+#undef S
+
+ btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(wcd_mbhc_cal);
+ btn_high = ((void *)&btn_cfg->_v_btn_low) +
+ (sizeof(btn_cfg->_v_btn_low[0]) * btn_cfg->num_btn);
+
+ btn_high[0] = 75;
+ btn_high[1] = 150;
+ btn_high[2] = 237;
+ btn_high[3] = 500;
+ btn_high[4] = 500;
+ btn_high[5] = 500;
+ btn_high[6] = 500;
+ btn_high[7] = 500;
+
+ return wcd_mbhc_cal;
+}
+
+static int msm_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 *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+ int ret = 0;
+ u32 rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+ u32 user_set_tx_ch = 0;
+ u32 rx_ch_count;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_5_RX) {
+ pr_debug("%s: rx_5_ch=%d\n", __func__,
+ slim_rx_cfg[5].channels);
+ rx_ch_count = slim_rx_cfg[5].channels;
+ } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_2_RX) {
+ pr_debug("%s: rx_2_ch=%d\n", __func__,
+ slim_rx_cfg[2].channels);
+ rx_ch_count = slim_rx_cfg[2].channels;
+ } else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_6_RX) {
+ pr_debug("%s: rx_6_ch=%d\n", __func__,
+ slim_rx_cfg[6].channels);
+ rx_ch_count = slim_rx_cfg[6].channels;
+ } else {
+ pr_debug("%s: rx_0_ch=%d\n", __func__,
+ slim_rx_cfg[0].channels);
+ rx_ch_count = slim_rx_cfg[0].channels;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ rx_ch_count, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ } else {
+
+ pr_debug("%s: %s_tx_dai_id_%d_ch=%d\n", __func__,
+ codec_dai->name, codec_dai->id, user_set_tx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get tx codec chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ /* For <codec>_tx1 case */
+ if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_0_TX)
+ user_set_tx_ch = slim_tx_cfg[0].channels;
+ /* For <codec>_tx3 case */
+ else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_1_TX)
+ user_set_tx_ch = slim_tx_cfg[1].channels;
+ else if (dai_link->id == MSM_BACKEND_DAI_SLIMBUS_4_TX)
+ user_set_tx_ch = msm_vi_feed_tx_ch;
+ else
+ user_set_tx_ch = tx_ch_cnt;
+
+ pr_debug("%s: msm_slim_0_tx_ch(%d) user_set_tx_ch(%d) tx_ch_cnt(%d), BE id (%d)\n",
+ __func__, slim_tx_cfg[0].channels, user_set_tx_ch,
+ tx_ch_cnt, dai_link->id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ user_set_tx_ch, tx_ch, 0, 0);
+ if (ret < 0)
+ pr_err("%s: failed to set tx cpu chan map, err:%d\n",
+ __func__, ret);
+ }
+
+err:
+ return ret;
+}
+
+static int msm_slimbus_2_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 *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ unsigned int rx_ch[SLIM_MAX_RX_PORTS], tx_ch[SLIM_MAX_TX_PORTS];
+ unsigned int rx_ch_cnt = 0, tx_ch_cnt = 0;
+ unsigned int num_tx_ch = 0;
+ unsigned int num_rx_ch = 0;
+ int ret = 0;
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ num_rx_ch = params_channels(params);
+ pr_debug("%s: %s rx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_rx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ num_rx_ch, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ } else {
+ num_tx_ch = params_channels(params);
+ pr_debug("%s: %s tx_dai_id = %d num_ch = %d\n", __func__,
+ codec_dai->name, codec_dai->id, num_tx_ch);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret < 0) {
+ pr_err("%s: failed to get tx codec chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ num_tx_ch, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set tx cpu chan map, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+
+err:
+ return ret;
+}
+
+static int msm_wcn_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 *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX];
+ u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+ int ret;
+
+ dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
+ codec_dai->name, codec_dai->id);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+ if (ret) {
+ dev_err(rtd->dev,
+ "%s: failed to get BTFM codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto err;
+ }
+
+ dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n",
+ __func__, tx_ch_cnt, dai_link->id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
+ if (ret)
+ dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+
+err:
+ return ret;
+}
+
+static int msm_get_port_id(int be_id)
+{
+ int afe_port_id;
+
+ switch (be_id) {
+ case MSM_BACKEND_DAI_PRI_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_PRI_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_PRIMARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_SECONDARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_SECONDARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_TERTIARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_TERTIARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_QUATERNARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_QUATERNARY_MI2S_TX;
+ break;
+ case MSM_BACKEND_DAI_QUINARY_MI2S_RX:
+ afe_port_id = AFE_PORT_ID_QUINARY_MI2S_RX;
+ break;
+ case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
+ afe_port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
+ break;
+ default:
+ pr_err("%s: Invalid BE id: %d\n", __func__, be_id);
+ afe_port_id = -EINVAL;
+ }
+
+ return afe_port_id;
+}
+
+static u32 get_mi2s_bits_per_sample(u32 bit_format)
+{
+ u32 bit_per_sample;
+
+ switch (bit_format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ case SNDRV_PCM_FORMAT_S24_3LE:
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bit_per_sample = 32;
+ break;
+ case SNDRV_PCM_FORMAT_S16_LE:
+ default:
+ bit_per_sample = 16;
+ break;
+ }
+
+ return bit_per_sample;
+}
+
+static void update_mi2s_clk_val(int dai_id, int stream)
+{
+ u32 bit_per_sample;
+
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ bit_per_sample =
+ get_mi2s_bits_per_sample(mi2s_rx_cfg[dai_id].bit_format);
+ mi2s_clk[dai_id].clk_freq_in_hz =
+ mi2s_rx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
+ } else {
+ bit_per_sample =
+ get_mi2s_bits_per_sample(mi2s_tx_cfg[dai_id].bit_format);
+ mi2s_clk[dai_id].clk_freq_in_hz =
+ mi2s_tx_cfg[dai_id].sample_rate * 2 * bit_per_sample;
+ }
+}
+
+static int msm_mi2s_set_sclk(struct snd_pcm_substream *substream, bool enable)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int port_id = 0;
+ int index = cpu_dai->id;
+
+ port_id = msm_get_port_id(rtd->dai_link->id);
+ if (port_id < 0) {
+ dev_err(rtd->card->dev, "%s: Invalid port_id\n", __func__);
+ ret = port_id;
+ goto err;
+ }
+
+ if (enable) {
+ update_mi2s_clk_val(index, substream->stream);
+ dev_dbg(rtd->card->dev, "%s: clock rate %ul\n", __func__,
+ mi2s_clk[index].clk_freq_in_hz);
+ }
+
+ mi2s_clk[index].enable = enable;
+ ret = afe_set_lpass_clock_v2(port_id,
+ &mi2s_clk[index]);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "%s: afe lpass clock failed for port 0x%x , err:%d\n",
+ __func__, port_id, ret);
+ goto err;
+ }
+
+err:
+ return ret;
+}
+
+static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info,
+ enum pinctrl_pin_state new_state)
+{
+ int ret = 0;
+ int curr_state = 0;
+
+ if (pinctrl_info == NULL) {
+ pr_err("%s: pinctrl_info is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ if (pinctrl_info->pinctrl == NULL) {
+ pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ curr_state = pinctrl_info->curr_state;
+ pinctrl_info->curr_state = new_state;
+ pr_debug("%s: curr_state = %s new_state = %s\n", __func__,
+ pin_states[curr_state], pin_states[pinctrl_info->curr_state]);
+
+ if (curr_state == pinctrl_info->curr_state) {
+ pr_debug("%s: Already in same state\n", __func__);
+ goto err;
+ }
+
+ if (curr_state != STATE_DISABLE &&
+ pinctrl_info->curr_state != STATE_DISABLE) {
+ pr_debug("%s: state already active cannot switch\n", __func__);
+ ret = -EIO;
+ goto err;
+ }
+
+ switch (pinctrl_info->curr_state) {
+ case STATE_MI2S_ACTIVE:
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_active);
+ if (ret) {
+ pr_err("%s: MI2S state select failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ case STATE_TDM_ACTIVE:
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->tdm_active);
+ if (ret) {
+ pr_err("%s: TDM state select failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ case STATE_DISABLE:
+ if (curr_state == STATE_MI2S_ACTIVE) {
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_disable);
+ } else {
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->tdm_disable);
+ }
+ if (ret) {
+ pr_err("%s: state disable failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ break;
+ default:
+ pr_err("%s: TLMM pin state is invalid\n", __func__);
+ return -EINVAL;
+ }
+
+err:
+ return ret;
+}
+
+static void msm_release_pinctrl(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ if (pinctrl_info->pinctrl) {
+ devm_pinctrl_put(pinctrl_info->pinctrl);
+ pinctrl_info->pinctrl = NULL;
+ }
+}
+
+static int msm_get_pinctrl(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = NULL;
+ struct pinctrl *pinctrl;
+ int ret;
+
+ pinctrl_info = &pdata->pinctrl_info;
+
+ if (pinctrl_info == NULL) {
+ pr_err("%s: pinctrl_info is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (IS_ERR_OR_NULL(pinctrl)) {
+ pr_err("%s: Unable to get pinctrl handle\n", __func__);
+ return -EINVAL;
+ }
+ pinctrl_info->pinctrl = pinctrl;
+
+ /* get all the states handles from Device Tree */
+ pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl,
+ "quat-mi2s-sleep");
+ if (IS_ERR(pinctrl_info->mi2s_disable)) {
+ pr_err("%s: could not get mi2s_disable pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl,
+ "quat-mi2s-active");
+ if (IS_ERR(pinctrl_info->mi2s_active)) {
+ pr_err("%s: could not get mi2s_active pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl,
+ "quat-tdm-sleep");
+ if (IS_ERR(pinctrl_info->tdm_disable)) {
+ pr_err("%s: could not get tdm_disable pinstate\n", __func__);
+ goto err;
+ }
+ pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl,
+ "quat-tdm-active");
+ if (IS_ERR(pinctrl_info->tdm_active)) {
+ pr_err("%s: could not get tdm_active pinstate\n",
+ __func__);
+ goto err;
+ }
+ /* Reset the TLMM pins to a default state */
+ ret = pinctrl_select_state(pinctrl_info->pinctrl,
+ pinctrl_info->mi2s_disable);
+ if (ret != 0) {
+ pr_err("%s: Disable TLMM pins failed with %d\n",
+ __func__, ret);
+ ret = -EIO;
+ goto err;
+ }
+ pinctrl_info->curr_state = STATE_DISABLE;
+
+ return 0;
+
+err:
+ devm_pinctrl_put(pinctrl);
+ pinctrl_info->pinctrl = NULL;
+ return -EINVAL;
+}
+
+static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ if (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUAT][TDM_0].bit_format);
+ rate->min = rate->max =
+ tdm_rx_cfg[TDM_QUAT][TDM_0].sample_rate;
+ } else if (cpu_dai->id == AFE_PORT_ID_SECONDARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_SEC][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_SEC][TDM_0].sample_rate;
+ } else if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX) {
+ channels->min = channels->max =
+ tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ tdm_rx_cfg[TDM_QUIN][TDM_0].bit_format);
+ rate->min = rate->max = tdm_rx_cfg[TDM_QUIN][TDM_0].sample_rate;
+ } else {
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ pr_debug("%s: dai id = 0x%x channels = %d rate = %d format = 0x%x\n",
+ __func__, cpu_dai->id, channels->max, rate->max,
+ params_format(params));
+
+ return 0;
+}
+
+static int sdm855_tdm_snd_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int ret = 0;
+ int slot_width = 32;
+ int channels, slots;
+ unsigned int slot_mask, rate, clk_freq;
+ unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
+
+ pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
+
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ switch (cpu_dai->id) {
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_QUINARY_TDM_RX:
+ slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
+ break;
+ case AFE_PORT_ID_QUINARY_TDM_TX:
+ slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
+ break;
+
+ default:
+ pr_err("%s: dai id 0x%x not supported\n",
+ __func__, cpu_dai->id);
+ return -EINVAL;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ /*2 slot config - bits 0 and 1 set for the first two slots */
+ slot_mask = 0x0000FFFF >> (16-slots);
+ channels = slots;
+
+ pr_debug("%s: tdm rx slot_width %d slots %d\n",
+ __func__, slot_width, slots);
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm rx slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ 0, NULL, channels, slot_offset);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm rx channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ /*2 slot config - bits 0 and 1 set for the first two slots */
+ slot_mask = 0x0000FFFF >> (16-slots);
+ channels = slots;
+
+ pr_debug("%s: tdm tx slot_width %d slots %d\n",
+ __func__, slot_width, slots);
+
+ ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm tx slot, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ channels, slot_offset, 0, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm tx channel map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ } else {
+ ret = -EINVAL;
+ pr_err("%s: invalid use case, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ rate = params_rate(params);
+ clk_freq = rate * slot_width * slots;
+ ret = snd_soc_dai_set_sysclk(cpu_dai, 0, clk_freq, SND_SOC_CLOCK_OUT);
+ if (ret < 0)
+ pr_err("%s: failed to set tdm clk, err:%d\n",
+ __func__, ret);
+
+end:
+ return ret;
+}
+
+static int sdm855_tdm_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
+ (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
+ if (ret)
+ pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ }
+
+ return ret;
+}
+
+static void sdm855_tdm_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+
+ /* currently only supporting TDM_RX_0 and TDM_TX_0 */
+ if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
+ (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
+ ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+ if (ret)
+ pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
+ __func__, ret);
+ }
+}
+
+static struct snd_soc_ops sdm855_tdm_be_ops = {
+ .hw_params = sdm855_tdm_snd_hw_params,
+ .startup = sdm855_tdm_snd_startup,
+ .shutdown = sdm855_tdm_snd_shutdown
+};
+
+static int msm_fe_qos_prepare(struct snd_pcm_substream *substream)
+{
+ cpumask_t mask;
+
+ if (pm_qos_request_active(&substream->latency_pm_qos_req))
+ pm_qos_remove_request(&substream->latency_pm_qos_req);
+
+ cpumask_clear(&mask);
+ cpumask_set_cpu(1, &mask); /* affine to core 1 */
+ cpumask_set_cpu(2, &mask); /* affine to core 2 */
+ cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask);
+
+ substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;
+
+ pm_qos_add_request(&substream->latency_pm_qos_req,
+ PM_QOS_CPU_DMA_LATENCY,
+ MSM_LL_QOS_VALUE);
+ return 0;
+}
+
+static struct snd_soc_ops msm_fe_qos_ops = {
+ .prepare = msm_fe_qos_prepare,
+};
+
+static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ int index = cpu_dai->id;
+ unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+ int ret_pinctrl = 0;
+
+ dev_dbg(rtd->card->dev,
+ "%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
+ __func__, substream->name, substream->stream,
+ cpu_dai->name, cpu_dai->id);
+
+ if (index < PRIM_MI2S || index >= MI2S_MAX) {
+ ret = -EINVAL;
+ dev_err(rtd->card->dev,
+ "%s: CPU DAI id (%d) out of range\n",
+ __func__, cpu_dai->id);
+ goto err;
+ }
+ /*
+ * Mutex protection in case the same MI2S
+ * interface using for both TX and RX so
+ * that the same clock won't be enable twice.
+ */
+ mutex_lock(&mi2s_intf_conf[index].lock);
+ if (++mi2s_intf_conf[index].ref_cnt == 1) {
+ /* Check if msm needs to provide the clock to the interface */
+ if (!mi2s_intf_conf[index].msm_is_mi2s_master) {
+ mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
+ fmt = SND_SOC_DAIFMT_CBM_CFM;
+ }
+ ret = msm_mi2s_set_sclk(substream, true);
+ if (ret < 0) {
+ dev_err(rtd->card->dev,
+ "%s: afe lpass clock failed to enable MI2S clock, err:%d\n",
+ __func__, ret);
+ goto clean_up;
+ }
+
+ ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
+ if (ret < 0) {
+ pr_err("%s: set fmt cpu dai failed for MI2S (%d), err:%d\n",
+ __func__, index, ret);
+ goto clk_off;
+ }
+ if (index == QUAT_MI2S) {
+ ret_pinctrl = msm_set_pinctrl(pinctrl_info,
+ STATE_MI2S_ACTIVE);
+ if (ret_pinctrl)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret_pinctrl);
+ }
+ }
+clk_off:
+ if (ret < 0)
+ msm_mi2s_set_sclk(substream, false);
+clean_up:
+ if (ret < 0)
+ mi2s_intf_conf[index].ref_cnt--;
+ mutex_unlock(&mi2s_intf_conf[index].lock);
+err:
+ return ret;
+}
+
+static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
+{
+ int ret;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int index = rtd->cpu_dai->id;
+ struct snd_soc_card *card = rtd->card;
+ struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+ struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
+ int ret_pinctrl = 0;
+
+ pr_debug("%s(): substream = %s stream = %d\n", __func__,
+ substream->name, substream->stream);
+ if (index < PRIM_MI2S || index >= MI2S_MAX) {
+ pr_err("%s:invalid MI2S DAI(%d)\n", __func__, index);
+ return;
+ }
+
+ mutex_lock(&mi2s_intf_conf[index].lock);
+ if (--mi2s_intf_conf[index].ref_cnt == 0) {
+ ret = msm_mi2s_set_sclk(substream, false);
+ if (ret < 0)
+ pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
+ __func__, index, ret);
+ if (index == QUAT_MI2S) {
+ ret_pinctrl = msm_set_pinctrl(pinctrl_info,
+ STATE_DISABLE);
+ if (ret_pinctrl)
+ pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
+ __func__, ret_pinctrl);
+ }
+ }
+ mutex_unlock(&mi2s_intf_conf[index].lock);
+}
+
+static struct snd_soc_ops msm_mi2s_be_ops = {
+ .startup = msm_mi2s_snd_startup,
+ .shutdown = msm_mi2s_snd_shutdown,
+};
+
+static struct snd_soc_ops msm_be_ops = {
+ .hw_params = msm_snd_hw_params,
+};
+
+static struct snd_soc_ops msm_slimbus_2_be_ops = {
+ .hw_params = msm_slimbus_2_hw_params,
+};
+
+static struct snd_soc_ops msm_wcn_ops = {
+ .hw_params = msm_wcn_hw_params,
+};
+
+
+/* Digital audio interface glue - connects codec <---> CPU */
+static struct snd_soc_dai_link msm_common_dai_links[] = {
+ /* FrontEnd DAI Links */
+ {
+ .name = MSM_DAILINK_NAME(Media1),
+ .stream_name = "MultiMedia1",
+ .cpu_dai_name = "MultiMedia1",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA1
+ },
+ {
+ .name = MSM_DAILINK_NAME(Media2),
+ .stream_name = "MultiMedia2",
+ .cpu_dai_name = "MultiMedia2",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA2,
+ },
+ {
+ .name = "VoiceMMode1",
+ .stream_name = "VoiceMMode1",
+ .cpu_dai_name = "VoiceMMode1",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_VOICEMMODE1,
+ },
+ {
+ .name = "MSM VoIP",
+ .stream_name = "VoIP",
+ .cpu_dai_name = "VoIP",
+ .platform_name = "msm-voip-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_VOIP,
+ },
+ {
+ .name = MSM_DAILINK_NAME(ULL),
+ .stream_name = "MultiMedia3",
+ .cpu_dai_name = "MultiMedia3",
+ .platform_name = "msm-pcm-dsp.2",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA3,
+ },
+ /* Hostless PCM purpose */
+ {
+ .name = "SLIMBUS_0 Hostless",
+ .stream_name = "SLIMBUS_0 Hostless",
+ .cpu_dai_name = "SLIMBUS0_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "MSM AFE-PCM RX",
+ .stream_name = "AFE-PROXY RX",
+ .cpu_dai_name = "msm-dai-q6-dev.241",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .platform_name = "msm-pcm-afe",
+ .dpcm_playback = 1,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = "MSM AFE-PCM TX",
+ .stream_name = "AFE-PROXY TX",
+ .cpu_dai_name = "msm-dai-q6-dev.240",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .platform_name = "msm-pcm-afe",
+ .dpcm_capture = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Compress1),
+ .stream_name = "Compress1",
+ .cpu_dai_name = "MultiMedia4",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_HW_PARAMS,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA4,
+ },
+ {
+ .name = "AUXPCM Hostless",
+ .stream_name = "AUXPCM Hostless",
+ .cpu_dai_name = "AUXPCM_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "SLIMBUS_1 Hostless",
+ .stream_name = "SLIMBUS_1 Hostless",
+ .cpu_dai_name = "SLIMBUS1_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "SLIMBUS_3 Hostless",
+ .stream_name = "SLIMBUS_3 Hostless",
+ .cpu_dai_name = "SLIMBUS3_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "SLIMBUS_4 Hostless",
+ .stream_name = "SLIMBUS_4 Hostless",
+ .cpu_dai_name = "SLIMBUS4_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = MSM_DAILINK_NAME(LowLatency),
+ .stream_name = "MultiMedia5",
+ .cpu_dai_name = "MultiMedia5",
+ .platform_name = "msm-pcm-dsp.1",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA5,
+ .ops = &msm_fe_qos_ops,
+ },
+ {
+ .name = "Listen 1 Audio Service",
+ .stream_name = "Listen 1 Audio Service",
+ .cpu_dai_name = "LSM1",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM1,
+ },
+ /* Multiple Tunnel instances */
+ {
+ .name = MSM_DAILINK_NAME(Compress2),
+ .stream_name = "Compress2",
+ .cpu_dai_name = "MultiMedia7",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA7,
+ },
+ {
+ .name = MSM_DAILINK_NAME(MultiMedia10),
+ .stream_name = "MultiMedia10",
+ .cpu_dai_name = "MultiMedia10",
+ .platform_name = "msm-pcm-dsp.1",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA10,
+ },
+ {
+ .name = MSM_DAILINK_NAME(ULL_NOIRQ),
+ .stream_name = "MM_NOIRQ",
+ .cpu_dai_name = "MultiMedia8",
+ .platform_name = "msm-pcm-dsp-noirq",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA8,
+ .ops = &msm_fe_qos_ops,
+ },
+ /* HDMI Hostless */
+ {
+ .name = "HDMI_RX_HOSTLESS",
+ .stream_name = "HDMI_RX_HOSTLESS",
+ .cpu_dai_name = "HDMI_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ {
+ .name = "VoiceMMode2",
+ .stream_name = "VoiceMMode2",
+ .cpu_dai_name = "VoiceMMode2",
+ .platform_name = "msm-pcm-voice",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_VOICEMMODE2,
+ },
+ /* LSM FE */
+ {
+ .name = "Listen 2 Audio Service",
+ .stream_name = "Listen 2 Audio Service",
+ .cpu_dai_name = "LSM2",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM2,
+ },
+ {
+ .name = "Listen 3 Audio Service",
+ .stream_name = "Listen 3 Audio Service",
+ .cpu_dai_name = "LSM3",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM3,
+ },
+ {
+ .name = "Listen 4 Audio Service",
+ .stream_name = "Listen 4 Audio Service",
+ .cpu_dai_name = "LSM4",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM4,
+ },
+ {
+ .name = "Listen 5 Audio Service",
+ .stream_name = "Listen 5 Audio Service",
+ .cpu_dai_name = "LSM5",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM5,
+ },
+ {
+ .name = "Listen 6 Audio Service",
+ .stream_name = "Listen 6 Audio Service",
+ .cpu_dai_name = "LSM6",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM6,
+ },
+ {
+ .name = "Listen 7 Audio Service",
+ .stream_name = "Listen 7 Audio Service",
+ .cpu_dai_name = "LSM7",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM7,
+ },
+ {
+ .name = "Listen 8 Audio Service",
+ .stream_name = "Listen 8 Audio Service",
+ .cpu_dai_name = "LSM8",
+ .platform_name = "msm-lsm-client",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = { SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST },
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .id = MSM_FRONTEND_DAI_LSM8,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Media9),
+ .stream_name = "MultiMedia9",
+ .cpu_dai_name = "MultiMedia9",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA9,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Compress4),
+ .stream_name = "Compress4",
+ .cpu_dai_name = "MultiMedia11",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA11,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Compress5),
+ .stream_name = "Compress5",
+ .cpu_dai_name = "MultiMedia12",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA12,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Compress6),
+ .stream_name = "Compress6",
+ .cpu_dai_name = "MultiMedia13",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA13,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Compress7),
+ .stream_name = "Compress7",
+ .cpu_dai_name = "MultiMedia14",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA14,
+ },
+ {
+ .name = MSM_DAILINK_NAME(Compress8),
+ .stream_name = "Compress8",
+ .cpu_dai_name = "MultiMedia15",
+ .platform_name = "msm-compress-dsp",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA15,
+ },
+ {
+ .name = MSM_DAILINK_NAME(ULL_NOIRQ_2),
+ .stream_name = "MM_NOIRQ_2",
+ .cpu_dai_name = "MultiMedia16",
+ .platform_name = "msm-pcm-dsp-noirq",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ /* this dainlink has playback support */
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA16,
+ },
+ {
+ .name = "SLIMBUS_8 Hostless",
+ .stream_name = "SLIMBUS8_HOSTLESS Capture",
+ .cpu_dai_name = "SLIMBUS8_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+};
+
+static struct snd_soc_dai_link msm_pahu_fe_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_4_TX,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_vifeedback",
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
+ /* Ultrasound RX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx2",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
+ /* Ultrasound TX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16389",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_tx2",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
+};
+
+static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_4_TX,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_vifeedback",
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
+ /* Ultrasound RX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx2",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
+ /* Ultrasound TX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16389",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx2",
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
+};
+
+static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
+ {
+ .name = MSM_DAILINK_NAME(ASM Loopback),
+ .stream_name = "MultiMedia6",
+ .cpu_dai_name = "MultiMedia6",
+ .platform_name = "msm-pcm-loopback",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .ignore_suspend = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA6,
+ },
+ {
+ .name = "USB Audio Hostless",
+ .stream_name = "USB Audio Hostless",
+ .cpu_dai_name = "USBAUDIO_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+};
+
+static struct snd_soc_dai_link msm_common_be_dai_links[] = {
+ /* Backend AFE DAI Links */
+ {
+ .name = LPASS_BE_AFE_PCM_RX,
+ .stream_name = "AFE Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.224",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_AFE_PCM_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_AFE_PCM_TX,
+ .stream_name = "AFE Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.225",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_AFE_PCM_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Uplink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_TX,
+ .stream_name = "Voice Uplink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32772",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_INCALL_RECORD_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Record Downlink BACK END DAI Link */
+ {
+ .name = LPASS_BE_INCALL_RECORD_RX,
+ .stream_name = "Voice Downlink Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.32771",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_INCALL_RECORD_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Incall Music BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE_PLAYBACK_TX,
+ .stream_name = "Voice Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32773",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ /* Incall Music 2 BACK END DAI Link */
+ {
+ .name = LPASS_BE_VOICE2_PLAYBACK_TX,
+ .stream_name = "Voice2 Farend Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.32770",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_VOICE2_PLAYBACK_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_USB_AUDIO_RX,
+ .stream_name = "USB Audio Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.28672",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_USB_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_USB_AUDIO_TX,
+ .stream_name = "USB Audio Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.28673",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_USB_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_RX_0,
+ .stream_name = "Primary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36864",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_TDM_TX_0,
+ .stream_name = "Primary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36865",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_RX_0,
+ .stream_name = "Secondary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36880",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_TDM_TX_0,
+ .stream_name = "Secondary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36881",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_RX_0,
+ .stream_name = "Tertiary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36896",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_TDM_TX_0,
+ .stream_name = "Tertiary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36897",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_RX_0,
+ .stream_name = "Quaternary TDM0 Playback",
+ .cpu_dai_name = "msm-dai-q6-tdm.36912",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_QUAT_TDM_RX_0,
+ .be_hw_params_fixup = msm_tdm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_TDM_TX_0,
+ .stream_name = "Quaternary TDM0 Capture",
+ .cpu_dai_name = "msm-dai-q6-tdm.36913",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_QUAT_TDM_TX_0,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &sdm855_tdm_be_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_pahu_be_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_init,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_RX,
+ .stream_name = "Slimbus1 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16386",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_TX,
+ .stream_name = "Slimbus1 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16387",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_tx3",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_2_RX,
+ .stream_name = "Slimbus2 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx2",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_RX,
+ .stream_name = "Slimbus3 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16390",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_TX,
+ .stream_name = "Slimbus3 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16391",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_4_RX,
+ .stream_name = "Slimbus4 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16392",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_5_RX,
+ .stream_name = "Slimbus5 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16394",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx3",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* MAD BE */
+ {
+ .name = LPASS_BE_SLIMBUS_5_TX,
+ .stream_name = "Slimbus5 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16395",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_mad1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_6_RX,
+ .stream_name = "Slimbus6 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16396",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_rx4",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* Slimbus VI Recording */
+ {
+ .name = LPASS_BE_SLIMBUS_TX_VI,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "pahu_codec",
+ .codec_dai_name = "pahu_vifeedback",
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_tavil_be_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_init,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_RX,
+ .stream_name = "Slimbus1 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16386",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_TX,
+ .stream_name = "Slimbus1 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16387",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx3",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_2_RX,
+ .stream_name = "Slimbus2 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx2",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_RX,
+ .stream_name = "Slimbus3 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16390",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_TX,
+ .stream_name = "Slimbus3 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16391",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_4_RX,
+ .stream_name = "Slimbus4 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16392",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_5_RX,
+ .stream_name = "Slimbus5 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16394",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx3",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* MAD BE */
+ {
+ .name = LPASS_BE_SLIMBUS_5_TX,
+ .stream_name = "Slimbus5 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16395",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_mad1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_6_RX,
+ .stream_name = "Slimbus6 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16396",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_rx4",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* Slimbus VI Recording */
+ {
+ .name = LPASS_BE_SLIMBUS_TX_VI,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tavil_codec",
+ .codec_dai_name = "tavil_vifeedback",
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
+ {
+ .name = LPASS_BE_SLIMBUS_7_RX,
+ .stream_name = "Slimbus7 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16398",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ /* BT codec driver determines capabilities based on
+ * dai name, bt codecdai name should always contains
+ * supported usecase information
+ */
+ .codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_wcn_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_7_TX,
+ .stream_name = "Slimbus7 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16399",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_bt_sco_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_wcn_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_8_TX,
+ .stream_name = "Slimbus8 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16401",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "btfmslim_slave",
+ .codec_dai_name = "btfm_fm_slim_tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .init = &msm_wcn_init,
+ .ops = &msm_wcn_ops,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
+ /* DISP PORT BACK END DAI Link */
+ {
+ .name = LPASS_BE_DISPLAY_PORT,
+ .stream_name = "Display Port Playback",
+ .cpu_dai_name = "msm-dai-q6-dp.24608",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-ext-disp-audio-codec-rx",
+ .codec_dai_name = "msm_dp_audio_codec_rx_dai",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_DISPLAY_PORT_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
+ {
+ .name = LPASS_BE_PRI_MI2S_RX,
+ .stream_name = "Primary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.0",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_PRI_MI2S_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_PRI_MI2S_TX,
+ .stream_name = "Primary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.0",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_PRI_MI2S_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_RX,
+ .stream_name = "Secondary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SECONDARY_MI2S_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_MI2S_TX,
+ .stream_name = "Secondary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_RX,
+ .stream_name = "Tertiary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_TERTIARY_MI2S_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_MI2S_TX,
+ .stream_name = "Tertiary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_RX,
+ .stream_name = "Quaternary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_MI2S_TX,
+ .stream_name = "Quaternary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUIN_MI2S_RX,
+ .stream_name = "Quinary MI2S Playback",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_QUINARY_MI2S_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ },
+ {
+ .name = LPASS_BE_QUIN_MI2S_TX,
+ .stream_name = "Quinary MI2S Capture",
+ .cpu_dai_name = "msm-dai-q6-mi2s.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_QUINARY_MI2S_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_mi2s_be_ops,
+ .ignore_suspend = 1,
+ },
+
+};
+
+static struct snd_soc_dai_link msm_auxpcm_be_dai_links[] = {
+ /* Primary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_AUXPCM_RX,
+ .stream_name = "AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_AUXPCM_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_AUXPCM_TX,
+ .stream_name = "AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.1",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_AUXPCM_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Secondary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_SEC_AUXPCM_RX,
+ .stream_name = "Sec AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SEC_AUXPCM_TX,
+ .stream_name = "Sec AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.2",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Tertiary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_TERT_AUXPCM_RX,
+ .stream_name = "Tert AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_TERT_AUXPCM_TX,
+ .stream_name = "Tert AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.3",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Quaternary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_QUAT_AUXPCM_RX,
+ .stream_name = "Quat AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUAT_AUXPCM_TX,
+ .stream_name = "Quat AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.4",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+ /* Quinary AUX PCM Backend DAI Links */
+ {
+ .name = LPASS_BE_QUIN_AUXPCM_RX,
+ .stream_name = "Quin AUX PCM Playback",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.5",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_QUIN_AUXPCM_TX,
+ .stream_name = "Quin AUX PCM Capture",
+ .cpu_dai_name = "msm-dai-q6-auxpcm.5",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ },
+};
+
+static struct snd_soc_dai_link msm_pahu_snd_card_dai_links[
+ ARRAY_SIZE(msm_common_dai_links) +
+ ARRAY_SIZE(msm_pahu_fe_dai_links) +
+ ARRAY_SIZE(msm_common_misc_fe_dai_links) +
+ ARRAY_SIZE(msm_common_be_dai_links) +
+ ARRAY_SIZE(msm_pahu_be_dai_links) +
+ ARRAY_SIZE(msm_wcn_be_dai_links) +
+ ARRAY_SIZE(ext_disp_be_dai_link) +
+ ARRAY_SIZE(msm_mi2s_be_dai_links) +
+ ARRAY_SIZE(msm_auxpcm_be_dai_links)];
+
+static struct snd_soc_dai_link msm_tavil_dai_links[
+ ARRAY_SIZE(msm_common_dai_links) +
+ ARRAY_SIZE(msm_tavil_fe_dai_links) +
+ ARRAY_SIZE(msm_common_misc_fe_dai_links) +
+ ARRAY_SIZE(msm_common_be_dai_links) +
+ ARRAY_SIZE(msm_tavil_be_dai_links) +
+ ARRAY_SIZE(msm_wcn_be_dai_links) +
+ ARRAY_SIZE(ext_disp_be_dai_link) +
+ ARRAY_SIZE(msm_mi2s_be_dai_links) +
+ ARRAY_SIZE(msm_auxpcm_be_dai_links)];
+
+static int msm_snd_card_tavil_late_probe(struct snd_soc_card *card)
+{
+ const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
+ struct snd_soc_pcm_runtime *rtd;
+ int ret = 0;
+ void *mbhc_calibration;
+
+ rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
+ if (!rtd) {
+ dev_err(card->dev,
+ "%s: snd_soc_get_pcm_runtime for %s failed!\n",
+ __func__, be_dl_name);
+ ret = -EINVAL;
+ goto err_pcm_runtime;
+ }
+
+ mbhc_calibration = def_wcd_mbhc_cal();
+ if (!mbhc_calibration) {
+ ret = -ENOMEM;
+ goto err_mbhc_cal;
+ }
+ wcd_mbhc_cfg.calibration = mbhc_calibration;
+ ret = tavil_mbhc_hs_detect(rtd->codec, &wcd_mbhc_cfg);
+ if (ret) {
+ dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
+ __func__, ret);
+ goto err_hs_detect;
+ }
+ return 0;
+
+err_hs_detect:
+ kfree(mbhc_calibration);
+err_mbhc_cal:
+err_pcm_runtime:
+ return ret;
+}
+
+struct snd_soc_card snd_soc_card_pahu_msm = {
+ .name = "sdm855-pahu-snd-card",
+};
+
+struct snd_soc_card snd_soc_card_tavil_msm = {
+ .name = "sdm855-tavil-snd-card",
+ .late_probe = msm_snd_card_tavil_late_probe,
+};
+
+static int msm_populate_dai_link_component_of_node(
+ struct snd_soc_card *card)
+{
+ int i, index, ret = 0;
+ struct device *cdev = card->dev;
+ struct snd_soc_dai_link *dai_link = card->dai_link;
+ struct device_node *np;
+
+ if (!cdev) {
+ pr_err("%s: Sound card device memory NULL\n", __func__);
+ return -ENODEV;
+ }
+
+ for (i = 0; i < card->num_links; i++) {
+ if (dai_link[i].platform_of_node && dai_link[i].cpu_of_node)
+ continue;
+
+ /* populate platform_of_node for snd card dai links */
+ if (dai_link[i].platform_name &&
+ !dai_link[i].platform_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-platform-names",
+ dai_link[i].platform_name);
+ if (index < 0) {
+ pr_err("%s: No match found for platform name: %s\n",
+ __func__, dai_link[i].platform_name);
+ ret = index;
+ goto err;
+ }
+ np = of_parse_phandle(cdev->of_node, "asoc-platform",
+ index);
+ if (!np) {
+ pr_err("%s: retrieving phandle for platform %s, index %d failed\n",
+ __func__, dai_link[i].platform_name,
+ index);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].platform_of_node = np;
+ dai_link[i].platform_name = NULL;
+ }
+
+ /* populate cpu_of_node for snd card dai links */
+ if (dai_link[i].cpu_dai_name && !dai_link[i].cpu_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-cpu-names",
+ dai_link[i].cpu_dai_name);
+ if (index >= 0) {
+ np = of_parse_phandle(cdev->of_node, "asoc-cpu",
+ index);
+ if (!np) {
+ pr_err("%s: retrieving phandle for cpu dai %s failed\n",
+ __func__,
+ dai_link[i].cpu_dai_name);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].cpu_of_node = np;
+ dai_link[i].cpu_dai_name = NULL;
+ }
+ }
+
+ /* populate codec_of_node for snd card dai links */
+ if (dai_link[i].codec_name && !dai_link[i].codec_of_node) {
+ index = of_property_match_string(cdev->of_node,
+ "asoc-codec-names",
+ dai_link[i].codec_name);
+ if (index < 0)
+ continue;
+ np = of_parse_phandle(cdev->of_node, "asoc-codec",
+ index);
+ if (!np) {
+ pr_err("%s: retrieving phandle for codec %s failed\n",
+ __func__, dai_link[i].codec_name);
+ ret = -ENODEV;
+ goto err;
+ }
+ dai_link[i].codec_of_node = np;
+ dai_link[i].codec_name = NULL;
+ }
+ }
+
+err:
+ return ret;
+}
+
+static int msm_audrx_stub_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret = 0;
+ struct snd_soc_codec *codec = rtd->codec;
+
+ ret = snd_soc_add_codec_controls(codec, msm_snd_controls,
+ ARRAY_SIZE(msm_snd_controls));
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "%s: add_codec_controls failed, err = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int msm_snd_stub_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;
+ unsigned int rx_ch[] = {144, 145, 146, 147, 148, 149, 150,
+ 151};
+ unsigned int tx_ch[] = {128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143};
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ ret = snd_soc_dai_set_channel_map(cpu_dai, 0, 0,
+ slim_rx_cfg[SLIM_RX_0].channels,
+ rx_ch);
+ if (ret < 0)
+ pr_err("%s: RX failed to set cpu chan map error %d\n",
+ __func__, ret);
+ } else {
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ slim_tx_cfg[SLIM_TX_0].channels,
+ tx_ch, 0, 0);
+ if (ret < 0)
+ pr_err("%s: TX failed to set cpu chan map error %d\n",
+ __func__, ret);
+ }
+
+ return ret;
+}
+
+static struct snd_soc_ops msm_stub_be_ops = {
+ .hw_params = msm_snd_stub_hw_params,
+};
+
+static struct snd_soc_dai_link msm_stub_fe_dai_links[] = {
+
+ /* FrontEnd DAI Links */
+ {
+ .name = "MSMSTUB Media1",
+ .stream_name = "MultiMedia1",
+ .cpu_dai_name = "MultiMedia1",
+ .platform_name = "msm-pcm-dsp.0",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA1
+ },
+};
+
+static struct snd_soc_dai_link msm_stub_be_dai_links[] = {
+
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-rx",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_stub_init,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_pmdown_time = 1, /* dai link has playback support */
+ .ignore_suspend = 1,
+ .ops = &msm_stub_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "msm-stub-codec.1",
+ .codec_dai_name = "msm-stub-tx",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msm_stub_be_ops,
+ },
+};
+
+static struct snd_soc_dai_link msm_stub_dai_links[
+ ARRAY_SIZE(msm_stub_fe_dai_links) +
+ ARRAY_SIZE(msm_stub_be_dai_links)];
+
+struct snd_soc_card snd_soc_card_stub_msm = {
+ .name = "sdm855-stub-snd-card",
+};
+
+static const struct of_device_id sdm855_asoc_machine_of_match[] = {
+ { .compatible = "qcom,sdm855-asoc-snd-pahu",
+ .data = "pahu_codec"},
+ { .compatible = "qcom,sdm855-asoc-snd-tavil",
+ .data = "tavil_codec"},
+ { .compatible = "qcom,sdm855-asoc-snd-stub",
+ .data = "stub_codec"},
+ {},
+};
+
+static struct snd_soc_card *populate_snd_card_dailinks(struct device *dev)
+{
+ struct snd_soc_card *card = NULL;
+ struct snd_soc_dai_link *dailink;
+ int len_1, len_2, len_3, len_4;
+ int total_links;
+ const struct of_device_id *match;
+
+ match = of_match_node(sdm855_asoc_machine_of_match, dev->of_node);
+ if (!match) {
+ dev_err(dev, "%s: No DT match found for sound card\n",
+ __func__);
+ return NULL;
+ }
+
+ if (!strcmp(match->data, "pahu_codec")) {
+ card = &snd_soc_card_pahu_msm;
+ len_1 = ARRAY_SIZE(msm_common_dai_links);
+ len_2 = len_1 + ARRAY_SIZE(msm_pahu_fe_dai_links);
+ len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links);
+ len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links);
+ total_links = len_4 + ARRAY_SIZE(msm_pahu_be_dai_links);
+ memcpy(msm_pahu_snd_card_dai_links,
+ msm_common_dai_links,
+ sizeof(msm_common_dai_links));
+ memcpy(msm_pahu_snd_card_dai_links + len_1,
+ msm_pahu_fe_dai_links,
+ sizeof(msm_pahu_fe_dai_links));
+ memcpy(msm_pahu_snd_card_dai_links + len_2,
+ msm_common_misc_fe_dai_links,
+ sizeof(msm_common_misc_fe_dai_links));
+ memcpy(msm_pahu_snd_card_dai_links + len_3,
+ msm_common_be_dai_links,
+ sizeof(msm_common_be_dai_links));
+ memcpy(msm_pahu_snd_card_dai_links + len_4,
+ msm_pahu_be_dai_links,
+ sizeof(msm_pahu_be_dai_links));
+
+ if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
+ dev_dbg(dev, "%s(): WCN BTFM support present\n",
+ __func__);
+ memcpy(msm_pahu_snd_card_dai_links + total_links,
+ msm_wcn_be_dai_links,
+ sizeof(msm_wcn_be_dai_links));
+ total_links += ARRAY_SIZE(msm_wcn_be_dai_links);
+ }
+
+ if (of_property_read_bool(dev->of_node,
+ "qcom,ext-disp-audio-rx")) {
+ dev_dbg(dev, "%s(): ext disp audio support present\n",
+ __func__);
+ memcpy(msm_pahu_snd_card_dai_links + total_links,
+ ext_disp_be_dai_link,
+ sizeof(ext_disp_be_dai_link));
+ total_links += ARRAY_SIZE(ext_disp_be_dai_link);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,mi2s-audio-intf")) {
+ memcpy(msm_pahu_snd_card_dai_links + total_links,
+ msm_mi2s_be_dai_links,
+ sizeof(msm_mi2s_be_dai_links));
+ total_links += ARRAY_SIZE(msm_mi2s_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,auxpcm-audio-intf")) {
+ memcpy(msm_pahu_snd_card_dai_links + total_links,
+ msm_auxpcm_be_dai_links,
+ sizeof(msm_auxpcm_be_dai_links));
+ total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links);
+ }
+
+ dailink = msm_pahu_snd_card_dai_links;
+ } else if (!strcmp(match->data, "tavil_codec")) {
+ card = &snd_soc_card_tavil_msm;
+ len_1 = ARRAY_SIZE(msm_common_dai_links);
+ len_2 = len_1 + ARRAY_SIZE(msm_tavil_fe_dai_links);
+ len_3 = len_2 + ARRAY_SIZE(msm_common_misc_fe_dai_links);
+ len_4 = len_3 + ARRAY_SIZE(msm_common_be_dai_links);
+ total_links = len_4 + ARRAY_SIZE(msm_tavil_be_dai_links);
+ memcpy(msm_tavil_dai_links,
+ msm_common_dai_links,
+ sizeof(msm_common_dai_links));
+ memcpy(msm_tavil_dai_links + len_1,
+ msm_tavil_fe_dai_links,
+ sizeof(msm_tavil_fe_dai_links));
+ memcpy(msm_tavil_dai_links + len_2,
+ msm_common_misc_fe_dai_links,
+ sizeof(msm_common_misc_fe_dai_links));
+ memcpy(msm_tavil_dai_links + len_3,
+ msm_common_be_dai_links,
+ sizeof(msm_common_be_dai_links));
+ memcpy(msm_tavil_dai_links + len_4,
+ msm_tavil_be_dai_links,
+ sizeof(msm_tavil_be_dai_links));
+
+ if (of_property_read_bool(dev->of_node, "qcom,wcn-btfm")) {
+ dev_dbg(dev, "%s(): WCN BTFM support present\n",
+ __func__);
+ memcpy(msm_tavil_dai_links + total_links,
+ msm_wcn_be_dai_links,
+ sizeof(msm_wcn_be_dai_links));
+ total_links += ARRAY_SIZE(msm_wcn_be_dai_links);
+ }
+
+ if (of_property_read_bool(dev->of_node,
+ "qcom,ext-disp-audio-rx")) {
+ dev_dbg(dev, "%s(): ext disp audio support present\n",
+ __func__);
+ memcpy(msm_tavil_dai_links + total_links,
+ ext_disp_be_dai_link,
+ sizeof(ext_disp_be_dai_link));
+ total_links += ARRAY_SIZE(ext_disp_be_dai_link);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,mi2s-audio-intf")) {
+ memcpy(msm_tavil_dai_links + total_links,
+ msm_mi2s_be_dai_links,
+ sizeof(msm_mi2s_be_dai_links));
+ total_links += ARRAY_SIZE(msm_mi2s_be_dai_links);
+ }
+ if (of_property_read_bool(dev->of_node,
+ "qcom,auxpcm-audio-intf")) {
+ memcpy(msm_tavil_dai_links + total_links,
+ msm_auxpcm_be_dai_links,
+ sizeof(msm_auxpcm_be_dai_links));
+ total_links += ARRAY_SIZE(msm_auxpcm_be_dai_links);
+ }
+ dailink = msm_tavil_dai_links;
+ } else if (!strcmp(match->data, "stub_codec")) {
+ card = &snd_soc_card_stub_msm;
+ len_1 = ARRAY_SIZE(msm_stub_fe_dai_links);
+ len_2 = len_1 + ARRAY_SIZE(msm_stub_be_dai_links);
+
+ memcpy(msm_stub_dai_links,
+ msm_stub_fe_dai_links,
+ sizeof(msm_stub_fe_dai_links));
+ memcpy(msm_stub_dai_links + len_1,
+ msm_stub_be_dai_links,
+ sizeof(msm_stub_be_dai_links));
+
+ dailink = msm_stub_dai_links;
+ total_links = len_2;
+ }
+
+ if (card) {
+ card->dai_link = dailink;
+ card->num_links = total_links;
+ }
+
+ return card;
+}
+
+static int msm_wsa881x_init(struct snd_soc_component *component)
+{
+ u8 spkleft_ports[WSA881X_MAX_SWR_PORTS] = {100, 101, 102, 106};
+ u8 spkright_ports[WSA881X_MAX_SWR_PORTS] = {103, 104, 105, 107};
+ unsigned int ch_rate[WSA881X_MAX_SWR_PORTS] = {2400, 600, 300, 1200};
+ unsigned int ch_mask[WSA881X_MAX_SWR_PORTS] = {0x1, 0xF, 0x3, 0x3};
+ struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
+ struct msm_asoc_mach_data *pdata;
+ struct snd_soc_dapm_context *dapm;
+ int ret = 0;
+
+ if (!codec) {
+ pr_err("%s codec is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ dapm = snd_soc_codec_get_dapm(codec);
+
+ if (!strcmp(component->name_prefix, "SpkrLeft")) {
+ dev_dbg(codec->dev, "%s: setting left ch map to codec %s\n",
+ __func__, codec->component.name);
+ wsa881x_set_channel_map(codec, &spkleft_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0]);
+ if (dapm->component) {
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft IN");
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrLeft SPKR");
+ }
+ } else if (!strcmp(component->name_prefix, "SpkrRight")) {
+ dev_dbg(codec->dev, "%s: setting right ch map to codec %s\n",
+ __func__, codec->component.name);
+ wsa881x_set_channel_map(codec, &spkright_ports[0],
+ WSA881X_MAX_SWR_PORTS, &ch_mask[0],
+ &ch_rate[0]);
+ if (dapm->component) {
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrRight IN");
+ snd_soc_dapm_ignore_suspend(dapm, "SpkrRight SPKR");
+ }
+ } else {
+ dev_err(codec->dev, "%s: wrong codec name %s\n", __func__,
+ codec->component.name);
+ ret = -EINVAL;
+ goto err;
+ }
+ pdata = snd_soc_card_get_drvdata(component->card);
+ if (pdata && pdata->codec_root)
+ wsa881x_codec_info_create_codec_entry(pdata->codec_root,
+ codec);
+
+err:
+ return ret;
+}
+
+static int msm_init_wsa_dev(struct platform_device *pdev,
+ struct snd_soc_card *card)
+{
+ struct device_node *wsa_of_node;
+ u32 wsa_max_devs;
+ u32 wsa_dev_cnt;
+ int i;
+ struct msm_wsa881x_dev_info *wsa881x_dev_info;
+ const char *wsa_auxdev_name_prefix[1];
+ char *dev_name_str = NULL;
+ int found = 0;
+ int ret = 0;
+
+ /* Get maximum WSA device count for this platform */
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,wsa-max-devs", &wsa_max_devs);
+ if (ret) {
+ dev_info(&pdev->dev,
+ "%s: wsa-max-devs property missing in DT %s, ret = %d\n",
+ __func__, pdev->dev.of_node->full_name, ret);
+ card->num_aux_devs = 0;
+ return 0;
+ }
+ if (wsa_max_devs == 0) {
+ dev_warn(&pdev->dev,
+ "%s: Max WSA devices is 0 for this target?\n",
+ __func__);
+ card->num_aux_devs = 0;
+ return 0;
+ }
+
+ /* Get count of WSA device phandles for this platform */
+ wsa_dev_cnt = of_count_phandle_with_args(pdev->dev.of_node,
+ "qcom,wsa-devs", NULL);
+ if (wsa_dev_cnt == -ENOENT) {
+ dev_warn(&pdev->dev, "%s: No wsa device defined in DT.\n",
+ __func__);
+ goto err;
+ } else if (wsa_dev_cnt <= 0) {
+ dev_err(&pdev->dev,
+ "%s: Error reading wsa device from DT. wsa_dev_cnt = %d\n",
+ __func__, wsa_dev_cnt);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /*
+ * Expect total phandles count to be NOT less than maximum possible
+ * WSA count. However, if it is less, then assign same value to
+ * max count as well.
+ */
+ if (wsa_dev_cnt < wsa_max_devs) {
+ dev_dbg(&pdev->dev,
+ "%s: wsa_max_devs = %d cannot exceed wsa_dev_cnt = %d\n",
+ __func__, wsa_max_devs, wsa_dev_cnt);
+ wsa_max_devs = wsa_dev_cnt;
+ }
+
+ /* Make sure prefix string passed for each WSA device */
+ ret = of_property_count_strings(pdev->dev.of_node,
+ "qcom,wsa-aux-dev-prefix");
+ if (ret != wsa_dev_cnt) {
+ dev_err(&pdev->dev,
+ "%s: expecting %d wsa prefix. Defined only %d in DT\n",
+ __func__, wsa_dev_cnt, ret);
+ ret = -EINVAL;
+ goto err;
+ }
+
+ /*
+ * Alloc mem to store phandle and index info of WSA device, if already
+ * registered with ALSA core
+ */
+ wsa881x_dev_info = devm_kcalloc(&pdev->dev, wsa_max_devs,
+ sizeof(struct msm_wsa881x_dev_info),
+ GFP_KERNEL);
+ if (!wsa881x_dev_info) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ /*
+ * search and check whether all WSA devices are already
+ * registered with ALSA core or not. If found a node, store
+ * the node and the index in a local array of struct for later
+ * use.
+ */
+ for (i = 0; i < wsa_dev_cnt; i++) {
+ wsa_of_node = of_parse_phandle(pdev->dev.of_node,
+ "qcom,wsa-devs", i);
+ if (unlikely(!wsa_of_node)) {
+ /* we should not be here */
+ dev_err(&pdev->dev,
+ "%s: wsa dev node is not present\n",
+ __func__);
+ ret = -EINVAL;
+ goto err_free_dev_info;
+ }
+ if (soc_find_component(wsa_of_node, NULL)) {
+ /* WSA device registered with ALSA core */
+ wsa881x_dev_info[found].of_node = wsa_of_node;
+ wsa881x_dev_info[found].index = i;
+ found++;
+ if (found == wsa_max_devs)
+ break;
+ }
+ }
+
+ if (found < wsa_max_devs) {
+ dev_dbg(&pdev->dev,
+ "%s: failed to find %d components. Found only %d\n",
+ __func__, wsa_max_devs, found);
+ return -EPROBE_DEFER;
+ }
+ dev_info(&pdev->dev,
+ "%s: found %d wsa881x devices registered with ALSA core\n",
+ __func__, found);
+
+ card->num_aux_devs = wsa_max_devs;
+ card->num_configs = wsa_max_devs;
+
+ /* Alloc array of AUX devs struct */
+ msm_aux_dev = devm_kcalloc(&pdev->dev, card->num_aux_devs,
+ sizeof(struct snd_soc_aux_dev),
+ GFP_KERNEL);
+ if (!msm_aux_dev) {
+ ret = -ENOMEM;
+ goto err_free_dev_info;
+ }
+
+ /* Alloc array of codec conf struct */
+ msm_codec_conf = devm_kcalloc(&pdev->dev, card->num_aux_devs,
+ sizeof(struct snd_soc_codec_conf),
+ GFP_KERNEL);
+ if (!msm_codec_conf) {
+ ret = -ENOMEM;
+ goto err_free_aux_dev;
+ }
+
+ for (i = 0; i < card->num_aux_devs; i++) {
+ dev_name_str = devm_kzalloc(&pdev->dev, DEV_NAME_STR_LEN,
+ GFP_KERNEL);
+ if (!dev_name_str) {
+ ret = -ENOMEM;
+ goto err_free_cdc_conf;
+ }
+
+ ret = of_property_read_string_index(pdev->dev.of_node,
+ "qcom,wsa-aux-dev-prefix",
+ wsa881x_dev_info[i].index,
+ wsa_auxdev_name_prefix);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: failed to read wsa aux dev prefix, ret = %d\n",
+ __func__, ret);
+ ret = -EINVAL;
+ goto err_free_dev_name_str;
+ }
+
+ snprintf(dev_name_str, strlen("wsa881x.%d"), "wsa881x.%d", i);
+ msm_aux_dev[i].name = dev_name_str;
+ msm_aux_dev[i].codec_name = NULL;
+ msm_aux_dev[i].codec_of_node =
+ wsa881x_dev_info[i].of_node;
+ msm_aux_dev[i].init = msm_wsa881x_init;
+ msm_codec_conf[i].dev_name = NULL;
+ msm_codec_conf[i].name_prefix = wsa_auxdev_name_prefix[0];
+ msm_codec_conf[i].of_node =
+ wsa881x_dev_info[i].of_node;
+ }
+ card->codec_conf = msm_codec_conf;
+ card->aux_dev = msm_aux_dev;
+
+ return 0;
+
+err_free_dev_name_str:
+ devm_kfree(&pdev->dev, dev_name_str);
+err_free_cdc_conf:
+ devm_kfree(&pdev->dev, msm_codec_conf);
+err_free_aux_dev:
+ devm_kfree(&pdev->dev, msm_aux_dev);
+err_free_dev_info:
+ devm_kfree(&pdev->dev, wsa881x_dev_info);
+err:
+ return ret;
+}
+
+static void msm_i2s_auxpcm_init(struct platform_device *pdev)
+{
+ int count;
+ u32 mi2s_master_slave[MI2S_MAX];
+ int ret;
+
+ for (count = 0; count < MI2S_MAX; count++) {
+ mutex_init(&mi2s_intf_conf[count].lock);
+ mi2s_intf_conf[count].ref_cnt = 0;
+ }
+
+ ret = of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,msm-mi2s-master",
+ mi2s_master_slave, MI2S_MAX);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: no qcom,msm-mi2s-master in DT node\n",
+ __func__);
+ } else {
+ for (count = 0; count < MI2S_MAX; count++) {
+ mi2s_intf_conf[count].msm_is_mi2s_master =
+ mi2s_master_slave[count];
+ }
+ }
+}
+
+static void msm_i2s_auxpcm_deinit(void)
+{
+ int count;
+
+ for (count = 0; count < MI2S_MAX; count++) {
+ mutex_destroy(&mi2s_intf_conf[count].lock);
+ mi2s_intf_conf[count].ref_cnt = 0;
+ mi2s_intf_conf[count].msm_is_mi2s_master = 0;
+ }
+}
+static int msm_asoc_machine_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card;
+ struct msm_asoc_mach_data *pdata;
+ const char *mbhc_audio_jack_type = NULL;
+ int ret;
+
+ if (!pdev->dev.of_node) {
+ dev_err(&pdev->dev, "No platform supplied from device tree\n");
+ return -EINVAL;
+ }
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct msm_asoc_mach_data), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ card = populate_snd_card_dailinks(&pdev->dev);
+ if (!card) {
+ dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ card->dev = &pdev->dev;
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, pdata);
+
+ ret = snd_soc_of_parse_card_name(card, "qcom,model");
+ if (ret) {
+ dev_err(&pdev->dev, "parse card name failed, err:%d\n",
+ ret);
+ goto err;
+ }
+
+ ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
+ if (ret) {
+ dev_err(&pdev->dev, "parse audio routing failed, err:%d\n",
+ ret);
+ goto err;
+ }
+
+ ret = msm_populate_dai_link_component_of_node(card);
+ if (ret) {
+ ret = -EPROBE_DEFER;
+ goto err;
+ }
+ ret = msm_init_wsa_dev(pdev, card);
+ if (ret)
+ goto err;
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret == -EPROBE_DEFER) {
+ if (codec_reg_done)
+ ret = -EINVAL;
+ goto err;
+ } else if (ret) {
+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
+ ret);
+ goto err;
+ }
+ dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
+ spdev = pdev;
+
+ ret = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s: failed to add child nodes, ret=%d\n",
+ __func__, ret);
+ } else {
+ pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en1-gpio", 0);
+ if (!pdata->hph_en1_gpio_p) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
+ "qcom,hph-en1-gpio",
+ pdev->dev.of_node->full_name);
+ }
+
+ pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en0-gpio", 0);
+ if (!pdata->hph_en0_gpio_p) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
+ "qcom,hph-en0-gpio",
+ pdev->dev.of_node->full_name);
+ }
+ }
+
+ ret = of_property_read_string(pdev->dev.of_node,
+ "qcom,mbhc-audio-jack-type", &mbhc_audio_jack_type);
+ if (ret) {
+ dev_dbg(&pdev->dev, "Looking up %s property in node %s failed\n",
+ "qcom,mbhc-audio-jack-type",
+ pdev->dev.of_node->full_name);
+ dev_dbg(&pdev->dev, "Jack type properties set to default\n");
+ } else {
+ if (!strcmp(mbhc_audio_jack_type, "4-pole-jack")) {
+ wcd_mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "This hardware has 4 pole jack");
+ } else if (!strcmp(mbhc_audio_jack_type, "5-pole-jack")) {
+ wcd_mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 5 pole jack");
+ } else if (!strcmp(mbhc_audio_jack_type, "6-pole-jack")) {
+ wcd_mbhc_cfg.enable_anc_mic_detect = true;
+ dev_dbg(&pdev->dev, "This hardware has 6 pole jack");
+ } else {
+ wcd_mbhc_cfg.enable_anc_mic_detect = false;
+ dev_dbg(&pdev->dev, "Unknown value, set to default\n");
+ }
+ }
+ /*
+ * Parse US-Euro gpio info from DT. Report no error if us-euro
+ * entry is not found in DT file as some targets do not support
+ * US-Euro detection
+ */
+ pdata->us_euro_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,us-euro-gpios", 0);
+ if (!pdata->us_euro_gpio_p) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,us-euro-gpios", pdev->dev.of_node->full_name);
+ } else {
+ dev_dbg(&pdev->dev, "%s detected\n",
+ "qcom,us-euro-gpios");
+ wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
+ }
+ pdata->fsa_handle = of_parse_phandle(pdev->dev.of_node,
+ "fsa4480-i2c-handle", 0);
+ if (!pdata->fsa_handle)
+ dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
+ "fsa4480-i2c-handle", pdev->dev.of_node->full_name);
+
+ /* Parse pinctrl info from devicetree */
+ ret = msm_get_pinctrl(pdev);
+ if (!ret) {
+ pr_debug("%s: pinctrl parsing successful\n", __func__);
+ } else {
+ dev_dbg(&pdev->dev,
+ "%s: Parsing pinctrl failed with %d. Cannot use Ports\n",
+ __func__, ret);
+ ret = 0;
+ }
+
+ msm_i2s_auxpcm_init(pdev);
+ is_initial_boot = true;
+ ret = audio_notifier_register("sdm855", AUDIO_NOTIFIER_ADSP_DOMAIN,
+ &service_nb);
+ if (ret < 0)
+ pr_err("%s: Audio notifier register failed ret = %d\n",
+ __func__, ret);
+
+ return 0;
+err:
+ msm_release_pinctrl(pdev);
+ devm_kfree(&pdev->dev, pdata);
+ return ret;
+}
+
+static int msm_asoc_machine_remove(struct platform_device *pdev)
+{
+ audio_notifier_deregister("sdm855");
+ msm_i2s_auxpcm_deinit();
+
+ msm_release_pinctrl(pdev);
+ return 0;
+}
+
+static struct platform_driver sdm855_asoc_machine_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .pm = &snd_soc_pm_ops,
+ .of_match_table = sdm855_asoc_machine_of_match,
+ },
+ .probe = msm_asoc_machine_probe,
+ .remove = msm_asoc_machine_remove,
+};
+module_platform_driver(sdm855_asoc_machine_driver);
+
+MODULE_DESCRIPTION("ALSA SoC msm");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
+MODULE_DEVICE_TABLE(of, sdm855_asoc_machine_of_match);
diff --git a/config/sdm670auto.conf b/config/sdm670auto.conf
index 07f195b..4c0b284 100644
--- a/config/sdm670auto.conf
+++ b/config/sdm670auto.conf
@@ -33,7 +33,7 @@
CONFIG_SND_SOC_WCD_MBHC_ADC=m
CONFIG_SND_SOC_WCD_MBHC_LEGACY=m
CONFIG_QTI_PP=m
-CONFIG_SND_HWDEP=m
+CONFIG_SND_HWDEP_ROUTING=m
CONFIG_DTS_EAGLE=m
CONFIG_DOLBY_DS2=m
CONFIG_DOLBY_LICENSE=m
diff --git a/config/sdm670auto_static.conf b/config/sdm670auto_static.conf
index dc55564..91a8464 100644
--- a/config/sdm670auto_static.conf
+++ b/config/sdm670auto_static.conf
@@ -33,7 +33,7 @@
CONFIG_SND_SOC_WCD_MBHC_ADC=y
CONFIG_SND_SOC_WCD_MBHC_LEGACY=y
CONFIG_QTI_PP=y
-CONFIG_SND_HWDEP=y
+CONFIG_SND_HWDEP_ROUTING=y
CONFIG_DTS_EAGLE=y
CONFIG_DOLBY_DS2=y
CONFIG_DOLBY_LICENSE=y
diff --git a/config/sdm670autoconf.h b/config/sdm670autoconf.h
index 462862f..55f9548 100644
--- a/config/sdm670autoconf.h
+++ b/config/sdm670autoconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -43,7 +43,7 @@
#define CONFIG_SND_SOC_QDSP6V2 1
#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1
#define CONFIG_QTI_PP 1
-#define CONFIG_SND_HWDEP 1
+#define CONFIG_SND_HWDEP_ROUTING 1
#define CONFIG_DTS_EAGLE 1
#define CONFIG_DOLBY_DS2 1
#define CONFIG_DOLBY_LICENSE 1
diff --git a/config/sdm845auto.conf b/config/sdm845auto.conf
index 5234e2b..4c195b4 100644
--- a/config/sdm845auto.conf
+++ b/config/sdm845auto.conf
@@ -27,7 +27,7 @@
CONFIG_SND_SOC_QDSP6V2=y
CONFIG_SND_SOC_WCD_MBHC_ADC=y
CONFIG_QTI_PP=y
-CONFIG_SND_HWDEP=y
+CONFIG_SND_HWDEP_ROUTING=y
CONFIG_DTS_EAGLE=y
CONFIG_DOLBY_DS2=y
CONFIG_DOLBY_LICENSE=y
diff --git a/config/sdm845autoconf.h b/config/sdm845autoconf.h
index fcef4c1..6ef465a 100644
--- a/config/sdm845autoconf.h
+++ b/config/sdm845autoconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,7 +38,7 @@
#define CONFIG_SND_SOC_QDSP6V2 1
#define CONFIG_MSM_CDC_PINCTRL 1
#define CONFIG_QTI_PP 1
-#define CONFIG_SND_HWDEP 1
+#define CONFIG_SND_HWDEP_ROUTING 1
#define CONFIG_DTS_EAGLE 1
#define CONFIG_DOLBY_DS2 1
#define CONFIG_DOLBY_LICENSE 1
diff --git a/config/sdm855auto.conf b/config/sdm855auto.conf
new file mode 100644
index 0000000..cfddf95
--- /dev/null
+++ b/config/sdm855auto.conf
@@ -0,0 +1,40 @@
+CONFIG_PINCTRL_WCD=m
+CONFIG_AUDIO_EXT_CLK=m
+CONFIG_SND_SOC_WCD9XXX_V2=m
+CONFIG_SND_SOC_WCD_MBHC=m
+CONFIG_SND_SOC_WSA881X=m
+CONFIG_SND_SOC_WCD9360=m
+CONFIG_SND_SOC_WCD_DSP_MGR=m
+CONFIG_SND_SOC_WCD_SPI=m
+CONFIG_SND_SOC_WCD934X=m
+CONFIG_SND_SOC_WCD934X_MBHC=m
+CONFIG_SND_SOC_WCD934X_DSD=m
+CONFIG_SND_SOC_WCD_CPE=m
+CONFIG_SOUNDWIRE_WCD_CTRL=m
+CONFIG_WCD9XXX_CODEC_CORE=m
+CONFIG_MSM_CDC_PINCTRL=m
+CONFIG_MSM_QDSP6V2_CODECS=m
+CONFIG_MSM_ULTRASOUND=m
+CONFIG_MSM_QDSP6_APRV2_RPMSG=m
+CONFIG_MSM_ADSP_LOADER=m
+CONFIG_REGMAP_SWR=m
+CONFIG_MSM_QDSP6_SSR=m
+CONFIG_MSM_QDSP6_PDR=m
+CONFIG_MSM_QDSP6_NOTIFIER=m
+CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m
+CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
+CONFIG_SND_SOC_SDM855=m
+CONFIG_MSM_GLINK_SPI_XPRT=m
+CONFIG_WCD_DSP_GLINK=m
+CONFIG_SOUNDWIRE=m
+CONFIG_SND_SOC_QDSP6V2=m
+CONFIG_SND_SOC_WCD_MBHC_ADC=m
+CONFIG_QTI_PP=m
+CONFIG_SND_HWDEP_ROUTING=m
+CONFIG_DTS_EAGLE=m
+CONFIG_DOLBY_DS2=m
+CONFIG_DOLBY_LICENSE=m
+CONFIG_DTS_SRS_TM=m
+CONFIG_SND_SOC_MSM_STUB=m
+CONFIG_MSM_AVTIMER=m
+CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
diff --git a/config/sdm855autoconf.h b/config/sdm855autoconf.h
new file mode 100644
index 0000000..9906d4b
--- /dev/null
+++ b/config/sdm855autoconf.h
@@ -0,0 +1,52 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define CONFIG_PINCTRL_WCD 1
+#define CONFIG_AUDIO_EXT_CLK 1
+#define CONFIG_SND_SOC_WCD9XXX_V2 1
+#define CONFIG_SND_SOC_WCD_MBHC 1
+#define CONFIG_SND_SOC_WSA881X 1
+#define CONFIG_SND_SOC_WCD9360 1
+#define CONFIG_SND_SOC_WCD_DSP_MGR 1
+#define CONFIG_SND_SOC_WCD_SPI 1
+#define CONFIG_SND_SOC_WCD934X 1
+#define CONFIG_SND_SOC_WCD934X_MBHC 1
+#define CONFIG_SND_SOC_WCD934X_DSD 1
+#define CONFIG_SND_SOC_WCD_CPE 1
+#define CONFIG_WCD9XXX_CODEC_CORE 1
+#define CONFIG_MSM_CDC_PINCTRL 1
+#define CONFIG_MSM_QDSP6V2_CODECS 1
+#define CONFIG_MSM_ULTRASOUND 1
+#define CONFIG_MSM_QDSP6_APRV2_RPMSG 1
+#define CONFIG_SND_SOC_MSM_QDSP6V2_INTF 1
+#define CONFIG_MSM_ADSP_LOADER 1
+#define CONFIG_REGMAP_SWR 1
+#define CONFIG_MSM_QDSP6_SSR 1
+#define CONFIG_MSM_QDSP6_PDR 1
+#define CONFIG_MSM_QDSP6_NOTIFIER 1
+#define CONFIG_SND_SOC_MSM_HOSTLESS_PCM 1
+#define CONFIG_SND_SOC_SDM855 1
+#define CONFIG_MSM_GLINK_SPI_XPRT 1
+#define CONFIG_WCD_DSP_GLINK 1
+#define CONFIG_SOUNDWIRE 1
+#define CONFIG_SOUNDWIRE_WCD_CTRL 1
+#define CONFIG_SND_SOC_WCD_MBHC_ADC 1
+#define CONFIG_SND_SOC_QDSP6V2 1
+#define CONFIG_QTI_PP 1
+#define CONFIG_SND_HWDEP_ROUTING 1
+#define CONFIG_DTS_EAGLE 1
+#define CONFIG_DOLBY_DS2 1
+#define CONFIG_DOLBY_LICENSE 1
+#define CONFIG_DTS_SRS_TM 1
+#define CONFIG_SND_SOC_MSM_STUB 1
+#define CONFIG_MSM_AVTIMER 1
+#define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1
diff --git a/config/sdxpoorwillsauto.conf b/config/sdxpoorwillsauto.conf
index d9dd081..dee34a0 100644
--- a/config/sdxpoorwillsauto.conf
+++ b/config/sdxpoorwillsauto.conf
@@ -24,6 +24,6 @@
CONFIG_WCD9XXX_CODEC_CORE=y
CONFIG_SND_SOC_WCD_MBHC_ADC=y
CONFIG_QTI_PP=y
-CONFIG_SND_HWDEP=y
+CONFIG_SND_HWDEP_ROUTING=y
CONFIG_SND_SOC_MACHINE_SDXPOORWILLS=y
CONFIG_SND_SOC_MSM_STUB=y
diff --git a/config/sdxpoorwillsautoconf.h b/config/sdxpoorwillsautoconf.h
index 9fc6258..7b7dac4 100644
--- a/config/sdxpoorwillsautoconf.h
+++ b/config/sdxpoorwillsautoconf.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -37,6 +37,6 @@
#define CONFIG_WCD9XXX_CODEC_CORE 1
#define CONFIG_SND_SOC_WCD_MBHC_ADC 1
#define CONFIG_QTI_PP 1
-#define CONFIG_SND_HWDEP 1
+#define CONFIG_SND_HWDEP_ROUTING 1
#define CONFIG_SND_SOC_MACHINE_SDXPOORWILLS 1
#define CONFIG_SND_SOC_MSM_STUB 1
diff --git a/dsp/Android.mk b/dsp/Android.mk
index 98f865b..cad30c8 100644
--- a/dsp/Android.mk
+++ b/dsp/Android.mk
@@ -11,9 +11,13 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/dsp/Kbuild b/dsp/Kbuild
index 73dcb2a..df73215 100644
--- a/dsp/Kbuild
+++ b/dsp/Kbuild
@@ -29,6 +29,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
@@ -68,6 +73,7 @@
Q6_OBJS += q6audio-v2.o
Q6_OBJS += q6voice.o
Q6_OBJS += q6core.o
+ Q6_OBJS += q6common.o
Q6_OBJS += rtac.o
Q6_OBJS += q6lsm.o
Q6_OBJS += audio_slimslave.o
diff --git a/dsp/audio_cal_utils.c b/dsp/audio_cal_utils.c
index ad1dc3d..77cb1c5 100644
--- a/dsp/audio_cal_utils.c
+++ b/dsp/audio_cal_utils.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -442,11 +442,9 @@
cal_block->client_info = NULL;
kfree(cal_block->cal_info);
cal_block->cal_info = NULL;
- if (cal_block->map_data.ion_client != NULL) {
- msm_audio_ion_free(cal_block->map_data.ion_client,
- cal_block->map_data.ion_handle);
- cal_block->map_data.ion_client = NULL;
- cal_block->map_data.ion_handle = NULL;
+ if (cal_block->map_data.dma_buf != NULL) {
+ msm_audio_ion_free(cal_block->map_data.dma_buf);
+ cal_block->map_data.dma_buf = NULL;
}
kfree(cal_block);
done:
@@ -604,9 +602,7 @@
goto done;
}
- ret = msm_audio_ion_import("audio_cal_client",
- &cal_block->map_data.ion_client,
- &cal_block->map_data.ion_handle,
+ ret = msm_audio_ion_import(&cal_block->map_data.dma_buf,
cal_block->map_data.ion_map_handle,
NULL, 0,
&cal_block->cal_data.paddr,
@@ -736,10 +732,8 @@
{
int ret = 0;
- msm_audio_ion_free(cal_block->map_data.ion_client,
- cal_block->map_data.ion_handle);
- cal_block->map_data.ion_client = NULL;
- cal_block->map_data.ion_handle = NULL;
+ msm_audio_ion_free(cal_block->map_data.dma_buf);
+ cal_block->map_data.dma_buf = NULL;
cal_block->cal_data.size = 0;
ret = cal_block_ion_alloc(cal_block);
@@ -1039,9 +1033,40 @@
((uint8_t *)data + sizeof(struct audio_cal_type_basic)),
data_size - sizeof(struct audio_cal_type_basic));
+ /* reset buffer stale flag */
+ cal_block->cal_stale = false;
+
err:
mutex_unlock(&cal_type->lock);
done:
return ret;
}
EXPORT_SYMBOL(cal_utils_set_cal);
+
+/**
+ * cal_utils_mark_cal_used
+ *
+ * @cal_block: pointer to cal block
+ */
+void cal_utils_mark_cal_used(struct cal_block_data *cal_block)
+{
+ if (cal_block)
+ cal_block->cal_stale = true;
+}
+EXPORT_SYMBOL(cal_utils_mark_cal_used);
+
+/**
+ * cal_utils_is_cal_stale
+ *
+ * @cal_block: pointer to cal block
+ *
+ * Returns true if cal block is stale, false otherwise
+ */
+bool cal_utils_is_cal_stale(struct cal_block_data *cal_block)
+{
+ if ((cal_block) && (cal_block->cal_stale))
+ return true;
+
+ return false;
+}
+EXPORT_SYMBOL(cal_utils_is_cal_stale);
diff --git a/dsp/audio_pdr.h b/dsp/audio_pdr.h
index 2a45c6a..d1235bc 100644
--- a/dsp/audio_pdr.h
+++ b/dsp/audio_pdr.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -83,6 +83,10 @@
return -ENODEV;
}
+static inline int audio_pdr_deregister(struct notifier_block *nb)
+{
+ return -ENODEV;
+}
static inline void *audio_pdr_service_register(int domain_id,
struct notifier_block *nb,
diff --git a/dsp/audio_slimslave.c b/dsp/audio_slimslave.c
index 25866d1..55982f3 100644
--- a/dsp/audio_slimslave.c
+++ b/dsp/audio_slimslave.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2014, 2017-2018 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -167,7 +167,7 @@
void audio_slimslave_exit(void)
{
-
+ slim_driver_unregister(&audio_slimslave_driver);
}
/* Module information */
diff --git a/dsp/codecs/Android.mk b/dsp/codecs/Android.mk
index 984a513..50ec167 100644
--- a/dsp/codecs/Android.mk
+++ b/dsp/codecs/Android.mk
@@ -11,9 +11,13 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild
index 34d39ad..0f2adf7 100644
--- a/dsp/codecs/Kbuild
+++ b/dsp/codecs/Kbuild
@@ -30,6 +30,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
# As per target team, build is done as follows:
diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c
index 93b1f50..87e4f4e 100644
--- a/dsp/codecs/audio_multi_aac.c
+++ b/dsp/codecs/audio_multi_aac.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -59,7 +59,7 @@
audio->ac->session);
if (audio->feedback == NON_TUNNEL_MODE) {
/* Configure PCM output block */
- rc = q6asm_enc_cfg_blk_pcm(audio->ac,
+ rc = q6asm_enc_cfg_blk_pcm_native(audio->ac,
audio->pcm_cfg.sample_rate,
audio->pcm_cfg.channel_count);
if (rc < 0) {
diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c
index e8f22e7..7f332f4 100644
--- a/dsp/codecs/audio_utils_aio.c
+++ b/dsp/codecs/audio_utils_aio.c
@@ -1,6 +1,6 @@
/* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -420,7 +420,7 @@
list_for_each_safe(ptr, next, &audio->ion_region_queue) {
region = list_entry(ptr, struct audio_aio_ion_region, list);
list_del(®ion->list);
- msm_audio_ion_free_legacy(audio->client, region->handle);
+ msm_audio_ion_free(region->dma_buf);
kfree(region);
}
}
@@ -614,7 +614,6 @@
audio_aio_disable(audio);
audio_aio_unmap_ion_region(audio);
audio_aio_reset_ion_region(audio);
- msm_audio_ion_client_destroy(audio->client);
audio->event_abort = 1;
wake_up(&audio->event_wait);
audio_aio_reset_event_queue(audio);
@@ -960,11 +959,11 @@
static int audio_aio_ion_add(struct q6audio_aio *audio,
struct msm_audio_ion_info *info)
{
- ion_phys_addr_t paddr = 0;
+ dma_addr_t paddr = 0;
size_t len = 0;
struct audio_aio_ion_region *region;
int rc = -EINVAL;
- struct ion_handle *handle = NULL;
+ struct dma_buf *dma_buf = NULL;
unsigned long ionflag;
void *kvaddr = NULL;
@@ -976,8 +975,7 @@
goto end;
}
- rc = msm_audio_ion_import_legacy("Audio_Dec_Client", audio->client,
- &handle, info->fd, &ionflag,
+ rc = msm_audio_ion_import(&dma_buf, info->fd, &ionflag,
0, &paddr, &len, &kvaddr);
if (rc) {
pr_err("%s: msm audio ion alloc failed\n", __func__);
@@ -990,7 +988,7 @@
goto ion_error;
}
- region->handle = handle;
+ region->dma_buf = dma_buf;
region->vaddr = info->vaddr;
region->fd = info->fd;
region->paddr = paddr;
@@ -1012,7 +1010,7 @@
mmap_error:
list_del(®ion->list);
ion_error:
- msm_audio_ion_free_legacy(audio->client, handle);
+ msm_audio_ion_free(dma_buf);
import_error:
kfree(region);
end:
@@ -1049,8 +1047,7 @@
__func__, audio);
list_del(®ion->list);
- msm_audio_ion_free_legacy(audio->client,
- region->handle);
+ msm_audio_ion_free(region->dma_buf);
kfree(region);
rc = 0;
break;
@@ -1378,22 +1375,12 @@
goto cleanup;
}
}
- audio->client = msm_audio_ion_client_create("Audio_Dec_Client");
- if (IS_ERR_OR_NULL(audio->client)) {
- pr_err("Unable to create ION client\n");
- rc = -ENOMEM;
- goto cleanup;
- }
- pr_debug("Ion client create in audio_aio_open %pK", audio->client);
rc = register_volume_listener(audio);
if (rc < 0)
- goto ion_cleanup;
+ goto cleanup;
return 0;
-ion_cleanup:
- msm_audio_ion_client_destroy(audio->client);
- audio->client = NULL;
cleanup:
list_for_each_safe(ptr, next, &audio->free_event_queue) {
e_node = list_first_entry(&audio->free_event_queue,
diff --git a/dsp/codecs/audio_utils_aio.h b/dsp/codecs/audio_utils_aio.h
index e44f9d9..1993f60 100644
--- a/dsp/codecs/audio_utils_aio.h
+++ b/dsp/codecs/audio_utils_aio.h
@@ -1,6 +1,6 @@
/* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -119,7 +119,7 @@
struct audio_aio_ion_region {
struct list_head list;
- struct ion_handle *handle;
+ struct dma_buf *dma_buf;
int fd;
void *vaddr;
phys_addr_t paddr;
@@ -182,7 +182,6 @@
struct list_head free_event_queue;
struct list_head event_queue;
struct list_head ion_region_queue; /* protected by lock */
- struct ion_client *client;
struct audio_aio_drv_operations drv_ops;
union msm_audio_event_payload eos_write_payload;
uint32_t device_events;
diff --git a/dsp/msm-dts-srs-tm-config.c b/dsp/msm-dts-srs-tm-config.c
index cd3da4d..fff98b5 100644
--- a/dsp/msm-dts-srs-tm-config.c
+++ b/dsp/msm-dts-srs-tm-config.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2014, 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2014, 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,8 +25,7 @@
static int srs_port_id[AFE_MAX_PORTS] = {-1};
static int srs_copp_idx[AFE_MAX_PORTS] = {-1};
static union srs_trumedia_params_u msm_srs_trumedia_params;
-static struct ion_client *ion_client;
-static struct ion_handle *ion_handle;
+struct dma_buf *dma_buf;
static struct param_outband po;
static atomic_t ref_cnt;
#define ION_MEM_SIZE (8 * 1024)
@@ -299,13 +298,13 @@
{
int rc;
- rc = msm_audio_ion_alloc("SRS_TRUMEDIA", &ion_client, &ion_handle,
- ION_MEM_SIZE, &po.paddr, (size_t *)&po.size,
+ rc = msm_audio_ion_alloc(&dma_buf, ION_MEM_SIZE,
+ &po.paddr, (size_t *)&po.size,
&po.kvaddr);
if (rc != 0)
pr_err("%s: failed to allocate memory.\n", __func__);
- pr_debug("%s: exited ion_client = %pK, ion_handle = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n",
- __func__, ion_client, ion_handle, (long)po.paddr,
+ pr_debug("%s: exited dma_buf = %pK, phys_addr = %lu, length = %d, vaddr = %pK, rc = 0x%x\n",
+ __func__, dma_buf, (long)po.paddr,
(unsigned int)po.size, po.kvaddr, rc);
return rc;
}
@@ -323,7 +322,8 @@
static void unreg_ion_mem(void)
{
- msm_audio_ion_free(ion_client, ion_handle);
+ msm_audio_ion_free(dma_buf);
+ dma_buf = NULL;
po.kvaddr = NULL;
po.paddr = 0;
po.size = 0;
diff --git a/dsp/msm_audio_ion.c b/dsp/msm_audio_ion.c
index 1138290..63a386b 100644
--- a/dsp/msm_audio_ion.c
+++ b/dsp/msm_audio_ion.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,9 +23,10 @@
#include <linux/dma-buf.h>
#include <linux/iommu.h>
#include <linux/platform_device.h>
-#include <ipc/apr.h>
#include <linux/of_device.h>
#include <linux/export.h>
+#include <linux/ion_kernel.h>
+#include <ipc/apr.h>
#include <asm/dma-iommu.h>
#include <dsp/msm_audio_ion.h>
@@ -40,7 +41,6 @@
#define MSM_AUDIO_SMMU_SID_OFFSET 32
struct msm_audio_ion_private {
- bool smmu_enabled;
bool audioheap_enabled;
struct device *cb_dev;
struct dma_iommu_mapping *mapping;
@@ -52,9 +52,8 @@
};
struct msm_audio_alloc_data {
- struct ion_client *client;
- struct ion_handle *handle;
size_t len;
+ void *vaddr;
struct dma_buf *dma_buf;
struct dma_buf_attachment *attach;
struct sg_table *table;
@@ -63,17 +62,6 @@
static struct msm_audio_ion_private msm_audio_ion_data = {0,};
-static int msm_audio_ion_get_phys(struct ion_client *client,
- struct ion_handle *handle,
- ion_phys_addr_t *addr, size_t *len);
-
-static int msm_audio_dma_buf_map(struct ion_client *client,
- struct ion_handle *handle,
- ion_phys_addr_t *addr, size_t *len);
-
-static int msm_audio_dma_buf_unmap(struct ion_client *client,
- struct ion_handle *handle);
-
static void msm_audio_ion_add_allocation(
struct msm_audio_ion_private *msm_audio_ion_data,
struct msm_audio_alloc_data *alloc_data)
@@ -89,196 +77,377 @@
mutex_unlock(&(msm_audio_ion_data->list_mutex));
}
+static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
+ dma_addr_t *addr, size_t *len)
+{
+
+ struct msm_audio_alloc_data *alloc_data;
+ struct device *cb_dev;
+ int rc = 0;
+
+ cb_dev = msm_audio_ion_data.cb_dev;
+
+ /* Data required per buffer mapping */
+ alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
+ if (!alloc_data)
+ return -ENOMEM;
+
+ alloc_data->dma_buf = dma_buf;
+ alloc_data->len = dma_buf->size;
+ *len = dma_buf->size;
+
+ /* Attach the dma_buf to context bank device */
+ alloc_data->attach = dma_buf_attach(alloc_data->dma_buf,
+ cb_dev);
+ if (IS_ERR(alloc_data->attach)) {
+ rc = PTR_ERR(alloc_data->attach);
+ dev_err(cb_dev,
+ "%s: Fail to attach dma_buf to CB, rc = %d\n",
+ __func__, rc);
+ goto err_attach;
+ }
+
+ /*
+ * Get the scatter-gather list.
+ * There is no info as this is a write buffer or
+ * read buffer, hence the request is bi-directional
+ * to accommodate both read and write mappings.
+ */
+ alloc_data->table = dma_buf_map_attachment(alloc_data->attach,
+ DMA_BIDIRECTIONAL);
+ if (IS_ERR(alloc_data->table)) {
+ rc = PTR_ERR(alloc_data->table);
+ dev_err(cb_dev,
+ "%s: Fail to map attachment, rc = %d\n",
+ __func__, rc);
+ goto err_map_attach;
+ }
+
+ /* physical address from mapping */
+ *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
+
+ msm_audio_ion_add_allocation(&msm_audio_ion_data,
+ alloc_data);
+ return rc;
+
+err_map_attach:
+ dma_buf_detach(alloc_data->dma_buf,
+ alloc_data->attach);
+err_attach:
+ kfree(alloc_data);
+
+ return rc;
+}
+
+static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf)
+{
+ int rc = 0;
+ struct msm_audio_alloc_data *alloc_data = NULL;
+ struct list_head *ptr, *next;
+ struct device *cb_dev = msm_audio_ion_data.cb_dev;
+ bool found = false;
+
+ /*
+ * Though list_for_each_safe is delete safe, lock
+ * should be explicitly acquired to avoid race condition
+ * on adding elements to the list.
+ */
+ mutex_lock(&(msm_audio_ion_data.list_mutex));
+ list_for_each_safe(ptr, next,
+ &(msm_audio_ion_data.alloc_list)) {
+
+ alloc_data = list_entry(ptr, struct msm_audio_alloc_data,
+ list);
+
+ if (alloc_data->dma_buf == dma_buf) {
+ found = true;
+ dma_buf_unmap_attachment(alloc_data->attach,
+ alloc_data->table,
+ DMA_BIDIRECTIONAL);
+
+ dma_buf_detach(alloc_data->dma_buf,
+ alloc_data->attach);
+
+ dma_buf_put(alloc_data->dma_buf);
+
+ list_del(&(alloc_data->list));
+ kfree(alloc_data);
+ break;
+ }
+ }
+ mutex_unlock(&(msm_audio_ion_data.list_mutex));
+
+ if (!found) {
+ dev_err(cb_dev,
+ "%s: cannot find allocation, dma_buf %pK",
+ __func__, dma_buf);
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
+ dma_addr_t *addr, size_t *len)
+{
+ int rc = 0;
+
+ rc = msm_audio_dma_buf_map(dma_buf, addr, len);
+ if (rc) {
+ pr_err("%s: failed to map DMA buf, err = %d\n",
+ __func__, rc);
+ goto err;
+ }
+ /* Append the SMMU SID information to the IOVA address */
+ *addr |= msm_audio_ion_data.smmu_sid_bits;
+
+ pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc);
+err:
+ return rc;
+}
+
+static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf)
+{
+ int rc = 0;
+ void *addr = NULL;
+ struct msm_audio_alloc_data *alloc_data = NULL;
+
+ rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
+ if (rc) {
+ pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__);
+ goto exit;
+ }
+
+ addr = dma_buf_vmap(dma_buf);
+ if (!addr) {
+ pr_err("%s: kernel mapping of dma_buf failed\n",
+ __func__);
+ goto exit;
+ }
+
+ /*
+ * TBD: remove the below section once new API
+ * for mapping kernel virtual address is available.
+ */
+ mutex_lock(&(msm_audio_ion_data.list_mutex));
+ list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
+ list) {
+ if (alloc_data->dma_buf == dma_buf) {
+ alloc_data->vaddr = addr;
+ break;
+ }
+ }
+ mutex_unlock(&(msm_audio_ion_data.list_mutex));
+
+exit:
+ return addr;
+}
+
+static void msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf)
+{
+ int rc = 0;
+ void *vaddr = NULL;
+ struct msm_audio_alloc_data *alloc_data = NULL;
+ struct device *cb_dev = msm_audio_ion_data.cb_dev;
+
+ /*
+ * TBD: remove the below section once new API
+ * for unmapping kernel virtual address is available.
+ */
+ mutex_lock(&(msm_audio_ion_data.list_mutex));
+ list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
+ list) {
+ if (alloc_data->dma_buf == dma_buf) {
+ vaddr = alloc_data->vaddr;
+ break;
+ }
+ }
+ mutex_unlock(&(msm_audio_ion_data.list_mutex));
+
+ if (!vaddr) {
+ dev_err(cb_dev,
+ "%s: cannot find allocation for dma_buf %pK",
+ __func__, dma_buf);
+ goto err;
+ }
+
+ dma_buf_vunmap(dma_buf, vaddr);
+
+ rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
+ if (rc) {
+ dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n",
+ __func__);
+ goto err;
+ }
+
+err:
+ return;
+}
+
+static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
+ size_t *plen, void **vaddr)
+{
+ int rc = 0;
+
+ rc = msm_audio_ion_get_phys(dma_buf, paddr, plen);
+ if (rc) {
+ pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
+ __func__, rc);
+ goto err;
+ }
+
+ *vaddr = msm_audio_ion_map_kernel(dma_buf);
+ if (IS_ERR_OR_NULL(*vaddr)) {
+ pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
+ rc = -ENOMEM;
+ goto err;
+ }
+
+err:
+ return rc;
+}
+
/**
* msm_audio_ion_alloc -
* Allocs ION memory for given client name
*
- * @name: Name of audio ION client
- * @client: ION client to be assigned
- * @handle: ION handle to be assigned
+ * @dma_buf: dma_buf for the ION memory
* @bufsz: buffer size
* @paddr: Physical address to be assigned with allocated region
- * @pa_len: length of allocated region to be assigned
+ * @plen: length of allocated region to be assigned
* vaddr: virtual address to be assigned
*
* Returns 0 on success or error on failure
*/
-int msm_audio_ion_alloc(const char *name, struct ion_client **client,
- struct ion_handle **handle, size_t bufsz,
- ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr)
+int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
+ dma_addr_t *paddr, size_t *plen, void **vaddr)
{
int rc = -EINVAL;
unsigned long err_ion_ptr = 0;
- if ((msm_audio_ion_data.smmu_enabled == true) &&
- !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
+ if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
pr_debug("%s:probe is not done, deferred\n", __func__);
return -EPROBE_DEFER;
}
- if (!name || !client || !handle || !paddr || !vaddr
- || !bufsz || !pa_len) {
+ if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) {
pr_err("%s: Invalid params\n", __func__);
return -EINVAL;
}
- *client = msm_audio_ion_client_create(name);
- if (IS_ERR_OR_NULL((void *)(*client))) {
- pr_err("%s: ION create client for AUDIO failed\n", __func__);
+
+ *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
+ if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
+ if (IS_ERR((void *)(*dma_buf)))
+ err_ion_ptr = PTR_ERR((int *)(*dma_buf));
+ pr_err("%s:ION alloc fail err ptr=%ld\n",
+ __func__, err_ion_ptr);
+ rc = -ENOMEM;
goto err;
}
- *handle = ion_alloc(*client, bufsz, SZ_4K,
- ION_HEAP(ION_AUDIO_HEAP_ID), 0);
- if (IS_ERR_OR_NULL((void *) (*handle))) {
- if (msm_audio_ion_data.smmu_enabled == true) {
- pr_debug("system heap is used");
- msm_audio_ion_data.audioheap_enabled = 0;
- *handle = ion_alloc(*client, bufsz, SZ_4K,
- ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
- }
- if (IS_ERR_OR_NULL((void *) (*handle))) {
- if (IS_ERR((void *)(*handle)))
- err_ion_ptr = PTR_ERR((int *)(*handle));
- pr_err("%s:ION alloc fail err ptr=%ld, smmu_enabled=%d\n",
- __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled);
- rc = -ENOMEM;
- goto err_ion_client;
- }
- } else {
- pr_debug("audio heap is used");
- msm_audio_ion_data.audioheap_enabled = 1;
- }
-
- rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len);
+ rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
if (rc) {
- pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
- __func__, rc);
- goto err_ion_handle;
- }
-
- *vaddr = ion_map_kernel(*client, *handle);
- if (IS_ERR_OR_NULL((void *)*vaddr)) {
- pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
- goto err_ion_handle;
+ pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
+ goto err_dma_buf;
}
pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
*vaddr, bufsz);
- if (bufsz != 0) {
- pr_debug("%s: memset to 0 %pK %zd\n", __func__, *vaddr, bufsz);
- memset((void *)*vaddr, 0, bufsz);
- }
+ memset(*vaddr, 0, bufsz);
return rc;
-err_ion_handle:
- ion_free(*client, *handle);
-err_ion_client:
- msm_audio_ion_client_destroy(*client);
- *handle = NULL;
- *client = NULL;
+err_dma_buf:
+ dma_buf_put(*dma_buf);
err:
return rc;
}
EXPORT_SYMBOL(msm_audio_ion_alloc);
-int msm_audio_ion_import(const char *name, struct ion_client **client,
- struct ion_handle **handle, int fd,
+/**
+ * msm_audio_ion_import-
+ * Import ION buffer with given file descriptor
+ *
+ * @dma_buf: dma_buf for the ION memory
+ * @fd: file descriptor for the ION memory
+ * @ionflag: flags associated with ION buffer
+ * @bufsz: buffer size
+ * @paddr: Physical address to be assigned with allocated region
+ * @plen: length of allocated region to be assigned
+ * vaddr: virtual address to be assigned
+ *
+ * Returns 0 on success or error on failure
+ */
+int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
- ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr)
+ dma_addr_t *paddr, size_t *plen, void **vaddr)
{
int rc = 0;
- if ((msm_audio_ion_data.smmu_enabled == true) &&
- !(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
+ if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
pr_debug("%s:probe is not done, deferred\n", __func__);
return -EPROBE_DEFER;
}
- if (!name || !client || !handle || !paddr || !vaddr || !pa_len) {
+ if (!dma_buf || !paddr || !vaddr || !plen) {
pr_err("%s: Invalid params\n", __func__);
- rc = -EINVAL;
- goto err;
+ return -EINVAL;
}
- *client = msm_audio_ion_client_create(name);
- if (IS_ERR_OR_NULL((void *)(*client))) {
- pr_err("%s: ION create client for AUDIO failed\n", __func__);
+ /* bufsz should be 0 and fd shouldn't be 0 as of now */
+ *dma_buf = dma_buf_get(fd);
+ pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
+ if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
+ pr_err("%s: dma_buf_get failed\n", __func__);
rc = -EINVAL;
goto err;
}
- /* name should be audio_acdb_client or Audio_Dec_Client,
- * bufsz should be 0 and fd shouldn't be 0 as of now
- */
- *handle = ion_import_dma_buf_fd(*client, fd);
- pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__,
- name, fd, *handle);
- if (IS_ERR_OR_NULL((void *) (*handle))) {
- pr_err("%s: ion import dma buffer failed\n",
- __func__);
- rc = -EINVAL;
- goto err_destroy_client;
- }
-
if (ionflag != NULL) {
- rc = ion_handle_get_flags(*client, *handle, ionflag);
+ rc = dma_buf_get_flags(*dma_buf, ionflag);
if (rc) {
- pr_err("%s: could not get flags for the handle\n",
+ pr_err("%s: could not get flags for the dma_buf\n",
__func__);
- goto err_ion_handle;
+ goto err_ion_flag;
}
}
- rc = msm_audio_ion_get_phys(*client, *handle, paddr, pa_len);
+ rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
if (rc) {
- pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
- __func__, rc);
- goto err_ion_handle;
- }
-
- *vaddr = ion_map_kernel(*client, *handle);
- if (IS_ERR_OR_NULL((void *)*vaddr)) {
- pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
- rc = -ENOMEM;
- goto err_ion_handle;
+ pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
+ goto err_ion_flag;
}
pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
*vaddr, bufsz);
return 0;
-err_ion_handle:
- ion_free(*client, *handle);
-err_destroy_client:
- msm_audio_ion_client_destroy(*client);
- *client = NULL;
- *handle = NULL;
+err_ion_flag:
+ dma_buf_put(*dma_buf);
err:
+ *dma_buf = NULL;
return rc;
}
+EXPORT_SYMBOL(msm_audio_ion_import);
/**
* msm_audio_ion_free -
* fress ION memory for given client and handle
*
- * @client: ION client
- * @handle: ION handle
+ * @dma_buf: dma_buf for the ION memory
*
* Returns 0 on success or error on failure
*/
-int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle)
+int msm_audio_ion_free(struct dma_buf *dma_buf)
{
- if (!client || !handle) {
- pr_err("%s Invalid params\n", __func__);
+ if (!dma_buf) {
+ pr_err("%s: dma_buf invalid\n", __func__);
return -EINVAL;
}
- if (msm_audio_ion_data.smmu_enabled)
- msm_audio_dma_buf_unmap(client, handle);
- ion_unmap_kernel(client, handle);
+ msm_audio_ion_unmap_kernel(dma_buf);
- ion_free(client, handle);
- msm_audio_ion_client_destroy(client);
+ msm_audio_dma_buf_unmap(dma_buf);
+
return 0;
}
EXPORT_SYMBOL(msm_audio_ion_free);
@@ -287,35 +456,42 @@
* msm_audio_ion_mmap -
* Audio ION memory map
*
- * @ab: audio buf pointer
+ * @abuff: audio buf pointer
* @vma: virtual mem area
*
* Returns 0 on success or error on failure
*/
-int msm_audio_ion_mmap(struct audio_buffer *ab,
+int msm_audio_ion_mmap(struct audio_buffer *abuff,
struct vm_area_struct *vma)
{
+ struct msm_audio_alloc_data *alloc_data = NULL;
struct sg_table *table;
unsigned long addr = vma->vm_start;
unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
struct scatterlist *sg;
unsigned int i;
struct page *page;
- int ret;
+ int ret = 0;
+ bool found = false;
+ struct device *cb_dev = msm_audio_ion_data.cb_dev;
- pr_debug("%s\n", __func__);
+ mutex_lock(&(msm_audio_ion_data.list_mutex));
+ list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
+ list) {
+ if (alloc_data->dma_buf == abuff->dma_buf) {
+ found = true;
+ table = alloc_data->table;
+ break;
+ }
+ }
+ mutex_unlock(&(msm_audio_ion_data.list_mutex));
- table = ion_sg_table(ab->client, ab->handle);
-
- if (IS_ERR(table)) {
- pr_err("%s: Unable to get sg_table from ion: %ld\n",
- __func__, PTR_ERR(table));
- return PTR_ERR(table);
- } else if (!table) {
- pr_err("%s: sg_list is NULL\n", __func__);
+ if (!found) {
+ dev_err(cb_dev,
+ "%s: cannot find allocation, dma_buf %pK",
+ __func__, abuff->dma_buf);
return -EINVAL;
}
-
/* uncached */
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
@@ -354,383 +530,79 @@
return 0;
}
} else {
- ion_phys_addr_t phys_addr;
- size_t phys_len;
- size_t va_len = 0;
-
pr_debug("%s: page is NULL\n", __func__);
- ret = ion_phys(ab->client, ab->handle, &phys_addr, &phys_len);
- if (ret) {
- pr_err("%s: Unable to get phys address from ION buffer: %d\n"
- , __func__, ret);
- return ret;
- }
- pr_debug("phys=%pKK len=%zd\n", &phys_addr, phys_len);
- pr_debug("vma=%pK, vm_start=%x vm_end=%x vm_pgoff=%ld vm_page_prot=%lu\n",
- vma, (unsigned int)vma->vm_start,
- (unsigned int)vma->vm_end, vma->vm_pgoff,
- (unsigned long)pgprot_val(vma->vm_page_prot));
- va_len = vma->vm_end - vma->vm_start;
- if ((offset > phys_len) || (va_len > phys_len-offset)) {
- pr_err("wrong offset size %ld, lens= %zd, va_len=%zd\n",
- offset, phys_len, va_len);
- return -EINVAL;
- }
- ret = remap_pfn_range(vma, vma->vm_start,
- __phys_to_pfn(phys_addr) + vma->vm_pgoff,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
+ ret = -EINVAL;
}
- return 0;
+
+ return ret;
}
EXPORT_SYMBOL(msm_audio_ion_mmap);
-
-bool msm_audio_ion_is_smmu_available(void)
-{
- return msm_audio_ion_data.smmu_enabled;
-}
-
-/* move to static section again */
-struct ion_client *msm_audio_ion_client_create(const char *name)
-{
- struct ion_client *pclient = NULL;
-
- pclient = msm_ion_client_create(name);
- return pclient;
-}
-EXPORT_SYMBOL(msm_audio_ion_client_create);
-
/**
- * msm_audio_ion_client_destroy -
- * Removes ION client handle
+ * msm_audio_ion_cache_operations-
+ * Cache operations on cached Audio ION buffers
*
- * @client: ION client
- *
- */
-void msm_audio_ion_client_destroy(struct ion_client *client)
-{
- pr_debug("%s: client = %pK smmu_enabled = %d\n", __func__,
- client, msm_audio_ion_data.smmu_enabled);
-
- ion_client_destroy(client);
-}
-EXPORT_SYMBOL(msm_audio_ion_client_destroy);
-
-/**
- * msm_audio_ion_import_legacy -
- * Alloc ION memory for given size
- *
- * @name: ION client name
- * @client: ION client
- * @handle: ION handle to be updated
- * @fd: ION fd
- * @ionflag: Flags for ION handle
- * @bufsz: buffer size
- * @paddr: pointer to be updated with physical address of allocated ION memory
- * @pa_len: pointer to be updated with size of physical memory
- * @vaddr: pointer to be updated with virtual address
+ * @abuff: audio buf pointer
+ * @cache_op: cache operation to be performed
*
* Returns 0 on success or error on failure
*/
-int msm_audio_ion_import_legacy(const char *name, struct ion_client *client,
- struct ion_handle **handle, int fd,
- unsigned long *ionflag, size_t bufsz,
- ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr)
-{
- int rc = 0;
-
- if (!name || !client || !handle || !paddr || !vaddr || !pa_len) {
- pr_err("%s: Invalid params\n", __func__);
- rc = -EINVAL;
- goto err;
- }
- /* client is already created for legacy and given
- * name should be audio_acdb_client or Audio_Dec_Client,
- * bufsz should be 0 and fd shouldn't be 0 as of now
- */
- *handle = ion_import_dma_buf_fd(client, fd);
- pr_debug("%s: DMA Buf name=%s, fd=%d handle=%pK\n", __func__,
- name, fd, *handle);
- if (IS_ERR_OR_NULL((void *)(*handle))) {
- pr_err("%s: ion import dma buffer failed\n",
- __func__);
- rc = -EINVAL;
- goto err;
- }
-
- if (ionflag != NULL) {
- rc = ion_handle_get_flags(client, *handle, ionflag);
- if (rc) {
- pr_err("%s: could not get flags for the handle\n",
- __func__);
- rc = -EINVAL;
- goto err_ion_handle;
- }
- }
-
- rc = msm_audio_ion_get_phys(client, *handle, paddr, pa_len);
- if (rc) {
- pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
- __func__, rc);
- rc = -EINVAL;
- goto err_ion_handle;
- }
-
- /*Need to add condition SMMU enable or not */
- *vaddr = ion_map_kernel(client, *handle);
- if (IS_ERR_OR_NULL((void *)*vaddr)) {
- pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
- rc = -EINVAL;
- goto err_ion_handle;
- }
-
- if (bufsz != 0)
- memset((void *)*vaddr, 0, bufsz);
-
- return 0;
-
-err_ion_handle:
- ion_free(client, *handle);
-err:
- return rc;
-}
-EXPORT_SYMBOL(msm_audio_ion_import_legacy);
-
-/**
- * msm_audio_ion_free_legacy -
- * Frees ION memory for given handle
- *
- * @client: ION client
- * @handle: ION handle
- *
- */
-int msm_audio_ion_free_legacy(struct ion_client *client,
- struct ion_handle *handle)
-{
- if (msm_audio_ion_data.smmu_enabled)
- msm_audio_dma_buf_unmap(client, handle);
-
- ion_unmap_kernel(client, handle);
-
- ion_free(client, handle);
- /* no client_destrody in legacy*/
- return 0;
-}
-EXPORT_SYMBOL(msm_audio_ion_free_legacy);
-
int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op)
{
unsigned long ionflag = 0;
int rc = 0;
- int msm_cache_ops = 0;
if (!abuff) {
pr_err("%s: Invalid params: %pK\n", __func__, abuff);
return -EINVAL;
}
- rc = ion_handle_get_flags(abuff->client, abuff->handle,
- &ionflag);
+ rc = dma_buf_get_flags(abuff->dma_buf, &ionflag);
if (rc) {
- pr_err("ion_handle_get_flags failed: %d\n", rc);
+ pr_err("%s: dma_buf_get_flags failed: %d\n", __func__, rc);
goto cache_op_failed;
}
- /* has to be CACHED */
- if (ION_IS_CACHED(ionflag)) {
- /* ION_IOC_INV_CACHES or ION_IOC_CLEAN_CACHES */
- msm_cache_ops = cache_op;
- rc = msm_ion_do_cache_op(abuff->client,
- abuff->handle,
- (unsigned long *) abuff->data,
- (unsigned long)abuff->size,
- msm_cache_ops);
- if (rc) {
- pr_err("cache operation failed %d\n", rc);
- goto cache_op_failed;
- }
- }
-cache_op_failed:
- return rc;
-}
-
-
-static int msm_audio_dma_buf_map(struct ion_client *client,
- struct ion_handle *handle,
- ion_phys_addr_t *addr, size_t *len)
-{
-
- struct msm_audio_alloc_data *alloc_data;
- struct device *cb_dev;
- int rc = 0;
-
- cb_dev = msm_audio_ion_data.cb_dev;
-
- /* Data required per buffer mapping */
- alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
- if (!alloc_data)
- return -ENOMEM;
-
- /* Get the ION handle size */
- ion_handle_get_size(client, handle, len);
-
- alloc_data->client = client;
- alloc_data->handle = handle;
- alloc_data->len = *len;
-
- /* Get the dma_buf handle from ion_handle */
- alloc_data->dma_buf = ion_share_dma_buf(client, handle);
- if (IS_ERR(alloc_data->dma_buf)) {
- rc = PTR_ERR(alloc_data->dma_buf);
- dev_err(cb_dev,
- "%s: Fail to get dma_buf handle, rc = %d\n",
- __func__, rc);
- goto err_dma_buf;
- }
-
- /* Attach the dma_buf to context bank device */
- alloc_data->attach = dma_buf_attach(alloc_data->dma_buf,
- cb_dev);
- if (IS_ERR(alloc_data->attach)) {
- rc = PTR_ERR(alloc_data->attach);
- dev_err(cb_dev,
- "%s: Fail to attach dma_buf to CB, rc = %d\n",
- __func__, rc);
- goto err_attach;
- }
-
- /*
- * Get the scatter-gather list.
- * There is no info as this is a write buffer or
- * read buffer, hence the request is bi-directional
- * to accommodate both read and write mappings.
- */
- alloc_data->table = dma_buf_map_attachment(alloc_data->attach,
- DMA_BIDIRECTIONAL);
- if (IS_ERR(alloc_data->table)) {
- rc = PTR_ERR(alloc_data->table);
- dev_err(cb_dev,
- "%s: Fail to map attachment, rc = %d\n",
- __func__, rc);
- goto err_map_attach;
- }
-
- rc = dma_map_sg(cb_dev, alloc_data->table->sgl,
- alloc_data->table->nents,
- DMA_BIDIRECTIONAL);
- if (rc != alloc_data->table->nents) {
- dev_err(cb_dev,
- "%s: Fail to map SG, rc = %d, nents = %d\n",
- __func__, rc, alloc_data->table->nents);
- goto err_map_sg;
- }
- /* Make sure not to return rc from dma_map_sg, as it can be nonzero */
- rc = 0;
-
- /* physical address from mapping */
- *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
-
- msm_audio_ion_add_allocation(&msm_audio_ion_data,
- alloc_data);
- return rc;
-
-err_map_sg:
- dma_buf_unmap_attachment(alloc_data->attach,
- alloc_data->table,
- DMA_BIDIRECTIONAL);
-err_map_attach:
- dma_buf_detach(alloc_data->dma_buf,
- alloc_data->attach);
-err_attach:
- dma_buf_put(alloc_data->dma_buf);
-
-err_dma_buf:
- kfree(alloc_data);
-
- return rc;
-}
-
-static int msm_audio_dma_buf_unmap(struct ion_client *client,
- struct ion_handle *handle)
-{
- int rc = 0;
- struct msm_audio_alloc_data *alloc_data = NULL;
- struct list_head *ptr, *next;
- struct device *cb_dev = msm_audio_ion_data.cb_dev;
- bool found = false;
-
- /*
- * Though list_for_each_safe is delete safe, lock
- * should be explicitly acquired to avoid race condition
- * on adding elements to the list.
- */
- mutex_lock(&(msm_audio_ion_data.list_mutex));
- list_for_each_safe(ptr, next,
- &(msm_audio_ion_data.alloc_list)) {
-
- alloc_data = list_entry(ptr, struct msm_audio_alloc_data,
- list);
-
- if (alloc_data->handle == handle &&
- alloc_data->client == client) {
- found = true;
- dma_unmap_sg(cb_dev,
- alloc_data->table->sgl,
- alloc_data->table->nents,
- DMA_BIDIRECTIONAL);
-
- dma_buf_unmap_attachment(alloc_data->attach,
- alloc_data->table,
- DMA_BIDIRECTIONAL);
-
- dma_buf_detach(alloc_data->dma_buf,
- alloc_data->attach);
-
- dma_buf_put(alloc_data->dma_buf);
-
- list_del(&(alloc_data->list));
- kfree(alloc_data);
+ /* Has to be CACHED */
+ if (ionflag & ION_FLAG_CACHED) {
+ /* MSM_AUDIO_ION_INV_CACHES or MSM_AUDIO_ION_CLEAN_CACHES */
+ switch (cache_op) {
+ case MSM_AUDIO_ION_INV_CACHES:
+ case MSM_AUDIO_ION_CLEAN_CACHES:
+ dma_buf_begin_cpu_access(abuff->dma_buf,
+ DMA_BIDIRECTIONAL);
+ dma_buf_end_cpu_access(abuff->dma_buf,
+ DMA_BIDIRECTIONAL);
break;
+ default:
+ pr_err("%s: Invalid cache operation %d\n",
+ __func__, cache_op);
}
- }
- mutex_unlock(&(msm_audio_ion_data.list_mutex));
-
- if (!found) {
- dev_err(cb_dev,
- "%s: cannot find allocation, ion_handle %pK, ion_client %pK",
- __func__, handle, client);
+ } else {
+ pr_err("%s: Cache ops called on uncached buffer: %pK\n",
+ __func__, abuff->dma_buf);
rc = -EINVAL;
}
+cache_op_failed:
return rc;
}
+EXPORT_SYMBOL(msm_audio_ion_cache_operations);
-static int msm_audio_ion_get_phys(struct ion_client *client,
- struct ion_handle *handle,
- ion_phys_addr_t *addr, size_t *len)
+/**
+ * msm_audio_populate_upper_32_bits -
+ * retrieve upper 32bits of 64bit address
+ *
+ * @pa: 64bit physical address
+ *
+ */
+u32 msm_audio_populate_upper_32_bits(dma_addr_t pa)
{
- int rc = 0;
-
- pr_debug("%s: smmu_enabled = %d\n", __func__,
- msm_audio_ion_data.smmu_enabled);
-
- if (msm_audio_ion_data.smmu_enabled) {
- rc = msm_audio_dma_buf_map(client, handle, addr, len);
- if (rc) {
- pr_err("%s: failed to map DMA buf, err = %d\n",
- __func__, rc);
- goto err;
- }
- /* Append the SMMU SID information to the IOVA address */
- *addr |= msm_audio_ion_data.smmu_sid_bits;
- } else {
- rc = ion_phys(client, handle, addr, len);
- }
-
- pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc);
-err:
- return rc;
+ if (sizeof(dma_addr_t) == sizeof(u32))
+ return upper_32_bits(msm_audio_ion_data.smmu_sid_bits);
+ else
+ return upper_32_bits(pa);
}
+EXPORT_SYMBOL(msm_audio_populate_upper_32_bits);
static int msm_audio_smmu_init(struct device *dev)
{
@@ -768,115 +640,75 @@
};
MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
-
-u32 msm_audio_ion_get_smmu_sid_mode32(void)
-{
- if (msm_audio_ion_data.smmu_enabled)
- return upper_32_bits(msm_audio_ion_data.smmu_sid_bits);
- else
- return 0;
-}
-
-/**
- * msm_audio_populate_upper_32_bits -
- * retrieve upper 32bits of 64bit address
- *
- * @pa: 64bit physical address
- *
- */
-u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa)
-{
- if (sizeof(ion_phys_addr_t) == sizeof(u32))
- return msm_audio_ion_get_smmu_sid_mode32();
- else
- return upper_32_bits(pa);
-}
-EXPORT_SYMBOL(msm_audio_populate_upper_32_bits);
-
static int msm_audio_ion_probe(struct platform_device *pdev)
{
int rc = 0;
- const char *msm_audio_ion_dt = "qcom,smmu-enabled";
const char *msm_audio_ion_smmu = "qcom,smmu-version";
const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask";
- bool smmu_enabled;
enum apr_subsys_state q6_state;
struct device *dev = &pdev->dev;
+ u64 smmu_sid = 0;
+ u64 smmu_sid_mask = 0;
+ struct of_phandle_args iommuspec;
if (dev->of_node == NULL) {
dev_err(dev,
"%s: device tree is not found\n",
__func__);
- msm_audio_ion_data.smmu_enabled = 0;
return 0;
}
- smmu_enabled = of_property_read_bool(dev->of_node,
- msm_audio_ion_dt);
- msm_audio_ion_data.smmu_enabled = smmu_enabled;
-
- if (smmu_enabled) {
- rc = of_property_read_u32(dev->of_node,
- msm_audio_ion_smmu,
- &msm_audio_ion_data.smmu_version);
- if (rc) {
- dev_err(dev,
- "%s: qcom,smmu_version missing in DT node\n",
- __func__);
- return rc;
- }
- dev_dbg(dev, "%s: SMMU version is (%d)", __func__,
- msm_audio_ion_data.smmu_version);
- q6_state = apr_get_q6_state();
- if (q6_state == APR_SUBSYS_DOWN) {
- dev_dbg(dev,
- "defering %s, adsp_state %d\n",
- __func__, q6_state);
- return -EPROBE_DEFER;
- }
- dev_dbg(dev, "%s: adsp is ready\n", __func__);
+ rc = of_property_read_u32(dev->of_node,
+ msm_audio_ion_smmu,
+ &msm_audio_ion_data.smmu_version);
+ if (rc) {
+ dev_err(dev,
+ "%s: qcom,smmu_version missing in DT node\n",
+ __func__);
+ return rc;
}
-
- dev_dbg(dev, "%s: SMMU is %s\n", __func__,
- (smmu_enabled) ? "Enabled" : "Disabled");
-
- if (smmu_enabled) {
- u64 smmu_sid = 0;
- u64 smmu_sid_mask = 0;
- struct of_phandle_args iommuspec;
-
- /* Get SMMU SID information from Devicetree */
- rc = of_property_read_u64(dev->of_node,
- msm_audio_ion_smmu_sid_mask,
- &smmu_sid_mask);
- if (rc) {
- dev_err(dev,
- "%s: qcom,smmu-sid-mask missing in DT node, using default\n",
- __func__);
- smmu_sid_mask = 0xFFFFFFFFFFFFFFFF;
- }
- rc = of_parse_phandle_with_args(dev->of_node, "iommus",
- "#iommu-cells", 0, &iommuspec);
- if (rc)
- dev_err(dev, "%s: could not get smmu SID, ret = %d\n",
- __func__, rc);
- else
- smmu_sid = (iommuspec.args[0] & smmu_sid_mask);
-
- msm_audio_ion_data.smmu_sid_bits =
- smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET;
-
- if (msm_audio_ion_data.smmu_version == 0x2) {
- rc = msm_audio_smmu_init(dev);
- } else {
- dev_err(dev, "%s: smmu version invalid %d\n",
- __func__, msm_audio_ion_data.smmu_version);
- rc = -EINVAL;
- }
- if (rc)
- dev_err(dev, "%s: smmu init failed, err = %d\n",
- __func__, rc);
+ dev_dbg(dev, "%s: SMMU version is (%d)", __func__,
+ msm_audio_ion_data.smmu_version);
+ q6_state = apr_get_q6_state();
+ if (q6_state == APR_SUBSYS_DOWN) {
+ dev_dbg(dev,
+ "defering %s, adsp_state %d\n",
+ __func__, q6_state);
+ return -EPROBE_DEFER;
}
+ dev_dbg(dev, "%s: adsp is ready\n", __func__);
+
+ /* Get SMMU SID information from Devicetree */
+ rc = of_property_read_u64(dev->of_node,
+ msm_audio_ion_smmu_sid_mask,
+ &smmu_sid_mask);
+ if (rc) {
+ dev_err(dev,
+ "%s: qcom,smmu-sid-mask missing in DT node, using default\n",
+ __func__);
+ smmu_sid_mask = 0xFFFFFFFFFFFFFFFF;
+ }
+ rc = of_parse_phandle_with_args(dev->of_node, "iommus",
+ "#iommu-cells", 0, &iommuspec);
+ if (rc)
+ dev_err(dev, "%s: could not get smmu SID, ret = %d\n",
+ __func__, rc);
+ else
+ smmu_sid = (iommuspec.args[0] & smmu_sid_mask);
+
+ msm_audio_ion_data.smmu_sid_bits =
+ smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET;
+
+ if (msm_audio_ion_data.smmu_version == 0x2) {
+ rc = msm_audio_smmu_init(dev);
+ } else {
+ dev_err(dev, "%s: smmu version invalid %d\n",
+ __func__, msm_audio_ion_data.smmu_version);
+ rc = -EINVAL;
+ }
+ if (rc)
+ dev_err(dev, "%s: smmu init failed, err = %d\n",
+ __func__, rc);
if (!rc)
msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED;
@@ -897,7 +729,6 @@
arm_iommu_release_mapping(mapping);
}
- msm_audio_ion_data.smmu_enabled = 0;
msm_audio_ion_data.device_status = 0;
return 0;
}
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 514af25..282d7f7 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,7 @@
#include <dsp/q6audio-v2.h>
#include <dsp/q6afe-v2.h>
#include <dsp/audio_cal_utils.h>
+#include <dsp/q6common.h>
#include <ipc/apr.h>
#include "adsp_err.h"
@@ -32,8 +33,8 @@
#define RESET_COPP_ID 99
#define INVALID_COPP_ID 0xFF
/* Used for inband payload copy, max size is 4k */
-/* 2 is to account for module & param ID in payload */
-#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 2 * sizeof(uint32_t))
+/* 3 is to account for module, instance & param ID in payload */
+#define ADM_GET_PARAMETER_LENGTH (4096 - APR_HDR_SIZE - 3 * sizeof(uint32_t))
#define ULL_SUPPORTED_BITS_PER_SAMPLE 16
#define ULL_SUPPORTED_SAMPLE_RATE 48000
@@ -74,8 +75,7 @@
};
struct source_tracking_data {
- struct ion_client *ion_client;
- struct ion_handle *ion_handle;
+ struct dma_buf *dma_buf;
struct param_outband memmap;
int apr_cmd_status;
};
@@ -104,7 +104,6 @@
int num_ec_ref_rx_chans;
int ec_ref_rx_bit_width;
int ec_ref_rx_sampling_rate;
- int lsm_port_id;
};
static struct adm_ctl this_adm;
@@ -126,8 +125,8 @@
};
static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
-static int adm_module_topo_list[
- MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH];
+static int adm_module_topo_list[MAX_COPPS_PER_PORT *
+ ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH];
static struct mutex dts_srs_lock;
void msm_dts_srs_acquire_lock(void)
@@ -318,266 +317,109 @@
int srs_trumedia_open(int port_id, int copp_idx, __s32 srs_tech_id,
void *srs_params)
{
- struct adm_cmd_set_pp_params_inband_v5 *adm_params = NULL;
- struct adm_cmd_set_pp_params_v5 *adm_params_ = NULL;
- __s32 sz = 0, param_id, module_id = SRS_TRUMEDIA_MODULE_ID, outband = 0;
- int ret = 0, port_idx;
+ struct param_hdr_v3 param_hdr;
+ struct mem_mapping_hdr mem_hdr;
+ u32 total_param_size = 0;
+ bool outband = false;
+ int port_idx;
+ int ret = 0;
pr_debug("SRS - %s", __func__);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
port_id = afe_convert_virtual_to_portid(port_id);
port_idx = adm_validate_and_get_port_index(port_id);
if (port_idx < 0) {
pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
return -EINVAL;
}
+
+ param_hdr.module_id = SRS_TRUMEDIA_MODULE_ID;
+ param_hdr.instance_id = INSTANCE_ID_0;
+
switch (srs_tech_id) {
case SRS_ID_GLOBAL: {
- struct srs_trumedia_params_GLOBAL *glb_params = NULL;
-
- sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS;
+ param_hdr.param_size =
sizeof(struct srs_trumedia_params_GLOBAL);
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
- adm_params->payload_size =
- sizeof(struct srs_trumedia_params_GLOBAL) +
- sizeof(struct adm_param_data_v5);
- param_id = SRS_TRUMEDIA_PARAMS;
- adm_params->params.param_size =
- sizeof(struct srs_trumedia_params_GLOBAL);
- glb_params = (struct srs_trumedia_params_GLOBAL *)
- ((u8 *)adm_params +
- sizeof(struct adm_cmd_set_pp_params_inband_v5));
- memcpy(glb_params, srs_params,
- sizeof(struct srs_trumedia_params_GLOBAL));
break;
}
case SRS_ID_WOWHD: {
- struct srs_trumedia_params_WOWHD *whd_params = NULL;
-
- sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
- sizeof(struct srs_trumedia_params_WOWHD);
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
- adm_params->payload_size =
- sizeof(struct srs_trumedia_params_WOWHD) +
- sizeof(struct adm_param_data_v5);
- param_id = SRS_TRUMEDIA_PARAMS_WOWHD;
- adm_params->params.param_size =
- sizeof(struct srs_trumedia_params_WOWHD);
- whd_params = (struct srs_trumedia_params_WOWHD *)
- ((u8 *)adm_params +
- sizeof(struct adm_cmd_set_pp_params_inband_v5));
- memcpy(whd_params, srs_params,
- sizeof(struct srs_trumedia_params_WOWHD));
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS_WOWHD;
+ param_hdr.param_size = sizeof(struct srs_trumedia_params_WOWHD);
break;
}
case SRS_ID_CSHP: {
- struct srs_trumedia_params_CSHP *chp_params = NULL;
-
- sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
- sizeof(struct srs_trumedia_params_CSHP);
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
- adm_params->payload_size =
- sizeof(struct srs_trumedia_params_CSHP) +
- sizeof(struct adm_param_data_v5);
- param_id = SRS_TRUMEDIA_PARAMS_CSHP;
- adm_params->params.param_size =
- sizeof(struct srs_trumedia_params_CSHP);
- chp_params = (struct srs_trumedia_params_CSHP *)
- ((u8 *)adm_params +
- sizeof(struct adm_cmd_set_pp_params_inband_v5));
- memcpy(chp_params, srs_params,
- sizeof(struct srs_trumedia_params_CSHP));
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS_CSHP;
+ param_hdr.param_size = sizeof(struct srs_trumedia_params_CSHP);
break;
}
case SRS_ID_HPF: {
- struct srs_trumedia_params_HPF *hpf_params = NULL;
-
- sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
- sizeof(struct srs_trumedia_params_HPF);
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
- adm_params->payload_size =
- sizeof(struct srs_trumedia_params_HPF) +
- sizeof(struct adm_param_data_v5);
- param_id = SRS_TRUMEDIA_PARAMS_HPF;
- adm_params->params.param_size =
- sizeof(struct srs_trumedia_params_HPF);
- hpf_params = (struct srs_trumedia_params_HPF *)
- ((u8 *)adm_params +
- sizeof(struct adm_cmd_set_pp_params_inband_v5));
- memcpy(hpf_params, srs_params,
- sizeof(struct srs_trumedia_params_HPF));
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS_HPF;
+ param_hdr.param_size = sizeof(struct srs_trumedia_params_HPF);
break;
}
case SRS_ID_AEQ: {
- int *update_params_ptr = (int *)this_adm.outband_memmap.kvaddr;
+ u8 *update_params_ptr = (u8 *) this_adm.outband_memmap.kvaddr;
- outband = 1;
- adm_params = kzalloc(sizeof(struct adm_cmd_set_pp_params_v5),
- GFP_KERNEL);
- adm_params_ = (struct adm_cmd_set_pp_params_v5 *)adm_params;
- if (!adm_params_) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
+ outband = true;
- sz = sizeof(struct srs_trumedia_params_AEQ);
if (update_params_ptr == NULL) {
pr_err("ADM_SRS_TRUMEDIA - %s: null memmap for AEQ params\n",
__func__);
ret = -EINVAL;
goto fail_cmd;
}
- param_id = SRS_TRUMEDIA_PARAMS_AEQ;
- *update_params_ptr++ = module_id;
- *update_params_ptr++ = param_id;
- *update_params_ptr++ = sz;
- memcpy(update_params_ptr, srs_params, sz);
- adm_params_->payload_size = sz + 12;
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS_AEQ;
+ param_hdr.param_size = sizeof(struct srs_trumedia_params_AEQ);
+ ret = q6common_pack_pp_params(update_params_ptr, ¶m_hdr,
+ srs_params, &total_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack param header and data, error %d\n",
+ __func__, ret);
+ goto fail_cmd;
+ }
break;
}
case SRS_ID_HL: {
- struct srs_trumedia_params_HL *hl_params = NULL;
-
- sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
- sizeof(struct srs_trumedia_params_HL);
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
- adm_params->payload_size =
- sizeof(struct srs_trumedia_params_HL) +
- sizeof(struct adm_param_data_v5);
- param_id = SRS_TRUMEDIA_PARAMS_HL;
- adm_params->params.param_size =
- sizeof(struct srs_trumedia_params_HL);
- hl_params = (struct srs_trumedia_params_HL *)
- ((u8 *)adm_params +
- sizeof(struct adm_cmd_set_pp_params_inband_v5));
- memcpy(hl_params, srs_params,
- sizeof(struct srs_trumedia_params_HL));
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS_HL;
+ param_hdr.param_size = sizeof(struct srs_trumedia_params_HL);
break;
}
case SRS_ID_GEQ: {
- struct srs_trumedia_params_GEQ *geq_params = NULL;
-
- sz = sizeof(struct adm_cmd_set_pp_params_inband_v5) +
- sizeof(struct srs_trumedia_params_GEQ);
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed\n",
- __func__);
- return -ENOMEM;
- }
- adm_params->payload_size =
- sizeof(struct srs_trumedia_params_GEQ) +
- sizeof(struct adm_param_data_v5);
- param_id = SRS_TRUMEDIA_PARAMS_GEQ;
- adm_params->params.param_size =
- sizeof(struct srs_trumedia_params_GEQ);
- geq_params = (struct srs_trumedia_params_GEQ *)
- ((u8 *)adm_params +
- sizeof(struct adm_cmd_set_pp_params_inband_v5));
- memcpy(geq_params, srs_params,
- sizeof(struct srs_trumedia_params_GEQ));
- pr_debug("SRS - %s: GEQ params prepared\n", __func__);
+ param_hdr.param_id = SRS_TRUMEDIA_PARAMS_GEQ;
+ param_hdr.param_size = sizeof(struct srs_trumedia_params_GEQ);
break;
}
default:
goto fail_cmd;
}
- adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_params->hdr.src_svc = APR_SVC_ADM;
- adm_params->hdr.src_domain = APR_DOMAIN_APPS;
- adm_params->hdr.src_port = port_id;
- adm_params->hdr.dest_svc = APR_SVC_ADM;
- adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_params->hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_params->hdr.token = port_idx << 16 | copp_idx;
- adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
if (outband && this_adm.outband_memmap.paddr) {
- adm_params->hdr.pkt_size =
- sizeof(struct adm_cmd_set_pp_params_v5);
- adm_params->payload_addr_lsw = lower_32_bits(
- this_adm.outband_memmap.paddr);
- adm_params->payload_addr_msw = msm_audio_populate_upper_32_bits(
- this_adm.outband_memmap.paddr);
- adm_params->mem_map_handle = atomic_read(&this_adm.
- mem_map_handles[ADM_SRS_TRUMEDIA]);
- } else {
- adm_params->hdr.pkt_size = sz;
- adm_params->payload_addr_lsw = 0;
- adm_params->payload_addr_msw = 0;
- adm_params->mem_map_handle = 0;
+ mem_hdr.data_payload_addr_lsw =
+ lower_32_bits(this_adm.outband_memmap.paddr);
+ mem_hdr.data_payload_addr_msw =
+ msm_audio_populate_upper_32_bits(
+ this_adm.outband_memmap.paddr);
+ mem_hdr.mem_map_handle = atomic_read(
+ &this_adm.mem_map_handles[ADM_SRS_TRUMEDIA]);
- adm_params->params.module_id = module_id;
- adm_params->params.param_id = param_id;
- adm_params->params.reserved = 0;
+ ret = adm_set_pp_params(port_id, copp_idx, &mem_hdr, NULL,
+ total_param_size);
+ } else {
+ ret = adm_pack_and_set_one_pp_param(port_id, copp_idx,
+ param_hdr,
+ (u8 *) srs_params);
}
- pr_debug("SRS - %s: Command was sent now check Q6 - port id = %d, size %d, module id %x, param id %x.\n",
- __func__, adm_params->hdr.dest_port,
- adm_params->payload_size, module_id, param_id);
-
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
- if (ret < 0) {
+ if (ret < 0)
pr_err("SRS - %s: ADM enable for port %d failed\n", __func__,
port_id);
- ret = -EINVAL;
- goto fail_cmd;
- }
- /* Wait for the callback with copp id */
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: SRS set params timed out port = %d\n",
- __func__, port_id);
- ret = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto fail_cmd;
- }
fail_cmd:
- kfree(adm_params);
return ret;
}
EXPORT_SYMBOL(srs_trumedia_open);
@@ -638,7 +480,7 @@
int channel_index)
{
struct adm_cmd_set_pspd_mtmx_strtr_params_v5 *adm_params = NULL;
- struct adm_param_data_v5 data_v5;
+ struct param_hdr_v3 data_v5;
int ret = 0, port_idx, sz = 0, param_size = 0;
u16 *adm_pspd_params;
u16 *ptr;
@@ -670,8 +512,8 @@
roundup(param_size, 4);
sz = sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5) +
- sizeof(struct default_chmixer_param_id_coeff) +
- sizeof(struct adm_param_data_v5) + param_size;
+ sizeof(struct default_chmixer_param_id_coeff) +
+ sizeof(struct param_hdr_v3) + param_size;
pr_debug("%s: sz = %d\n", __func__, sz);
adm_params = kzalloc(sz, GFP_KERNEL);
if (!adm_params)
@@ -689,13 +531,17 @@
&this_adm.copp.id[port_idx][copp_idx]);
adm_params->reserved = 0;
+ /*
+ * This module is internal to ADSP and cannot be configured with
+ * an instance id
+ */
data_v5.module_id = MTMX_MODULE_ID_DEFAULT_CHMIXER;
data_v5.param_id = DEFAULT_CHMIXER_PARAM_ID_COEFF;
data_v5.reserved = 0;
data_v5.param_size = param_size;
adm_params->payload_size =
- sizeof(struct default_chmixer_param_id_coeff) +
- sizeof(struct adm_param_data_v5) + data_v5.param_size;
+ sizeof(struct default_chmixer_param_id_coeff) +
+ sizeof(struct param_hdr_v3) + data_v5.param_size;
adm_pspd_params = (u16 *)((u8 *)adm_params +
sizeof(struct adm_cmd_set_pspd_mtmx_strtr_params_v5));
memcpy(adm_pspd_params, &data_v5, sizeof(data_v5));
@@ -943,335 +789,269 @@
}
EXPORT_SYMBOL(adm_set_stereo_to_custom_stereo);
-/**
- * adm_dolby_dap_send_params -
- * command to send dolby dap params
- *
- * @port_id: Port ID number
- * @copp_idx: copp index of ADM copp
- * @params: params pointer
- * @param_length: length of params
- *
- * Returns 0 on success or error on failure
+/*
+ * With pre-packed data, only the opcode differes from V5 and V6.
+ * Use q6common_pack_pp_params to pack the data correctly.
*/
-int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params,
- uint32_t params_length)
+int adm_set_pp_params(int port_id, int copp_idx,
+ struct mem_mapping_hdr *mem_hdr, u8 *param_data,
+ u32 param_size)
{
- struct adm_cmd_set_pp_params_v5 *adm_params = NULL;
- int sz, rc = 0;
- int port_idx;
-
- pr_debug("%s:\n", __func__);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
- return -EINVAL;
- }
-
- sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length;
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed", __func__);
- return -ENOMEM;
- }
-
- memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)),
- params, params_length);
- adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_params->hdr.pkt_size = sz;
- adm_params->hdr.src_svc = APR_SVC_ADM;
- adm_params->hdr.src_domain = APR_DOMAIN_APPS;
- adm_params->hdr.src_port = port_id;
- adm_params->hdr.dest_svc = APR_SVC_ADM;
- adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_params->hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_params->hdr.token = port_idx << 16 | copp_idx;
- adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- adm_params->payload_addr_lsw = 0;
- adm_params->payload_addr_msw = 0;
- adm_params->mem_map_handle = 0;
- adm_params->payload_size = params_length;
-
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
- if (rc < 0) {
- pr_err("%s: Set params failed port = 0x%x rc %d\n",
- __func__, port_id, rc);
- rc = -EINVAL;
- goto dolby_dap_send_param_return;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Set params timed out port = 0x%x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto dolby_dap_send_param_return;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto dolby_dap_send_param_return;
- }
- rc = 0;
-dolby_dap_send_param_return:
- kfree(adm_params);
- return rc;
-}
-EXPORT_SYMBOL(adm_dolby_dap_send_params);
-
-/**
- * adm_get_params_v5 -
- * command to retrieve ADM params for given module
- *
- * @port_id: Port ID number
- * @copp_idx: copp index of ADM copp
- * @params: params pointer
- * @param_length: length of params
- *
- * Returns 0 on success or error on failure
- */
-int adm_send_params_v5(int port_id, int copp_idx, char *params,
- uint32_t params_length)
-{
- struct adm_cmd_set_pp_params_v5 *adm_params = NULL;
- int rc = 0;
- int sz, port_idx;
-
- pr_debug("%s:\n", __func__);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
- return -EINVAL;
- }
-
- sz = sizeof(struct adm_cmd_set_pp_params_v5) + params_length;
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed", __func__);
- return -ENOMEM;
- }
-
- memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)),
- params, params_length);
- adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_params->hdr.pkt_size = sz;
- adm_params->hdr.src_svc = APR_SVC_ADM;
- adm_params->hdr.src_domain = APR_DOMAIN_APPS;
- adm_params->hdr.src_port = port_id;
- adm_params->hdr.dest_svc = APR_SVC_ADM;
- adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_params->hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_params->hdr.token = port_idx << 16 | copp_idx;
- adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- adm_params->payload_addr_lsw = 0;
- adm_params->payload_addr_msw = 0;
- adm_params->mem_map_handle = 0;
- adm_params->payload_size = params_length;
-
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
- if (rc < 0) {
- pr_err("%s: Set params failed port = 0x%x rc %d\n",
- __func__, port_id, rc);
- rc = -EINVAL;
- goto send_param_return;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Set params timed out port = 0x%x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto send_param_return;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto send_param_return;
- }
- rc = 0;
-send_param_return:
- kfree(adm_params);
- return rc;
-}
-EXPORT_SYMBOL(adm_send_params_v5);
-
-int adm_get_params_v2(int port_id, int copp_idx, uint32_t module_id,
- uint32_t param_id, uint32_t params_length,
- char *params, uint32_t client_id)
-{
- struct adm_cmd_get_pp_params_v5 *adm_params = NULL;
- int rc = 0, i = 0;
- int port_idx, idx;
- int *params_data = (int *)params;
- uint64_t sz = 0;
+ struct adm_cmd_set_pp_params *adm_set_params = NULL;
+ int size = 0;
+ int port_idx = 0;
+ atomic_t *copp_stat = NULL;
+ int ret = 0;
port_id = afe_convert_virtual_to_portid(port_id);
port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+ if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
+ pr_err("%s: Invalid port_idx 0x%x\n", __func__, port_idx);
+ return -EINVAL;
+ } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
+ pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx);
return -EINVAL;
}
- sz = (uint64_t)sizeof(struct adm_cmd_get_pp_params_v5) +
- (uint64_t)params_length;
- /*
- * Check if the value of "sz" (which is ultimately assigned to
- * "hdr.pkt_size") crosses U16_MAX.
- */
- if (sz > U16_MAX) {
- pr_err("%s: Invalid params_length\n", __func__);
- return -EINVAL;
- }
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s: adm params memory alloc failed", __func__);
+ /* Only add params_size in inband case */
+ size = sizeof(struct adm_cmd_set_pp_params);
+ if (param_data != NULL)
+ size += param_size;
+ adm_set_params = kzalloc(size, GFP_KERNEL);
+ if (!adm_set_params)
return -ENOMEM;
- }
- memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_get_pp_params_v5)),
- params, params_length);
- adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_params->hdr.pkt_size = sz;
- adm_params->hdr.src_svc = APR_SVC_ADM;
- adm_params->hdr.src_domain = APR_DOMAIN_APPS;
- adm_params->hdr.src_port = port_id;
- adm_params->hdr.dest_svc = APR_SVC_ADM;
- adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_params->hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_params->hdr.token = port_idx << 16 | client_id << 8 | copp_idx;
- adm_params->hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
- adm_params->data_payload_addr_lsw = 0;
- adm_params->data_payload_addr_msw = 0;
- adm_params->mem_map_handle = 0;
- adm_params->module_id = module_id;
- adm_params->param_id = param_id;
- adm_params->param_max_size = params_length;
- adm_params->reserved = 0;
+ adm_set_params->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ adm_set_params->apr_hdr.pkt_size = size;
+ adm_set_params->apr_hdr.src_svc = APR_SVC_ADM;
+ adm_set_params->apr_hdr.src_domain = APR_DOMAIN_APPS;
+ adm_set_params->apr_hdr.src_port = port_id;
+ adm_set_params->apr_hdr.dest_svc = APR_SVC_ADM;
+ adm_set_params->apr_hdr.dest_domain = APR_DOMAIN_ADSP;
+ adm_set_params->apr_hdr.dest_port =
+ atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
+ adm_set_params->apr_hdr.token = port_idx << 16 | copp_idx;
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
- if (rc < 0) {
- pr_err("%s: Failed to Get Params on port_id 0x%x %d\n",
- __func__, port_id, rc);
- rc = -EINVAL;
- goto adm_get_param_return;
- }
- /* Wait for the callback with copp id */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: get params timed out port_id = 0x%x\n", __func__,
- port_id);
- rc = -EINVAL;
- goto adm_get_param_return;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto adm_get_param_return;
- }
- idx = ADM_GET_PARAMETER_LENGTH * copp_idx;
+ if (q6common_is_instance_id_supported())
+ adm_set_params->apr_hdr.opcode = ADM_CMD_SET_PP_PARAMS_V6;
+ else
+ adm_set_params->apr_hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- if (adm_get_parameters[idx] < 0) {
- pr_err("%s: Size is invalid %d\n", __func__,
- adm_get_parameters[idx]);
- rc = -EINVAL;
- goto adm_get_param_return;
- }
- if ((params_data) &&
- (ARRAY_SIZE(adm_get_parameters) >
- idx) &&
- (ARRAY_SIZE(adm_get_parameters) >=
- 1+adm_get_parameters[idx]+idx) &&
- (params_length/sizeof(uint32_t) >=
- adm_get_parameters[idx])) {
- for (i = 0; i < adm_get_parameters[idx]; i++)
- params_data[i] = adm_get_parameters[1+i+idx];
+ adm_set_params->payload_size = param_size;
+ if (mem_hdr != NULL) {
+ /* Out of Band Case */
+ adm_set_params->mem_hdr = *mem_hdr;
+ } else if (param_data != NULL) {
+ /*
+ * In band case. Parameter data must be pre-packed with its
+ * header before calling this function. Use
+ * q6common_pack_pp_params to pack parameter data and header
+ * correctly.
+ */
+ memcpy(&adm_set_params->param_data, param_data, param_size);
} else {
- pr_err("%s: Get param data not copied! get_param array size %zd, index %d, params array size %zd, index %d\n",
- __func__, ARRAY_SIZE(adm_get_parameters),
- (1+adm_get_parameters[idx]+idx),
- params_length/sizeof(int),
- adm_get_parameters[idx]);
+ pr_err("%s: Received NULL pointers for both memory header and param data\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
}
- rc = 0;
-adm_get_param_return:
- kfree(adm_params);
- return rc;
+ copp_stat = &this_adm.copp.stat[port_idx][copp_idx];
+ atomic_set(copp_stat, -1);
+ ret = apr_send_pkt(this_adm.apr, (uint32_t *) adm_set_params);
+ if (ret < 0) {
+ pr_err("%s: Set params APR send failed port = 0x%x ret %d\n",
+ __func__, port_id, ret);
+ goto done;
+ }
+ ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
+ atomic_read(copp_stat) >= 0,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Set params timed out port = 0x%x\n", __func__,
+ port_id);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+ if (atomic_read(copp_stat) > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(atomic_read(copp_stat)));
+ ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat));
+ goto done;
+ }
+
+ ret = 0;
+done:
+ kfree(adm_set_params);
+ return ret;
}
+EXPORT_SYMBOL(adm_set_pp_params);
-/**
- * adm_get_params -
- * command to retrieve ADM params for given module
- *
- * @port_id: Port ID number
- * @copp_idx: copp index of ADM copp
- * @module_id: module ID
- * @param_id: Param index
- * @param_length: length of params
- * @params: params pointer
- *
- * Returns 0 on success or error on failure
- */
-int adm_get_params(int port_id, int copp_idx, uint32_t module_id,
- uint32_t param_id, uint32_t params_length, char *params)
+int adm_pack_and_set_one_pp_param(int port_id, int copp_idx,
+ struct param_hdr_v3 param_hdr, u8 *param_data)
{
- return adm_get_params_v2(port_id, copp_idx, module_id, param_id,
- params_length, params, 0);
+ u8 *packed_data = NULL;
+ u32 total_size = 0;
+ int ret = 0;
+
+ total_size = sizeof(union param_hdrs) + param_hdr.param_size;
+ packed_data = kzalloc(total_size, GFP_KERNEL);
+ if (!packed_data)
+ return -ENOMEM;
+
+ ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data,
+ &total_size);
+ if (ret) {
+ pr_err("%s: Failed to pack parameter data, error %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = adm_set_pp_params(port_id, copp_idx, NULL, packed_data,
+ total_size);
+ if (ret)
+ pr_err("%s: Failed to set parameter data, error %d\n", __func__,
+ ret);
+done:
+ kfree(packed_data);
+ return ret;
}
-EXPORT_SYMBOL(adm_get_params);
+EXPORT_SYMBOL(adm_pack_and_set_one_pp_param);
-/**
- * adm_get_pp_topo_module_list -
- * command to update PP top module list
- *
- * @port_id: Port ID number
- * @copp_idx: copp index of ADM copp
- * @param_length: length of params
- * @params: pointer with PP top module params
- *
- * Returns 0 on success or error on failure
+/*
+ * Only one parameter can be requested at a time. Therefore, packing and sending
+ * the request can be handled locally.
*/
-int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length,
- char *params)
+int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id,
+ struct mem_mapping_hdr *mem_hdr,
+ struct param_hdr_v3 *param_hdr, u8 *returned_param_data)
{
- struct adm_cmd_get_pp_topo_module_list_t *adm_pp_module_list = NULL;
- int sz, rc = 0, i = 0;
- int port_idx, idx;
- int32_t *params_data = (int32_t *)params;
+ struct adm_cmd_get_pp_params adm_get_params;
+ int total_size = 0;
+ int get_param_array_sz = ARRAY_SIZE(adm_get_parameters);
+ int returned_param_size = 0;
+ int returned_param_size_in_bytes = 0;
+ int port_idx = 0;
+ int idx = 0;
+ atomic_t *copp_stat = NULL;
+ int ret = 0;
+
+ if (param_hdr == NULL) {
+ pr_err("%s: Received NULL pointer for parameter header\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ port_id = afe_convert_virtual_to_portid(port_id);
+ port_idx = adm_validate_and_get_port_index(port_id);
+ if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
+ pr_err("%s: Invalid port_idx 0x%x\n", __func__, port_idx);
+ return -EINVAL;
+ }
+ if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
+ pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx);
+ return -EINVAL;
+ }
+
+ memset(&adm_get_params, 0, sizeof(adm_get_params));
+
+ if (mem_hdr != NULL)
+ adm_get_params.mem_hdr = *mem_hdr;
+
+ q6common_pack_pp_params((u8 *) &adm_get_params.param_hdr, param_hdr,
+ NULL, &total_size);
+
+ /* Pack APR header after filling body so total_size has correct value */
+ adm_get_params.apr_hdr.pkt_size = total_size;
+ adm_get_params.apr_hdr.src_svc = APR_SVC_ADM;
+ adm_get_params.apr_hdr.src_domain = APR_DOMAIN_APPS;
+ adm_get_params.apr_hdr.src_port = port_id;
+ adm_get_params.apr_hdr.dest_svc = APR_SVC_ADM;
+ adm_get_params.apr_hdr.dest_domain = APR_DOMAIN_ADSP;
+ adm_get_params.apr_hdr.dest_port =
+ atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
+ adm_get_params.apr_hdr.token =
+ port_idx << 16 | client_id << 8 | copp_idx;
+
+ if (q6common_is_instance_id_supported())
+ adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V6;
+ else
+ adm_get_params.apr_hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
+
+ copp_stat = &this_adm.copp.stat[port_idx][copp_idx];
+ atomic_set(copp_stat, -1);
+ ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_params);
+ if (ret) {
+ pr_err("%s: Get params APR send failed port = 0x%x ret %d\n",
+ __func__, port_id, ret);
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
+ atomic_read(copp_stat) >= 0,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Get params timed out port = 0x%x\n", __func__,
+ port_id);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+ if (atomic_read(copp_stat) > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(atomic_read(copp_stat)));
+ ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat));
+ goto done;
+ }
+
+ ret = 0;
+
+ /* Copy data to caller if sent in band */
+ if (!returned_param_data) {
+ pr_debug("%s: Received NULL pointer for param destination, not copying payload\n",
+ __func__);
+ return 0;
+ }
+
+ idx = ADM_GET_PARAMETER_LENGTH * copp_idx;
+ returned_param_size = adm_get_parameters[idx];
+ if (returned_param_size < 0 ||
+ returned_param_size + idx + 1 > get_param_array_sz) {
+ pr_err("%s: Invalid parameter size %d\n", __func__,
+ returned_param_size);
+ return -EINVAL;
+ }
+
+ returned_param_size_in_bytes = returned_param_size * sizeof(uint32_t);
+ if (param_hdr->param_size < returned_param_size_in_bytes) {
+ pr_err("%s: Provided buffer is not big enough, provided buffer size(%d) size needed(%d)\n",
+ __func__, param_hdr->param_size,
+ returned_param_size_in_bytes);
+ return -EINVAL;
+ }
+
+ memcpy(returned_param_data, &adm_get_parameters[idx + 1],
+ returned_param_size_in_bytes);
+done:
+ return ret;
+}
+EXPORT_SYMBOL(adm_get_pp_params);
+
+int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx,
+ int32_t param_length,
+ int32_t *returned_params)
+{
+ struct adm_cmd_get_pp_topo_module_list adm_get_module_list;
+ bool iid_supported = q6common_is_instance_id_supported();
int *topo_list;
+ int num_modules = 0;
+ int list_size = 0;
+ int port_idx, idx;
+ int i = 0;
+ atomic_t *copp_stat = NULL;
+ int ret = 0;
pr_debug("%s : port_id %x", __func__, port_id);
port_id = afe_convert_virtual_to_portid(port_id);
@@ -1286,81 +1066,96 @@
return -EINVAL;
}
- sz = sizeof(struct adm_cmd_get_pp_topo_module_list_t) + param_length;
- adm_pp_module_list = kzalloc(sz, GFP_KERNEL);
- if (!adm_pp_module_list) {
- pr_err("%s, adm params memory alloc failed", __func__);
- return -ENOMEM;
+ memset(&adm_get_module_list, 0, sizeof(adm_get_module_list));
+
+ adm_get_module_list.apr_hdr.pkt_size = sizeof(adm_get_module_list);
+ adm_get_module_list.apr_hdr.src_svc = APR_SVC_ADM;
+ adm_get_module_list.apr_hdr.src_domain = APR_DOMAIN_APPS;
+ adm_get_module_list.apr_hdr.src_port = port_id;
+ adm_get_module_list.apr_hdr.dest_svc = APR_SVC_ADM;
+ adm_get_module_list.apr_hdr.dest_domain = APR_DOMAIN_ADSP;
+ adm_get_module_list.apr_hdr.dest_port =
+ atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
+ adm_get_module_list.apr_hdr.token = port_idx << 16 | copp_idx;
+ /*
+ * Out of band functionality is not currently utilized.
+ * Assume in band.
+ */
+ if (iid_supported) {
+ adm_get_module_list.apr_hdr.opcode =
+ ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2;
+ adm_get_module_list.param_max_size = param_length;
+ } else {
+ adm_get_module_list.apr_hdr.opcode =
+ ADM_CMD_GET_PP_TOPO_MODULE_LIST;
+
+ if (param_length > U16_MAX) {
+ pr_err("%s: Invalid param length for V1 %d\n", __func__,
+ param_length);
+ return -EINVAL;
+ }
+ adm_get_module_list.param_max_size = param_length << 16;
}
- memcpy(((u8 *)adm_pp_module_list +
- sizeof(struct adm_cmd_get_pp_topo_module_list_t)),
- params, param_length);
- adm_pp_module_list->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_pp_module_list->hdr.pkt_size = sz;
- adm_pp_module_list->hdr.src_svc = APR_SVC_ADM;
- adm_pp_module_list->hdr.src_domain = APR_DOMAIN_APPS;
- adm_pp_module_list->hdr.src_port = port_id;
- adm_pp_module_list->hdr.dest_svc = APR_SVC_ADM;
- adm_pp_module_list->hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_pp_module_list->hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_pp_module_list->hdr.token = port_idx << 16 | copp_idx;
- adm_pp_module_list->hdr.opcode = ADM_CMD_GET_PP_TOPO_MODULE_LIST;
- adm_pp_module_list->param_max_size = param_length;
- /* Payload address and mmap handle set to zero by kzalloc */
+ copp_stat = &this_adm.copp.stat[port_idx][copp_idx];
+ atomic_set(copp_stat, -1);
+ ret = apr_send_pkt(this_adm.apr, (uint32_t *) &adm_get_module_list);
+ if (ret) {
+ pr_err("%s: APR send pkt failed for port_id: 0x%x failed ret %d\n",
+ __func__, port_id, ret);
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
+ atomic_read(copp_stat) >= 0,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: Timeout for port_id: 0x%x\n", __func__, port_id);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+ if (atomic_read(copp_stat) > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(atomic_read(copp_stat)));
+ ret = adsp_err_get_lnx_err_code(atomic_read(copp_stat));
+ goto done;
+ }
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
+ ret = 0;
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_pp_module_list);
- if (rc < 0) {
- pr_err("%s: Failed to Get Params on port %d\n", __func__,
- port_id);
- rc = -EINVAL;
- goto adm_pp_module_list_l;
+ if (returned_params) {
+ /*
+ * When processing ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST IID is
+ * added since it is not present. Therefore, there is no need to
+ * do anything different if IID is not supported here as it is
+ * already taken care of.
+ */
+ idx = ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH * copp_idx;
+ num_modules = adm_module_topo_list[idx];
+ if (num_modules < 0 || num_modules > MAX_MODULES_IN_TOPO) {
+ pr_err("%s: Invalid number of modules returned %d\n",
+ __func__, num_modules);
+ return -EINVAL;
+ }
+
+ list_size = num_modules * sizeof(struct module_instance_info);
+ if (param_length < list_size) {
+ pr_err("%s: Provided buffer not big enough to hold module-instance list, provided size %d, needed size %d\n",
+ __func__, param_length, list_size);
+ return -EINVAL;
+ }
+
+ topo_list = (int32_t *) (&adm_module_topo_list[idx]);
+ memcpy(returned_params, topo_list, list_size);
+ for (i = 1; i <= num_modules; i += 2) {
+ pr_debug("module = 0x%x instance = 0x%x\n",
+ returned_params[i], returned_params[i + 1]);
+ }
}
- /* Wait for the callback with copp id */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: get params timed out port = %d\n", __func__,
- port_id);
- rc = -EINVAL;
- goto adm_pp_module_list_l;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto adm_pp_module_list_l;
- }
- if (params_data) {
- idx = ADM_GET_TOPO_MODULE_LIST_LENGTH * copp_idx;
- topo_list = (int *)(adm_module_topo_list + idx);
- if (param_length <= ADM_GET_TOPO_MODULE_LIST_LENGTH &&
- idx <
- (MAX_COPPS_PER_PORT * ADM_GET_TOPO_MODULE_LIST_LENGTH))
- memcpy(params_data, topo_list, param_length);
- else
- pr_debug("%s: i/p size:%d > MAX param size:%d\n",
- __func__, param_length,
- (int)ADM_GET_TOPO_MODULE_LIST_LENGTH);
- for (i = 1; i <= params_data[0]; i++)
- pr_debug("module = 0x%x\n", params_data[i]);
- }
- rc = 0;
-adm_pp_module_list_l:
- kfree(adm_pp_module_list);
- pr_debug("%s : rc = %d ", __func__, rc);
- return rc;
+done:
+ return ret;
}
-EXPORT_SYMBOL(adm_get_pp_topo_module_list);
+EXPORT_SYMBOL(adm_get_pp_topo_module_list_v2);
static void adm_callback_debug_print(struct apr_client_data *data)
{
@@ -1442,10 +1237,178 @@
}
EXPORT_SYMBOL(adm_get_multi_ch_map);
+static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
+ u32 payload_size)
+{
+ struct adm_cmd_rsp_get_pp_params_v5 *v5_rsp = NULL;
+ struct adm_cmd_rsp_get_pp_params_v6 *v6_rsp = NULL;
+ u32 *param_data = NULL;
+ int data_size = 0;
+ int struct_size = 0;
+
+ if (payload == NULL) {
+ pr_err("%s: Payload is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (opcode) {
+ case ADM_CMDRSP_GET_PP_PARAMS_V5:
+ struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v5);
+ v5_rsp = (struct adm_cmd_rsp_get_pp_params_v5 *) payload;
+ data_size = v5_rsp->param_hdr.param_size;
+ param_data = v5_rsp->param_data;
+ break;
+ case ADM_CMDRSP_GET_PP_PARAMS_V6:
+ struct_size = sizeof(struct adm_cmd_rsp_get_pp_params_v6);
+ v6_rsp = (struct adm_cmd_rsp_get_pp_params_v6 *) payload;
+ data_size = v6_rsp->param_hdr.param_size;
+ param_data = v6_rsp->param_data;
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ return -EINVAL;
+ }
+
+ /*
+ * Just store the returned parameter data, not the header. The calling
+ * function is expected to know what it asked for. Therefore, there is
+ * no difference between V5 and V6.
+ */
+ if ((payload_size >= struct_size + data_size) &&
+ (ARRAY_SIZE(adm_get_parameters) > idx) &&
+ (ARRAY_SIZE(adm_get_parameters) >= idx + 1 + data_size)) {
+ /*
+ * data_size is expressed in number of bytes, store in number of
+ * ints
+ */
+ adm_get_parameters[idx] =
+ data_size / sizeof(*adm_get_parameters);
+ pr_debug("%s: GET_PP PARAM: received parameter length: 0x%x\n",
+ __func__, adm_get_parameters[idx]);
+ /* store params after param_size */
+ memcpy(&adm_get_parameters[idx + 1], param_data, data_size);
+ return 0;
+ }
+
+ pr_err("%s: Invalid parameter combination, payload_size %d, idx %d\n",
+ __func__, payload_size, idx);
+ return -EINVAL;
+}
+
+static int adm_process_get_topo_list_response(u32 opcode, int copp_idx,
+ u32 num_modules, u32 *payload,
+ u32 payload_size)
+{
+ u32 *fill_list = NULL;
+ int idx = 0;
+ int i = 0;
+ int j = 0;
+
+ if (payload == NULL) {
+ pr_err("%s: Payload is NULL\n", __func__);
+ return -EINVAL;
+ } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
+ pr_err("%s: Invalid COPP index %d\n", __func__, copp_idx);
+ return -EINVAL;
+ }
+
+ idx = ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH * copp_idx;
+ fill_list = adm_module_topo_list + idx;
+ *fill_list++ = num_modules;
+ for (i = 0; i < num_modules; i++) {
+ if (j > payload_size / sizeof(u32)) {
+ pr_err("%s: Invalid number of modules specified %d\n",
+ __func__, num_modules);
+ return -EINVAL;
+ }
+
+ /* store module ID */
+ *fill_list++ = payload[j];
+ j++;
+
+ switch (opcode) {
+ case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2:
+ /* store instance ID */
+ *fill_list++ = payload[j];
+ j++;
+ break;
+ case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST:
+ /* Insert IID 0 when repacking */
+ *fill_list++ = INSTANCE_ID_0;
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void adm_reset_data(void)
+{
+ int i, j;
+
+ apr_reset(this_adm.apr);
+ for (i = 0; i < AFE_MAX_PORTS; i++) {
+ for (j = 0; j < MAX_COPPS_PER_PORT; j++) {
+ atomic_set(&this_adm.copp.id[i][j],
+ RESET_COPP_ID);
+ atomic_set(&this_adm.copp.cnt[i][j], 0);
+ atomic_set(
+ &this_adm.copp.topology[i][j], 0);
+ atomic_set(&this_adm.copp.mode[i][j],
+ 0);
+ atomic_set(&this_adm.copp.stat[i][j],
+ 0);
+ atomic_set(&this_adm.copp.rate[i][j],
+ 0);
+ atomic_set(
+ &this_adm.copp.channels[i][j],
+ 0);
+ atomic_set(
+ &this_adm.copp.bit_width[i][j], 0);
+ atomic_set(
+ &this_adm.copp.app_type[i][j], 0);
+ atomic_set(
+ &this_adm.copp.acdb_id[i][j], 0);
+ this_adm.copp.adm_status[i][j] =
+ ADM_STATUS_CALIBRATION_REQUIRED;
+ }
+ }
+ this_adm.apr = NULL;
+ cal_utils_clear_cal_block_q6maps(ADM_MAX_CAL_TYPES,
+ this_adm.cal_data);
+ mutex_lock(&this_adm.cal_data
+ [ADM_CUSTOM_TOP_CAL]->lock);
+ this_adm.set_custom_topology = 1;
+ mutex_unlock(&this_adm.cal_data[
+ ADM_CUSTOM_TOP_CAL]->lock);
+ rtac_clear_mapping(ADM_RTAC_CAL);
+ /*
+ * Free the ION memory and clear the map handles
+ * for Source Tracking
+ */
+ if (this_adm.sourceTrackingData.memmap.paddr != 0) {
+ msm_audio_ion_free(
+ this_adm.sourceTrackingData.dma_buf);
+ this_adm.sourceTrackingData.dma_buf = NULL;
+ this_adm.sourceTrackingData.memmap.size = 0;
+ this_adm.sourceTrackingData.memmap.kvaddr =
+ NULL;
+ this_adm.sourceTrackingData.memmap.paddr = 0;
+ this_adm.sourceTrackingData.apr_cmd_status = -1;
+ atomic_set(&this_adm.mem_map_handles[
+ ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0);
+ }
+}
+
static int32_t adm_callback(struct apr_client_data *data, void *priv)
{
uint32_t *payload;
- int i, j, port_idx, copp_idx, idx, client_id;
+ int port_idx, copp_idx, idx, client_id;
+ int num_modules;
+ int ret;
if (data == NULL) {
pr_err("%s: data parameter is null\n", __func__);
@@ -1458,62 +1421,8 @@
pr_debug("%s: Reset event is received: %d %d apr[%pK]\n",
__func__,
data->reset_event, data->reset_proc, this_adm.apr);
- if (this_adm.apr) {
- apr_reset(this_adm.apr);
- for (i = 0; i < AFE_MAX_PORTS; i++) {
- for (j = 0; j < MAX_COPPS_PER_PORT; j++) {
- atomic_set(&this_adm.copp.id[i][j],
- RESET_COPP_ID);
- atomic_set(&this_adm.copp.cnt[i][j], 0);
- atomic_set(
- &this_adm.copp.topology[i][j], 0);
- atomic_set(&this_adm.copp.mode[i][j],
- 0);
- atomic_set(&this_adm.copp.stat[i][j],
- 0);
- atomic_set(&this_adm.copp.rate[i][j],
- 0);
- atomic_set(
- &this_adm.copp.channels[i][j],
- 0);
- atomic_set(
- &this_adm.copp.bit_width[i][j], 0);
- atomic_set(
- &this_adm.copp.app_type[i][j], 0);
- atomic_set(
- &this_adm.copp.acdb_id[i][j], 0);
- this_adm.copp.adm_status[i][j] =
- ADM_STATUS_CALIBRATION_REQUIRED;
- }
- }
- this_adm.apr = NULL;
- cal_utils_clear_cal_block_q6maps(ADM_MAX_CAL_TYPES,
- this_adm.cal_data);
- mutex_lock(&this_adm.cal_data
- [ADM_CUSTOM_TOP_CAL]->lock);
- this_adm.set_custom_topology = 1;
- mutex_unlock(&this_adm.cal_data[
- ADM_CUSTOM_TOP_CAL]->lock);
- rtac_clear_mapping(ADM_RTAC_CAL);
- /*
- * Free the ION memory and clear the map handles
- * for Source Tracking
- */
- if (this_adm.sourceTrackingData.memmap.paddr != 0) {
- msm_audio_ion_free(
- this_adm.sourceTrackingData.ion_client,
- this_adm.sourceTrackingData.ion_handle);
- this_adm.sourceTrackingData.ion_client = NULL;
- this_adm.sourceTrackingData.ion_handle = NULL;
- this_adm.sourceTrackingData.memmap.size = 0;
- this_adm.sourceTrackingData.memmap.kvaddr =
- NULL;
- this_adm.sourceTrackingData.memmap.paddr = 0;
- this_adm.sourceTrackingData.apr_cmd_status = -1;
- atomic_set(&this_adm.mem_map_handles[
- ADM_MEM_MAP_INDEX_SOURCE_TRACKING], 0);
- }
- }
+ if (this_adm.apr)
+ adm_reset_data();
return 0;
}
@@ -1546,8 +1455,9 @@
}
switch (payload[0]) {
case ADM_CMD_SET_PP_PARAMS_V5:
- pr_debug("%s: ADM_CMD_SET_PP_PARAMS_V5\n",
- __func__);
+ case ADM_CMD_SET_PP_PARAMS_V6:
+ pr_debug("%s: ADM_CMD_SET_PP_PARAMS\n",
+ __func__);
if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING)
this_adm.sourceTrackingData.
apr_cmd_status = payload[1];
@@ -1603,8 +1513,9 @@
}
break;
case ADM_CMD_GET_PP_PARAMS_V5:
- pr_debug("%s: ADM_CMD_GET_PP_PARAMS_V5\n",
- __func__);
+ case ADM_CMD_GET_PP_PARAMS_V6:
+ pr_debug("%s: ADM_CMD_GET_PP_PARAMS\n",
+ __func__);
/* Should only come here if there is an APR */
/* error or malformed APR packet. Otherwise */
/* response will be returned as */
@@ -1641,11 +1552,12 @@
&this_adm.copp.wait[port_idx][copp_idx]);
break;
case ADM_CMD_GET_PP_TOPO_MODULE_LIST:
+ case ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2:
pr_debug("%s:ADM_CMD_GET_PP_TOPO_MODULE_LIST\n",
__func__);
if (payload[1] != 0)
- pr_err("%s: ADM get topo list error = %d,\n",
- __func__, payload[1]);
+ pr_err("%s: ADM get topo list error = %d\n",
+ __func__, payload[1]);
break;
default:
pr_err("%s: Unknown Cmd: 0x%x\n", __func__,
@@ -1680,80 +1592,60 @@
}
break;
case ADM_CMDRSP_GET_PP_PARAMS_V5:
- pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS_V5\n", __func__);
- if (payload[0] != 0)
- pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS_V5 returned error = 0x%x\n",
- __func__, payload[0]);
+ case ADM_CMDRSP_GET_PP_PARAMS_V6:
+ pr_debug("%s: ADM_CMDRSP_GET_PP_PARAMS\n", __func__);
if (client_id == ADM_CLIENT_ID_SOURCE_TRACKING)
this_adm.sourceTrackingData.apr_cmd_status =
- payload[0];
+ payload[0];
else if (rtac_make_adm_callback(payload,
- data->payload_size))
+ data->payload_size))
break;
idx = ADM_GET_PARAMETER_LENGTH * copp_idx;
- if ((payload[0] == 0) && (data->payload_size >
- (4 * sizeof(*payload))) &&
- (data->payload_size - 4 >=
- payload[3]) &&
- (ARRAY_SIZE(adm_get_parameters) >
- idx) &&
- (ARRAY_SIZE(adm_get_parameters)-idx-1 >=
- payload[3])) {
- adm_get_parameters[idx] = payload[3] /
- sizeof(uint32_t);
- /*
- * payload[3] is param_size which is
- * expressed in number of bytes
- */
- pr_debug("%s: GET_PP PARAM:received parameter length: 0x%x\n",
- __func__, adm_get_parameters[idx]);
- /* storing param size then params */
- for (i = 0; i < payload[3] /
- sizeof(uint32_t); i++)
- adm_get_parameters[idx+1+i] =
- payload[4+i];
- } else if (payload[0] == 0) {
+ if (payload[0] == 0 && data->payload_size > 0) {
+ pr_debug("%s: Received parameter data in band\n",
+ __func__);
+ ret = adm_process_get_param_response(
+ data->opcode, idx, payload,
+ data->payload_size);
+ if (ret)
+ pr_err("%s: Failed to process get param response, error %d\n",
+ __func__, ret);
+ } else if (payload[0] == 0 && data->payload_size == 0) {
adm_get_parameters[idx] = -1;
- pr_err("%s: Out of band case, setting size to %d\n",
+ pr_debug("%s: Out of band case, setting size to %d\n",
__func__, adm_get_parameters[idx]);
} else {
adm_get_parameters[idx] = -1;
- pr_err("%s: GET_PP_PARAMS failed, setting size to %d\n",
- __func__, adm_get_parameters[idx]);
+ pr_err("%s: ADM_CMDRSP_GET_PP_PARAMS returned error 0x%x\n",
+ __func__, payload[0]);
}
- atomic_set(&this_adm.copp.stat
- [port_idx][copp_idx], payload[0]);
+ atomic_set(&this_adm.copp.stat[port_idx][copp_idx],
+ payload[0]);
wake_up(&this_adm.copp.wait[port_idx][copp_idx]);
break;
case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST:
+ case ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2:
pr_debug("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST\n",
__func__);
- if (payload[0] != 0) {
- pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST",
- __func__);
- pr_err(":err = 0x%x\n", payload[0]);
- } else if (payload[1] >
- ((ADM_GET_TOPO_MODULE_LIST_LENGTH /
- sizeof(uint32_t)) - 1)) {
- pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST",
- __func__);
- pr_err(":size = %d\n", payload[1]);
+ num_modules = payload[1];
+ pr_debug("%s: Num modules %d\n", __func__, num_modules);
+ if (payload[0]) {
+ pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST, error = %d\n",
+ __func__, payload[0]);
+ } else if (num_modules > MAX_MODULES_IN_TOPO) {
+ pr_err("%s: ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST invalid num modules received, num modules = %d\n",
+ __func__, num_modules);
} else {
- idx = ADM_GET_TOPO_MODULE_LIST_LENGTH *
- copp_idx;
- pr_debug("%s:Num modules payload[1] %d\n",
- __func__, payload[1]);
- adm_module_topo_list[idx] = payload[1];
- for (i = 1; i <= payload[1]; i++) {
- adm_module_topo_list[idx+i] =
- payload[1+i];
- pr_debug("%s:payload[%d] = %x\n",
- __func__, (i+1), payload[1+i]);
- }
+ ret = adm_process_get_topo_list_response(
+ data->opcode, copp_idx, num_modules,
+ payload, data->payload_size);
+ if (ret)
+ pr_err("%s: Failed to process get topo modules list response, error %d\n",
+ __func__, ret);
}
- atomic_set(&this_adm.copp.stat
- [port_idx][copp_idx], payload[0]);
+ atomic_set(&this_adm.copp.stat[port_idx][copp_idx],
+ payload[0]);
wake_up(&this_adm.copp.wait[port_idx][copp_idx]);
break;
case ADM_CMDRSP_SHARED_MEM_MAP_REGIONS:
@@ -1919,7 +1811,7 @@
{
int ret = 0;
- if (cal_block->map_data.ion_client == NULL) {
+ if (cal_block->map_data.dma_buf == NULL) {
pr_err("%s: No ION allocation for cal index %d!\n",
__func__, cal_index);
ret = -EINVAL;
@@ -1964,7 +1856,7 @@
this_adm.set_custom_topology = 0;
cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]);
- if (cal_block == NULL)
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block))
goto unlock;
pr_debug("%s: Sending cal_index %d\n", __func__, cal_index);
@@ -2034,21 +1926,16 @@
}
static int send_adm_cal_block(int port_id, int copp_idx,
- struct cal_block_data *cal_block, int perf_mode,
- int app_type, int acdb_id, int sample_rate)
+ struct cal_block_data *cal_block, int perf_mode)
{
- s32 result = 0;
- struct adm_cmd_set_pp_params_v5 adm_params;
- int port_idx;
+ struct mem_mapping_hdr mem_hdr;
+ int payload_size = 0;
+ int port_idx = 0;
+ int topology = 0;
+ int result = 0;
- pr_debug("%s: Port id 0x%x sample_rate %d ,\n", __func__,
- port_id, sample_rate);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
- return -EINVAL;
- }
+ pr_debug("%s: Port id 0x%x,\n", __func__, port_id);
+
if (!cal_block) {
pr_debug("%s: No ADM cal to send for port_id = 0x%x!\n",
__func__, port_id);
@@ -2056,75 +1943,39 @@
goto done;
}
if (cal_block->cal_data.size <= 0) {
- pr_debug("%s: No ADM cal send for port_id = 0x%x!\n",
- __func__, port_id);
+ pr_debug("%s: No ADM cal sent for port_id = 0x%x!\n", __func__,
+ port_id);
result = -EINVAL;
goto done;
}
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
+ port_id = afe_convert_virtual_to_portid(port_id);
+ port_idx = adm_validate_and_get_port_index(port_id);
+ if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
+ pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+ return -EINVAL;
+ } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
+ pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx);
+ return -EINVAL;
+ }
+
+ topology = atomic_read(&this_adm.copp.topology[port_idx][copp_idx]);
if (perf_mode == LEGACY_PCM_MODE &&
- ((atomic_read(&this_adm.copp.topology[port_idx][copp_idx])) ==
- DS2_ADM_COPP_TOPOLOGY_ID)) {
+ topology == DS2_ADM_COPP_TOPOLOGY_ID) {
pr_err("%s: perf_mode %d, topology 0x%x\n", __func__, perf_mode,
- atomic_read(
- &this_adm.copp.topology[port_idx][copp_idx]));
+ topology);
goto done;
}
- adm_params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(20), APR_PKT_VER);
- adm_params.hdr.pkt_size = sizeof(adm_params);
- adm_params.hdr.src_svc = APR_SVC_ADM;
- adm_params.hdr.src_domain = APR_DOMAIN_APPS;
- adm_params.hdr.src_port = port_id;
- adm_params.hdr.dest_svc = APR_SVC_ADM;
- adm_params.hdr.dest_domain = APR_DOMAIN_ADSP;
+ mem_hdr.data_payload_addr_lsw =
+ lower_32_bits(cal_block->cal_data.paddr);
+ mem_hdr.data_payload_addr_msw =
+ msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
+ mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle;
+ payload_size = cal_block->cal_data.size;
- adm_params.hdr.token = port_idx << 16 | copp_idx;
- adm_params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- adm_params.payload_addr_lsw = lower_32_bits(cal_block->cal_data.paddr);
- adm_params.payload_addr_msw = msm_audio_populate_upper_32_bits(
- cal_block->cal_data.paddr);
- adm_params.mem_map_handle = cal_block->map_data.q6map_handle;
- adm_params.payload_size = cal_block->cal_data.size;
-
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- pr_debug("%s: Sending SET_PARAMS payload = 0x%pK, size = %d\n",
- __func__, &cal_block->cal_data.paddr,
- adm_params.payload_size);
- result = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_params);
- if (result < 0) {
- pr_err("%s: Set params failed port 0x%x result %d\n",
- __func__, port_id, result);
- pr_debug("%s: Set params failed port = 0x%x payload = 0x%pK result %d\n",
- __func__, port_id, &cal_block->cal_data.paddr, result);
- result = -EINVAL;
- goto done;
- }
- /* Wait for the callback */
- result = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!result) {
- pr_err("%s: Set params timed out port = 0x%x\n",
- __func__, port_id);
- pr_debug("%s: Set params timed out port = 0x%x, payload = 0x%pK\n",
- __func__, port_id, &cal_block->cal_data.paddr);
- result = -EINVAL;
- goto done;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- result = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto done;
- }
+ adm_set_pp_params(port_id, copp_idx, &mem_hdr, NULL, payload_size);
done:
return result;
@@ -2145,8 +1996,11 @@
cal_block = list_entry(ptr,
struct cal_block_data, list);
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
+
if (cal_index == ADM_AUDPROC_CAL ||
- cal_index == ADM_LSM_AUDPROC_CAL) {
+ cal_index == ADM_LSM_AUDPROC_CAL) {
audproc_cal_info = cal_block->cal_info;
if ((audproc_cal_info->path == path) &&
(cal_block->cal_data.size > 0))
@@ -2179,8 +2033,11 @@
cal_block = list_entry(ptr,
struct cal_block_data, list);
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
+
if (cal_index == ADM_AUDPROC_CAL ||
- cal_index == ADM_LSM_AUDPROC_CAL) {
+ cal_index == ADM_LSM_AUDPROC_CAL) {
audproc_cal_info = cal_block->cal_info;
if ((audproc_cal_info->path == path) &&
(audproc_cal_info->app_type == app_type) &&
@@ -2216,6 +2073,8 @@
cal_block = list_entry(ptr,
struct cal_block_data, list);
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
if (cal_index == ADM_AUDPROC_CAL ||
cal_index == ADM_LSM_AUDPROC_CAL) {
@@ -2253,8 +2112,7 @@
__func__, cal_index);
goto done;
}
- ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode,
- app_type, acdb_id, sample_rate);
+ ret = send_adm_cal_block(port_id, copp_idx, cal_block, perf_mode);
if (ret < 0)
pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d sample_rate %d\n",
__func__, cal_index, port_id, ret, sample_rate);
@@ -2285,6 +2143,8 @@
ret = adm_remap_and_send_cal_block(cal_index, port_id, copp_idx,
cal_block, perf_mode, app_type, acdb_id, sample_rate);
+
+ cal_utils_mark_cal_used(cal_block);
unlock:
mutex_unlock(&this_adm.cal_data[cal_index]->lock);
done:
@@ -2299,25 +2159,13 @@
return TX_DEVICE;
}
-/*
- * Command to set LSM port ID
- * which is used to send LSM cal
- *
- * @port_id: Port ID number to be set
- *
- */
-void adm_set_lsm_port_id(int port_id)
-{
- this_adm.lsm_port_id = port_id;
-}
-EXPORT_SYMBOL(adm_set_lsm_port_id);
-
static void send_adm_cal(int port_id, int copp_idx, int path, int perf_mode,
- int app_type, int acdb_id, int sample_rate)
+ int app_type, int acdb_id, int sample_rate,
+ int passthr_mode)
{
pr_debug("%s: port id 0x%x copp_idx %d\n", __func__, port_id, copp_idx);
- if (port_id != this_adm.lsm_port_id)
+ if (passthr_mode != LISTEN)
send_adm_cal_type(ADM_AUDPROC_CAL, path, port_id, copp_idx,
perf_mode, app_type, acdb_id, sample_rate);
else
@@ -2818,10 +2666,10 @@
*/
void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate)
{
- struct audproc_mfc_output_media_fmt mfc_cfg;
+ struct audproc_mfc_param_media_fmt mfc_cfg;
struct adm_cmd_device_open_v5 open;
+ struct param_hdr_v3 param_hdr;
int port_idx;
- int sz = 0;
int rc = 0;
int i = 0;
@@ -2838,32 +2686,15 @@
goto fail_cmd;
}
- sz = sizeof(struct audproc_mfc_output_media_fmt);
+ memset(&mfc_cfg, 0, sizeof(mfc_cfg));
+ memset(&open, 0, sizeof(open));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
- mfc_cfg.params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- mfc_cfg.params.hdr.pkt_size = sz;
- mfc_cfg.params.hdr.src_svc = APR_SVC_ADM;
- mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS;
- mfc_cfg.params.hdr.src_port = port_id;
- mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM;
- mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- mfc_cfg.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx;
- mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- mfc_cfg.params.payload_addr_lsw = 0;
- mfc_cfg.params.payload_addr_msw = 0;
- mfc_cfg.params.mem_map_handle = 0;
- mfc_cfg.params.payload_size = sizeof(mfc_cfg) -
- sizeof(mfc_cfg.params);
- mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC;
- mfc_cfg.data.param_id =
- AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
- mfc_cfg.data.param_size = mfc_cfg.params.payload_size -
- sizeof(mfc_cfg.data);
- mfc_cfg.data.reserved = 0;
+ param_hdr.module_id = AUDPROC_MODULE_ID_MFC;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
+ param_hdr.param_size = sizeof(mfc_cfg);
+
mfc_cfg.sampling_rate = dst_sample_rate;
mfc_cfg.bits_per_sample =
atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]);
@@ -2889,31 +2720,12 @@
mfc_cfg.bits_per_sample, mfc_cfg.num_channels,
mfc_cfg.sampling_rate);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg);
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &mfc_cfg);
+ if (rc)
+ pr_err("%s: Failed to set media format configuration data, err %d\n",
+ __func__, rc);
- if (rc < 0) {
- pr_err("%s: port_id: for[0x%x] failed %d\n",
- __func__, port_id, rc);
- goto fail_cmd;
- }
- /* Wait for the callback with copp id */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n",
- __func__, port_id);
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- goto fail_cmd;
- }
- rc = 0;
fail_cmd:
return;
}
@@ -3083,7 +2895,8 @@
get_cal_path(path), perf_mode,
payload_map.app_type[i],
payload_map.acdb_dev_id[i],
- payload_map.sample_rate[i]);
+ payload_map.sample_rate[i],
+ passthr_mode);
/* ADM COPP calibration is already sent */
clear_bit(ADM_STATUS_CALIBRATION_REQUIRED,
(void *)&this_adm.copp.
@@ -3223,10 +3036,8 @@
__func__, ret);
}
msm_audio_ion_free(
- this_adm.sourceTrackingData.ion_client,
- this_adm.sourceTrackingData.ion_handle);
- this_adm.sourceTrackingData.ion_client = NULL;
- this_adm.sourceTrackingData.ion_handle = NULL;
+ this_adm.sourceTrackingData.dma_buf);
+ this_adm.sourceTrackingData.dma_buf = NULL;
this_adm.sourceTrackingData.memmap.size = 0;
this_adm.sourceTrackingData.memmap.kvaddr = NULL;
this_adm.sourceTrackingData.memmap.paddr = 0;
@@ -3310,7 +3121,7 @@
cal_block = cal_utils_get_only_cal_block(
this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]);
- if (cal_block == NULL) {
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
pr_err("%s: can't find cal block!\n", __func__);
goto unlock;
}
@@ -3738,79 +3549,25 @@
int adm_set_volume(int port_id, int copp_idx, int volume)
{
struct audproc_volume_ctrl_master_gain audproc_vol;
- int sz = 0;
+ struct param_hdr_v3 param_hdr;
int rc = 0;
- int port_idx;
pr_debug("%s: port_id %d, volume %d\n", __func__, port_id, volume);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
- return -EINVAL;
- }
+ memset(&audproc_vol, 0, sizeof(audproc_vol));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN;
+ param_hdr.param_size = sizeof(audproc_vol);
- sz = sizeof(struct audproc_volume_ctrl_master_gain);
- audproc_vol.params.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- audproc_vol.params.hdr.pkt_size = sz;
- audproc_vol.params.hdr.src_svc = APR_SVC_ADM;
- audproc_vol.params.hdr.src_domain = APR_DOMAIN_APPS;
- audproc_vol.params.hdr.src_port = port_id;
- audproc_vol.params.hdr.dest_svc = APR_SVC_ADM;
- audproc_vol.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- audproc_vol.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- audproc_vol.params.hdr.token = port_idx << 16 | copp_idx;
- audproc_vol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- audproc_vol.params.payload_addr_lsw = 0;
- audproc_vol.params.payload_addr_msw = 0;
- audproc_vol.params.mem_map_handle = 0;
- audproc_vol.params.payload_size = sizeof(audproc_vol) -
- sizeof(audproc_vol.params);
- audproc_vol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
- audproc_vol.data.param_id = AUDPROC_PARAM_ID_VOL_CTRL_MASTER_GAIN;
- audproc_vol.data.param_size = audproc_vol.params.payload_size -
- sizeof(audproc_vol.data);
- audproc_vol.data.reserved = 0;
audproc_vol.master_gain = volume;
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_vol);
- if (rc < 0) {
- pr_err("%s: Set params failed port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Vol cntrl Set params timed out port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &audproc_vol);
+ if (rc)
+ pr_err("%s: Failed to set volume, err %d\n", __func__, rc);
+
return rc;
}
EXPORT_SYMBOL(adm_set_volume);
@@ -3829,53 +3586,20 @@
struct audproc_softvolume_params *softvol_param)
{
struct audproc_soft_step_volume_params audproc_softvol;
- int sz = 0;
+ struct param_hdr_v3 param_hdr;
int rc = 0;
- int port_idx;
pr_debug("%s: period %d step %d curve %d\n", __func__,
softvol_param->period, softvol_param->step,
softvol_param->rampingcurve);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ memset(&audproc_softvol, 0, sizeof(audproc_softvol));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS;
+ param_hdr.param_size = sizeof(audproc_softvol);
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
- return -EINVAL;
- }
-
- sz = sizeof(struct audproc_soft_step_volume_params);
-
- audproc_softvol.params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- audproc_softvol.params.hdr.pkt_size = sz;
- audproc_softvol.params.hdr.src_svc = APR_SVC_ADM;
- audproc_softvol.params.hdr.src_domain = APR_DOMAIN_APPS;
- audproc_softvol.params.hdr.src_port = port_id;
- audproc_softvol.params.hdr.dest_svc = APR_SVC_ADM;
- audproc_softvol.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- audproc_softvol.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- audproc_softvol.params.hdr.token = port_idx << 16 | copp_idx;
- audproc_softvol.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- audproc_softvol.params.payload_addr_lsw = 0;
- audproc_softvol.params.payload_addr_msw = 0;
- audproc_softvol.params.mem_map_handle = 0;
- audproc_softvol.params.payload_size = sizeof(audproc_softvol) -
- sizeof(audproc_softvol.params);
- audproc_softvol.data.module_id = AUDPROC_MODULE_ID_VOL_CTRL;
- audproc_softvol.data.param_id =
- AUDPROC_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS;
- audproc_softvol.data.param_size = audproc_softvol.params.payload_size -
- sizeof(audproc_softvol.data);
- audproc_softvol.data.reserved = 0;
audproc_softvol.period = softvol_param->period;
audproc_softvol.step = softvol_param->step;
audproc_softvol.ramping_curve = softvol_param->rampingcurve;
@@ -3884,36 +3608,11 @@
audproc_softvol.period, audproc_softvol.step,
audproc_softvol.ramping_curve);
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)&audproc_softvol);
- if (rc < 0) {
- pr_err("%s: Set params failed port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Soft volume Set params timed out port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &audproc_softvol);
+ if (rc)
+ pr_err("%s: Failed to set soft volume, err %d\n", __func__, rc);
+
return rc;
}
EXPORT_SYMBOL(adm_set_softvolume);
@@ -3930,79 +3629,27 @@
*/
int adm_set_mic_gain(int port_id, int copp_idx, int volume)
{
- struct adm_set_mic_gain_params mic_gain_params;
+ struct admx_mic_gain mic_gain_params;
+ struct param_hdr_v3 param_hdr;
int rc = 0;
- int sz, port_idx;
- pr_debug("%s:\n", __func__);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
- return -EINVAL;
- }
+ pr_debug("%s: Setting mic gain to %d at port_id 0x%x\n", __func__,
+ volume, port_id);
- sz = sizeof(struct adm_set_mic_gain_params);
+ memset(&mic_gain_params, 0, sizeof(mic_gain_params));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = ADM_PARAM_IDX_MIC_GAIN;
+ param_hdr.param_size = sizeof(mic_gain_params);
- mic_gain_params.params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- mic_gain_params.params.hdr.pkt_size = sz;
- mic_gain_params.params.hdr.src_svc = APR_SVC_ADM;
- mic_gain_params.params.hdr.src_domain = APR_DOMAIN_APPS;
- mic_gain_params.params.hdr.src_port = port_id;
- mic_gain_params.params.hdr.dest_svc = APR_SVC_ADM;
- mic_gain_params.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- mic_gain_params.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- mic_gain_params.params.hdr.token = port_idx << 16 | copp_idx;
- mic_gain_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- mic_gain_params.params.payload_addr_lsw = 0;
- mic_gain_params.params.payload_addr_msw = 0;
- mic_gain_params.params.mem_map_handle = 0;
- mic_gain_params.params.payload_size =
- sizeof(struct adm_param_data_v5) +
- sizeof(struct admx_mic_gain);
- mic_gain_params.data.module_id = ADM_MODULE_IDX_MIC_GAIN_CTRL;
- mic_gain_params.data.param_id = ADM_PARAM_IDX_MIC_GAIN;
- mic_gain_params.data.param_size =
- sizeof(struct admx_mic_gain);
- mic_gain_params.data.reserved = 0;
- mic_gain_params.mic_gain_data.tx_mic_gain = volume;
- mic_gain_params.mic_gain_data.reserved = 0;
- pr_debug("%s: Mic Gain set to %d at port_id 0x%x\n",
- __func__, volume, port_id);
+ mic_gain_params.tx_mic_gain = volume;
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)&mic_gain_params);
- if (rc < 0) {
- pr_err("%s: Set params failed port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Mic Gain Set params timed out port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &mic_gain_params);
+ if (rc)
+ pr_err("%s: Failed to set mic gain, err %d\n", __func__, rc);
+
return rc;
}
EXPORT_SYMBOL(adm_set_mic_gain);
@@ -4020,88 +3667,29 @@
int adm_send_set_multichannel_ec_primary_mic_ch(int port_id, int copp_idx,
int primary_mic_ch)
{
- struct adm_set_sec_primary_ch_params sec_primary_ch_params;
+ struct admx_sec_primary_mic_ch sec_primary_ch_params;
+ struct param_hdr_v3 param_hdr;
int rc = 0;
- int sz, port_idx;
pr_debug("%s port_id 0x%x, copp_idx 0x%x, primary_mic_ch %d\n",
__func__, port_id, copp_idx, primary_mic_ch);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
- return -EINVAL;
- }
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx);
- return -EINVAL;
- }
+ memset(&sec_primary_ch_params, 0, sizeof(sec_primary_ch_params));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_VOICE_TX_SECNS;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH;
+ param_hdr.param_size = sizeof(sec_primary_ch_params);
- sz = sizeof(struct adm_set_sec_primary_ch_params);
+ sec_primary_ch_params.version = 0;
+ sec_primary_ch_params.sec_primary_mic_ch = primary_mic_ch;
- sec_primary_ch_params.params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- sec_primary_ch_params.params.hdr.pkt_size = sz;
- sec_primary_ch_params.params.hdr.src_svc = APR_SVC_ADM;
- sec_primary_ch_params.params.hdr.src_domain = APR_DOMAIN_APPS;
- sec_primary_ch_params.params.hdr.src_port = port_id;
- sec_primary_ch_params.params.hdr.dest_svc = APR_SVC_ADM;
- sec_primary_ch_params.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- sec_primary_ch_params.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- sec_primary_ch_params.params.hdr.token = port_idx << 16 | copp_idx;
- sec_primary_ch_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- sec_primary_ch_params.params.payload_addr_lsw = 0;
- sec_primary_ch_params.params.payload_addr_msw = 0;
- sec_primary_ch_params.params.mem_map_handle = 0;
- sec_primary_ch_params.params.payload_size =
- sizeof(struct adm_param_data_v5) +
- sizeof(struct admx_sec_primary_mic_ch);
- sec_primary_ch_params.data.module_id =
- AUDPROC_MODULE_ID_VOICE_TX_SECNS;
- sec_primary_ch_params.data.param_id =
- AUDPROC_PARAM_IDX_SEC_PRIMARY_MIC_CH;
- sec_primary_ch_params.data.param_size =
- sizeof(struct admx_sec_primary_mic_ch);
- sec_primary_ch_params.data.reserved = 0;
- sec_primary_ch_params.sec_primary_mic_ch_data.version = 0;
- sec_primary_ch_params.sec_primary_mic_ch_data.reserved = 0;
- sec_primary_ch_params.sec_primary_mic_ch_data.sec_primary_mic_ch =
- primary_mic_ch;
- sec_primary_ch_params.sec_primary_mic_ch_data.reserved1 = 0;
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &sec_primary_ch_params);
+ if (rc)
+ pr_err("%s: Failed to set primary mic chanel, err %d\n",
+ __func__, rc);
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)&sec_primary_ch_params);
- if (rc < 0) {
- pr_err("%s: Set params failed port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Mic Set params timed out port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
return rc;
}
EXPORT_SYMBOL(adm_send_set_multichannel_ec_primary_mic_ch);
@@ -4119,90 +3707,62 @@
*/
int adm_param_enable(int port_id, int copp_idx, int module_id, int enable)
{
- struct audproc_enable_param_t adm_mod_enable;
- int sz = 0;
- int rc = 0;
- int port_idx;
+ struct module_instance_info mod_inst_info;
- pr_debug("%s port_id %d, module_id 0x%x, enable %d\n",
- __func__, port_id, module_id, enable);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
+ mod_inst_info.module_id = module_id;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
+ return adm_param_enable_v2(port_id, copp_idx, mod_inst_info, enable);
+}
+EXPORT_SYMBOL(adm_param_enable);
+
+/**
+ * adm_param_enable_v2 -
+ * command to send params to ADM for given module
+ *
+ * @port_id: Port ID number
+ * @copp_idx: copp index assigned
+ * @mod_inst_info: module and instance ID info
+ * @enable: flag to enable or disable module
+ *
+ * Returns 0 on success or error on failure
+ */
+int adm_param_enable_v2(int port_id, int copp_idx,
+ struct module_instance_info mod_inst_info, int enable)
+{
+ uint32_t enable_param;
+ struct param_hdr_v3 param_hdr;
+ int rc = 0;
+
+ if (enable < 0 || enable > 1) {
+ pr_err("%s: Invalid value for enable %d\n", __func__, enable);
return -EINVAL;
}
- sz = sizeof(struct audproc_enable_param_t);
+ pr_debug("%s port_id %d, module_id 0x%x, instance_id 0x%x, enable %d\n",
+ __func__, port_id, mod_inst_info.module_id,
+ mod_inst_info.instance_id, enable);
- adm_mod_enable.pp_params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_mod_enable.pp_params.hdr.pkt_size = sz;
- adm_mod_enable.pp_params.hdr.src_svc = APR_SVC_ADM;
- adm_mod_enable.pp_params.hdr.src_domain = APR_DOMAIN_APPS;
- adm_mod_enable.pp_params.hdr.src_port = port_id;
- adm_mod_enable.pp_params.hdr.dest_svc = APR_SVC_ADM;
- adm_mod_enable.pp_params.hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_mod_enable.pp_params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_mod_enable.pp_params.hdr.token = port_idx << 16 | copp_idx;
- adm_mod_enable.pp_params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- adm_mod_enable.pp_params.payload_addr_lsw = 0;
- adm_mod_enable.pp_params.payload_addr_msw = 0;
- adm_mod_enable.pp_params.mem_map_handle = 0;
- adm_mod_enable.pp_params.payload_size = sizeof(adm_mod_enable) -
- sizeof(adm_mod_enable.pp_params) +
- sizeof(adm_mod_enable.pp_params.params);
- adm_mod_enable.pp_params.params.module_id = module_id;
- adm_mod_enable.pp_params.params.param_id = AUDPROC_PARAM_ID_ENABLE;
- adm_mod_enable.pp_params.params.param_size =
- adm_mod_enable.pp_params.payload_size -
- sizeof(adm_mod_enable.pp_params.params);
- adm_mod_enable.pp_params.params.reserved = 0;
- adm_mod_enable.enable = enable;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = mod_inst_info.module_id;
+ param_hdr.instance_id = mod_inst_info.instance_id;
+ param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
+ param_hdr.param_size = sizeof(enable_param);
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
+ enable_param = enable;
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)&adm_mod_enable);
- if (rc < 0) {
- pr_err("%s: Set params failed port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: module %x enable %d timed out on port = %#x\n",
- __func__, module_id, enable, port_id);
- rc = -EINVAL;
- goto fail_cmd;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
+ rc = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &enable_param);
+ if (rc)
+ pr_err("%s: Failed to set enable of module(%d) instance(%d) to %d, err %d\n",
+ __func__, mod_inst_info.module_id,
+ mod_inst_info.instance_id, enable, rc);
+
return rc;
}
-EXPORT_SYMBOL(adm_param_enable);
+EXPORT_SYMBOL(adm_param_enable_v2);
/**
* adm_send_calibration -
@@ -4222,26 +3782,11 @@
int cal_type, char *params, int size)
{
- struct adm_cmd_set_pp_params_v5 *adm_params = NULL;
- int sz, rc = 0;
- int port_idx;
+ int rc = 0;
pr_debug("%s:port_id %d, path %d, perf_mode %d, cal_type %d, size %d\n",
__func__, port_id, path, perf_mode, cal_type, size);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
- rc = -EINVAL;
- goto end;
- }
-
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
- return -EINVAL;
- }
-
/* Maps audio_dev_ctrl path definition to ACDB definition */
if (get_cal_path(path) != RX_DEVICE) {
pr_err("%s: acdb_path %d\n", __func__, path);
@@ -4249,64 +3794,9 @@
goto end;
}
- sz = sizeof(struct adm_cmd_set_pp_params_v5) + size;
- adm_params = kzalloc(sz, GFP_KERNEL);
- if (!adm_params) {
- pr_err("%s, adm params memory alloc failed", __func__);
- rc = -ENOMEM;
- goto end;
- }
-
- memcpy(((u8 *)adm_params + sizeof(struct adm_cmd_set_pp_params_v5)),
- params, size);
-
- adm_params->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- adm_params->hdr.pkt_size = sz;
- adm_params->hdr.src_svc = APR_SVC_ADM;
- adm_params->hdr.src_domain = APR_DOMAIN_APPS;
- adm_params->hdr.src_port = port_id;
- adm_params->hdr.dest_svc = APR_SVC_ADM;
- adm_params->hdr.dest_domain = APR_DOMAIN_ADSP;
- adm_params->hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- adm_params->hdr.token = port_idx << 16 | copp_idx;
- adm_params->hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- /* payload address and mmap handle initialized to zero by kzalloc */
- adm_params->payload_size = size;
-
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- rc = apr_send_pkt(this_adm.apr, (uint32_t *)adm_params);
- if (rc < 0) {
- pr_err("%s: Set params failed port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto end;
- }
- /* Wait for the callback */
- rc = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!rc) {
- pr_err("%s: Set params timed out port = %#x\n",
- __func__, port_id);
- rc = -EINVAL;
- goto end;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto end;
- }
- rc = 0;
+ rc = adm_set_pp_params(port_id, copp_idx, NULL, (u8 *) params, size);
end:
- kfree(adm_params);
return rc;
}
EXPORT_SYMBOL(adm_send_calibration);
@@ -4537,78 +4027,24 @@
*/
int adm_send_compressed_device_mute(int port_id, int copp_idx, bool mute_on)
{
- struct adm_set_compressed_device_mute mute_params;
+ u32 mute_param = mute_on ? 1 : 0;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int port_idx;
pr_debug("%s port_id: 0x%x, copp_idx %d, mute_on: %d\n",
__func__, port_id, copp_idx, mute_on);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
- pr_err("%s: Invalid port_id %#x copp_idx %d\n",
- __func__, port_id, copp_idx);
- ret = -EINVAL;
- goto end;
- }
- mute_params.command.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- mute_params.command.hdr.pkt_size =
- sizeof(struct adm_set_compressed_device_mute);
- mute_params.command.hdr.src_svc = APR_SVC_ADM;
- mute_params.command.hdr.src_domain = APR_DOMAIN_APPS;
- mute_params.command.hdr.src_port = port_id;
- mute_params.command.hdr.dest_svc = APR_SVC_ADM;
- mute_params.command.hdr.dest_domain = APR_DOMAIN_ADSP;
- mute_params.command.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- mute_params.command.hdr.token = port_idx << 16 | copp_idx;
- mute_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- mute_params.command.payload_addr_lsw = 0;
- mute_params.command.payload_addr_msw = 0;
- mute_params.command.mem_map_handle = 0;
- mute_params.command.payload_size = sizeof(mute_params) -
- sizeof(mute_params.command);
- mute_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE;
- mute_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE;
- mute_params.params.param_size = mute_params.command.payload_size -
- sizeof(mute_params.params);
- mute_params.params.reserved = 0;
- mute_params.mute_on = mute_on;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_COMPRESSED_MUTE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_COMPRESSED_MUTE;
+ param_hdr.param_size = sizeof(mute_param);
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mute_params);
- if (ret < 0) {
- pr_err("%s: device mute for port %d copp %d failed, ret %d\n",
- __func__, port_id, copp_idx, ret);
- ret = -EINVAL;
- goto end;
- }
+ ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &mute_param);
+ if (ret)
+ pr_err("%s: Failed to set mute, err %d\n", __func__, ret);
- /* Wait for the callback */
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: send device mute for port %d copp %d failed\n",
- __func__, port_id, copp_idx);
- ret = -EINVAL;
- goto end;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto end;
- }
- ret = 0;
-end:
return ret;
}
EXPORT_SYMBOL(adm_send_compressed_device_mute);
@@ -4625,78 +4061,31 @@
*/
int adm_send_compressed_device_latency(int port_id, int copp_idx, int latency)
{
- struct adm_set_compressed_device_latency latency_params;
- int port_idx;
+ u32 latency_param;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
pr_debug("%s port_id: 0x%x, copp_idx %d latency: %d\n", __func__,
port_id, copp_idx, latency);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
- pr_err("%s: Invalid port_id %#x copp_idx %d\n",
- __func__, port_id, copp_idx);
- ret = -EINVAL;
- goto end;
+
+ if (latency < 0) {
+ pr_err("%s: Invalid value for latency %d", __func__, latency);
+ return -EINVAL;
}
- latency_params.command.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- latency_params.command.hdr.pkt_size =
- sizeof(struct adm_set_compressed_device_latency);
- latency_params.command.hdr.src_svc = APR_SVC_ADM;
- latency_params.command.hdr.src_domain = APR_DOMAIN_APPS;
- latency_params.command.hdr.src_port = port_id;
- latency_params.command.hdr.dest_svc = APR_SVC_ADM;
- latency_params.command.hdr.dest_domain = APR_DOMAIN_ADSP;
- latency_params.command.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- latency_params.command.hdr.token = port_idx << 16 | copp_idx;
- latency_params.command.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- latency_params.command.payload_addr_lsw = 0;
- latency_params.command.payload_addr_msw = 0;
- latency_params.command.mem_map_handle = 0;
- latency_params.command.payload_size = sizeof(latency_params) -
- sizeof(latency_params.command);
- latency_params.params.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY;
- latency_params.params.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY;
- latency_params.params.param_size = latency_params.command.payload_size -
- sizeof(latency_params.params);
- latency_params.params.reserved = 0;
- latency_params.latency = latency;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AUDPROC_MODULE_ID_COMPRESSED_LATENCY;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_COMPRESSED_LATENCY;
+ param_hdr.param_size = sizeof(latency_param);
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&latency_params);
- if (ret < 0) {
- pr_err("%s: send device latency err %d for port %d copp %d\n",
- __func__, port_id, copp_idx, ret);
- ret = -EINVAL;
- goto end;
- }
+ latency_param = latency;
- /* Wait for the callback */
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: send device latency for port %d failed\n", __func__,
- port_id);
- ret = -EINVAL;
- goto end;
- } else if (atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto end;
- }
- ret = 0;
-end:
+ ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &latency_param);
+ if (ret)
+ pr_err("%s: Failed to set latency, err %d\n", __func__, ret);
+
return ret;
}
EXPORT_SYMBOL(adm_send_compressed_device_latency);
@@ -4716,9 +4105,10 @@
int adm_swap_speaker_channels(int port_id, int copp_idx,
int sample_rate, bool spk_swap)
{
- struct audproc_mfc_output_media_fmt mfc_cfg;
+ struct audproc_mfc_param_media_fmt mfc_cfg;
+ struct param_hdr_v3 param_hdr;
uint16_t num_channels;
- int port_idx;
+ int port_idx = 0;
int ret = 0;
pr_debug("%s: Enter, port_id %d, copp_idx %d\n",
@@ -4727,50 +4117,27 @@
port_idx = adm_validate_and_get_port_index(port_id);
if (port_idx < 0 || port_idx >= AFE_MAX_PORTS) {
pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
+ } else if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
+ pr_err("%s: Invalid copp_idx 0x%x\n", __func__, copp_idx);
+ return -EINVAL;
}
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
- ret = -EINVAL;
- goto done;
- }
-
- num_channels = atomic_read(
- &this_adm.copp.channels[port_idx][copp_idx]);
+ num_channels = atomic_read(&this_adm.copp.channels[port_idx][copp_idx]);
if (num_channels != 2) {
pr_debug("%s: Invalid number of channels: %d\n",
__func__, num_channels);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
}
memset(&mfc_cfg, 0, sizeof(mfc_cfg));
- mfc_cfg.params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- mfc_cfg.params.hdr.pkt_size =
- sizeof(mfc_cfg);
- mfc_cfg.params.hdr.src_svc = APR_SVC_ADM;
- mfc_cfg.params.hdr.src_domain = APR_DOMAIN_APPS;
- mfc_cfg.params.hdr.src_port = port_id;
- mfc_cfg.params.hdr.dest_svc = APR_SVC_ADM;
- mfc_cfg.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- mfc_cfg.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- mfc_cfg.params.hdr.token = port_idx << 16 | copp_idx;
- mfc_cfg.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- mfc_cfg.params.payload_addr_lsw = 0;
- mfc_cfg.params.payload_addr_msw = 0;
- mfc_cfg.params.mem_map_handle = 0;
- mfc_cfg.params.payload_size = sizeof(mfc_cfg) -
- sizeof(mfc_cfg.params);
- mfc_cfg.data.module_id = AUDPROC_MODULE_ID_MFC;
- mfc_cfg.data.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
- mfc_cfg.data.param_size = mfc_cfg.params.payload_size -
- sizeof(mfc_cfg.data);
- mfc_cfg.data.reserved = 0;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ param_hdr.module_id = AUDPROC_MODULE_ID_MFC;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
+ param_hdr.param_size = sizeof(mfc_cfg);
+
mfc_cfg.sampling_rate = sample_rate;
mfc_cfg.bits_per_sample =
atomic_read(&this_adm.copp.bit_width[port_idx][copp_idx]);
@@ -4789,45 +4156,16 @@
(uint16_t) PCM_CHANNEL_FR;
}
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- pr_debug("%s: mfc config: port_idx %d copp_idx %d copp SR %d copp BW %d copp chan %d\n",
- __func__, port_idx, copp_idx, mfc_cfg.sampling_rate,
- mfc_cfg.bits_per_sample, mfc_cfg.num_channels);
-
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&mfc_cfg);
+ ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (u8 *) &mfc_cfg);
if (ret < 0) {
- pr_err("%s: port_id: for[0x%x] failed %d\n",
- __func__, port_id, ret);
- goto done;
- }
- /* Wait for the callback with copp id */
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: mfc_cfg Set params timed out for port_id: for [0x%x]\n",
- __func__, port_id);
- ret = -ETIMEDOUT;
- goto done;
- }
-
- if (atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [port_idx][copp_idx]));
- goto done;
+ pr_err("%s: Failed to set swap speaker channels on port[0x%x] failed %d\n",
+ __func__, port_id, ret);
+ return ret;
}
pr_debug("%s: mfc_cfg Set params returned success", __func__);
- ret = 0;
-
-done:
- return ret;
+ return 0;
}
EXPORT_SYMBOL(adm_swap_speaker_channels);
@@ -4844,108 +4182,41 @@
int adm_set_sound_focus(int port_id, int copp_idx,
struct sound_focus_param soundFocusData)
{
- struct adm_set_fluence_soundfocus_param soundfocus_params;
- int sz = 0;
+ struct adm_param_fluence_soundfocus_t soundfocus_params;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int port_idx;
int i;
pr_debug("%s: Enter, port_id %d, copp_idx %d\n",
__func__, port_id, copp_idx);
- port_id = afe_convert_virtual_to_portid(port_id);
- port_idx = adm_validate_and_get_port_index(port_id);
- if (port_idx < 0) {
- pr_err("%s: Invalid port_id %#x\n", __func__, port_id);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS;
+ param_hdr.param_size = sizeof(soundfocus_params);
- ret = -EINVAL;
- goto done;
- }
-
- if (copp_idx < 0 || copp_idx >= MAX_COPPS_PER_PORT) {
- pr_err("%s: Invalid copp_num: %d\n", __func__, copp_idx);
-
- ret = -EINVAL;
- goto done;
- }
-
- sz = sizeof(struct adm_set_fluence_soundfocus_param);
- soundfocus_params.params.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- soundfocus_params.params.hdr.pkt_size = sz;
- soundfocus_params.params.hdr.src_svc = APR_SVC_ADM;
- soundfocus_params.params.hdr.src_domain = APR_DOMAIN_APPS;
- soundfocus_params.params.hdr.src_port = port_id;
- soundfocus_params.params.hdr.dest_svc = APR_SVC_ADM;
- soundfocus_params.params.hdr.dest_domain = APR_DOMAIN_ADSP;
- soundfocus_params.params.hdr.dest_port =
- atomic_read(&this_adm.copp.id[port_idx][copp_idx]);
- soundfocus_params.params.hdr.token = port_idx << 16 |
- ADM_CLIENT_ID_SOURCE_TRACKING << 8 | copp_idx;
- soundfocus_params.params.hdr.opcode = ADM_CMD_SET_PP_PARAMS_V5;
- soundfocus_params.params.payload_addr_lsw = 0;
- soundfocus_params.params.payload_addr_msw = 0;
- soundfocus_params.params.mem_map_handle = 0;
- soundfocus_params.params.payload_size = sizeof(soundfocus_params) -
- sizeof(soundfocus_params.params);
- soundfocus_params.data.module_id = VOICEPROC_MODULE_ID_GENERIC_TX;
- soundfocus_params.data.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS;
- soundfocus_params.data.param_size =
- soundfocus_params.params.payload_size -
- sizeof(soundfocus_params.data);
- soundfocus_params.data.reserved = 0;
-
- memset(&(soundfocus_params.soundfocus_data), 0xFF,
- sizeof(struct adm_param_fluence_soundfocus_t));
+ memset(&(soundfocus_params), 0xFF, sizeof(soundfocus_params));
for (i = 0; i < MAX_SECTORS; i++) {
- soundfocus_params.soundfocus_data.start_angles[i] =
+ soundfocus_params.start_angles[i] =
soundFocusData.start_angle[i];
- soundfocus_params.soundfocus_data.enables[i] =
- soundFocusData.enable[i];
+ soundfocus_params.enables[i] = soundFocusData.enable[i];
pr_debug("%s: start_angle[%d] = %d\n",
__func__, i, soundFocusData.start_angle[i]);
pr_debug("%s: enable[%d] = %d\n",
__func__, i, soundFocusData.enable[i]);
}
- soundfocus_params.soundfocus_data.gain_step =
- soundFocusData.gain_step;
+ soundfocus_params.gain_step = soundFocusData.gain_step;
pr_debug("%s: gain_step = %d\n", __func__, soundFocusData.gain_step);
- soundfocus_params.soundfocus_data.reserved = 0;
+ soundfocus_params.reserved = 0;
- atomic_set(&this_adm.copp.stat[port_idx][copp_idx], -1);
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&soundfocus_params);
- if (ret < 0) {
- pr_err("%s: Set params failed\n", __func__);
+ ret = adm_pack_and_set_one_pp_param(port_id, copp_idx, param_hdr,
+ (uint8_t *) &soundfocus_params);
+ if (ret)
+ pr_err("%s: Failed to set sound focus params, err %d\n",
+ __func__, ret);
- ret = -EINVAL;
- goto done;
- }
- /* Wait for the callback */
- ret = wait_event_timeout(this_adm.copp.wait[port_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[port_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: Set params timed out\n", __func__);
-
- ret = -EINVAL;
- goto done;
- }
-
- if (this_adm.sourceTrackingData.apr_cmd_status != 0) {
- pr_err("%s - set params returned error [%s]\n",
- __func__, adsp_err_get_err_str(
- this_adm.sourceTrackingData.apr_cmd_status));
-
- ret = adsp_err_get_lnx_err_code(
- this_adm.sourceTrackingData.apr_cmd_status);
- goto done;
- }
-
- ret = 0;
-
-done:
pr_debug("%s: Exit, ret=%d\n", __func__, ret);
return ret;
@@ -4967,28 +4238,29 @@
{
int ret = 0, i;
char *params_value;
- uint32_t param_payload_len = sizeof(struct adm_param_data_v5) +
- sizeof(struct adm_param_fluence_soundfocus_t);
- struct adm_param_fluence_soundfocus_t *soundfocus_params;
+ uint32_t max_param_size = 0;
+ struct adm_param_fluence_soundfocus_t *soundfocus_params = NULL;
+ struct param_hdr_v3 param_hdr;
pr_debug("%s: Enter, port_id %d, copp_idx %d\n",
__func__, port_id, copp_idx);
- params_value = kzalloc(param_payload_len, GFP_KERNEL);
- if (!params_value) {
- ret = -ENOMEM;
- goto done;
- }
- ret = adm_get_params_v2(port_id, copp_idx,
- VOICEPROC_MODULE_ID_GENERIC_TX,
- VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS,
- param_payload_len,
- params_value,
- ADM_CLIENT_ID_SOURCE_TRACKING);
+ max_param_size = sizeof(struct adm_param_fluence_soundfocus_t) +
+ sizeof(union param_hdrs);
+ params_value = kzalloc(max_param_size, GFP_KERNEL);
+ if (!params_value)
+ return -ENOMEM;
+
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOUNDFOCUS;
+ param_hdr.param_size = max_param_size;
+ ret = adm_get_pp_params(port_id, copp_idx,
+ ADM_CLIENT_ID_SOURCE_TRACKING, NULL, ¶m_hdr,
+ params_value);
if (ret) {
pr_err("%s: get parameters failed ret:%d\n", __func__, ret);
-
- kfree(params_value);
ret = -EINVAL;
goto done;
}
@@ -4997,8 +4269,6 @@
pr_err("%s - get params returned error [%s]\n",
__func__, adsp_err_get_err_str(
this_adm.sourceTrackingData.apr_cmd_status));
-
- kfree(params_value);
ret = adsp_err_get_lnx_err_code(
this_adm.sourceTrackingData.apr_cmd_status);
goto done;
@@ -5018,11 +4288,10 @@
soundFocusData->gain_step = soundfocus_params->gain_step;
pr_debug("%s: gain_step = %d\n", __func__, soundFocusData->gain_step);
- kfree(params_value);
-
done:
pr_debug("%s: Exit, ret = %d\n", __func__, ret);
+ kfree(params_value);
return ret;
}
EXPORT_SYMBOL(adm_get_sound_focus);
@@ -5033,9 +4302,7 @@
pr_debug("%s: Enter\n", __func__);
- ret = msm_audio_ion_alloc("SOURCE_TRACKING",
- &this_adm.sourceTrackingData.ion_client,
- &this_adm.sourceTrackingData.ion_handle,
+ ret = msm_audio_ion_alloc(&this_adm.sourceTrackingData.dma_buf,
AUD_PROC_BLOCK_SIZE,
&this_adm.sourceTrackingData.memmap.paddr,
&this_adm.sourceTrackingData.memmap.size,
@@ -5058,10 +4325,8 @@
(void *)this_adm.sourceTrackingData.memmap.paddr,
(uint32_t)this_adm.sourceTrackingData.memmap.size);
- msm_audio_ion_free(this_adm.sourceTrackingData.ion_client,
- this_adm.sourceTrackingData.ion_handle);
- this_adm.sourceTrackingData.ion_client = NULL;
- this_adm.sourceTrackingData.ion_handle = NULL;
+ msm_audio_ion_free(this_adm.sourceTrackingData.dma_buf);
+ this_adm.sourceTrackingData.dma_buf = NULL;
this_adm.sourceTrackingData.memmap.size = 0;
this_adm.sourceTrackingData.memmap.kvaddr = NULL;
this_adm.sourceTrackingData.memmap.paddr = 0;
@@ -5098,9 +4363,12 @@
int adm_get_source_tracking(int port_id, int copp_idx,
struct source_tracking_param *sourceTrackingData)
{
- struct adm_cmd_get_pp_params_v5 admp;
- int p_idx, ret = 0, i;
- struct adm_param_fluence_sourcetracking_t *source_tracking_params;
+ struct adm_param_fluence_sourcetracking_t *source_tracking_params =
+ NULL;
+ struct mem_mapping_hdr mem_hdr;
+ struct param_hdr_v3 param_hdr;
+ int i = 0;
+ int ret = 0;
pr_debug("%s: Enter, port_id %d, copp_idx %d\n",
__func__, port_id, copp_idx);
@@ -5114,68 +4382,36 @@
}
}
- port_id = afe_convert_virtual_to_portid(port_id);
- p_idx = adm_validate_and_get_port_index(port_id);
- if (p_idx < 0) {
- pr_err("%s - invalid port index %i, port id %i, copp idx %i\n",
- __func__, p_idx, port_id, copp_idx);
-
- ret = -EINVAL;
- goto done;
- }
-
- admp.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- admp.hdr.pkt_size = sizeof(admp);
- admp.hdr.src_svc = APR_SVC_ADM;
- admp.hdr.src_domain = APR_DOMAIN_APPS;
- admp.hdr.src_port = port_id;
- admp.hdr.dest_svc = APR_SVC_ADM;
- admp.hdr.dest_domain = APR_DOMAIN_ADSP;
- admp.hdr.dest_port = atomic_read(&this_adm.copp.id[p_idx][copp_idx]);
- admp.hdr.token = p_idx << 16 | ADM_CLIENT_ID_SOURCE_TRACKING << 8 |
- copp_idx;
- admp.hdr.opcode = ADM_CMD_GET_PP_PARAMS_V5;
- admp.data_payload_addr_lsw =
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ mem_hdr.data_payload_addr_lsw =
lower_32_bits(this_adm.sourceTrackingData.memmap.paddr);
- admp.data_payload_addr_msw =
- msm_audio_populate_upper_32_bits(
- this_adm.sourceTrackingData.memmap.paddr);
- admp.mem_map_handle = atomic_read(&this_adm.mem_map_handles[
- ADM_MEM_MAP_INDEX_SOURCE_TRACKING]);
- admp.module_id = VOICEPROC_MODULE_ID_GENERIC_TX;
- admp.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING;
- admp.param_max_size = sizeof(struct adm_param_fluence_sourcetracking_t)
- + sizeof(struct adm_param_data_v5);
- admp.reserved = 0;
+ mem_hdr.data_payload_addr_msw = msm_audio_populate_upper_32_bits(
+ this_adm.sourceTrackingData.memmap.paddr);
+ mem_hdr.mem_map_handle = atomic_read(
+ &this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING]);
- atomic_set(&this_adm.copp.stat[p_idx][copp_idx], -1);
+ param_hdr.module_id = VOICEPROC_MODULE_ID_GENERIC_TX;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = VOICEPROC_PARAM_ID_FLUENCE_SOURCETRACKING;
+ /*
+ * This size should be the max size of the calibration data + header.
+ * Use the union size to ensure max size is used.
+ */
+ param_hdr.param_size =
+ sizeof(struct adm_param_fluence_sourcetracking_t) +
+ sizeof(union param_hdrs);
- ret = apr_send_pkt(this_adm.apr, (uint32_t *)&admp);
- if (ret < 0) {
- pr_err("%s - failed to get Source Tracking Params\n",
- __func__);
-
- ret = -EINVAL;
- goto done;
- }
- ret = wait_event_timeout(this_adm.copp.wait[p_idx][copp_idx],
- atomic_read(&this_adm.copp.stat[p_idx][copp_idx]) >= 0,
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s - get params timed out\n", __func__);
-
- ret = -EINVAL;
- goto done;
- } else if (atomic_read(&this_adm.copp.stat
- [p_idx][copp_idx]) > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_adm.copp.stat
- [p_idx][copp_idx])));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_adm.copp.stat
- [p_idx][copp_idx]));
+ /*
+ * Retrieving parameters out of band, so no need to provide a buffer for
+ * the returned parameter data as it will be at the memory location
+ * provided.
+ */
+ ret = adm_get_pp_params(port_id, copp_idx,
+ ADM_CLIENT_ID_SOURCE_TRACKING, &mem_hdr,
+ ¶m_hdr, NULL);
+ if (ret) {
+ pr_err("%s: Failed to get params, error %d\n", __func__, ret);
goto done;
}
@@ -5189,9 +4425,11 @@
goto done;
}
- source_tracking_params = (struct adm_param_fluence_sourcetracking_t *)
- (this_adm.sourceTrackingData.memmap.kvaddr +
- sizeof(struct adm_param_data_v5));
+ /* How do we know what the param data was retrieved with for hdr size */
+ source_tracking_params =
+ (struct adm_param_fluence_sourcetracking_t
+ *) (this_adm.sourceTrackingData.memmap.kvaddr +
+ sizeof(struct param_hdr_v1));
for (i = 0; i < MAX_SECTORS; i++) {
sourceTrackingData->vad[i] = source_tracking_params->vad[i];
pr_debug("%s: vad[%d] = %d\n",
@@ -5227,57 +4465,34 @@
{
int i = 0, j;
- this_adm.apr = NULL;
this_adm.ec_ref_rx = -1;
- this_adm.num_ec_ref_rx_chans = 0;
- this_adm.ec_ref_rx_bit_width = 0;
- this_adm.ec_ref_rx_sampling_rate = 0;
- atomic_set(&this_adm.matrix_map_stat, 0);
init_waitqueue_head(&this_adm.matrix_map_wait);
- atomic_set(&this_adm.adm_stat, 0);
init_waitqueue_head(&this_adm.adm_wait);
for (i = 0; i < AFE_MAX_PORTS; i++) {
for (j = 0; j < MAX_COPPS_PER_PORT; j++) {
atomic_set(&this_adm.copp.id[i][j], RESET_COPP_ID);
- atomic_set(&this_adm.copp.cnt[i][j], 0);
- atomic_set(&this_adm.copp.topology[i][j], 0);
- atomic_set(&this_adm.copp.mode[i][j], 0);
- atomic_set(&this_adm.copp.stat[i][j], 0);
- atomic_set(&this_adm.copp.rate[i][j], 0);
- atomic_set(&this_adm.copp.channels[i][j], 0);
- atomic_set(&this_adm.copp.bit_width[i][j], 0);
- atomic_set(&this_adm.copp.app_type[i][j], 0);
- atomic_set(&this_adm.copp.acdb_id[i][j], 0);
init_waitqueue_head(&this_adm.copp.wait[i][j]);
- atomic_set(&this_adm.copp.adm_delay_stat[i][j], 0);
init_waitqueue_head(
&this_adm.copp.adm_delay_wait[i][j]);
- atomic_set(&this_adm.copp.topology[i][j], 0);
- this_adm.copp.adm_delay[i][j] = 0;
- this_adm.copp.adm_status[i][j] =
- ADM_STATUS_CALIBRATION_REQUIRED;
}
}
if (adm_init_cal_data())
pr_err("%s: could not init cal data!\n", __func__);
- this_adm.sourceTrackingData.ion_client = NULL;
- this_adm.sourceTrackingData.ion_handle = NULL;
+ this_adm.sourceTrackingData.dma_buf = NULL;
this_adm.sourceTrackingData.memmap.size = 0;
this_adm.sourceTrackingData.memmap.kvaddr = NULL;
this_adm.sourceTrackingData.memmap.paddr = 0;
this_adm.sourceTrackingData.apr_cmd_status = -1;
- atomic_set(&this_adm.mem_map_handles[ADM_MEM_MAP_INDEX_SOURCE_TRACKING],
- 0);
- mutex_init(&dts_srs_lock);
return 0;
}
void adm_exit(void)
{
- mutex_destroy(&dts_srs_lock);
+ if (this_adm.apr)
+ adm_reset_data();
adm_delete_cal_data();
}
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 391a7f7..781a436 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,7 @@
#include <dsp/audio_cal_utils.h>
#include <dsp/q6afe-v2.h>
#include <dsp/q6audio-v2.h>
+#include <dsp/q6common.h>
#include <ipc/apr_tal.h>
#include "adsp_err.h"
@@ -199,100 +200,127 @@
__func__, data->opcode, data->payload_size);
}
-static void av_dev_drift_afe_cb_handler(uint32_t *payload,
+static void av_dev_drift_afe_cb_handler(uint32_t opcode, uint32_t *payload,
uint32_t payload_size)
{
u32 param_id;
- struct afe_av_dev_drift_get_param_resp *resp =
- (struct afe_av_dev_drift_get_param_resp *) payload;
+ size_t expected_size =
+ sizeof(u32) + sizeof(struct afe_param_id_dev_timing_stats);
- if (!(&(resp->pdata))) {
- pr_err("%s: Error: resp pdata is NULL\n", __func__);
+ /* Get param ID depending on command type */
+ param_id = (opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ? payload[3] :
+ payload[2];
+ if (param_id != AFE_PARAM_ID_DEV_TIMING_STATS) {
+ pr_err("%s: Unrecognized param ID %d\n", __func__, param_id);
return;
}
- param_id = resp->pdata.param_id;
- if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
- if (payload_size < sizeof(this_afe.av_dev_drift_resp)) {
- pr_err("%s: Error: received size %d, resp size %zu\n",
- __func__, payload_size,
- sizeof(this_afe.av_dev_drift_resp));
+ switch (opcode) {
+ case AFE_PORT_CMDRSP_GET_PARAM_V2:
+ expected_size += sizeof(struct param_hdr_v1);
+ if (payload_size < expected_size) {
+ pr_err("%s: Error: received size %d, expected size %zu\n",
+ __func__, payload_size, expected_size);
+ return;
+ }
+ /* Repack response to add IID */
+ this_afe.av_dev_drift_resp.status = payload[0];
+ this_afe.av_dev_drift_resp.pdata.module_id = payload[1];
+ this_afe.av_dev_drift_resp.pdata.instance_id = INSTANCE_ID_0;
+ this_afe.av_dev_drift_resp.pdata.param_id = payload[2];
+ this_afe.av_dev_drift_resp.pdata.param_size = payload[3];
+ memcpy(&this_afe.av_dev_drift_resp.timing_stats, &payload[4],
+ sizeof(struct afe_param_id_dev_timing_stats));
+ break;
+ case AFE_PORT_CMDRSP_GET_PARAM_V3:
+ expected_size += sizeof(struct param_hdr_v3);
+ if (payload_size < expected_size) {
+ pr_err("%s: Error: received size %d, expected size %zu\n",
+ __func__, payload_size, expected_size);
return;
}
memcpy(&this_afe.av_dev_drift_resp, payload,
sizeof(this_afe.av_dev_drift_resp));
- if (!this_afe.av_dev_drift_resp.status) {
- atomic_set(&this_afe.state, 0);
- } else {
- pr_debug("%s: av_dev_drift_resp status: %d", __func__,
- this_afe.av_dev_drift_resp.status);
- atomic_set(&this_afe.state, -1);
- }
+ break;
+ default:
+ pr_err("%s: Unrecognized command %d\n", __func__, opcode);
+ return;
+ }
+
+ if (!this_afe.av_dev_drift_resp.status) {
+ atomic_set(&this_afe.state, 0);
+ } else {
+ pr_debug("%s: av_dev_drift_resp status: %d", __func__,
+ this_afe.av_dev_drift_resp.status);
+ atomic_set(&this_afe.state, -1);
}
}
-static int32_t sp_make_afe_callback(uint32_t *payload, uint32_t payload_size)
+static int32_t sp_make_afe_callback(uint32_t opcode, uint32_t *payload,
+ uint32_t payload_size)
{
- u32 param_id;
- struct afe_spkr_prot_calib_get_resp *resp =
- (struct afe_spkr_prot_calib_get_resp *) payload;
+ struct param_hdr_v3 param_hdr;
+ u32 *data_dest = NULL;
+ u32 *data_start = NULL;
+ size_t expected_size = sizeof(u32);
- if (!(&(resp->pdata))) {
- pr_err("%s: Error: resp pdata is NULL\n", __func__);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ /* Set command specific details */
+ switch (opcode) {
+ case AFE_PORT_CMDRSP_GET_PARAM_V2:
+ expected_size += sizeof(struct param_hdr_v1);
+ param_hdr.module_id = payload[1];
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = payload[2];
+ param_hdr.param_size = payload[3];
+ data_start = &payload[4];
+ break;
+ case AFE_PORT_CMDRSP_GET_PARAM_V3:
+ expected_size += sizeof(struct param_hdr_v3);
+ memcpy(¶m_hdr, &payload[1], sizeof(struct param_hdr_v3));
+ data_start = &payload[5];
+ break;
+ default:
+ pr_err("%s: Unrecognized command %d\n", __func__, opcode);
return -EINVAL;
}
- param_id = resp->pdata.param_id;
- if (param_id == AFE_PARAM_ID_CALIB_RES_CFG_V2) {
- if (payload_size < sizeof(this_afe.calib_data)) {
- pr_err("%s: Error: received size %d, calib_data size %zu\n",
- __func__, payload_size,
- sizeof(this_afe.calib_data));
- return -EINVAL;
- }
- memcpy(&this_afe.calib_data, payload,
- sizeof(this_afe.calib_data));
- if (!this_afe.calib_data.status) {
- atomic_set(&this_afe.state, 0);
- } else {
- pr_debug("%s: calib resp status: %d", __func__,
- this_afe.calib_data.status);
- atomic_set(&this_afe.state, -1);
- }
+ switch (param_hdr.param_id) {
+ case AFE_PARAM_ID_CALIB_RES_CFG_V2:
+ expected_size += sizeof(struct asm_calib_res_cfg);
+ data_dest = (u32 *) &this_afe.calib_data;
+ break;
+ case AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS:
+ expected_size += sizeof(struct afe_sp_th_vi_ftm_params);
+ data_dest = (u32 *) &this_afe.th_vi_resp;
+ break;
+ case AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS:
+ expected_size += sizeof(struct afe_sp_ex_vi_ftm_params);
+ data_dest = (u32 *) &this_afe.ex_vi_resp;
+ break;
+ default:
+ pr_err("%s: Unrecognized param ID %d\n", __func__,
+ param_hdr.param_id);
+ return -EINVAL;
}
- if (param_id == AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS) {
- if (payload_size < sizeof(this_afe.th_vi_resp)) {
- pr_err("%s: Error: received size %d, th_vi_resp size %zu\n",
- __func__, payload_size,
- sizeof(this_afe.th_vi_resp));
- return -EINVAL;
- }
- memcpy(&this_afe.th_vi_resp, payload,
- sizeof(this_afe.th_vi_resp));
- if (!this_afe.th_vi_resp.status) {
- atomic_set(&this_afe.state, 0);
- } else {
- pr_debug("%s: th vi resp status: %d", __func__,
- this_afe.th_vi_resp.status);
- atomic_set(&this_afe.state, -1);
- }
+
+ if (payload_size < expected_size) {
+ pr_err("%s: Error: received size %d, expected size %zu for param %d\n",
+ __func__, payload_size, expected_size,
+ param_hdr.param_id);
+ return -EINVAL;
}
- if (param_id == AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS) {
- if (payload_size < sizeof(this_afe.ex_vi_resp)) {
- pr_err("%s: Error: received size %d, ex_vi_resp size %zu\n",
- __func__, payload_size,
- sizeof(this_afe.ex_vi_resp));
- return -EINVAL;
- }
- memcpy(&this_afe.ex_vi_resp, payload,
- sizeof(this_afe.ex_vi_resp));
- if (!this_afe.ex_vi_resp.status) {
- atomic_set(&this_afe.state, 0);
- } else {
- pr_debug("%s: ex vi resp status: %d", __func__,
- this_afe.ex_vi_resp.status);
- atomic_set(&this_afe.state, -1);
- }
+
+ data_dest[0] = payload[0];
+ memcpy(&data_dest[1], ¶m_hdr, sizeof(struct param_hdr_v3));
+ memcpy(&data_dest[5], data_start, param_hdr.param_size);
+
+ if (!data_dest[0]) {
+ atomic_set(&this_afe.state, 0);
+ } else {
+ pr_debug("%s: status: %d", __func__, data_dest[0]);
+ atomic_set(&this_afe.state, -1);
}
return 0;
@@ -350,8 +378,10 @@
return 0;
}
afe_callback_debug_print(data);
- if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2) {
+ if (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V2 ||
+ data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) {
uint32_t *payload = data->payload;
+ uint32_t param_id;
if (!payload || (data->token >= AFE_MAX_PORTS)) {
pr_err("%s: Error: size %d payload %pK token %d\n",
@@ -360,15 +390,18 @@
return -EINVAL;
}
- if (payload[2] == AFE_PARAM_ID_DEV_TIMING_STATS) {
- av_dev_drift_afe_cb_handler(data->payload,
+ param_id = (data->opcode == AFE_PORT_CMDRSP_GET_PARAM_V3) ?
+ payload[3] :
+ payload[2];
+ if (param_id == AFE_PARAM_ID_DEV_TIMING_STATS) {
+ av_dev_drift_afe_cb_handler(data->opcode, data->payload,
data->payload_size);
} else {
if (rtac_make_afe_callback(data->payload,
data->payload_size))
return 0;
- if (sp_make_afe_callback(data->payload,
+ if (sp_make_afe_callback(data->opcode, data->payload,
data->payload_size))
return -EINVAL;
}
@@ -390,8 +423,9 @@
}
switch (payload[0]) {
case AFE_PORT_CMD_SET_PARAM_V2:
+ case AFE_PORT_CMD_SET_PARAM_V3:
if (rtac_make_afe_callback(payload,
- data->payload_size))
+ data->payload_size))
return 0;
case AFE_PORT_CMD_DEVICE_STOP:
case AFE_PORT_CMD_DEVICE_START:
@@ -402,6 +436,7 @@
case AFE_SERVICE_CMD_UNREGISTER_RT_PORT_DRIVER:
case AFE_PORTS_CMD_DTMF_CTL:
case AFE_SVC_CMD_SET_PARAM:
+ case AFE_SVC_CMD_SET_PARAM_V2:
atomic_set(&this_afe.state, 0);
wake_up(&this_afe.wait[data->token]);
break;
@@ -419,6 +454,28 @@
pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n",
__func__, payload[1]);
break;
+ case AFE_PORT_CMD_GET_PARAM_V2:
+ case AFE_PORT_CMD_GET_PARAM_V3:
+ /*
+ * Should only come here if there is an APR
+ * error or malformed APR packet. Otherwise
+ * response will be returned as
+ * AFE_PORT_CMDRSP_GET_PARAM_V2/3
+ */
+ pr_debug("%s: AFE Get Param opcode 0x%x token 0x%x src %d dest %d\n",
+ __func__, data->opcode, data->token,
+ data->src_port, data->dest_port);
+ if (payload[1] != 0) {
+ pr_err("%s: AFE Get Param failed with error %d\n",
+ __func__, payload[1]);
+ if (rtac_make_afe_callback(
+ payload,
+ data->payload_size))
+ return 0;
+ }
+ atomic_set(&this_afe.state, payload[1]);
+ wake_up(&this_afe.wait[data->token]);
+ break;
default:
pr_err("%s: Unknown cmd 0x%x\n", __func__,
payload[0]);
@@ -796,11 +853,403 @@
return ret;
}
+/* This function shouldn't be called directly. Instead call q6afe_set_params. */
+static int q6afe_set_params_v2(u16 port_id, int index,
+ struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ struct afe_port_cmd_set_param_v2 *set_param = NULL;
+ uint32_t size = sizeof(struct afe_port_cmd_set_param_v2);
+ int rc = 0;
+
+ if (packed_param_data != NULL)
+ size += packed_data_size;
+ set_param = kzalloc(size, GFP_KERNEL);
+ if (set_param == NULL)
+ return -ENOMEM;
+
+ set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ set_param->apr_hdr.pkt_size = size;
+ set_param->apr_hdr.src_port = 0;
+ set_param->apr_hdr.dest_port = 0;
+ set_param->apr_hdr.token = index;
+ set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+ set_param->port_id = port_id;
+ if (packed_data_size > U16_MAX) {
+ pr_err("%s: Invalid data size for set params V2 %d\n", __func__,
+ packed_data_size);
+ rc = -EINVAL;
+ goto done;
+ }
+ set_param->payload_size = packed_data_size;
+ if (mem_hdr != NULL) {
+ set_param->mem_hdr = *mem_hdr;
+ } else if (packed_param_data != NULL) {
+ memcpy(&set_param->param_data, packed_param_data,
+ packed_data_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ rc = afe_apr_send_pkt(set_param, &this_afe.wait[index]);
+done:
+ kfree(set_param);
+ return rc;
+}
+
+/* This function shouldn't be called directly. Instead call q6afe_set_params. */
+static int q6afe_set_params_v3(u16 port_id, int index,
+ struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ struct afe_port_cmd_set_param_v3 *set_param = NULL;
+ uint32_t size = sizeof(struct afe_port_cmd_set_param_v3);
+ int rc = 0;
+
+ if (packed_param_data != NULL)
+ size += packed_data_size;
+ set_param = kzalloc(size, GFP_KERNEL);
+ if (set_param == NULL)
+ return -ENOMEM;
+
+ set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ set_param->apr_hdr.pkt_size = size;
+ set_param->apr_hdr.src_port = 0;
+ set_param->apr_hdr.dest_port = 0;
+ set_param->apr_hdr.token = index;
+ set_param->apr_hdr.opcode = AFE_PORT_CMD_SET_PARAM_V3;
+ set_param->port_id = port_id;
+ set_param->payload_size = packed_data_size;
+ if (mem_hdr != NULL) {
+ set_param->mem_hdr = *mem_hdr;
+ } else if (packed_param_data != NULL) {
+ memcpy(&set_param->param_data, packed_param_data,
+ packed_data_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ rc = afe_apr_send_pkt(set_param, &this_afe.wait[index]);
+done:
+ kfree(set_param);
+ return rc;
+}
+
+static int q6afe_set_params(u16 port_id, int index,
+ struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ int ret = 0;
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ port_id = q6audio_get_port_id(port_id);
+ ret = q6audio_validate_port(port_id);
+ if (ret < 0) {
+ pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__,
+ port_id, ret);
+ return -EINVAL;
+ }
+
+ if (index < 0 || index >= AFE_MAX_PORTS) {
+ pr_err("%s: AFE port index[%d] invalid\n", __func__, index);
+ return -EINVAL;
+ }
+
+ if (q6common_is_instance_id_supported())
+ return q6afe_set_params_v3(port_id, index, mem_hdr,
+ packed_param_data, packed_data_size);
+ else
+ return q6afe_set_params_v2(port_id, index, mem_hdr,
+ packed_param_data, packed_data_size);
+}
+
+static int q6afe_pack_and_set_param_in_band(u16 port_id, int index,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data)
+{
+ u8 *packed_param_data = NULL;
+ int packed_data_size = sizeof(union param_hdrs) + param_hdr.param_size;
+ int ret;
+
+ packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
+ if (packed_param_data == NULL)
+ return -ENOMEM;
+
+ ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data,
+ &packed_data_size);
+ if (ret) {
+ pr_err("%s: Failed to pack param header and data, error %d\n",
+ __func__, ret);
+ goto fail_cmd;
+ }
+
+ ret = q6afe_set_params(port_id, index, NULL, packed_param_data,
+ packed_data_size);
+
+fail_cmd:
+ kfree(packed_param_data);
+ return ret;
+}
+
+/* This function shouldn't be called directly. Instead call q6afe_get_param. */
+static int q6afe_get_params_v2(u16 port_id, int index,
+ struct mem_mapping_hdr *mem_hdr,
+ struct param_hdr_v3 *param_hdr)
+{
+ struct afe_port_cmd_get_param_v2 afe_get_param;
+ u32 param_size = param_hdr->param_size;
+
+ memset(&afe_get_param, 0, sizeof(afe_get_param));
+ afe_get_param.apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param) + param_size;
+ afe_get_param.apr_hdr.src_port = 0;
+ afe_get_param.apr_hdr.dest_port = 0;
+ afe_get_param.apr_hdr.token = index;
+ afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
+ afe_get_param.port_id = port_id;
+ afe_get_param.payload_size = sizeof(struct param_hdr_v1) + param_size;
+ if (mem_hdr != NULL)
+ afe_get_param.mem_hdr = *mem_hdr;
+ /* Set MID and PID in command */
+ afe_get_param.module_id = param_hdr->module_id;
+ afe_get_param.param_id = param_hdr->param_id;
+ /* Set param header in payload */
+ afe_get_param.param_hdr.module_id = param_hdr->module_id;
+ afe_get_param.param_hdr.param_id = param_hdr->param_id;
+ afe_get_param.param_hdr.param_size = param_size;
+
+ return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]);
+}
+
+/* This function shouldn't be called directly. Instead call q6afe_get_param. */
+static int q6afe_get_params_v3(u16 port_id, int index,
+ struct mem_mapping_hdr *mem_hdr,
+ struct param_hdr_v3 *param_hdr)
+{
+ struct afe_port_cmd_get_param_v3 afe_get_param;
+
+ memset(&afe_get_param, 0, sizeof(afe_get_param));
+ afe_get_param.apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ afe_get_param.apr_hdr.pkt_size = sizeof(afe_get_param);
+ afe_get_param.apr_hdr.src_port = 0;
+ afe_get_param.apr_hdr.dest_port = 0;
+ afe_get_param.apr_hdr.token = index;
+ afe_get_param.apr_hdr.opcode = AFE_PORT_CMD_GET_PARAM_V3;
+ afe_get_param.port_id = port_id;
+ if (mem_hdr != NULL)
+ afe_get_param.mem_hdr = *mem_hdr;
+ /* Set param header in command, no payload in V3 */
+ afe_get_param.param_hdr = *param_hdr;
+
+ return afe_apr_send_pkt(&afe_get_param, &this_afe.wait[index]);
+}
+
+/*
+ * Calling functions copy param data directly from this_afe. Do not copy data
+ * back to caller here.
+ */
+static int q6afe_get_params(u16 port_id, struct mem_mapping_hdr *mem_hdr,
+ struct param_hdr_v3 *param_hdr)
+{
+ int index;
+ int ret;
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ port_id = q6audio_get_port_id(port_id);
+ ret = q6audio_validate_port(port_id);
+ if (ret < 0) {
+ pr_err("%s: Not a valid port id = 0x%x ret %d\n", __func__,
+ port_id, ret);
+ return -EINVAL;
+ }
+
+ 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;
+ }
+
+ if (q6common_is_instance_id_supported())
+ return q6afe_get_params_v3(port_id, index, NULL, param_hdr);
+ else
+ return q6afe_get_params_v2(port_id, index, NULL, param_hdr);
+}
+
+/*
+ * This function shouldn't be called directly. Instead call
+ * q6afe_svc_set_params.
+ */
+static int q6afe_svc_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL;
+ uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1);
+ int rc = 0;
+
+ if (packed_param_data != NULL)
+ size += packed_data_size;
+ svc_set_param = kzalloc(size, GFP_KERNEL);
+ if (svc_set_param == NULL)
+ return -ENOMEM;
+
+ svc_set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ svc_set_param->apr_hdr.pkt_size = size;
+ svc_set_param->apr_hdr.src_port = 0;
+ svc_set_param->apr_hdr.dest_port = 0;
+ svc_set_param->apr_hdr.token = index;
+ svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ svc_set_param->payload_size = packed_data_size;
+
+ if (mem_hdr != NULL) {
+ /* Out of band case. */
+ svc_set_param->mem_hdr = *mem_hdr;
+ } else if (packed_param_data != NULL) {
+ /* In band case. */
+ memcpy(&svc_set_param->param_data, packed_param_data,
+ packed_data_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ rc = afe_apr_send_pkt(svc_set_param, &this_afe.wait[index]);
+done:
+ kfree(svc_set_param);
+ return rc;
+}
+
+/*
+ * This function shouldn't be called directly. Instead call
+ * q6afe_svc_set_params.
+ */
+static int q6afe_svc_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL;
+ uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2);
+ int rc = 0;
+
+ if (packed_param_data != NULL)
+ size += packed_data_size;
+ svc_set_param = kzalloc(size, GFP_KERNEL);
+ if (svc_set_param == NULL)
+ return -ENOMEM;
+
+ svc_set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ svc_set_param->apr_hdr.pkt_size = size;
+ svc_set_param->apr_hdr.src_port = 0;
+ svc_set_param->apr_hdr.dest_port = 0;
+ svc_set_param->apr_hdr.token = index;
+ svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2;
+ svc_set_param->payload_size = packed_data_size;
+
+ if (mem_hdr != NULL) {
+ /* Out of band case. */
+ svc_set_param->mem_hdr = *mem_hdr;
+ } else if (packed_param_data != NULL) {
+ /* In band case. */
+ memcpy(&svc_set_param->param_data, packed_param_data,
+ packed_data_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ rc = afe_apr_send_pkt(svc_set_param, &this_afe.wait[index]);
+done:
+ kfree(svc_set_param);
+ return rc;
+}
+
+static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ int ret;
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (q6common_is_instance_id_supported())
+ return q6afe_svc_set_params_v2(index, mem_hdr,
+ packed_param_data,
+ packed_data_size);
+ else
+ return q6afe_svc_set_params_v1(index, mem_hdr,
+ packed_param_data,
+ packed_data_size);
+}
+
+static int q6afe_svc_pack_and_set_param_in_band(int index,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data)
+{
+ u8 *packed_param_data = NULL;
+ u32 packed_data_size =
+ sizeof(struct param_hdr_v3) + param_hdr.param_size;
+ int ret = 0;
+
+ packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
+ if (!packed_param_data)
+ return -ENOMEM;
+
+ ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr, param_data,
+ &packed_data_size);
+ if (ret) {
+ pr_err("%s: Failed to pack parameter header and data, error %d\n",
+ __func__, ret);
+ goto done;
+ }
+
+ ret = q6afe_svc_set_params(index, NULL, packed_param_data,
+ packed_data_size);
+
+done:
+ kfree(packed_param_data);
+ return ret;
+}
+
static int afe_send_cal_block(u16 port_id, struct cal_block_data *cal_block)
{
- int result = 0;
- int index = 0;
- struct afe_audioif_config_command_no_payload afe_cal;
+ struct mem_mapping_hdr mem_hdr;
+ int payload_size = 0;
+ int result = 0;
+
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
if (!cal_block) {
pr_debug("%s: No AFE cal to send!\n", __func__);
@@ -813,34 +1262,19 @@
goto done;
}
- 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);
- result = -EINVAL;
- goto done;
- }
-
- afe_cal.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- afe_cal.hdr.pkt_size = sizeof(afe_cal);
- afe_cal.hdr.src_port = 0;
- afe_cal.hdr.dest_port = 0;
- afe_cal.hdr.token = index;
- afe_cal.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- afe_cal.param.port_id = port_id;
- afe_cal.param.payload_size = cal_block->cal_data.size;
- afe_cal.param.payload_address_lsw =
+ payload_size = cal_block->cal_data.size;
+ mem_hdr.data_payload_addr_lsw =
lower_32_bits(cal_block->cal_data.paddr);
- afe_cal.param.payload_address_msw =
+ mem_hdr.data_payload_addr_msw =
msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
- afe_cal.param.mem_map_handle = cal_block->map_data.q6map_handle;
+ mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle;
pr_debug("%s: AFE cal sent for device port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
__func__, port_id,
cal_block->cal_data.size, &cal_block->cal_data.paddr);
- result = afe_apr_send_pkt(&afe_cal, &this_afe.wait[index]);
+ result = q6afe_set_params(port_id, q6audio_get_port_index(port_id),
+ &mem_hdr, NULL, payload_size);
if (result)
pr_err("%s: AFE cal for port 0x%x failed %d\n",
__func__, port_id, result);
@@ -910,7 +1344,7 @@
goto unlock;
this_afe.set_custom_topology = 0;
cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
- if (cal_block == NULL) {
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
pr_err("%s cal_block not found!!\n", __func__);
goto unlock;
}
@@ -936,9 +1370,10 @@
static int afe_spk_ramp_dn_cfg(int port)
{
+ struct param_hdr_v3 param_info;
int ret = -EINVAL;
- int index = 0;
- struct afe_spkr_prot_config_command config;
+
+ memset(¶m_info, 0, sizeof(param_info));
if (afe_get_port_type(port) != MSM_AFE_PORT_TYPE_RX) {
pr_debug("%s: port doesn't match 0x%x\n", __func__, port);
@@ -950,84 +1385,41 @@
__func__, port, ret, this_afe.vi_rx_port);
return 0;
}
- memset(&config, 0, sizeof(config));
- ret = q6audio_validate_port(port);
- if (ret < 0) {
- pr_err("%s: Invalid port 0x%x ret %d", __func__, port, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
- index = q6audio_get_port_index(port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid!\n",
- __func__, index);
- ret = -EINVAL;
- goto fail_cmd;
- }
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
+ param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG;
+ param_info.param_size = 0;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port);
- config.param.payload_size =
- sizeof(config) - sizeof(config.hdr) - sizeof(config.param)
- - sizeof(config.prot_config);
- config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
- config.pdata.param_id = AFE_PARAM_ID_FBSP_PTONE_RAMP_CFG;
- config.pdata.param_size = 0;
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
- if (ret < 0) {
- pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
- __func__, port, config.pdata.param_id, ret);
+ ret = q6afe_pack_and_set_param_in_band(port,
+ q6audio_get_port_index(port),
+ param_info, NULL);
+ if (ret) {
+ pr_err("%s: Failed to set speaker ramp duration param, err %d\n",
+ __func__, ret);
goto fail_cmd;
}
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
+
/* dsp needs atleast 15ms to ramp down pilot tone*/
usleep_range(15000, 15010);
ret = 0;
fail_cmd:
- pr_debug("%s: config.pdata.param_id 0x%x status %d\n",
- __func__, config.pdata.param_id, ret);
-return ret;
+ pr_debug("%s: config.pdata.param_id 0x%x status %d\n", __func__,
+ param_info.param_id, ret);
+ return ret;
}
static int afe_spk_prot_prepare(int src_port, int dst_port, int param_id,
- union afe_spkr_prot_config *prot_config)
+ union afe_spkr_prot_config *prot_config)
{
+ struct param_hdr_v3 param_info;
int ret = -EINVAL;
- int index = 0;
- struct afe_spkr_prot_config_command config;
- memset(&config, 0, sizeof(config));
- if (!prot_config) {
- pr_err("%s: Invalid params\n", __func__);
- goto fail_cmd;
- }
+ memset(¶m_info, 0, sizeof(param_info));
+
ret = q6audio_validate_port(src_port);
if (ret < 0) {
- pr_err("%s: Invalid src port 0x%x ret %d",
- __func__, src_port, ret);
+ pr_err("%s: Invalid src port 0x%x ret %d", __func__, src_port,
+ ret);
ret = -EINVAL;
goto fail_cmd;
}
@@ -1038,22 +1430,16 @@
ret = -EINVAL;
goto fail_cmd;
}
- index = q6audio_get_port_index(src_port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid!\n",
- __func__, index);
- ret = -EINVAL;
- goto fail_cmd;
- }
+
switch (param_id) {
case AFE_PARAM_ID_FBSP_MODE_RX_CFG:
case AFE_PARAM_ID_SP_RX_LIMITER_TH:
- config.pdata.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
+ param_info.module_id = AFE_MODULE_FB_SPKR_PROT_V2_RX;
break;
case AFE_PARAM_ID_FEEDBACK_PATH_CFG:
this_afe.vi_tx_port = src_port;
this_afe.vi_rx_port = dst_port;
- config.pdata.module_id = AFE_MODULE_FEEDBACK;
+ param_info.module_id = AFE_MODULE_FEEDBACK;
break;
/*
* AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2 is same as
@@ -1061,59 +1447,31 @@
*/
case AFE_PARAM_ID_SPKR_CALIB_VI_PROC_CFG_V2:
case AFE_PARAM_ID_SP_V2_TH_VI_FTM_CFG:
- config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
+ param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
break;
case AFE_PARAM_ID_SP_V2_EX_VI_MODE_CFG:
case AFE_PARAM_ID_SP_V2_EX_VI_FTM_CFG:
- config.pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
+ param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
break;
default:
pr_err("%s: default case 0x%x\n", __func__, param_id);
goto fail_cmd;
}
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = param_id;
+ param_info.param_size = sizeof(union afe_spkr_prot_config);
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(src_port);
- config.param.payload_size = sizeof(config) - sizeof(config.hdr)
- - sizeof(config.param);
- config.pdata.param_id = param_id;
- config.pdata.param_size = sizeof(config.prot_config);
- config.prot_config = *prot_config;
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
- if (ret < 0) {
- pr_err("%s: port = 0x%x param = 0x%x failed %d\n",
- __func__, src_port, param_id, ret);
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
- ret = 0;
+ ret = q6afe_pack_and_set_param_in_band(src_port,
+ q6audio_get_port_index(src_port),
+ param_info, (u8 *) prot_config);
+ if (ret)
+ pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__,
+ src_port, param_id, ret);
+
fail_cmd:
- pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n",
- __func__, config.pdata.param_id, ret, src_port);
+ pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__,
+ param_info.param_id, ret, src_port);
return ret;
}
@@ -1286,14 +1644,16 @@
static int afe_send_hw_delay(u16 port_id, u32 rate)
{
- struct audio_cal_hw_delay_entry delay_entry;
- struct afe_audioif_config_command config;
- int index = 0;
+ struct audio_cal_hw_delay_entry delay_entry;
+ struct afe_param_id_device_hw_delay_cfg hw_delay;
+ struct param_hdr_v3 param_info;
int ret = -EINVAL;
pr_debug("%s:\n", __func__);
memset(&delay_entry, 0, sizeof(delay_entry));
+ memset(¶m_info, 0, sizeof(param_info));
+
delay_entry.sample_rate = rate;
if (afe_get_port_type(port_id) == MSM_AFE_PORT_TYPE_TX)
ret = afe_get_cal_hw_delay(TX_DEVICE, &delay_entry);
@@ -1311,42 +1671,21 @@
goto fail_cmd;
}
- 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);
- ret = -EINVAL;
- goto fail_cmd;
- }
+ param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY;
+ param_info.param_size = sizeof(hw_delay);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
+ hw_delay.delay_in_us = delay_entry.delay_usec;
+ hw_delay.device_hw_delay_minor_version =
+ AFE_API_VERSION_DEVICE_HW_DELAY;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = AFE_PARAM_ID_DEVICE_HW_DELAY;
- config.pdata.param_size = sizeof(config.port);
-
- config.port.hw_delay.delay_in_us = delay_entry.delay_usec;
- config.port.hw_delay.device_hw_delay_minor_version =
- AFE_API_VERSION_DEVICE_HW_DELAY;
-
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
- if (ret) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_info, (u8 *) &hw_delay);
+ if (ret)
pr_err("%s: AFE hw delay for port 0x%x failed %d\n",
__func__, port_id, ret);
- goto fail_cmd;
- }
fail_cmd:
pr_debug("%s: port_id 0x%x rate %u delay_usec %d status %d\n",
@@ -1370,7 +1709,9 @@
&cal_type->cal_blocks) {
cal_block = list_entry(ptr,
struct cal_block_data, list);
-
+ /* Skip cal_block if it is already marked stale */
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
path = ((afe_get_port_type(port_id) ==
MSM_AFE_PORT_TYPE_TX)?(TX_DEVICE):(RX_DEVICE));
afe_top =
@@ -1398,6 +1739,11 @@
return NULL;
}
+/*
+ * Retrieving cal_block will mark cal_block as stale.
+ * Hence it cannot be reused or resent unless the flag
+ * is reset.
+ */
static int afe_get_cal_topology_id(u16 port_id, u32 *topology_id,
int cal_type_index)
{
@@ -1407,7 +1753,8 @@
struct audio_cal_info_afe_top *afe_top_info = NULL;
if (this_afe.cal_data[cal_type_index] == NULL) {
- pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized\n", __func__);
+ pr_err("%s: cal_type %d not initialized\n", __func__,
+ cal_type_index);
return -EINVAL;
}
if (topology_id == NULL) {
@@ -1420,8 +1767,8 @@
cal_block = afe_find_cal_topo_id_by_port(
this_afe.cal_data[cal_type_index], port_id);
if (cal_block == NULL) {
- pr_err("%s: [AFE_TOPOLOGY_CAL] not initialized for this port %d\n",
- __func__, port_id);
+ pr_err("%s: cal_type %d not initialized for this port %d\n",
+ __func__, cal_type_index, port_id);
ret = -EINVAL;
goto unlock;
}
@@ -1435,6 +1782,7 @@
goto unlock;
}
*topology_id = (u32)afe_top_info->topology;
+ cal_utils_mark_cal_used(cal_block);
pr_debug("%s: port_id = %u acdb_id = %d topology_id = %u ret=%d\n",
__func__, port_id, afe_top_info->acdb_id,
@@ -1446,11 +1794,14 @@
static int afe_send_port_topology_id(u16 port_id)
{
- struct afe_audioif_config_command config;
+ struct afe_param_id_set_topology_cfg topology;
+ struct param_hdr_v3 param_info;
+ u32 topology_id = 0;
int index = 0;
int ret = 0;
- u32 topology_id = 0;
+ memset(&topology, 0, sizeof(topology));
+ memset(¶m_info, 0, sizeof(param_info));
index = q6audio_get_port_index(port_id);
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
@@ -1470,32 +1821,17 @@
goto done;
}
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
+ param_info.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_SET_TOPOLOGY;
+ param_info.param_size = sizeof(topology);
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = AFE_PARAM_ID_SET_TOPOLOGY;
- config.pdata.param_size = sizeof(config.port);
- config.port.topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1;
- config.port.topology.topology_id = topology_id;
+ topology.minor_version = AFE_API_VERSION_TOPOLOGY_V1;
+ topology.topology_id = topology_id;
- pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n",
- __func__, config.param.payload_size, config.pdata.param_size,
- sizeof(config), sizeof(config.param), sizeof(config.port),
- sizeof(struct apr_hdr), config.pdata.param_id);
-
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_info, (u8 *) &topology);
if (ret) {
pr_err("%s: AFE set topology id enable for port 0x%x failed %d\n",
__func__, port_id, ret);
@@ -1515,7 +1851,7 @@
{
int ret = 0;
- if (cal_block->map_data.ion_client == NULL) {
+ if (cal_block->map_data.dma_buf == NULL) {
pr_err("%s: No ION allocation for cal index %d!\n",
__func__, cal_index);
ret = -EINVAL;
@@ -1613,7 +1949,7 @@
cal_block = cal_utils_get_only_cal_block(
this_afe.cal_data[cal_index]);
- if (cal_block == NULL) {
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
pr_err("%s cal_block not found!!\n", __func__);
ret = -EINVAL;
goto unlock;
@@ -1632,6 +1968,9 @@
if (ret < 0)
pr_debug("%s: No cal sent for cal_index %d, port_id = 0x%x! ret %d\n",
__func__, cal_index, port_id, ret);
+
+ cal_utils_mark_cal_used(cal_block);
+
unlock:
mutex_unlock(&this_afe.cal_data[cal_index]->lock);
done:
@@ -1657,33 +1996,26 @@
int afe_turn_onoff_hw_mad(u16 mad_type, u16 enable)
{
+ struct afe_param_hw_mad_ctrl mad_enable_param;
+ struct param_hdr_v3 param_info;
int ret;
- struct afe_cmd_hw_mad_ctrl config;
pr_debug("%s: enter\n", __func__);
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = SLIMBUS_5_TX;
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_HW_MAD;
- config.pdata.param_id = AFE_PARAM_ID_HW_MAD_CTRL;
- config.pdata.param_size = sizeof(config.payload);
- config.payload.minor_version = 1;
- config.payload.mad_type = mad_type;
- config.payload.mad_enable = enable;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ memset(&mad_enable_param, 0, sizeof(mad_enable_param));
+ memset(¶m_info, 0, sizeof(param_info));
+ param_info.module_id = AFE_MODULE_HW_MAD;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = AFE_PARAM_ID_HW_MAD_CTRL;
+ param_info.param_size = sizeof(mad_enable_param);
+
+ mad_enable_param.minor_version = 1;
+ mad_enable_param.mad_type = mad_type;
+ mad_enable_param.mad_enable = enable;
+
+ ret = q6afe_pack_and_set_param_in_band(SLIMBUS_5_TX, IDX_GLOBAL_CFG,
+ param_info,
+ (u8 *) &mad_enable_param);
if (ret)
pr_err("%s: AFE_PARAM_ID_HW_MAD_CTRL failed %d\n", __func__,
ret);
@@ -1693,31 +2025,19 @@
static int afe_send_slimbus_slave_cfg(
struct afe_param_cdc_slimbus_slave_cfg *sb_slave_cfg)
{
+ struct param_hdr_v3 param_hdr;
int ret;
- struct afe_svc_cmd_sb_slave_cfg config;
pr_debug("%s: enter\n", __func__);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
- config.pdata.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG;
- config.pdata.param_size =
- sizeof(struct afe_param_cdc_slimbus_slave_cfg);
- config.sb_slave_cfg = *sb_slave_cfg;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG;
+ param_hdr.param_size = sizeof(struct afe_param_cdc_slimbus_slave_cfg);
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ (u8 *) sb_slave_cfg);
if (ret)
pr_err("%s: AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG failed %d\n",
__func__, ret);
@@ -1729,29 +2049,17 @@
static int afe_send_codec_reg_page_config(
struct afe_param_cdc_reg_page_cfg *cdc_reg_page_cfg)
{
- struct afe_svc_cmd_cdc_reg_page_cfg config;
+ struct param_hdr_v3 param_hdr;
int ret;
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
- config.pdata.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG;
- config.pdata.param_size =
- sizeof(struct afe_param_cdc_reg_page_cfg);
- config.cdc_reg_page_cfg = *cdc_reg_page_cfg;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CDC_REG_PAGE_CFG;
+ param_hdr.param_size = sizeof(struct afe_param_cdc_reg_page_cfg);
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ (u8 *) cdc_reg_page_cfg);
if (ret)
pr_err("%s: AFE_PARAM_ID_CDC_REG_PAGE_CFG failed %d\n",
__func__, ret);
@@ -1762,186 +2070,123 @@
static int afe_send_codec_reg_config(
struct afe_param_cdc_reg_cfg_data *cdc_reg_cfg)
{
- int i, j, ret = -EINVAL;
- int pkt_size, payload_size, reg_per_pkt, num_pkts, num_regs;
- struct afe_svc_cmd_cdc_reg_cfg *config;
- struct afe_svc_cmd_set_param *param;
+ u8 *packed_param_data = NULL;
+ u32 packed_data_size = 0;
+ u32 single_param_size = 0;
+ u32 max_data_size = 0;
+ u32 max_single_param = 0;
+ struct param_hdr_v3 param_hdr;
+ int idx = 0;
+ int ret = -EINVAL;
- reg_per_pkt = (APR_MAX_BUF - sizeof(*config)) /
- sizeof(struct afe_param_cdc_reg_cfg_payload);
- if (reg_per_pkt > 0) {
- num_pkts = (cdc_reg_cfg->num_registers / reg_per_pkt) +
- (cdc_reg_cfg->num_registers % reg_per_pkt == 0 ? 0 : 1);
- } else {
- pr_err("%s: Failed to build codec reg config APR packet\n",
- __func__);
- return -EINVAL;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ max_single_param = sizeof(struct param_hdr_v3) +
+ sizeof(struct afe_param_cdc_reg_cfg);
+ max_data_size = APR_MAX_BUF - sizeof(struct afe_svc_cmd_set_param_v2);
+ packed_param_data = kzalloc(max_data_size, GFP_KERNEL);
+ if (!packed_param_data)
+ return -ENOMEM;
- for (j = 0; j < num_pkts; ++j) {
- /*
- * num_regs is set to reg_per_pkt on each pass through the loop
- * except the last, when it is set to the number of registers
- * remaining from the total
- */
- num_regs = (j < (num_pkts - 1) ? reg_per_pkt :
- cdc_reg_cfg->num_registers - (reg_per_pkt * j));
- payload_size = sizeof(struct afe_param_cdc_reg_cfg_payload) *
- num_regs;
- pkt_size = sizeof(*config) + payload_size;
- pr_debug("%s: pkt_size %d, payload_size %d\n", __func__,
- pkt_size, payload_size);
- config = kzalloc(pkt_size, GFP_KERNEL);
- if (!config)
- return -ENOMEM;
+ /* param_hdr is the same for all params sent, set once at top */
+ param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG;
+ param_hdr.param_size = sizeof(struct afe_param_cdc_reg_cfg);
- config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config->hdr.pkt_size = pkt_size;
- config->hdr.src_port = 0;
- config->hdr.dest_port = 0;
- config->hdr.token = IDX_GLOBAL_CFG;
- config->hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ while (idx < cdc_reg_cfg->num_registers) {
+ memset(packed_param_data, 0, max_data_size);
+ packed_data_size = 0;
+ single_param_size = 0;
- param = &config->param;
- param->payload_size = payload_size;
- param->payload_address_lsw = 0x00;
- param->payload_address_msw = 0x00;
- param->mem_map_handle = 0x00;
-
- for (i = 0; i < num_regs; i++) {
- config->reg_data[i].common.module_id =
- AFE_MODULE_CDC_DEV_CFG;
- config->reg_data[i].common.param_id =
- AFE_PARAM_ID_CDC_REG_CFG;
- config->reg_data[i].common.param_size =
- sizeof(config->reg_data[i].reg_cfg);
- config->reg_data[i].reg_cfg =
- cdc_reg_cfg->reg_data[i + (j * reg_per_pkt)];
+ while (packed_data_size + max_single_param < max_data_size &&
+ idx < cdc_reg_cfg->num_registers) {
+ ret = q6common_pack_pp_params(
+ packed_param_data + packed_data_size,
+ ¶m_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx],
+ &single_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack parameters with error %d\n",
+ __func__, ret);
+ goto done;
+ }
+ packed_data_size += single_param_size;
+ idx++;
}
- ret = afe_apr_send_pkt(config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL,
+ packed_param_data, packed_data_size);
if (ret) {
pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n",
__func__, ret);
- kfree(config);
break;
}
- kfree(config);
}
-
+done:
+ kfree(packed_param_data);
return ret;
}
static int afe_init_cdc_reg_config(void)
{
+ struct param_hdr_v3 param_hdr;
int ret;
- struct afe_svc_cmd_init_cdc_reg_cfg config;
pr_debug("%s: enter\n", __func__);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT;
- config.param.payload_size = sizeof(struct afe_port_param_data_v2);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
-
- config.init.module_id = AFE_MODULE_CDC_DEV_CFG;
- config.init.param_id = AFE_PARAM_ID_CDC_REG_CFG_INIT;
- config.init.param_size = 0;
-
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
- if (ret) {
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ NULL);
+ if (ret)
pr_err("%s: AFE_PARAM_ID_CDC_INIT_REG_CFG failed %d\n",
__func__, ret);
- }
return ret;
}
static int afe_send_slimbus_slave_port_cfg(
- struct afe_param_slimbus_slave_port_cfg *port_config, u16 port_id)
+ struct afe_param_slimbus_slave_port_cfg *slim_slave_config, u16 port_id)
{
- int ret, index;
- struct afe_cmd_hw_mad_slimbus_slave_port_cfg config;
+ struct param_hdr_v3 param_hdr;
+ int ret;
pr_debug("%s: enter, 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;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_HW_MAD;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.reserved = 0;
+ param_hdr.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG;
+ param_hdr.param_size = sizeof(struct afe_param_slimbus_slave_port_cfg);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = port_id;
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_HW_MAD;
- config.pdata.param_id = AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG;
- config.pdata.param_size = sizeof(*port_config);
- config.sb_port_cfg = *port_config;
-
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
- if (ret) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) slim_slave_config);
+ if (ret)
pr_err("%s: AFE_PARAM_ID_SLIMBUS_SLAVE_PORT_CFG failed %d\n",
__func__, ret);
- }
+
pr_debug("%s: leave %d\n", __func__, ret);
return ret;
}
static int afe_aanc_port_cfg(void *apr, uint16_t tx_port, uint16_t rx_port)
{
- struct afe_port_cmd_set_aanc_param cfg;
+ struct afe_param_aanc_port_cfg aanc_port_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
pr_debug("%s: tx_port 0x%x, rx_port 0x%x\n",
__func__, tx_port, rx_port);
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return -EINVAL;
- }
+ pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n", __func__,
+ this_afe.aanc_info.aanc_tx_port_sample_rate,
+ this_afe.aanc_info.aanc_rx_port_sample_rate);
- index = q6audio_get_port_index(tx_port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid!\n",
- __func__, index);
- return -EINVAL;
- }
- ret = q6audio_validate_port(tx_port);
- if (ret < 0) {
- pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret);
- return -EINVAL;
- }
- pr_debug("%s: AANC sample rate tx rate: %d rx rate %d\n",
- __func__, this_afe.aanc_info.aanc_tx_port_sample_rate,
- this_afe.aanc_info.aanc_rx_port_sample_rate);
+ memset(&aanc_port_cfg, 0, sizeof(aanc_port_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
/*
* If aanc tx sample rate or rx sample rate is zero, skip aanc
* configuration as AFE resampler will fail for invalid sample
@@ -1952,177 +2197,107 @@
return -EINVAL;
}
- cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- cfg.hdr.pkt_size = sizeof(cfg);
- cfg.hdr.src_port = 0;
- cfg.hdr.dest_port = 0;
- cfg.hdr.token = index;
- cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+ param_hdr.module_id = AFE_MODULE_AANC;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_aanc_port_cfg);
- cfg.param.port_id = tx_port;
- cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) +
- sizeof(struct afe_param_aanc_port_cfg);
- cfg.param.payload_address_lsw = 0;
- cfg.param.payload_address_msw = 0;
- cfg.param.mem_map_handle = 0;
-
- cfg.pdata.module_id = AFE_MODULE_AANC;
- cfg.pdata.param_id = AFE_PARAM_ID_AANC_PORT_CONFIG;
- cfg.pdata.param_size = sizeof(struct afe_param_aanc_port_cfg);
- cfg.pdata.reserved = 0;
-
- cfg.data.aanc_port_cfg.aanc_port_cfg_minor_version =
+ aanc_port_cfg.aanc_port_cfg_minor_version =
AFE_API_VERSION_AANC_PORT_CONFIG;
- cfg.data.aanc_port_cfg.tx_port_sample_rate =
+ aanc_port_cfg.tx_port_sample_rate =
this_afe.aanc_info.aanc_tx_port_sample_rate;
- cfg.data.aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC;
- cfg.data.aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC;
- cfg.data.aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC;
- cfg.data.aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED;
- cfg.data.aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED;
- cfg.data.aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED;
- cfg.data.aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED;
- cfg.data.aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED;
- cfg.data.aanc_port_cfg.tx_port_num_channels = 3;
- cfg.data.aanc_port_cfg.rx_path_ref_port_id = rx_port;
- cfg.data.aanc_port_cfg.ref_port_sample_rate =
- this_afe.aanc_info.aanc_rx_port_sample_rate;
+ aanc_port_cfg.tx_port_channel_map[0] = AANC_TX_VOICE_MIC;
+ aanc_port_cfg.tx_port_channel_map[1] = AANC_TX_NOISE_MIC;
+ aanc_port_cfg.tx_port_channel_map[2] = AANC_TX_ERROR_MIC;
+ aanc_port_cfg.tx_port_channel_map[3] = AANC_TX_MIC_UNUSED;
+ aanc_port_cfg.tx_port_channel_map[4] = AANC_TX_MIC_UNUSED;
+ aanc_port_cfg.tx_port_channel_map[5] = AANC_TX_MIC_UNUSED;
+ aanc_port_cfg.tx_port_channel_map[6] = AANC_TX_MIC_UNUSED;
+ aanc_port_cfg.tx_port_channel_map[7] = AANC_TX_MIC_UNUSED;
+ aanc_port_cfg.tx_port_num_channels = 3;
+ aanc_port_cfg.rx_path_ref_port_id = rx_port;
+ aanc_port_cfg.ref_port_sample_rate =
+ this_afe.aanc_info.aanc_rx_port_sample_rate;
- ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]);
- if (ret) {
+ ret = q6afe_pack_and_set_param_in_band(tx_port,
+ q6audio_get_port_index(tx_port),
+ param_hdr,
+ (u8 *) &aanc_port_cfg);
+ if (ret)
pr_err("%s: AFE AANC port config failed for tx_port 0x%x, rx_port 0x%x ret %d\n",
- __func__, tx_port, rx_port, ret);
- }
+ __func__, tx_port, rx_port, ret);
return ret;
}
static int afe_aanc_mod_enable(void *apr, uint16_t tx_port, uint16_t enable)
{
- struct afe_port_cmd_set_aanc_param cfg;
+ struct afe_mod_enable_param mod_enable;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
- pr_debug("%s: tx_port 0x%x\n",
- __func__, tx_port);
+ pr_debug("%s: tx_port 0x%x\n", __func__, tx_port);
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return -EINVAL;
- }
+ memset(&mod_enable, 0, sizeof(mod_enable));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_AANC;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_ENABLE;
+ param_hdr.param_size = sizeof(struct afe_mod_enable_param);
- index = q6audio_get_port_index(tx_port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid!\n",
- __func__, index);
- return -EINVAL;
- }
- ret = q6audio_validate_port(tx_port);
- if (ret < 0) {
- pr_err("%s: port id: 0x%x ret %d\n", __func__, tx_port, ret);
- return -EINVAL;
- }
+ mod_enable.enable = enable;
+ mod_enable.reserved = 0;
- cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- cfg.hdr.pkt_size = sizeof(cfg);
- cfg.hdr.src_port = 0;
- cfg.hdr.dest_port = 0;
- cfg.hdr.token = index;
- cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
-
- cfg.param.port_id = tx_port;
- cfg.param.payload_size = sizeof(struct afe_port_param_data_v2) +
- sizeof(struct afe_mod_enable_param);
- cfg.param.payload_address_lsw = 0;
- cfg.param.payload_address_lsw = 0;
- cfg.param.mem_map_handle = 0;
-
- cfg.pdata.module_id = AFE_MODULE_AANC;
- cfg.pdata.param_id = AFE_PARAM_ID_ENABLE;
- cfg.pdata.param_size = sizeof(struct afe_mod_enable_param);
- cfg.pdata.reserved = 0;
-
- cfg.data.mod_enable.enable = enable;
- cfg.data.mod_enable.reserved = 0;
-
- ret = afe_apr_send_pkt((uint32_t *) &cfg, &this_afe.wait[index]);
- if (ret) {
+ ret = q6afe_pack_and_set_param_in_band(tx_port,
+ q6audio_get_port_index(tx_port),
+ param_hdr, (u8 *) &mod_enable);
+ if (ret)
pr_err("%s: AFE AANC enable failed for tx_port 0x%x ret %d\n",
__func__, tx_port, ret);
- }
return ret;
}
static int afe_send_bank_selection_clip(
struct afe_param_id_clip_bank_sel *param)
{
+ struct param_hdr_v3 param_hdr;
int ret;
- struct afe_svc_cmd_set_clip_bank_selection config;
if (!param) {
pr_err("%s: Invalid params", __func__);
return -EINVAL;
}
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG;
+ param_hdr.param_size = sizeof(struct afe_param_id_clip_bank_sel);
- config.param.payload_size = sizeof(struct afe_port_param_data_v2) +
- sizeof(struct afe_param_id_clip_bank_sel);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
-
- config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
- config.pdata.param_id = AFE_PARAM_ID_CLIP_BANK_SEL_CFG;
- config.pdata.param_size =
- sizeof(struct afe_param_id_clip_bank_sel);
- config.bank_sel = *param;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
- if (ret) {
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ (u8 *) param);
+ if (ret)
pr_err("%s: AFE_PARAM_ID_CLIP_BANK_SEL_CFG failed %d\n",
__func__, ret);
- }
return ret;
}
int afe_send_aanc_version(
struct afe_param_id_cdc_aanc_version *version_cfg)
{
+ struct param_hdr_v3 param_hdr;
int ret;
- struct afe_svc_cmd_cdc_aanc_version config;
pr_debug("%s: enter\n", __func__);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_CDC_DEV_CFG;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CDC_AANC_VERSION;
+ param_hdr.param_size = sizeof(struct afe_param_id_cdc_aanc_version);
- config.param.payload_size = sizeof(struct afe_port_param_data_v2) +
- sizeof(struct afe_param_id_cdc_aanc_version);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
-
- config.pdata.module_id = AFE_MODULE_CDC_DEV_CFG;
- config.pdata.param_id = AFE_PARAM_ID_CDC_AANC_VERSION;
- config.pdata.param_size =
- sizeof(struct afe_param_id_cdc_aanc_version);
- config.version = *version_cfg;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
- if (ret) {
+ ret = q6afe_svc_pack_and_set_param_in_band(IDX_GLOBAL_CFG, param_hdr,
+ (u8 *) version_cfg);
+ if (ret)
pr_err("%s: AFE_PARAM_ID_CDC_AANC_VERSION failed %d\n",
__func__, ret);
- }
return ret;
}
@@ -2261,86 +2436,32 @@
int afe_send_spdif_clk_cfg(struct afe_param_id_spdif_clk_cfg *cfg,
u16 port_id)
{
- struct afe_spdif_clk_config_command clk_cfg;
+ struct afe_param_id_spdif_clk_cfg clk_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
if (!cfg) {
pr_err("%s: Error, no configuration data\n", __func__);
- ret = -EINVAL;
- return ret;
- }
- 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) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
- clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
- clk_cfg.hdr.src_port = 0;
- clk_cfg.hdr.dest_port = 0;
- clk_cfg.hdr.token = index;
+ memset(&clk_cfg, 0, sizeof(clk_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_id_spdif_clk_cfg);
- clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- clk_cfg.param.port_id = q6audio_get_port_id(port_id);
- clk_cfg.param.payload_address_lsw = 0x00;
- clk_cfg.param.payload_address_msw = 0x00;
- clk_cfg.param.mem_map_handle = 0x00;
- clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- clk_cfg.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
- clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
- clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
- - sizeof(clk_cfg.param);
- clk_cfg.clk_cfg = *cfg;
+ pr_debug("%s: Minor version = 0x%x clk val = %d clk root = 0x%x port id = 0x%x\n",
+ __func__, clk_cfg.clk_cfg_minor_version, clk_cfg.clk_value,
+ clk_cfg.clk_root, q6audio_get_port_id(port_id));
- pr_debug("%s: Minor version = 0x%x clk val = %d\n"
- "clk root = 0x%x\n port id = 0x%x\n",
- __func__, cfg->clk_cfg_minor_version,
- cfg->clk_value, cfg->clk_root,
- q6audio_get_port_id(port_id));
-
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &clk_cfg);
+ if (ret < 0)
pr_err("%s: AFE send clock config for port 0x%x failed ret = %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
-
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
return ret;
}
@@ -2357,80 +2478,25 @@
int afe_send_spdif_ch_status_cfg(struct afe_param_id_spdif_ch_status_cfg
*ch_status_cfg, u16 port_id)
{
- struct afe_spdif_chstatus_config_command ch_status;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
- if (!ch_status_cfg) {
+ if (!ch_status_cfg)
pr_err("%s: Error, no configuration data\n", __func__);
- ret = -EINVAL;
- return ret;
- }
- 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;
- }
+ return -EINVAL;
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
- ch_status.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- ch_status.hdr.pkt_size = sizeof(ch_status_cfg);
- ch_status.hdr.src_port = 0;
- ch_status.hdr.dest_port = 0;
- ch_status.hdr.token = index;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_id_spdif_ch_status_cfg);
- ch_status.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- ch_status.param.port_id = q6audio_get_port_id(port_id);
- ch_status.param.payload_address_lsw = 0x00;
- ch_status.param.payload_address_msw = 0x00;
- ch_status.param.mem_map_handle = 0x00;
- ch_status.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- ch_status.pdata.param_id = AFE_PARAM_ID_SPDIF_CLK_CONFIG;
- ch_status.pdata.param_size = sizeof(ch_status.ch_status);
- ch_status.param.payload_size = sizeof(ch_status)
- - sizeof(struct apr_hdr) - sizeof(ch_status.param);
- ch_status.ch_status = *ch_status_cfg;
-
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &ch_status);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) ch_status_cfg);
+ if (ret < 0)
pr_err("%s: AFE send channel status for port 0x%x failed ret = %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
-
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
return ret;
}
EXPORT_SYMBOL(afe_send_spdif_ch_status_cfg);
@@ -2509,10 +2575,9 @@
int afe_spdif_port_start(u16 port_id, struct afe_spdif_port_config *spdif_port,
u32 rate)
{
- struct afe_audioif_config_command config;
- int ret = 0;
- int index = 0;
+ struct param_hdr_v3 param_hdr;
uint16_t port_index;
+ int ret = 0;
if (!spdif_port) {
pr_err("%s: Error, no configuration data\n", __func__);
@@ -2522,12 +2587,7 @@
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;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
ret = q6audio_validate_port(port_id);
if (ret < 0) {
pr_err("%s: port id: 0x%x ret %d\n", __func__, port_id, ret);
@@ -2537,24 +2597,14 @@
afe_send_cal(port_id);
afe_send_hw_delay(port_id, rate);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = AFE_PARAM_ID_SPDIF_CONFIG;
- config.pdata.param_size = sizeof(config.port);
- config.port.spdif = spdif_port->cfg;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_SPDIF_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_spdif_port_config);
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) spdif_port);
if (ret) {
pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
__func__, port_id, ret);
@@ -2587,9 +2637,8 @@
struct afe_param_id_slot_mapping_cfg *slot_mapping_cfg,
u16 port_id)
{
- struct afe_slot_mapping_config_command config;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
if (!slot_mapping_cfg) {
pr_err("%s: Error, no configuration data\n", __func__);
@@ -2598,67 +2647,19 @@
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;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_TDM;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_id_slot_mapping_cfg);
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
-
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config)
- - sizeof(struct apr_hdr) - sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_TDM;
- config.pdata.param_id = AFE_PARAM_ID_PORT_SLOT_MAPPING_CONFIG;
- config.pdata.param_size = sizeof(config.slot_mapping);
- config.slot_mapping = *slot_mapping_cfg;
-
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) slot_mapping_cfg);
+ if (ret < 0)
pr_err("%s: AFE send slot mapping for port 0x%x failed ret = %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
-
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
return ret;
}
@@ -2666,9 +2667,8 @@
struct afe_param_id_custom_tdm_header_cfg *custom_tdm_header_cfg,
u16 port_id)
{
- struct afe_custom_tdm_header_config_command config;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
if (!custom_tdm_header_cfg) {
pr_err("%s: Error, no configuration data\n", __func__);
@@ -2677,67 +2677,20 @@
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;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_TDM;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG;
+ param_hdr.param_size =
+ sizeof(struct afe_param_id_custom_tdm_header_cfg);
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
-
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config)
- - sizeof(struct apr_hdr) - sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_TDM;
- config.pdata.param_id = AFE_PARAM_ID_CUSTOM_TDM_HEADER_CONFIG;
- config.pdata.param_size = sizeof(config.custom_tdm_header);
- config.custom_tdm_header = *custom_tdm_header_cfg;
-
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &config);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) custom_tdm_header_cfg);
+ if (ret < 0)
pr_err("%s: AFE send custom tdm header for port 0x%x failed ret = %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
-
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n",
- __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
return ret;
}
@@ -2755,11 +2708,11 @@
int afe_tdm_port_start(u16 port_id, struct afe_tdm_port_config *tdm_port,
u32 rate, u16 num_groups)
{
- struct afe_audioif_config_command config;
- int ret = 0;
+ struct param_hdr_v3 param_hdr;
int index = 0;
uint16_t port_index = 0;
enum afe_mad_type mad_type = MAD_HW_NONE;
+ int ret = 0;
if (!tdm_port) {
pr_err("%s: Error, no configuration data\n", __func__);
@@ -2768,6 +2721,7 @@
pr_debug("%s: port id: 0x%x\n", __func__, port_id);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
index = q6audio_get_port_index(port_id);
if (index < 0 || index >= AFE_MAX_PORTS) {
pr_err("%s: AFE port index[%d] invalid!\n",
@@ -2823,26 +2777,15 @@
}
}
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = AFE_PARAM_ID_TDM_CONFIG;
- config.pdata.param_size = sizeof(config.port);
- config.port.tdm = tdm_port->tdm;
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_TDM_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_param_id_tdm_cfg);
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &tdm_port->tdm);
if (ret) {
pr_err("%s: AFE enable for port 0x%x failed ret = %d\n",
__func__, port_id, ret);
@@ -2913,61 +2856,48 @@
int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config)
{
- struct afe_usb_audio_dev_param_command config;
- int ret = 0, index = 0;
+ struct afe_param_id_usb_audio_dev_params usb_dev;
+ struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt;
+ struct param_hdr_v3 param_hdr;
+ int ret = 0;
if (!afe_config) {
pr_err("%s: Error, no configuration data\n", __func__);
ret = -EINVAL;
goto exit;
}
- index = q6audio_get_port_index(port_id);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n",
- __func__, index, port_id);
- ret = -EINVAL;
- goto exit;
- }
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS;
- config.pdata.param_size = sizeof(config.usb_dev);
- config.usb_dev.cfg_minor_version =
- AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
- config.usb_dev.dev_token = afe_config->usb_audio.dev_token;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ memset(&usb_dev, 0, sizeof(usb_dev));
+ memset(&lpcm_fmt, 0, sizeof(lpcm_fmt));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+
+ param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS;
+ param_hdr.param_size = sizeof(usb_dev);
+ usb_dev.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
+ usb_dev.dev_token = afe_config->usb_audio.dev_token;
+
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &usb_dev);
if (ret) {
pr_err("%s: AFE device param cmd failed %d\n",
__func__, ret);
- ret = -EINVAL;
goto exit;
}
- config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT;
- config.pdata.param_size = sizeof(config.lpcm_fmt);
- config.lpcm_fmt.cfg_minor_version =
- AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
- config.lpcm_fmt.endian = afe_config->usb_audio.endian;
+ param_hdr.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_LPCM_FMT;
+ param_hdr.param_size = sizeof(lpcm_fmt);
+ lpcm_fmt.cfg_minor_version = AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG;
+ lpcm_fmt.endian = afe_config->usb_audio.endian;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &lpcm_fmt);
if (ret) {
pr_err("%s: AFE device param cmd LPCM_FMT failed %d\n",
__func__, ret);
- ret = -EINVAL;
goto exit;
}
@@ -2981,62 +2911,58 @@
u16 afe_in_channels, u16 afe_in_bit_width,
u32 scrambler_mode)
{
- struct afe_audioif_config_command config;
- int index;
+ u32 enc_fmt;
+ struct afe_enc_cfg_blk_param_t enc_blk_param;
+ struct afe_param_id_aptx_sync_mode sync_mode_param;
+ struct avs_enc_packetizer_id_param_t enc_pkt_id_param;
+ struct avs_enc_set_scrambler_param_t enc_set_scrambler_param;
+ struct afe_port_media_type_t media_type;
+ struct param_hdr_v3 param_hdr;
int ret;
- int payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param) - sizeof(config.port);
pr_debug("%s:update DSP for enc format = %d\n", __func__, format);
+
+ memset(&enc_blk_param, 0, sizeof(enc_blk_param));
+ memset(&sync_mode_param, 0, sizeof(sync_mode_param));
+ memset(&enc_pkt_id_param, 0, sizeof(enc_pkt_id_param));
+ memset(&enc_set_scrambler_param, 0, sizeof(enc_set_scrambler_param));
+ memset(&media_type, 0, sizeof(media_type));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD &&
format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC) {
pr_err("%s:Unsuppported format Ignore AFE config\n", __func__);
return 0;
}
- memset(&config, 0, sizeof(config));
- index = q6audio_get_port_index(port_id);
- if (index < 0) {
- pr_err("%s: Invalid index number: %d\n", __func__, index);
- return -EINVAL;
- }
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
+ param_hdr.module_id = AFE_MODULE_ID_ENCODER;
+ param_hdr.instance_id = INSTANCE_ID_0;
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = payload_size + sizeof(config.port.enc_fmt);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_ID_ENCODER;
- config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
- config.pdata.param_size = sizeof(config.port.enc_fmt);
- config.port.enc_fmt.fmt_id = format;
- pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload: %d\n",
- __func__, config.param.payload_size);
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_FMT_ID;
+ param_hdr.param_size = sizeof(enc_fmt);
+ enc_fmt = format;
+ pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENC_FMT_ID payload\n",
+ __func__);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &enc_fmt);
if (ret) {
pr_err("%s:unable to send AFE_ENCODER_PARAM_ID_ENC_FMT_ID",
__func__);
goto exit;
}
- config.param.payload_size = payload_size
- + sizeof(config.port.enc_blk_param);
- pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload:%d\n",
- __func__, config.param.payload_size);
- config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
- config.pdata.param_size = sizeof(config.port.enc_blk_param);
- config.port.enc_blk_param.enc_cfg_blk_size =
- sizeof(config.port.enc_blk_param.enc_blk_config);
- config.port.enc_blk_param.enc_blk_config = *cfg;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payloadn",
+ __func__);
+ param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
+ param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t);
+ enc_blk_param.enc_cfg_blk_size = sizeof(union afe_enc_config_data);
+ enc_blk_param.enc_blk_config = *cfg;
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &enc_blk_param);
if (ret) {
pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
__func__, port_id, ret);
@@ -3044,16 +2970,18 @@
}
if (format == ASM_MEDIA_FMT_APTX) {
- config.param.payload_size =
- payload_size + sizeof(config.port.sync_mode_param);
pr_debug("%s: sending AFE_PARAM_ID_APTX_SYNC_MODE to DSP",
__func__);
- config.pdata.param_id = AFE_PARAM_ID_APTX_SYNC_MODE;
- config.pdata.param_size = sizeof(config.port.sync_mode_param);
- config.port.sync_mode_param.sync_mode =
- config.port.enc_blk_param.enc_blk_config.aptx_config.
+ param_hdr.param_id = AFE_PARAM_ID_APTX_SYNC_MODE;
+ param_hdr.param_size =
+ sizeof(struct afe_param_id_aptx_sync_mode);
+ sync_mode_param.sync_mode =
+ enc_blk_param.enc_blk_config.aptx_config.
aptx_v2_cfg.sync_mode;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &sync_mode_param);
if (ret) {
pr_err("%s: AFE_PARAM_ID_APTX_SYNC_MODE for port 0x%x failed %d\n",
__func__, port_id, ret);
@@ -3061,67 +2989,57 @@
}
}
- config.param.payload_size =
- payload_size + sizeof(config.port.enc_pkt_id_param);
- pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP payload = %d",
- __func__, config.param.payload_size);
- config.pdata.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
- config.pdata.param_size = sizeof(config.port.enc_pkt_id_param);
- config.port.enc_pkt_id_param.enc_packetizer_id =
- AFE_MODULE_ID_PACKETIZER_COP;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n",
+ __func__);
+ param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
+ param_hdr.param_size = sizeof(struct avs_enc_packetizer_id_param_t);
+ enc_pkt_id_param.enc_packetizer_id = AFE_MODULE_ID_PACKETIZER_COP;
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &enc_pkt_id_param);
if (ret) {
pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
__func__, port_id, ret);
goto exit;
}
- config.param.payload_size =
- payload_size + sizeof(config.port.enc_set_scrambler_param);
- pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload = %d\n",
- __func__, scrambler_mode, config.param.payload_size);
- config.pdata.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING;
- config.pdata.param_size = sizeof(config.port.enc_set_scrambler_param);
- config.port.enc_set_scrambler_param.enable_scrambler = scrambler_mode;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload\n",
+ __func__, scrambler_mode);
+ param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING;
+ param_hdr.param_size = sizeof(struct avs_enc_set_scrambler_param_t);
+ enc_set_scrambler_param.enable_scrambler = scrambler_mode;
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &enc_set_scrambler_param);
if (ret) {
pr_err("%s: AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING for port 0x%x failed %d\n",
__func__, port_id, ret);
goto exit;
}
- config.param.payload_size =
- payload_size + sizeof(config.port.media_type);
- config.pdata.param_size = sizeof(config.port.media_type);
-
pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
- config.pdata.module_id = AFE_MODULE_PORT;
- config.pdata.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
- config.port.media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
- if (format == ASM_MEDIA_FMT_LDAC) {
- config.port.media_type.sample_rate =
- config.port.enc_blk_param.enc_blk_config.ldac_config.
- custom_config.sample_rate;
- } else {
- config.port.media_type.sample_rate =
- afe_config.slim_sch.sample_rate;
- }
-
+ param_hdr.module_id = AFE_MODULE_PORT;
+ param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
+ param_hdr.param_size = sizeof(struct afe_port_media_type_t);
+ media_type.minor_version = AFE_API_VERSION_PORT_MEDIA_TYPE;
+ media_type.sample_rate = afe_config.slim_sch.sample_rate;
if (afe_in_bit_width)
- config.port.media_type.bit_width = afe_in_bit_width;
+ media_type.bit_width = afe_in_bit_width;
else
- config.port.media_type.bit_width =
- afe_config.slim_sch.bit_width;
+ media_type.bit_width = afe_config.slim_sch.bit_width;
if (afe_in_channels)
- config.port.media_type.num_channels = afe_in_channels;
+ media_type.num_channels = afe_in_channels;
else
- config.port.media_type.num_channels =
- afe_config.slim_sch.num_channels;
- config.port.media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
- config.port.media_type.reserved = 0;
+ media_type.num_channels = afe_config.slim_sch.num_channels;
+ media_type.data_format = AFE_PORT_DATA_FORMAT_PCM;
+ media_type.reserved = 0;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &media_type);
if (ret) {
pr_err("%s: AFE_API_VERSION_PORT_MEDIA_TYPE for port 0x%x failed %d\n",
__func__, port_id, ret);
@@ -3137,13 +3055,17 @@
union afe_enc_config_data *cfg, u32 enc_format,
u32 scrambler_mode)
{
- struct afe_audioif_config_command config;
+ union afe_port_config port_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
int cfg_type;
int index = 0;
enum afe_mad_type mad_type;
uint16_t port_index;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ memset(&port_cfg, 0, sizeof(port_cfg));
+
if (!afe_config) {
pr_err("%s: Error, no configuration data\n", __func__);
ret = -EINVAL;
@@ -3264,13 +3186,6 @@
}
}
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
-
switch (port_id) {
case AFE_PORT_ID_PRIMARY_PCM_RX:
case AFE_PORT_ID_PRIMARY_PCM_TX:
@@ -3368,24 +3283,21 @@
ret = -EINVAL;
goto fail_cmd;
}
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = cfg_type;
- config.pdata.param_size = sizeof(config.port);
- config.port = *afe_config;
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = cfg_type;
+ param_hdr.param_size = sizeof(union afe_port_config);
+
+ port_cfg = *afe_config;
if ((enc_format != ASM_MEDIA_FMT_NONE) &&
(cfg_type == AFE_PARAM_ID_SLIMBUS_CONFIG)) {
- config.port.slim_sch.data_format =
- AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
+ port_cfg.slim_sch.data_format =
+ AFE_SB_DATA_FORMAT_GENERIC_COMPRESSED;
}
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &port_cfg);
if (ret) {
pr_err("%s: AFE enable for port 0x%x failed %d\n",
__func__, port_id, ret);
@@ -3778,11 +3690,16 @@
union afe_port_config *afe_config, int rate)
{
struct afe_port_cmd_device_start start;
- struct afe_audioif_config_command config;
+ union afe_port_config port_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
int cfg_type;
int index = 0;
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ memset(&start, 0, sizeof(start));
+ memset(&port_cfg, 0, sizeof(port_cfg));
+
if (!afe_config) {
pr_err("%s: Error, no configuration data\n", __func__);
ret = -EINVAL;
@@ -3837,12 +3754,6 @@
}
mutex_lock(&this_afe.afe_cmd_lock);
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = index;
switch (port_id) {
case PRIMARY_I2S_RX:
case PRIMARY_I2S_TX:
@@ -3906,24 +3817,16 @@
ret = -EINVAL;
goto fail_cmd;
}
- config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- config.param.port_id = q6audio_get_port_id(port_id);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr)
- - sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- config.pdata.param_id = cfg_type;
- config.pdata.param_size = sizeof(config.port);
- config.port = *afe_config;
- pr_debug("%s: param PL size=%d iparam_size[%d][%zd %zd %zd %zd] param_id[0x%x]\n",
- __func__, config.param.payload_size, config.pdata.param_size,
- sizeof(config), sizeof(config.param), sizeof(config.port),
- sizeof(struct apr_hdr), config.pdata.param_id);
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = cfg_type;
+ param_hdr.param_size = sizeof(union afe_port_config);
+ port_cfg = *afe_config;
- ret = afe_apr_send_pkt(&config, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &port_cfg);
if (ret) {
pr_err("%s: AFE enable for port 0x%x opcode[0x%x]failed %d\n",
__func__, port_id, cfg_type, ret);
@@ -3965,57 +3868,31 @@
*/
int afe_loopback(u16 enable, u16 rx_port, u16 tx_port)
{
- struct afe_loopback_cfg_v1 lb_cmd;
+ struct afe_loopback_cfg_v1 lb_param;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
+
+ memset(&lb_param, 0, sizeof(lb_param));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
if (rx_port == MI2S_RX)
rx_port = AFE_PORT_ID_PRIMARY_MI2S_RX;
if (tx_port == MI2S_TX)
tx_port = AFE_PORT_ID_PRIMARY_MI2S_TX;
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
+ param_hdr.module_id = AFE_MODULE_LOOPBACK;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_loopback_cfg_v1);
- index = q6audio_get_port_index(rx_port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid!\n",
- __func__, index);
- return -EINVAL;
- }
- ret = q6audio_validate_port(rx_port);
- if (ret < 0) {
- pr_err("%s: Invalid port 0x%x ret %d", __func__, rx_port, ret);
- return -EINVAL;
- }
+ lb_param.dst_port_id = rx_port;
+ lb_param.routing_mode = LB_MODE_DEFAULT;
+ lb_param.enable = (enable ? 1 : 0);
+ lb_param.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
- lb_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(20), APR_PKT_VER);
- lb_cmd.hdr.pkt_size = sizeof(lb_cmd);
- lb_cmd.hdr.src_port = 0;
- lb_cmd.hdr.dest_port = 0;
- lb_cmd.hdr.token = index;
- lb_cmd.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- lb_cmd.param.port_id = tx_port;
- lb_cmd.param.payload_size = (sizeof(lb_cmd) - sizeof(struct apr_hdr) -
- sizeof(struct afe_port_cmd_set_param_v2));
- lb_cmd.param.payload_address_lsw = 0x00;
- lb_cmd.param.payload_address_msw = 0x00;
- lb_cmd.param.mem_map_handle = 0x00;
- lb_cmd.pdata.module_id = AFE_MODULE_LOOPBACK;
- lb_cmd.pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
- lb_cmd.pdata.param_size = lb_cmd.param.payload_size -
- sizeof(struct afe_port_param_data_v2);
-
- lb_cmd.dst_port_id = rx_port;
- lb_cmd.routing_mode = LB_MODE_DEFAULT;
- lb_cmd.enable = (enable ? 1 : 0);
- lb_cmd.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
-
- ret = afe_apr_send_pkt(&lb_cmd, &this_afe.wait[index]);
+ ret = q6afe_pack_and_set_param_in_band(tx_port,
+ q6audio_get_port_index(tx_port),
+ param_hdr, (u8 *) &lb_param);
if (ret)
pr_err("%s: AFE loopback failed %d\n", __func__, ret);
return ret;
@@ -4034,8 +3911,11 @@
int afe_loopback_gain(u16 port_id, u16 volume)
{
struct afe_loopback_gain_per_path_param set_param;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- int index = 0;
+
+ memset(&set_param, 0, sizeof(set_param));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
if (this_afe.apr == NULL) {
this_afe.apr = apr_register("ADSP", "AFE", afe_callback,
@@ -4056,18 +3936,6 @@
ret = -EINVAL;
goto fail_cmd;
}
- 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: Invalid port 0x%x ret %d",
- __func__, port_id, ret);
- return -EINVAL;
- }
/* RX ports numbers are even .TX ports numbers are odd. */
if (port_id % 2 == 0) {
@@ -4079,36 +3947,19 @@
pr_debug("%s: port 0x%x volume %d\n", __func__, port_id, volume);
- set_param.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- set_param.hdr.pkt_size = sizeof(set_param);
- set_param.hdr.src_port = 0;
- set_param.hdr.dest_port = 0;
- set_param.hdr.token = index;
- set_param.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
-
- set_param.param.port_id = port_id;
- set_param.param.payload_size =
- (sizeof(struct afe_loopback_gain_per_path_param) -
- sizeof(struct apr_hdr) - sizeof(struct afe_port_cmd_set_param_v2));
- set_param.param.payload_address_lsw = 0;
- set_param.param.payload_address_msw = 0;
- set_param.param.mem_map_handle = 0;
-
- set_param.pdata.module_id = AFE_MODULE_LOOPBACK;
- set_param.pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
- set_param.pdata.param_size =
- (set_param.param.payload_size -
- sizeof(struct afe_port_param_data_v2));
+ param_hdr.module_id = AFE_MODULE_LOOPBACK;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
+ param_hdr.param_size = sizeof(struct afe_loopback_gain_per_path_param);
set_param.rx_port_id = port_id;
set_param.gain = volume;
- ret = afe_apr_send_pkt(&set_param, &this_afe.wait[index]);
- if (ret) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &set_param);
+ if (ret)
pr_err("%s: AFE param set failed for port 0x%x ret %d\n",
__func__, port_id, ret);
- goto fail_cmd;
- }
fail_cmd:
return ret;
@@ -4237,9 +4088,9 @@
int afe_port_group_set_param(u16 group_id,
union afe_port_group_config *afe_group_config)
{
- int ret;
- struct afe_port_group_create config;
+ struct param_hdr_v3 param_hdr;
int cfg_type;
+ int ret;
if (!afe_group_config) {
pr_err("%s: Error, no configuration data\n", __func__);
@@ -4248,6 +4099,8 @@
pr_debug("%s: group id: 0x%x\n", __func__, group_id);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
ret = afe_q6_interface_prepare();
if (ret != 0) {
pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
@@ -4272,27 +4125,13 @@
return -EINVAL;
}
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ 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(union afe_port_group_config);
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_GROUP_DEVICE;
- config.pdata.param_id = cfg_type;
- config.pdata.param_size = sizeof(config.data);
- config.data = *afe_group_config;
-
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ 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);
@@ -4314,12 +4153,16 @@
union afe_port_group_config *afe_group_config,
u16 enable)
{
+ struct afe_group_device_enable group_enable;
+ struct param_hdr_v3 param_hdr;
int ret;
- struct afe_port_group_create config;
pr_debug("%s: group id: 0x%x enable: %d\n", __func__,
group_id, enable);
+ memset(&group_enable, 0, sizeof(group_enable));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
ret = afe_q6_interface_prepare();
if (ret != 0) {
pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
@@ -4334,28 +4177,15 @@
}
}
- memset(&config, 0, sizeof(config));
- config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- config.hdr.pkt_size = sizeof(config);
- config.hdr.src_port = 0;
- config.hdr.dest_port = 0;
- config.hdr.token = IDX_GLOBAL_CFG;
- config.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ 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;
- config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) -
- sizeof(config.param);
- config.param.payload_address_lsw = 0x00;
- config.param.payload_address_msw = 0x00;
- config.param.mem_map_handle = 0x00;
- config.pdata.module_id = AFE_MODULE_GROUP_DEVICE;
- config.pdata.param_id = AFE_PARAM_ID_GROUP_DEVICE_ENABLE;
- config.pdata.param_size = sizeof(config.data);
- config.data.group_enable.group_id = group_id;
- config.data.group_enable.enable = enable;
-
- ret = afe_apr_send_pkt(&config, &this_afe.wait[IDX_GLOBAL_CFG]);
+ 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);
@@ -4502,8 +4332,8 @@
ac->port[dir].buf = buf;
- rc = msm_audio_ion_alloc("afe_client", &buf[0].client,
- &buf[0].handle, bufsz*bufcnt,
+ rc = msm_audio_ion_alloc(&buf[0].dma_buf,
+ bufsz * bufcnt,
&buf[0].phys, &len,
&buf[0].data);
if (rc) {
@@ -4777,16 +4607,13 @@
cnt = port->max_buf_cnt - 1;
if (port->buf[0].data) {
- pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n",
+ pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n",
__func__,
port->buf[0].data,
&port->buf[0].phys,
- &port->buf[0].phys,
- port->buf[0].client,
- port->buf[0].handle);
- msm_audio_ion_free(port->buf[0].client, port->buf[0].handle);
- port->buf[0].client = NULL;
- port->buf[0].handle = NULL;
+ port->buf[0].dma_buf);
+ msm_audio_ion_free(port->buf[0].dma_buf);
+ port->buf[0].dma_buf = NULL;
}
while (cnt >= 0) {
@@ -5430,9 +5257,7 @@
static int afe_sidetone_iir(u16 tx_port_id)
{
- struct afe_loopback_iir_cfg_v2 iir_sidetone;
int ret;
- int index = 0;
uint16_t size = 0;
int cal_index = AFE_SIDETONE_IIR_CAL;
int iir_pregain = 0;
@@ -5440,20 +5265,17 @@
int iir_enable;
struct cal_block_data *cal_block;
int mid;
+ struct afe_mod_enable_param enable;
+ struct afe_sidetone_iir_filter_config_params filter_data;
+ struct param_hdr_v3 param_hdr;
+ u8 *packed_param_data = NULL;
+ u32 packed_param_size = 0;
+ u32 single_param_size = 0;
+ struct audio_cal_info_sidetone_iir *st_iir_cal_info = NULL;
- memset(&iir_sidetone, 0, sizeof(iir_sidetone));
- index = q6audio_get_port_index(tx_port_id);
- iir_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- iir_sidetone.hdr.pkt_size = sizeof(iir_sidetone);
- iir_sidetone.hdr.src_port = 0;
- iir_sidetone.hdr.dest_port = 0;
- iir_sidetone.hdr.token = index;
- iir_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- iir_sidetone.param.port_id = tx_port_id;
- iir_sidetone.param.payload_address_lsw = 0x00;
- iir_sidetone.param.payload_address_msw = 0x00;
- iir_sidetone.param.mem_map_handle = 0x00;
+ memset(&enable, 0, sizeof(enable));
+ memset(&filter_data, 0, sizeof(filter_data));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
if (this_afe.cal_data[cal_index] == NULL) {
pr_err("%s: cal data is NULL\n", __func__);
@@ -5462,21 +5284,20 @@
}
mutex_lock(&this_afe.cal_data[cal_index]->lock);
cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
- if (cal_block == NULL) {
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
pr_err("%s: cal_block not found\n ", __func__);
mutex_unlock(&this_afe.cal_data[cal_index]->lock);
ret = -EINVAL;
goto done;
}
- iir_pregain = ((struct audio_cal_info_sidetone_iir *)
- cal_block->cal_info)->pregain;
- iir_enable = ((struct audio_cal_info_sidetone_iir *)
- cal_block->cal_info)->iir_enable;
- iir_num_biquad_stages = ((struct audio_cal_info_sidetone_iir *)
- cal_block->cal_info)->num_biquad_stages;
- mid = ((struct audio_cal_info_sidetone_iir *)
- cal_block->cal_info)->mid;
+ /* Cache data from cal block while inside lock to reduce locked time */
+ st_iir_cal_info =
+ (struct audio_cal_info_sidetone_iir *) cal_block->cal_info;
+ iir_pregain = st_iir_cal_info->pregain;
+ iir_enable = st_iir_cal_info->iir_enable;
+ iir_num_biquad_stages = st_iir_cal_info->num_biquad_stages;
+ mid = st_iir_cal_info->mid;
/*
* calculate the actual size of payload based on no of stages
@@ -5492,142 +5313,165 @@
pr_debug("%s: adding 2 to size:%d\n", __func__, size);
size = size + 2;
}
- memcpy(&iir_sidetone.st_iir_filter_config_data.iir_config,
- &((struct audio_cal_info_sidetone_iir *)
- cal_block->cal_info)->iir_config,
- sizeof(iir_sidetone.st_iir_filter_config_data.iir_config));
+ memcpy(&filter_data.iir_config, &st_iir_cal_info->iir_config, size);
mutex_unlock(&this_afe.cal_data[cal_index]->lock);
- /*
- * Calculate the payload size for setparams command
- */
- iir_sidetone.param.payload_size = (sizeof(iir_sidetone) -
- sizeof(struct apr_hdr) -
- sizeof(struct afe_port_cmd_set_param_v2) -
- (MAX_SIDETONE_IIR_DATA_SIZE - size));
-
- pr_debug("%s: payload size :%d\n", __func__,
- iir_sidetone.param.payload_size);
+ packed_param_size =
+ sizeof(param_hdr) * 2 + sizeof(enable) + sizeof(filter_data);
+ packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
+ if (!packed_param_data)
+ return -ENOMEM;
+ packed_param_size = 0;
/*
* Set IIR enable params
*/
- iir_sidetone.st_iir_enable_pdata.module_id = mid;
- iir_sidetone.st_iir_enable_pdata.param_id =
- AFE_PARAM_ID_ENABLE;
- iir_sidetone.st_iir_enable_pdata.param_size =
- sizeof(iir_sidetone.st_iir_mode_enable_data);
- iir_sidetone.st_iir_mode_enable_data.enable = iir_enable;
+ param_hdr.module_id = mid;
+ param_hdr.param_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_ENABLE;
+ param_hdr.param_size = sizeof(enable);
+ enable.enable = iir_enable;
+ ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr,
+ (u8 *) &enable, &single_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack param data, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+ packed_param_size += single_param_size;
/*
* Set IIR filter config params
*/
- iir_sidetone.st_iir_filter_config_pdata.module_id = mid;
- iir_sidetone.st_iir_filter_config_pdata.param_id =
- AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG;
- iir_sidetone.st_iir_filter_config_pdata.param_size =
- sizeof(iir_sidetone.st_iir_filter_config_data.num_biquad_stages)
- +
- sizeof(iir_sidetone.st_iir_filter_config_data.pregain) + size;
- iir_sidetone.st_iir_filter_config_pdata.reserved = 0;
- iir_sidetone.st_iir_filter_config_data.num_biquad_stages =
- iir_num_biquad_stages;
- iir_sidetone.st_iir_filter_config_data.pregain = iir_pregain;
+ param_hdr.module_id = mid;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_SIDETONE_IIR_FILTER_CONFIG;
+ param_hdr.param_size = sizeof(filter_data.num_biquad_stages) +
+ sizeof(filter_data.pregain) + size;
+ filter_data.num_biquad_stages = iir_num_biquad_stages;
+ filter_data.pregain = iir_pregain;
+ ret = q6common_pack_pp_params(packed_param_data + packed_param_size,
+ ¶m_hdr, (u8 *) &filter_data,
+ &single_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack param data, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+ packed_param_size += single_param_size;
+
pr_debug("%s: tx(0x%x)mid(0x%x)iir_en(%d)stg(%d)gain(0x%x)size(%d)\n",
- __func__, tx_port_id, mid,
- iir_sidetone.st_iir_mode_enable_data.enable,
- iir_sidetone.st_iir_filter_config_data.num_biquad_stages,
- iir_sidetone.st_iir_filter_config_data.pregain,
- iir_sidetone.st_iir_filter_config_pdata.param_size);
- ret = afe_apr_send_pkt(&iir_sidetone, &this_afe.wait[index]);
+ __func__, tx_port_id, mid, enable.enable,
+ filter_data.num_biquad_stages, filter_data.pregain,
+ param_hdr.param_size);
+
+ ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id),
+ NULL, packed_param_data, packed_param_size);
if (ret)
pr_err("%s: AFE sidetone failed for tx_port(0x%x)\n",
__func__, tx_port_id);
done:
+ kfree(packed_param_data);
return ret;
-
}
static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable)
{
- struct afe_st_loopback_cfg_v1 cmd_sidetone;
int ret;
- int index;
int cal_index = AFE_SIDETONE_CAL;
int sidetone_gain;
int sidetone_enable;
struct cal_block_data *cal_block;
int mid = 0;
+ struct afe_loopback_sidetone_gain gain_data;
+ struct loopback_cfg_data cfg_data;
+ struct param_hdr_v3 param_hdr;
+ u8 *packed_param_data = NULL;
+ u32 packed_param_size = 0;
+ u32 single_param_size = 0;
+ struct audio_cal_info_sidetone *st_cal_info = NULL;
- memset(&cmd_sidetone, 0, sizeof(cmd_sidetone));
if (this_afe.cal_data[cal_index] == NULL) {
pr_err("%s: cal data is NULL\n", __func__);
ret = -EINVAL;
goto done;
}
+
+ memset(&gain_data, 0, sizeof(gain_data));
+ memset(&cfg_data, 0, sizeof(cfg_data));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ packed_param_size =
+ sizeof(param_hdr) * 2 + sizeof(gain_data) + sizeof(cfg_data);
+ packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
+ if (!packed_param_data)
+ return -ENOMEM;
+ packed_param_size = 0;
+
mutex_lock(&this_afe.cal_data[cal_index]->lock);
cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
- if (cal_block == NULL) {
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
pr_err("%s: cal_block not found\n", __func__);
mutex_unlock(&this_afe.cal_data[cal_index]->lock);
ret = -EINVAL;
goto done;
}
- sidetone_gain = ((struct audio_cal_info_sidetone *)
- cal_block->cal_info)->gain;
- sidetone_enable = ((struct audio_cal_info_sidetone *)
- cal_block->cal_info)->enable;
- mid = ((struct audio_cal_info_sidetone *)
- cal_block->cal_info)->mid;
+
+ /* Cache data from cal block while inside lock to reduce locked time */
+ st_cal_info = (struct audio_cal_info_sidetone *) cal_block->cal_info;
+ sidetone_gain = st_cal_info->gain;
+ sidetone_enable = st_cal_info->enable;
+ mid = st_cal_info->mid;
mutex_unlock(&this_afe.cal_data[cal_index]->lock);
- index = q6audio_get_port_index(tx_port_id);
- cmd_sidetone.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- cmd_sidetone.hdr.pkt_size = sizeof(cmd_sidetone);
- cmd_sidetone.hdr.src_port = 0;
- cmd_sidetone.hdr.dest_port = 0;
- cmd_sidetone.hdr.token = index;
- cmd_sidetone.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- cmd_sidetone.param.port_id = tx_port_id;
- cmd_sidetone.param.payload_size = (sizeof(cmd_sidetone) -
- sizeof(struct apr_hdr) -
- sizeof(struct afe_port_cmd_set_param_v2));
- cmd_sidetone.param.payload_address_lsw = 0x00;
- cmd_sidetone.param.payload_address_msw = 0x00;
- cmd_sidetone.param.mem_map_handle = 0x00;
- cmd_sidetone.gain_pdata.module_id = AFE_MODULE_LOOPBACK;
- cmd_sidetone.gain_pdata.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
- /*
- * size of actual payload only
- */
- cmd_sidetone.gain_pdata.param_size = sizeof(
- struct afe_loopback_sidetone_gain);
- cmd_sidetone.gain_data.rx_port_id = rx_port_id;
- cmd_sidetone.gain_data.gain = sidetone_gain;
+ /* Set gain data. */
+ param_hdr.module_id = AFE_MODULE_LOOPBACK;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH;
+ param_hdr.param_size = sizeof(struct afe_loopback_sidetone_gain);
+ gain_data.rx_port_id = rx_port_id;
+ gain_data.gain = sidetone_gain;
+ ret = q6common_pack_pp_params(packed_param_data, ¶m_hdr,
+ (u8 *) &gain_data, &single_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack param data, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+ packed_param_size += single_param_size;
- cmd_sidetone.cfg_pdata.module_id = AFE_MODULE_LOOPBACK;
- cmd_sidetone.cfg_pdata.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
- /*
- * size of actual payload only
- */
- cmd_sidetone.cfg_pdata.param_size = sizeof(struct loopback_cfg_data);
- cmd_sidetone.cfg_data.loopback_cfg_minor_version =
- AFE_API_VERSION_LOOPBACK_CONFIG;
- cmd_sidetone.cfg_data.dst_port_id = rx_port_id;
- cmd_sidetone.cfg_data.routing_mode = LB_MODE_SIDETONE;
- cmd_sidetone.cfg_data.enable = enable;
+ /* Set configuration data. */
+ param_hdr.module_id = AFE_MODULE_LOOPBACK;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_LOOPBACK_CONFIG;
+ param_hdr.param_size = sizeof(struct loopback_cfg_data);
+ cfg_data.loopback_cfg_minor_version = AFE_API_VERSION_LOOPBACK_CONFIG;
+ cfg_data.dst_port_id = rx_port_id;
+ cfg_data.routing_mode = LB_MODE_SIDETONE;
+ cfg_data.enable = enable;
+ ret = q6common_pack_pp_params(packed_param_data + packed_param_size,
+ ¶m_hdr, (u8 *) &cfg_data,
+ &single_param_size);
+ if (ret) {
+ pr_err("%s: Failed to pack param data, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+ packed_param_size += single_param_size;
pr_debug("%s rx(0x%x) tx(0x%x) enable(%d) mid(0x%x) gain(%d) sidetone_enable(%d)\n",
__func__, rx_port_id, tx_port_id,
enable, mid, sidetone_gain, sidetone_enable);
- ret = afe_apr_send_pkt(&cmd_sidetone, &this_afe.wait[index]);
+ ret = q6afe_set_params(tx_port_id, q6audio_get_port_index(tx_port_id),
+ NULL, packed_param_data, packed_param_size);
if (ret)
pr_err("%s: AFE sidetone send failed for tx_port:%d rx_port:%d ret:%d\n",
__func__, tx_port_id, rx_port_id, ret);
+
done:
+ kfree(packed_param_data);
return ret;
}
@@ -6038,75 +5882,36 @@
int afe_set_digital_codec_core_clock(u16 port_id,
struct afe_digital_clk_cfg *cfg)
{
- struct afe_lpass_digital_clk_config_command clk_cfg;
- int index = 0;
+ struct afe_digital_clk_cfg clk_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
if (!cfg) {
pr_err("%s: clock cfg is NULL\n", __func__);
- ret = -EINVAL;
- return ret;
+ return -EINVAL;
}
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
+ memset(&clk_cfg, 0, sizeof(clk_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
- clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
- clk_cfg.hdr.src_port = 0;
- clk_cfg.hdr.dest_port = 0;
- clk_cfg.hdr.token = index;
-
- clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
/*default rx port is taken to enable the codec digital clock*/
- clk_cfg.param.port_id = q6audio_get_port_id(port_id);
- clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
- - sizeof(clk_cfg.param);
- clk_cfg.param.payload_address_lsw = 0x00;
- clk_cfg.param.payload_address_msw = 0x00;
- clk_cfg.param.mem_map_handle = 0x00;
- clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
- clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
- clk_cfg.clk_cfg = *cfg;
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
+ param_hdr.param_size = sizeof(struct afe_digital_clk_cfg);
+ clk_cfg = *cfg;
pr_debug("%s: Minor version =0x%x clk val = %d\n"
"clk root = 0x%x resrv = 0x%x\n",
- __func__, cfg->i2s_cfg_minor_version,
- cfg->clk_val, cfg->clk_root, cfg->reserved);
+ __func__, cfg->i2s_cfg_minor_version, cfg->clk_val,
+ cfg->clk_root, cfg->reserved);
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
- if (ret < 0) {
- pr_err("%s: AFE enable for port 0x%x ret %d\n",
- __func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
-
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &clk_cfg);
+ if (ret < 0)
+ pr_err("%s: AFE enable for port 0x%x ret %d\n", __func__,
+ port_id, ret);
return ret;
}
@@ -6120,21 +5925,18 @@
*/
int afe_set_lpass_clock(u16 port_id, struct afe_clk_cfg *cfg)
{
- struct afe_lpass_clk_config_command clk_cfg;
- int index = 0;
+ struct afe_clk_cfg clk_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
if (!cfg) {
pr_err("%s: clock cfg is NULL\n", __func__);
- ret = -EINVAL;
- return ret;
- }
- 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;
}
+
+ memset(&clk_cfg, 0, sizeof(clk_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
ret = q6audio_is_digital_pcm_interface(port_id);
if (ret < 0) {
pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
@@ -6142,31 +5944,12 @@
return -EINVAL;
}
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
-
mutex_lock(&this_afe.afe_cmd_lock);
- clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
- clk_cfg.hdr.src_port = 0;
- clk_cfg.hdr.dest_port = 0;
- clk_cfg.hdr.token = index;
-
- clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- clk_cfg.param.port_id = q6audio_get_port_id(port_id);
- clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
- - sizeof(clk_cfg.param);
- clk_cfg.param.payload_address_lsw = 0x00;
- clk_cfg.param.payload_address_msw = 0x00;
- clk_cfg.param.mem_map_handle = 0x00;
- clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- clk_cfg.pdata.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
- clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
- clk_cfg.clk_cfg = *cfg;
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_LPAIF_CLK_CONFIG;
+ param_hdr.param_size = sizeof(clk_cfg);
+ clk_cfg = *cfg;
pr_debug("%s: Minor version =0x%x clk val1 = %d\n"
"clk val2 = %d, clk src = 0x%x\n"
@@ -6177,34 +5960,13 @@
cfg->clk_root, cfg->clk_set_mode,
cfg->reserved, q6audio_get_port_id(port_id));
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &clk_cfg);
+ if (ret < 0)
pr_err("%s: AFE enable for port 0x%x ret %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
mutex_unlock(&this_afe.afe_cmd_lock);
return ret;
}
@@ -6220,7 +5982,7 @@
*/
int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
{
- struct afe_lpass_clk_config_command_v2 clk_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
if (!cfg) {
@@ -6234,6 +5996,8 @@
return -EINVAL;
}
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
ret = afe_q6_interface_prepare();
if (ret != 0) {
pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
@@ -6241,23 +6005,10 @@
}
mutex_lock(&this_afe.afe_cmd_lock);
- clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
- clk_cfg.hdr.src_port = 0;
- clk_cfg.hdr.dest_port = 0;
- clk_cfg.hdr.token = index;
-
- clk_cfg.hdr.opcode = AFE_SVC_CMD_SET_PARAM;
- clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
- - sizeof(clk_cfg.param);
- clk_cfg.param.payload_address_lsw = 0x00;
- clk_cfg.param.payload_address_msw = 0x00;
- clk_cfg.param.mem_map_handle = 0x00;
- clk_cfg.pdata.module_id = AFE_MODULE_CLOCK_SET;
- clk_cfg.pdata.param_id = AFE_PARAM_ID_CLOCK_SET;
- clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
- clk_cfg.clk_cfg = *cfg;
+ param_hdr.module_id = AFE_MODULE_CLOCK_SET;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET;
+ param_hdr.param_size = sizeof(struct afe_clk_set);
pr_debug("%s: Minor version =0x%x clk id = %d\n"
@@ -6267,34 +6018,12 @@
cfg->clk_id, cfg->clk_freq_in_hz, cfg->clk_attri,
cfg->clk_root, cfg->enable);
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
- if (ret < 0) {
+ ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
+ (u8 *) cfg);
+ if (ret < 0)
pr_err("%s: AFE clk cfg failed with ret %d\n",
__func__, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- } else {
- /* set ret to 0 as no timeout happened */
- ret = 0;
- }
- if (atomic_read(&this_afe.status) != 0) {
- pr_err("%s: config cmd failed\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
-
-fail_cmd:
mutex_unlock(&this_afe.afe_cmd_lock);
return ret;
}
@@ -6338,21 +6067,18 @@
int afe_set_lpass_internal_digital_codec_clock(u16 port_id,
struct afe_digital_clk_cfg *cfg)
{
- struct afe_lpass_digital_clk_config_command clk_cfg;
- int index = 0;
+ struct afe_digital_clk_cfg clk_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
if (!cfg) {
pr_err("%s: clock cfg is NULL\n", __func__);
- ret = -EINVAL;
- return ret;
- }
- 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;
}
+
+ memset(&clk_cfg, 0, sizeof(clk_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
ret = q6audio_is_digital_pcm_interface(port_id);
if (ret < 0) {
pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
@@ -6360,30 +6086,11 @@
return -EINVAL;
}
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
-
- clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
- clk_cfg.hdr.src_port = 0;
- clk_cfg.hdr.dest_port = 0;
- clk_cfg.hdr.token = index;
-
- clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- clk_cfg.param.port_id = q6audio_get_port_id(port_id);
- clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
- - sizeof(clk_cfg.param);
- clk_cfg.param.payload_address_lsw = 0x00;
- clk_cfg.param.payload_address_msw = 0x00;
- clk_cfg.param.mem_map_handle = 0x00;
- clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- clk_cfg.pdata.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
- clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
- clk_cfg.clk_cfg = *cfg;
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_INTERNAL_DIGIATL_CDC_CLK_CONFIG;
+ param_hdr.param_size = sizeof(clk_cfg);
+ clk_cfg = *cfg;
pr_debug("%s: Minor version =0x%x clk val = %d\n"
"clk root = 0x%x resrv = 0x%x port id = 0x%x\n",
@@ -6391,49 +6098,25 @@
cfg->clk_val, cfg->clk_root, cfg->reserved,
q6audio_get_port_id(port_id));
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &clk_cfg);
+ if (ret < 0)
pr_err("%s: AFE enable for port 0x0x%x ret %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
return ret;
}
int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable)
{
- struct afe_lpass_core_shared_clk_config_command clk_cfg;
- int index = 0;
+ struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- 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;
- }
+ memset(&clk_cfg, 0, sizeof(clk_cfg));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
ret = q6audio_is_digital_pcm_interface(port_id);
if (ret < 0) {
pr_err("%s: q6audio_is_digital_pcm_interface fail %d\n",
@@ -6441,65 +6124,25 @@
return -EINVAL;
}
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
-
mutex_lock(&this_afe.afe_cmd_lock);
- clk_cfg.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- clk_cfg.hdr.pkt_size = sizeof(clk_cfg);
- clk_cfg.hdr.src_port = 0;
- clk_cfg.hdr.dest_port = 0;
- clk_cfg.hdr.token = index;
-
- clk_cfg.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
- clk_cfg.param.port_id = q6audio_get_port_id(port_id);
- clk_cfg.param.payload_size = sizeof(clk_cfg) - sizeof(struct apr_hdr)
- - sizeof(clk_cfg.param);
- clk_cfg.param.payload_address_lsw = 0x00;
- clk_cfg.param.payload_address_msw = 0x00;
- clk_cfg.param.mem_map_handle = 0x00;
- clk_cfg.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- clk_cfg.pdata.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG;
- clk_cfg.pdata.param_size = sizeof(clk_cfg.clk_cfg);
- clk_cfg.clk_cfg.lpass_core_shared_clk_cfg_minor_version =
- AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG;
- clk_cfg.clk_cfg.enable = enable;
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG;
+ param_hdr.param_size = sizeof(clk_cfg);
+ clk_cfg.lpass_core_shared_clk_cfg_minor_version =
+ AFE_API_VERSION_LPASS_CORE_SHARED_CLK_CONFIG;
+ clk_cfg.enable = enable;
pr_debug("%s: port id = %d, enable = %d\n",
__func__, q6audio_get_port_id(port_id), enable);
- atomic_set(&this_afe.state, 1);
- atomic_set(&this_afe.status, 0);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *) &clk_cfg);
- if (ret < 0) {
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr, (u8 *) &clk_cfg);
+ if (ret < 0)
pr_err("%s: AFE enable for port 0x%x ret %d\n",
__func__, port_id, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
- goto fail_cmd;
- }
-
-fail_cmd:
mutex_unlock(&this_afe.afe_cmd_lock);
return ret;
}
@@ -6510,6 +6153,7 @@
switch (freq) {
case Q6AFE_LPASS_OSR_CLK_12_P288_MHZ:
+ case Q6AFE_LPASS_OSR_CLK_9_P600_MHZ:
case Q6AFE_LPASS_OSR_CLK_8_P192_MHZ:
case Q6AFE_LPASS_OSR_CLK_6_P144_MHZ:
case Q6AFE_LPASS_OSR_CLK_4_P096_MHZ:
@@ -6521,7 +6165,7 @@
case Q6AFE_LPASS_OSR_CLK_512_kHZ:
break;
default:
- pr_err("%s: deafault freq 0x%x\n",
+ pr_err("%s: default freq 0x%x\n",
__func__, freq);
ret = -EINVAL;
}
@@ -6530,8 +6174,9 @@
int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi)
{
+ struct param_hdr_v3 param_hdr;
+ int port = SLIMBUS_4_TX;
int ret = -EINVAL;
- int index = 0, port = SLIMBUS_4_TX;
if (!th_vi) {
pr_err("%s: Invalid params\n", __func__);
@@ -6540,59 +6185,20 @@
if (this_afe.vi_tx_port != -1)
port = this_afe.vi_tx_port;
- ret = q6audio_validate_port(port);
- if (ret < 0) {
- pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
+ param_hdr.param_size = sizeof(struct afe_sp_th_vi_ftm_params);
+
+ ret = q6afe_get_params(port, NULL, ¶m_hdr);
+ if (ret) {
+ pr_err("%s: Failed to get TH VI FTM data\n", __func__);
goto done;
}
- index = q6audio_get_port_index(port);
- if (index < 0) {
- pr_err("%s: invalid port 0x%x, index %d\n",
- __func__, port, index);
- ret = -EINVAL;
- goto done;
- }
- th_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- th_vi->hdr.pkt_size = sizeof(*th_vi);
- th_vi->hdr.src_port = 0;
- th_vi->hdr.dest_port = 0;
- th_vi->hdr.token = index;
- th_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
- th_vi->get_param.mem_map_handle = 0;
- th_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
- th_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
- th_vi->get_param.payload_address_lsw = 0;
- th_vi->get_param.payload_address_msw = 0;
- th_vi->get_param.payload_size = sizeof(*th_vi)
- - sizeof(th_vi->get_param) - sizeof(th_vi->hdr);
- th_vi->get_param.port_id = q6audio_get_port_id(port);
- th_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_TH_VI;
- th_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_TH_VI_FTM_PARAMS;
- th_vi->pdata.param_size = sizeof(th_vi->param);
- atomic_set(&this_afe.status, 0);
- atomic_set(&this_afe.state, 1);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *)th_vi);
- if (ret < 0) {
- pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
- __func__, port, th_vi->get_param.param_id, ret);
- goto done;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto done;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status));
- goto done;
- }
+
+ th_vi->pdata = param_hdr;
memcpy(&th_vi->param, &this_afe.th_vi_resp.param,
sizeof(this_afe.th_vi_resp.param));
pr_debug("%s: DC resistance %d %d temp %d %d status %d %d\n",
@@ -6609,8 +6215,9 @@
int afe_get_sp_ex_vi_ftm_data(struct afe_sp_ex_vi_get_param *ex_vi)
{
+ struct param_hdr_v3 param_hdr;
+ int port = SLIMBUS_4_TX;
int ret = -EINVAL;
- int index = 0, port = SLIMBUS_4_TX;
if (!ex_vi) {
pr_err("%s: Invalid params\n", __func__);
@@ -6619,61 +6226,21 @@
if (this_afe.vi_tx_port != -1)
port = this_afe.vi_tx_port;
- ret = q6audio_validate_port(port);
- if (ret < 0) {
- pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
- goto done;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
- index = q6audio_get_port_index(port);
- if (index < 0) {
- pr_err("%s: invalid index %d port 0x%x\n", __func__,
- index, port);
- ret = -EINVAL;
- goto done;
- }
+ param_hdr.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
+ param_hdr.param_size = sizeof(struct afe_sp_ex_vi_ftm_params);
- ex_vi->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- ex_vi->hdr.pkt_size = sizeof(*ex_vi);
- ex_vi->hdr.src_port = 0;
- ex_vi->hdr.dest_port = 0;
- ex_vi->hdr.token = index;
- ex_vi->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
- ex_vi->get_param.mem_map_handle = 0;
- ex_vi->get_param.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
- ex_vi->get_param.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
- ex_vi->get_param.payload_address_lsw = 0;
- ex_vi->get_param.payload_address_msw = 0;
- ex_vi->get_param.payload_size = sizeof(*ex_vi)
- - sizeof(ex_vi->get_param) - sizeof(ex_vi->hdr);
- ex_vi->get_param.port_id = q6audio_get_port_id(port);
- ex_vi->pdata.module_id = AFE_MODULE_SPEAKER_PROTECTION_V2_EX_VI;
- ex_vi->pdata.param_id = AFE_PARAM_ID_SP_V2_EX_VI_FTM_PARAMS;
- ex_vi->pdata.param_size = sizeof(ex_vi->param);
- atomic_set(&this_afe.status, 0);
- atomic_set(&this_afe.state, 1);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *)ex_vi);
+ ret = q6afe_get_params(port, NULL, ¶m_hdr);
if (ret < 0) {
pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
- __func__, port, ex_vi->get_param.param_id, ret);
+ __func__, port, param_hdr.param_id, ret);
goto done;
}
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto done;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(atomic_read(&this_afe.status));
- goto done;
- }
+
+ ex_vi->pdata = param_hdr;
memcpy(&ex_vi->param, &this_afe.ex_vi_resp.param,
sizeof(this_afe.ex_vi_resp.param));
pr_debug("%s: freq %d %d resistance %d %d qfactor %d %d state %d %d\n",
@@ -6702,80 +6269,29 @@
int afe_get_av_dev_drift(struct afe_param_id_dev_timing_stats *timing_stats,
u16 port)
{
+ struct param_hdr_v3 param_hdr;
int ret = -EINVAL;
- int index = 0;
- struct afe_av_dev_drift_get_param av_dev_drift;
if (!timing_stats) {
pr_err("%s: Invalid params\n", __func__);
goto exit;
}
- ret = q6audio_validate_port(port);
- if (ret < 0) {
- pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
- ret = -EINVAL;
- goto exit;
- }
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
+ param_hdr.param_size = sizeof(struct afe_param_id_dev_timing_stats);
- index = q6audio_get_port_index(port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: Invalid AFE port index[%d]\n",
- __func__, index);
- ret = -EINVAL;
- goto exit;
- }
-
- memset(&av_dev_drift, 0, sizeof(struct afe_av_dev_drift_get_param));
-
- av_dev_drift.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- av_dev_drift.hdr.pkt_size = sizeof(av_dev_drift);
- av_dev_drift.hdr.src_port = 0;
- av_dev_drift.hdr.dest_port = 0;
- av_dev_drift.hdr.token = index;
- av_dev_drift.hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
- av_dev_drift.get_param.mem_map_handle = 0;
- av_dev_drift.get_param.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- av_dev_drift.get_param.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
- av_dev_drift.get_param.payload_address_lsw = 0;
- av_dev_drift.get_param.payload_address_msw = 0;
- av_dev_drift.get_param.payload_size = sizeof(av_dev_drift)
- - sizeof(av_dev_drift.get_param) - sizeof(av_dev_drift.hdr);
- av_dev_drift.get_param.port_id = q6audio_get_port_id(port);
- av_dev_drift.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE;
- av_dev_drift.pdata.param_id = AFE_PARAM_ID_DEV_TIMING_STATS;
- av_dev_drift.pdata.param_size = sizeof(av_dev_drift.timing_stats);
- atomic_set(&this_afe.status, 0);
- atomic_set(&this_afe.state, 1);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *)&av_dev_drift);
+ ret = q6afe_get_params(port, NULL, ¶m_hdr);
if (ret < 0) {
pr_err("%s: get param port 0x%x param id[0x%x] failed %d\n",
- __func__, port, av_dev_drift.get_param.param_id, ret);
- goto exit;
- }
-
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto exit;
- }
-
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
+ __func__, port, param_hdr.param_id, ret);
goto exit;
}
memcpy(timing_stats, &this_afe.av_dev_drift_resp.timing_stats,
- sizeof(this_afe.av_dev_drift_resp.timing_stats));
+ param_hdr.param_size);
ret = 0;
exit:
return ret;
@@ -6784,8 +6300,9 @@
int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib_resp)
{
+ struct param_hdr_v3 param_hdr;
+ int port = SLIMBUS_4_TX;
int ret = -EINVAL;
- int index = 0, port = SLIMBUS_4_TX;
if (!calib_resp) {
pr_err("%s: Invalid params\n", __func__);
@@ -6794,60 +6311,16 @@
if (this_afe.vi_tx_port != -1)
port = this_afe.vi_tx_port;
- ret = q6audio_validate_port(port);
- if (ret < 0) {
- pr_err("%s: invalid port 0x%x ret %d\n", __func__, port, ret);
- ret = -EINVAL;
- goto fail_cmd;
- }
- index = q6audio_get_port_index(port);
- if (index < 0 || index >= AFE_MAX_PORTS) {
- pr_err("%s: AFE port index[%d] invalid!\n",
- __func__, index);
- ret = -EINVAL;
- goto fail_cmd;
- }
- calib_resp->hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
- calib_resp->hdr.pkt_size = sizeof(*calib_resp);
- calib_resp->hdr.src_port = 0;
- calib_resp->hdr.dest_port = 0;
- calib_resp->hdr.token = index;
- calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
- calib_resp->get_param.mem_map_handle = 0;
- calib_resp->get_param.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
- calib_resp->get_param.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
- calib_resp->get_param.payload_address_lsw = 0;
- calib_resp->get_param.payload_address_msw = 0;
- calib_resp->get_param.payload_size = sizeof(*calib_resp)
- - sizeof(calib_resp->get_param) - sizeof(calib_resp->hdr);
- calib_resp->get_param.port_id = q6audio_get_port_id(port);
- calib_resp->pdata.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
- calib_resp->pdata.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
- calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg);
- atomic_set(&this_afe.status, 0);
- atomic_set(&this_afe.state, 1);
- ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = AFE_MODULE_FB_SPKR_PROT_VI_PROC_V2;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = AFE_PARAM_ID_CALIB_RES_CFG_V2;
+ param_hdr.param_size = sizeof(struct afe_spkr_prot_get_vi_calib);
+
+ ret = q6afe_get_params(port, NULL, ¶m_hdr);
if (ret < 0) {
pr_err("%s: get param port 0x%x param id[0x%x]failed %d\n",
- __func__, port, calib_resp->get_param.param_id, ret);
- goto fail_cmd;
- }
- ret = wait_event_timeout(this_afe.wait[index],
- (atomic_read(&this_afe.state) == 0),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto fail_cmd;
- }
- if (atomic_read(&this_afe.status) > 0) {
- pr_err("%s: config cmd failed [%s]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&this_afe.status)));
- ret = adsp_err_get_lnx_err_code(
- atomic_read(&this_afe.status));
+ __func__, port, param_hdr.param_id, ret);
goto fail_cmd;
}
memcpy(&calib_resp->res_cfg, &this_afe.calib_data.res_cfg,
@@ -7072,6 +6545,9 @@
cal_block = list_entry(ptr,
struct cal_block_data, list);
+ if (cal_utils_is_cal_stale(cal_block))
+ continue;
+
if (((struct audio_cal_info_hw_delay *)cal_block->cal_info)
->path == path) {
return cal_block;
@@ -7135,6 +6611,8 @@
ret = -EFAULT;
goto unlock;
}
+
+ cal_utils_mark_cal_used(cal_block);
pr_debug("%s: Path = %d samplerate = %u usec = %u status %d\n",
__func__, path, entry->sample_rate, entry->delay_usec, ret);
unlock:
@@ -7639,6 +7117,12 @@
void afe_exit(void)
{
+ if (this_afe.apr) {
+ apr_reset(this_afe.apr);
+ atomic_set(&this_afe.state, 0);
+ this_afe.apr = NULL;
+ rtac_set_afe_handle(this_afe.apr);
+ }
afe_delete_cal_data();
config_debug_fs_exit();
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index caf7df1..5bfed89 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -39,6 +39,7 @@
#include <dsp/audio_cal_utils.h>
#include <dsp/q6asm-v2.h>
#include <dsp/q6audio-v2.h>
+#include <dsp/q6common.h>
#include "adsp_err.h"
#define TRUE 0x01
@@ -124,8 +125,7 @@
void *q6asm_mmap_apr_reg(void);
static int q6asm_is_valid_session(struct apr_client_data *data, void *priv);
-static int q6asm_get_asm_topology_cal(void);
-static int q6asm_get_asm_app_type_cal(void);
+static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info);
/* for ASM custom topology */
static struct cal_type_data *cal_data[ASM_MAX_CAL_TYPES];
@@ -661,7 +661,7 @@
{
int ret = 0;
- if (cal_block->map_data.ion_client == NULL) {
+ if (cal_block->map_data.dma_buf == NULL) {
pr_err("%s: No ION allocation for cal type %d!\n",
__func__, cal_type);
ret = -EINVAL;
@@ -758,7 +758,7 @@
set_custom_topology = 0;
cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]);
- if (cal_block == NULL)
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block))
goto unlock;
if (cal_block->cal_data.size == 0) {
@@ -982,11 +982,9 @@
if (port->buf[cnt].data) {
if (!rc || atomic_read(&ac->reset))
msm_audio_ion_free(
- port->buf[cnt].client,
- port->buf[cnt].handle);
+ port->buf[cnt].dma_buf);
- port->buf[cnt].client = NULL;
- port->buf[cnt].handle = NULL;
+ port->buf[cnt].dma_buf = NULL;
port->buf[cnt].data = NULL;
port->buf[cnt].phys = 0;
--(port->max_buf_cnt);
@@ -1033,18 +1031,14 @@
}
if (port->buf[0].data) {
- pr_debug("%s: data[%pK]phys[%pK][%pK] , client[%pK] handle[%pK]\n",
+ pr_debug("%s: data[%pK], phys[%pK], dma_buf[%pK]\n",
__func__,
port->buf[0].data,
&port->buf[0].phys,
- &port->buf[0].phys,
- port->buf[0].client,
- port->buf[0].handle);
+ port->buf[0].dma_buf);
if (!rc || atomic_read(&ac->reset))
- msm_audio_ion_free(port->buf[0].client,
- port->buf[0].handle);
- port->buf[0].client = NULL;
- port->buf[0].handle = NULL;
+ msm_audio_ion_free(port->buf[0].dma_buf);
+ port->buf[0].dma_buf = NULL;
}
while (cnt >= 0) {
@@ -1438,10 +1432,10 @@
while (cnt < bufcnt) {
if (bufsz > 0) {
if (!buf[cnt].data) {
- rc = msm_audio_ion_alloc("asm_client",
- &buf[cnt].client, &buf[cnt].handle,
+ rc = msm_audio_ion_alloc(
+ &buf[cnt].dma_buf,
bufsz,
- (ion_phys_addr_t *)&buf[cnt].phys,
+ &buf[cnt].phys,
&len,
&buf[cnt].data);
if (rc) {
@@ -1544,9 +1538,9 @@
/* The size to allocate should be multiple of 4K bytes */
bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc);
- rc = msm_audio_ion_alloc("asm_client", &buf[0].client, &buf[0].handle,
+ rc = msm_audio_ion_alloc(&buf[0].dma_buf,
bytes_to_alloc,
- (ion_phys_addr_t *)&buf[0].phys, &len,
+ &buf[0].phys, &len,
&buf[0].data);
if (rc) {
pr_err("%s: Audio ION alloc is failed, rc = %d\n",
@@ -1904,6 +1898,7 @@
if (data->opcode == APR_BASIC_RSP_RESULT) {
switch (payload[0]) {
case ASM_STREAM_CMD_SET_PP_PARAMS_V2:
+ case ASM_STREAM_CMD_SET_PP_PARAMS_V3:
if (rtac_make_asm_callback(ac->session, payload,
data->payload_size))
break;
@@ -1951,9 +1946,12 @@
pr_err("%s: cmd = 0x%x returned error = 0x%x\n",
__func__, payload[0], payload[1]);
if (wakeup_flag) {
- if ((is_adsp_reg_event(payload[0]) >= 0)
- || (payload[0] ==
- ASM_STREAM_CMD_SET_PP_PARAMS_V2))
+ if ((is_adsp_reg_event(payload[0]) >=
+ 0) ||
+ (payload[0] ==
+ ASM_STREAM_CMD_SET_PP_PARAMS_V2) ||
+ (payload[0] ==
+ ASM_STREAM_CMD_SET_PP_PARAMS_V3))
atomic_set(&ac->cmd_state_pp,
payload[1]);
else
@@ -1966,7 +1964,8 @@
return 0;
}
if ((is_adsp_reg_event(payload[0]) >= 0) ||
- (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2)) {
+ (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V2) ||
+ (payload[0] == ASM_STREAM_CMD_SET_PP_PARAMS_V3)) {
if (atomic_read(&ac->cmd_state_pp) &&
wakeup_flag) {
atomic_set(&ac->cmd_state_pp, 0);
@@ -2011,10 +2010,10 @@
break;
}
case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
- pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n",
- __func__, ac->session,
- data->opcode, data->token,
- data->src_port, data->dest_port);
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V3:
+ pr_debug("%s: ASM_STREAM_CMD_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n",
+ __func__, ac->session, data->opcode,
+ data->token, data->src_port, data->dest_port);
/* Should only come here if there is an APR */
/* error or malformed APR packet. Otherwise */
/* response will be returned as */
@@ -2091,13 +2090,13 @@
break;
}
case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2:
- pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 session %d opcode 0x%x token 0x%x src %d dest %d\n",
- __func__, ac->session, data->opcode,
- data->token,
- data->src_port, data->dest_port);
+ case ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3:
+ pr_debug("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS session %d opcode 0x%x token 0x%x src %d dest %d\n",
+ __func__, ac->session, data->opcode, data->token,
+ data->src_port, data->dest_port);
if (payload[0] != 0) {
- pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 returned error = 0x%x\n",
- __func__, payload[0]);
+ pr_err("%s: ASM_STREAM_CMDRSP_GET_PP_PARAMS returned error = 0x%x\n",
+ __func__, payload[0]);
} else if (generic_get_data) {
generic_get_data->valid = 1;
if (generic_get_data->is_inband) {
@@ -2625,6 +2624,174 @@
hdr->pkt_size = pkt_size;
}
+/**
+ * q6asm_set_pp_params
+ * command to set ASM parameter data
+ * send memory mapping header for out of band case
+ * send pre-packed parameter data for in band case
+ *
+ * @ac: audio client handle
+ * @mem_hdr: memory mapping header
+ * @param_data: pre-packed parameter payload
+ * @param_size: size of pre-packed parameter data
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6asm_set_pp_params(struct audio_client *ac,
+ struct mem_mapping_hdr *mem_hdr, u8 *param_data,
+ u32 param_size)
+{
+ struct asm_stream_cmd_set_pp_params *asm_set_param = NULL;
+ int pkt_size = 0;
+ int ret = 0;
+
+ if (ac == NULL) {
+ pr_err("%s: Audio Client is NULL\n", __func__);
+ return -EINVAL;
+ } else if (ac->apr == NULL) {
+ pr_err("%s: APR pointer is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ pkt_size = sizeof(struct asm_stream_cmd_set_pp_params);
+ /* Add param size to packet size when sending in-band only */
+ if (param_data != NULL)
+ pkt_size += param_size;
+ asm_set_param = kzalloc(pkt_size, GFP_KERNEL);
+ if (!asm_set_param)
+ return -ENOMEM;
+
+ q6asm_add_hdr_async(ac, &asm_set_param->apr_hdr, pkt_size, TRUE);
+
+ /* With pre-packed data, only the opcode differs from V2 and V3. */
+ if (q6common_is_instance_id_supported())
+ asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V3;
+ else
+ asm_set_param->apr_hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
+
+ asm_set_param->payload_size = param_size;
+
+ if (mem_hdr != NULL) {
+ /* Out of band case */
+ asm_set_param->mem_hdr = *mem_hdr;
+ } else if (param_data != NULL) {
+ /*
+ * In band case. Parameter data must be pre-packed with its
+ * header before calling this function. Use
+ * q6common_pack_pp_params to pack parameter data and header
+ * correctly.
+ */
+ memcpy(&asm_set_param->param_data, param_data, param_size);
+ } else {
+ pr_err("%s: Received NULL pointers for both mem header and param data\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ atomic_set(&ac->cmd_state_pp, -1);
+ ret = apr_send_pkt(ac->apr, (uint32_t *)asm_set_param);
+ if (ret < 0) {
+ pr_err("%s: apr send failed rc %d\n", __func__, ret);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = wait_event_timeout(ac->cmd_wait,
+ atomic_read(&ac->cmd_state_pp) >= 0, 5 * HZ);
+ if (!ret) {
+ pr_err("%s: timeout sending apr pkt\n", __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (atomic_read(&ac->cmd_state_pp) > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(atomic_read(&ac->cmd_state_pp)));
+ ret = adsp_err_get_lnx_err_code(atomic_read(&ac->cmd_state_pp));
+ goto done;
+ }
+ ret = 0;
+done:
+ kfree(asm_set_param);
+ return ret;
+}
+EXPORT_SYMBOL(q6asm_set_pp_params);
+
+/**
+ * q6asm_pack_and_set_pp_param_in_band
+ * command to pack and set parameter data for in band case
+ *
+ * @ac: audio client handle
+ * @param_hdr: parameter header
+ * @param_data: parameter data
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data)
+{
+ u8 *packed_data = NULL;
+ u32 packed_size = sizeof(union param_hdrs) + param_hdr.param_size;
+ int ret = 0;
+
+ if (ac == NULL) {
+ pr_err("%s: Audio Client is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ packed_data = kzalloc(packed_size, GFP_KERNEL);
+ if (packed_data == NULL)
+ return -ENOMEM;
+
+ ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data,
+ &packed_size);
+ if (ret) {
+ pr_err("%s: Failed to pack params, error %d\n", __func__, ret);
+ goto done;
+ }
+
+ ret = q6asm_set_pp_params(ac, NULL, packed_data, packed_size);
+done:
+ kfree(packed_data);
+ return ret;
+}
+EXPORT_SYMBOL(q6asm_pack_and_set_pp_param_in_band);
+
+/**
+ * q6asm_set_soft_volume_module_instance_ids
+ * command to set module and instance ids for soft volume
+ *
+ * @instance: soft volume instance
+ * @param_hdr: parameter header
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6asm_set_soft_volume_module_instance_ids(int instance,
+ struct param_hdr_v3 *param_hdr)
+{
+ if (param_hdr == NULL) {
+ pr_err("%s: Param header is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ switch (instance) {
+ case SOFT_VOLUME_INSTANCE_2:
+ param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL2;
+ param_hdr->instance_id = INSTANCE_ID_0;
+ return 0;
+ case SOFT_VOLUME_INSTANCE_1:
+ param_hdr->module_id = ASM_MODULE_ID_VOL_CTRL;
+ param_hdr->instance_id = INSTANCE_ID_0;
+ return 0;
+ default:
+ pr_err("%s: Invalid instance %d\n", __func__, instance);
+ return -EINVAL;
+ }
+}
+EXPORT_SYMBOL(q6asm_set_soft_volume_module_instance_ids);
+
static int __q6asm_open_read(struct audio_client *ac,
uint32_t format, uint16_t bits_per_sample,
uint32_t pcm_format_block_ver,
@@ -2632,6 +2799,7 @@
{
int rc = 0x00;
struct asm_stream_cmd_open_read_v3 open;
+ struct q6asm_cal_info cal_info;
config_debug_fs_reset_index();
@@ -2651,12 +2819,15 @@
/* Stream prio : High, provide meta info with encoded frames */
open.src_endpointype = ASM_END_POINT_DEVICE_MATRIX;
- open.preprocopo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open.preprocopo_id = cal_info.topology_id;
+
+
open.bits_per_sample = bits_per_sample;
open.mode_flags = 0x0;
ac->topology = open.preprocopo_id;
- ac->app_type = q6asm_get_asm_app_type_cal();
+ ac->app_type = cal_info.app_type;
if (ac->perf_mode == LOW_LATENCY_PCM_MODE) {
open.mode_flags |= ASM_LOW_LATENCY_TX_STREAM_SESSION <<
ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
@@ -2918,6 +3089,7 @@
{
int rc = 0x00;
struct asm_stream_cmd_open_write_v3 open;
+ struct q6asm_cal_info cal_info;
if (ac == NULL) {
pr_err("%s: APR handle NULL\n", __func__);
@@ -2966,7 +3138,9 @@
open.sink_endpointype = ASM_END_POINT_DEVICE_MATRIX;
open.bits_per_sample = bits_per_sample;
- open.postprocopo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open.postprocopo_id = cal_info.topology_id;
+
if (ac->perf_mode != LEGACY_PCM_MODE)
open.postprocopo_id = ASM_STREAM_POSTPROCOPO_ID_NONE;
@@ -2979,7 +3153,7 @@
*/
if (!ac->topology) {
ac->topology = open.postprocopo_id;
- ac->app_type = q6asm_get_asm_app_type_cal();
+ ac->app_type = cal_info.app_type;
}
switch (format) {
case FORMAT_LINEAR_PCM:
@@ -3166,6 +3340,7 @@
{
int rc = 0x00;
struct asm_stream_cmd_open_readwrite_v2 open;
+ struct q6asm_cal_info cal_info;
if (ac == NULL) {
pr_err("%s: APR handle NULL\n", __func__);
@@ -3187,12 +3362,13 @@
open.mode_flags = is_meta_data_mode ? BUFFER_META_ENABLE : 0;
open.bits_per_sample = bits_per_sample;
/* source endpoint : matrix */
- open.postprocopo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open.postprocopo_id = cal_info.topology_id;
open.postprocopo_id = overwrite_topology ?
topology : open.postprocopo_id;
ac->topology = open.postprocopo_id;
- ac->app_type = q6asm_get_asm_app_type_cal();
+ ac->app_type = cal_info.app_type;
switch (wr_format) {
@@ -3385,6 +3561,7 @@
int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
{
int rc = 0x00;
+ struct q6asm_cal_info cal_info;
if (ac == NULL) {
pr_err("%s: APR handle NULL\n", __func__);
@@ -3409,9 +3586,10 @@
open.src_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
open.sink_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
/* source endpoint : matrix */
- open.audproc_topo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open.audproc_topo_id = cal_info.topology_id;
- ac->app_type = q6asm_get_asm_app_type_cal();
+ ac->app_type = cal_info.app_type;
if (ac->perf_mode == LOW_LATENCY_PCM_MODE)
open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION;
else
@@ -3440,9 +3618,10 @@
open.src_endpointype = 0;
open.sink_endpointype = 0;
/* source endpoint : matrix */
- open.postprocopo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open.postprocopo_id = cal_info.topology_id;
- ac->app_type = q6asm_get_asm_app_type_cal();
+ ac->app_type = cal_info.app_type;
ac->topology = open.postprocopo_id;
open.bits_per_sample = bits_per_sample;
open.reserved = 0;
@@ -3497,6 +3676,7 @@
{
int rc = 0x00;
struct asm_stream_cmd_open_transcode_loopback_t open;
+ struct q6asm_cal_info cal_info;
if (ac == NULL) {
pr_err("%s: APR handle NULL\n", __func__);
@@ -3544,9 +3724,11 @@
}
/* source endpoint : matrix */
- open.audproc_topo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open.audproc_topo_id = cal_info.topology_id;
- ac->app_type = q6asm_get_asm_app_type_cal();
+
+ ac->app_type = cal_info.app_type;
if (ac->perf_mode == LOW_LATENCY_PCM_MODE)
open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION;
else
@@ -3615,9 +3797,9 @@
bytes_to_alloc = bufsz * bufcnt;
bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc);
- rc = msm_audio_ion_alloc("audio_client", &buf_circ->client,
- &buf_circ->handle, bytes_to_alloc,
- (ion_phys_addr_t *)&buf_circ->phys,
+ rc = msm_audio_ion_alloc(&buf_circ->dma_buf,
+ bytes_to_alloc,
+ &buf_circ->phys,
&len, &buf_circ->data);
if (rc) {
@@ -3669,9 +3851,9 @@
bytes_to_alloc = PAGE_ALIGN(bytes_to_alloc);
- rc = msm_audio_ion_alloc("audio_client", &buf_pos->client,
- &buf_pos->handle, bytes_to_alloc,
- (ion_phys_addr_t *)&buf_pos->phys, &len,
+ rc = msm_audio_ion_alloc(&buf_pos->dma_buf,
+ bytes_to_alloc,
+ &buf_pos->phys, &len,
&buf_pos->data);
if (rc) {
@@ -3716,6 +3898,7 @@
struct asm_stream_cmd_open_shared_io *open;
u8 *channel_mapping;
int i, size_of_open, num_watermarks, bufsz, bufcnt, rc, flags = 0;
+ struct q6asm_cal_info cal_info;
if (!ac || !config)
return -EINVAL;
@@ -3782,7 +3965,8 @@
open->endpoint_type = ASM_END_POINT_DEVICE_MATRIX;
open->topo_bits_per_sample = config->bits_per_sample;
- open->topo_id = q6asm_get_asm_topology_cal();
+ rc = q6asm_get_asm_topology_apptype(&cal_info);
+ open->topo_id = cal_info.topology_id;
if (config->format == FORMAT_LINEAR_PCM)
open->fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3;
@@ -3900,18 +4084,15 @@
port = &ac->port[dir];
mutex_lock(&ac->cmd_lock);
if (port->buf && port->buf->data) {
- msm_audio_ion_free(port->buf->client, port->buf->handle);
- port->buf->client = NULL;
- port->buf->handle = NULL;
+ msm_audio_ion_free(port->buf->dma_buf);
+ port->buf->dma_buf = NULL;
port->max_buf_cnt = 0;
kfree(port->buf);
port->buf = NULL;
}
if (ac->shared_pos_buf.data) {
- msm_audio_ion_free(ac->shared_pos_buf.client,
- ac->shared_pos_buf.handle);
- ac->shared_pos_buf.client = NULL;
- ac->shared_pos_buf.handle = NULL;
+ msm_audio_ion_free(ac->shared_pos_buf.dma_buf);
+ ac->shared_pos_buf.dma_buf = NULL;
}
mutex_unlock(&ac->cmd_lock);
return 0;
@@ -7345,67 +7526,28 @@
int q6asm_set_lrgain(struct audio_client *ac, int left_gain, int right_gain)
{
struct asm_volume_ctrl_multichannel_gain multi_ch_gain;
- int sz = 0;
+ struct param_hdr_v3 param_info;
int rc = 0;
- if (ac == NULL) {
- pr_err("%s: APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
-
+ memset(¶m_info, 0, sizeof(param_info));
memset(&multi_ch_gain, 0, sizeof(multi_ch_gain));
- sz = sizeof(struct asm_volume_ctrl_multichannel_gain);
- q6asm_add_hdr_async(ac, &multi_ch_gain.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- multi_ch_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- multi_ch_gain.param.data_payload_addr_lsw = 0;
- multi_ch_gain.param.data_payload_addr_msw = 0;
- multi_ch_gain.param.mem_map_handle = 0;
- multi_ch_gain.param.data_payload_size = sizeof(multi_ch_gain) -
- sizeof(multi_ch_gain.hdr) - sizeof(multi_ch_gain.param);
- multi_ch_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL;
- multi_ch_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN;
- multi_ch_gain.data.param_size = multi_ch_gain.param.data_payload_size -
- sizeof(multi_ch_gain.data);
- multi_ch_gain.data.reserved = 0;
+
+ param_info.module_id = ASM_MODULE_ID_VOL_CTRL;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN;
+ param_info.param_size = sizeof(multi_ch_gain);
+
multi_ch_gain.gain_data[0].channeltype = PCM_CHANNEL_FL;
multi_ch_gain.gain_data[0].gain = left_gain << 15;
multi_ch_gain.gain_data[1].channeltype = PCM_CHANNEL_FR;
multi_ch_gain.gain_data[1].gain = right_gain << 15;
multi_ch_gain.num_channels = 2;
- rc = apr_send_pkt(ac->apr, (uint32_t *) &multi_ch_gain);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
+ (u8 *) &multi_ch_gain);
+ if (rc < 0)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, multi_ch_gain.data.param_id, rc);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ __func__, param_info.param_id, rc);
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- multi_ch_gain.data.param_id);
- rc = -ETIMEDOUT;
- goto fail_cmd;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] , set-params paramid[0x%x]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)),
- multi_ch_gain.data.param_id);
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
return rc;
}
@@ -7421,20 +7563,14 @@
uint32_t *gains, uint8_t *ch_map, bool use_default)
{
struct asm_volume_ctrl_multichannel_gain multich_gain;
- int sz = 0;
+ struct param_hdr_v3 param_info;
int rc = 0;
int i;
u8 default_chmap[VOLUME_CONTROL_MAX_CHANNELS];
if (ac == NULL) {
- pr_err("%s: ac is NULL\n", __func__);
- rc = -EINVAL;
- goto done;
- }
- if (ac->apr == NULL) {
- dev_err(ac->dev, "%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto done;
+ pr_err("%s: Audio client is NULL\n", __func__);
+ return -EINVAL;
}
if (gains == NULL) {
dev_err(ac->dev, "%s: gain_list is NULL\n", __func__);
@@ -7453,21 +7589,12 @@
goto done;
}
+ memset(¶m_info, 0, sizeof(param_info));
memset(&multich_gain, 0, sizeof(multich_gain));
- sz = sizeof(struct asm_volume_ctrl_multichannel_gain);
- q6asm_add_hdr_async(ac, &multich_gain.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- multich_gain.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- multich_gain.param.data_payload_addr_lsw = 0;
- multich_gain.param.data_payload_addr_msw = 0;
- multich_gain.param.mem_map_handle = 0;
- multich_gain.param.data_payload_size = sizeof(multich_gain) -
- sizeof(multich_gain.hdr) - sizeof(multich_gain.param);
- multich_gain.data.module_id = ASM_MODULE_ID_VOL_CTRL;
- multich_gain.data.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN;
- multich_gain.data.param_size = multich_gain.param.data_payload_size -
- sizeof(multich_gain.data);
- multich_gain.data.reserved = 0;
+ param_info.module_id = ASM_MODULE_ID_VOL_CTRL;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = ASM_PARAM_ID_MULTICHANNEL_GAIN;
+ param_info.param_size = sizeof(multich_gain);
if (use_default) {
rc = q6asm_map_channels(default_chmap, channels, false);
@@ -7486,29 +7613,11 @@
}
multich_gain.num_channels = channels;
- rc = apr_send_pkt(ac->apr, (uint32_t *) &multich_gain);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
+ (u8 *) &multich_gain);
+ if (rc)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, multich_gain.data.param_id, rc);
- goto done;
- }
-
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- multich_gain.data.param_id);
- rc = -EINVAL;
- goto done;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%d] , set-params paramid[0x%x]\n",
- __func__, atomic_read(&ac->cmd_state_pp),
- multich_gain.data.param_id);
- rc = -EINVAL;
- goto done;
- }
- rc = 0;
+ __func__, param_info.param_id, rc);
done:
return rc;
}
@@ -7526,62 +7635,21 @@
int q6asm_set_mute(struct audio_client *ac, int muteflag)
{
struct asm_volume_ctrl_mute_config mute;
- int sz = 0;
+ struct param_hdr_v3 param_info;
int rc = 0;
- if (ac == NULL) {
- pr_err("%s: APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
-
- sz = sizeof(struct asm_volume_ctrl_mute_config);
- q6asm_add_hdr_async(ac, &mute.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- mute.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- mute.param.data_payload_addr_lsw = 0;
- mute.param.data_payload_addr_msw = 0;
- mute.param.mem_map_handle = 0;
- mute.param.data_payload_size = sizeof(mute) -
- sizeof(mute.hdr) - sizeof(mute.param);
- mute.data.module_id = ASM_MODULE_ID_VOL_CTRL;
- mute.data.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG;
- mute.data.param_size = mute.param.data_payload_size - sizeof(mute.data);
- mute.data.reserved = 0;
+ memset(&mute, 0, sizeof(mute));
+ memset(¶m_info, 0, sizeof(param_info));
+ param_info.module_id = ASM_MODULE_ID_VOL_CTRL;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MUTE_CONFIG;
+ param_info.param_size = sizeof(mute);
mute.mute_flag = muteflag;
- rc = apr_send_pkt(ac->apr, (uint32_t *) &mute);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &mute);
+ if (rc)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, mute.data.param_id, rc);
- rc = -EINVAL;
- goto fail_cmd;
- }
-
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- mute.data.param_id);
- rc = -ETIMEDOUT;
- goto fail_cmd;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)),
- mute.data.param_id);
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
+ __func__, param_info.param_id, rc);
return rc;
}
EXPORT_SYMBOL(q6asm_set_mute);
@@ -7589,74 +7657,28 @@
static int __q6asm_set_volume(struct audio_client *ac, int volume, int instance)
{
struct asm_volume_ctrl_master_gain vol;
- int sz = 0;
- int rc = 0;
- int module_id;
+ struct param_hdr_v3 param_info;
+ int rc = 0;
- if (ac == NULL) {
- pr_err("%s: APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
+ memset(&vol, 0, sizeof(vol));
+ memset(¶m_info, 0, sizeof(param_info));
+
+ rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info);
+ if (rc) {
+ pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n",
+ __func__, rc);
+ return rc;
}
- switch (instance) {
- case SOFT_VOLUME_INSTANCE_2:
- module_id = ASM_MODULE_ID_VOL_CTRL2;
- break;
- case SOFT_VOLUME_INSTANCE_1:
- default:
- module_id = ASM_MODULE_ID_VOL_CTRL;
- break;
- }
-
- sz = sizeof(struct asm_volume_ctrl_master_gain);
- q6asm_add_hdr_async(ac, &vol.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- vol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- vol.param.data_payload_addr_lsw = 0;
- vol.param.data_payload_addr_msw = 0;
- vol.param.mem_map_handle = 0;
- vol.param.data_payload_size = sizeof(vol) -
- sizeof(vol.hdr) - sizeof(vol.param);
- vol.data.module_id = module_id;
- vol.data.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
- vol.data.param_size = vol.param.data_payload_size - sizeof(vol.data);
- vol.data.reserved = 0;
+ param_info.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
+ param_info.param_size = sizeof(vol);
vol.master_gain = volume;
- rc = apr_send_pkt(ac->apr, (uint32_t *) &vol);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &vol);
+ if (rc)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, vol.data.param_id, rc);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ __func__, param_info.param_id, rc);
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- vol.data.param_id);
- rc = -ETIMEDOUT;
- goto fail_cmd;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)),
- vol.data.param_id);
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_cmd;
- }
-
- rc = 0;
-fail_cmd:
return rc;
}
@@ -7764,9 +7786,8 @@
*/
int q6asm_send_ion_fd(struct audio_client *ac, int fd)
{
- struct ion_client *client;
- struct ion_handle *handle;
- ion_phys_addr_t paddr;
+ struct dma_buf *dma_buf;
+ dma_addr_t paddr;
size_t pa_len = 0;
void *vaddr;
int ret;
@@ -7784,9 +7805,7 @@
goto fail_cmd;
}
- ret = msm_audio_ion_import("audio_mem_client",
- &client,
- &handle,
+ ret = msm_audio_ion_import(&dma_buf,
fd,
NULL,
0,
@@ -7937,67 +7956,27 @@
struct asm_softpause_params *pause_param)
{
struct asm_soft_pause_params softpause;
- int sz = 0;
+ struct param_hdr_v3 param_info;
int rc = 0;
- if (ac == NULL) {
- pr_err("%s: APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ memset(&softpause, 0, sizeof(softpause));
+ memset(¶m_info, 0, sizeof(param_info));
+ param_info.module_id = ASM_MODULE_ID_VOL_CTRL;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS;
+ param_info.param_size = sizeof(softpause);
- sz = sizeof(struct asm_soft_pause_params);
- q6asm_add_hdr_async(ac, &softpause.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- softpause.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
-
- softpause.param.data_payload_addr_lsw = 0;
- softpause.param.data_payload_addr_msw = 0;
- softpause.param.mem_map_handle = 0;
- softpause.param.data_payload_size = sizeof(softpause) -
- sizeof(softpause.hdr) - sizeof(softpause.param);
- softpause.data.module_id = ASM_MODULE_ID_VOL_CTRL;
- softpause.data.param_id = ASM_PARAM_ID_SOFT_PAUSE_PARAMETERS;
- softpause.data.param_size = softpause.param.data_payload_size -
- sizeof(softpause.data);
- softpause.data.reserved = 0;
softpause.enable_flag = pause_param->enable;
softpause.period = pause_param->period;
softpause.step = pause_param->step;
softpause.ramping_curve = pause_param->rampingcurve;
- rc = apr_send_pkt(ac->apr, (uint32_t *) &softpause);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
+ (u8 *) &softpause);
+ if (rc)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, softpause.data.param_id, rc);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ __func__, param_info.param_id, rc);
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- softpause.data.param_id);
- rc = -ETIMEDOUT;
- goto fail_cmd;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)),
- softpause.data.param_id);
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
return rc;
}
EXPORT_SYMBOL(q6asm_set_softpause);
@@ -8007,76 +7986,32 @@
int instance)
{
struct asm_soft_step_volume_params softvol;
- int sz = 0;
- int rc = 0;
- int module_id;
+ struct param_hdr_v3 param_info;
+ int rc = 0;
- if (ac == NULL) {
- pr_err("%s: APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
+ memset(&softvol, 0, sizeof(softvol));
+ memset(¶m_info, 0, sizeof(param_info));
+
+ rc = q6asm_set_soft_volume_module_instance_ids(instance, ¶m_info);
+ if (rc) {
+ pr_err("%s: Failed to pack soft volume module and instance IDs, error %d\n",
+ __func__, rc);
+ return rc;
}
- switch (instance) {
- case SOFT_VOLUME_INSTANCE_2:
- module_id = ASM_MODULE_ID_VOL_CTRL2;
- break;
- case SOFT_VOLUME_INSTANCE_1:
- default:
- module_id = ASM_MODULE_ID_VOL_CTRL;
- break;
- }
+ param_info.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS;
+ param_info.param_size = sizeof(softvol);
- sz = sizeof(struct asm_soft_step_volume_params);
- q6asm_add_hdr_async(ac, &softvol.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- softvol.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- softvol.param.data_payload_addr_lsw = 0;
- softvol.param.data_payload_addr_msw = 0;
- softvol.param.mem_map_handle = 0;
- softvol.param.data_payload_size = sizeof(softvol) -
- sizeof(softvol.hdr) - sizeof(softvol.param);
- softvol.data.module_id = module_id;
- softvol.data.param_id = ASM_PARAM_ID_SOFT_VOL_STEPPING_PARAMETERS;
- softvol.data.param_size = softvol.param.data_payload_size -
- sizeof(softvol.data);
- softvol.data.reserved = 0;
softvol.period = softvol_param->period;
softvol.step = softvol_param->step;
softvol.ramping_curve = softvol_param->rampingcurve;
- rc = apr_send_pkt(ac->apr, (uint32_t *) &softvol);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info,
+ (u8 *) &softvol);
+ if (rc)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, softvol.data.param_id, rc);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ __func__, param_info.param_id, rc);
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- softvol.data.param_id);
- rc = -ETIMEDOUT;
- goto fail_cmd;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)),
- softvol.data.param_id);
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_cmd;
- }
- rc = 0;
-fail_cmd:
return rc;
}
@@ -8128,40 +8063,27 @@
{
struct asm_eq_params eq;
struct msm_audio_eq_stream_config *eq_params = NULL;
+ struct param_hdr_v3 param_info;
int i = 0;
- int sz = 0;
int rc = 0;
if (ac == NULL) {
- pr_err("%s: APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
+ pr_err("%s: Audio client is NULL\n", __func__);
+ return -EINVAL;
}
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- rc = -EINVAL;
- goto fail_cmd;
- }
-
if (eq_p == NULL) {
pr_err("%s: [%d]: Invalid Eq param\n", __func__, ac->session);
rc = -EINVAL;
goto fail_cmd;
}
- sz = sizeof(struct asm_eq_params);
- eq_params = (struct msm_audio_eq_stream_config *) eq_p;
- q6asm_add_hdr(ac, &eq.hdr, sz, TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- eq.hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- eq.param.data_payload_addr_lsw = 0;
- eq.param.data_payload_addr_msw = 0;
- eq.param.mem_map_handle = 0;
- eq.param.data_payload_size = sizeof(eq) -
- sizeof(eq.hdr) - sizeof(eq.param);
- eq.data.module_id = ASM_MODULE_ID_EQUALIZER;
- eq.data.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS;
- eq.data.param_size = eq.param.data_payload_size - sizeof(eq.data);
+ memset(&eq, 0, sizeof(eq));
+ memset(¶m_info, 0, sizeof(param_info));
+ eq_params = (struct msm_audio_eq_stream_config *) eq_p;
+ param_info.module_id = ASM_MODULE_ID_EQUALIZER;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = ASM_PARAM_ID_EQUALIZER_PARAMETERS;
+ param_info.param_size = sizeof(eq);
eq.enable_flag = eq_params->enable;
eq.num_bands = eq_params->num_bands;
@@ -8187,32 +8109,11 @@
pr_debug("%s: q_factor:%d bandnum:%d\n", __func__,
eq_params->eq_bands[i].q_factor, i);
}
- rc = apr_send_pkt(ac->apr, (uint32_t *)&eq);
- if (rc < 0) {
+ rc = q6asm_pack_and_set_pp_param_in_band(ac, param_info, (u8 *) &eq);
+ if (rc)
pr_err("%s: set-params send failed paramid[0x%x] rc %d\n",
- __func__, eq.data.param_id, rc);
- rc = -EINVAL;
- goto fail_cmd;
- }
+ __func__, param_info.param_id, rc);
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5*HZ);
- if (!rc) {
- pr_err("%s: timeout, set-params paramid[0x%x]\n", __func__,
- eq.data.param_id);
- rc = -ETIMEDOUT;
- goto fail_cmd;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] set-params paramid[0x%x]\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)),
- eq.data.param_id);
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_cmd;
- }
- rc = 0;
fail_cmd:
return rc;
}
@@ -8809,7 +8710,7 @@
mtmx_params.param_info.param_id =
ASM_SESSION_MTMX_STRTR_PARAM_SESSION_TIME_V3;
mtmx_params.param_info.param_max_size =
- sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct param_hdr_v1) +
sizeof(struct asm_session_mtmx_strtr_param_session_time_v3_t);
atomic_set(&ac->time_flag, 1);
@@ -8894,89 +8795,6 @@
EXPORT_SYMBOL(q6asm_get_session_time_legacy);
/**
- * q6asm_send_audio_effects_params -
- * command to send audio effects params
- *
- * @ac: Audio client handle
- * @params: audio effects params
- * @params_length: size of params
- *
- * Returns 0 on success or error on failure
- */
-int q6asm_send_audio_effects_params(struct audio_client *ac, char *params,
- uint32_t params_length)
-{
- char *asm_params = NULL;
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 payload_params;
- int sz, rc;
-
- pr_debug("%s:\n", __func__);
- if (!ac) {
- pr_err("%s: APR handle NULL\n", __func__);
- return -EINVAL;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- pr_err("%s: params NULL\n", __func__);
- return -EINVAL;
- }
- sz = sizeof(struct apr_hdr) +
- sizeof(struct asm_stream_cmd_set_pp_params_v2) +
- params_length;
- asm_params = kzalloc(sz, GFP_KERNEL);
- if (!asm_params) {
- pr_err("%s, asm params memory alloc failed", __func__);
- return -ENOMEM;
- }
- q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) +
- sizeof(struct asm_stream_cmd_set_pp_params_v2) +
- params_length), TRUE);
- atomic_set(&ac->cmd_state_pp, -1);
- hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- payload_params.data_payload_addr_lsw = 0;
- payload_params.data_payload_addr_msw = 0;
- payload_params.mem_map_handle = 0;
- payload_params.data_payload_size = params_length;
- memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr));
- memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params,
- sizeof(struct asm_stream_cmd_set_pp_params_v2));
- memcpy(((u8 *)asm_params + sizeof(struct apr_hdr) +
- sizeof(struct asm_stream_cmd_set_pp_params_v2)),
- params, params_length);
- rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
- if (rc < 0) {
- pr_err("%s: audio effects set-params send failed\n", __func__);
- rc = -EINVAL;
- goto fail_send_param;
- }
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 1*HZ);
- if (!rc) {
- pr_err("%s: timeout, audio effects set-params\n", __func__);
- rc = -ETIMEDOUT;
- goto fail_send_param;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%s] set-params\n",
- __func__, adsp_err_get_err_str(
- atomic_read(&ac->cmd_state_pp)));
- rc = adsp_err_get_lnx_err_code(
- atomic_read(&ac->cmd_state_pp));
- goto fail_send_param;
- }
-
- rc = 0;
-fail_send_param:
- kfree(asm_params);
- return rc;
-}
-EXPORT_SYMBOL(q6asm_send_audio_effects_params);
-
-/**
* q6asm_send_mtmx_strtr_window -
* command to send matrix for window params
*
@@ -9018,7 +8836,7 @@
matrix.param.data_payload_addr_msw = 0;
matrix.param.mem_map_handle = 0;
matrix.param.data_payload_size =
- sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct param_hdr_v1) +
sizeof(struct asm_session_mtmx_strtr_param_window_v2_t);
matrix.param.direction = 0; /* RX */
matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
@@ -9113,7 +8931,7 @@
matrix.param.data_payload_addr_msw = 0;
matrix.param.mem_map_handle = 0;
matrix.param.data_payload_size =
- sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct param_hdr_v1) +
sizeof(struct asm_session_mtmx_strtr_param_render_mode_t);
matrix.param.direction = 0; /* RX */
matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
@@ -9208,7 +9026,7 @@
matrix.param.data_payload_addr_msw = 0;
matrix.param.mem_map_handle = 0;
matrix.param.data_payload_size =
- sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct param_hdr_v1) +
sizeof(struct asm_session_mtmx_strtr_param_clk_rec_t);
matrix.param.direction = 0; /* RX */
matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
@@ -9293,7 +9111,7 @@
matrix.param.data_payload_addr_msw = 0;
matrix.param.mem_map_handle = 0;
matrix.param.data_payload_size =
- sizeof(struct asm_stream_param_data_v2) +
+ sizeof(struct param_hdr_v1) +
sizeof(struct asm_session_mtmx_param_adjust_session_time_ctl_t);
matrix.param.direction = 0; /* RX */
matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
@@ -9964,51 +9782,39 @@
return app_type;
}
-static int q6asm_get_asm_topology_cal(void)
+/*
+ * Retrieving cal_block will mark cal_block as stale.
+ * Hence it cannot be reused or resent unless the flag
+ * is reset.
+ */
+static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info)
{
- int topology = DEFAULT_POPP_TOPOLOGY;
struct cal_block_data *cal_block = NULL;
+ cal_info->topology_id = DEFAULT_POPP_TOPOLOGY;
+ cal_info->app_type = DEFAULT_APP_TYPE;
+
if (cal_data[ASM_TOPOLOGY_CAL] == NULL)
goto done;
mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]);
- if (cal_block == NULL)
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block))
goto unlock;
-
- topology = ((struct audio_cal_info_asm_top *)
+ cal_info->topology_id = ((struct audio_cal_info_asm_top *)
cal_block->cal_info)->topology;
-unlock:
- mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
-done:
- pr_debug("%s: Using topology %d\n", __func__, topology);
- return topology;
-}
-
-static int q6asm_get_asm_app_type_cal(void)
-{
- int app_type = DEFAULT_APP_TYPE;
- struct cal_block_data *cal_block = NULL;
-
- if (cal_data[ASM_TOPOLOGY_CAL] == NULL)
- goto done;
-
- mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
- cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]);
- if (cal_block == NULL)
- goto unlock;
-
- app_type = ((struct audio_cal_info_asm_top *)
+ cal_info->app_type = ((struct audio_cal_info_asm_top *)
cal_block->cal_info)->app_type;
- if (app_type == 0)
- app_type = DEFAULT_APP_TYPE;
+ cal_utils_mark_cal_used(cal_block);
+
unlock:
mutex_unlock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
done:
- pr_debug("%s: Using app_type %d\n", __func__, app_type);
- return app_type;
+ pr_debug("%s: Using topology %d app_type %d\n", __func__,
+ cal_info->topology_id, cal_info->app_type);
+
+ return 0;
}
/**
@@ -10022,20 +9828,14 @@
int q6asm_send_cal(struct audio_client *ac)
{
struct cal_block_data *cal_block = NULL;
- struct apr_hdr hdr;
- char *asm_params = NULL;
- struct asm_stream_cmd_set_pp_params_v2 payload_params;
- int sz, rc = -EINVAL;
-
+ struct mem_mapping_hdr mem_hdr;
+ u32 payload_size = 0;
+ int rc = -EINVAL;
pr_debug("%s:\n", __func__);
if (!ac) {
- pr_err("%s: APR handle NULL\n", __func__);
- goto done;
- }
- if (ac->apr == NULL) {
- pr_err("%s: AC APR handle NULL\n", __func__);
- goto done;
+ pr_err("%s: Audio client is NULL\n", __func__);
+ return -EINVAL;
}
if (ac->io_mode & NT_MODE) {
pr_debug("%s: called for NT MODE, exiting\n", __func__);
@@ -10050,10 +9850,12 @@
goto done;
}
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
mutex_lock(&cal_data[ASM_AUDSTRM_CAL]->lock);
cal_block = cal_utils_get_only_cal_block(cal_data[ASM_AUDSTRM_CAL]);
- if (cal_block == NULL) {
- pr_err("%s: cal_block is NULL\n",
+ if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
+ rc = 0; /* not error case */
+ pr_err("%s: cal_block is NULL or stale\n",
__func__);
goto unlock;
}
@@ -10072,62 +9874,28 @@
goto unlock;
}
- sz = sizeof(struct apr_hdr) +
- sizeof(struct asm_stream_cmd_set_pp_params_v2);
- asm_params = kzalloc(sz, GFP_KERNEL);
- if (!asm_params) {
- pr_err("%s, asm params memory alloc failed", __func__);
- rc = -ENOMEM;
+ mem_hdr.data_payload_addr_lsw =
+ lower_32_bits(cal_block->cal_data.paddr);
+ mem_hdr.data_payload_addr_msw =
+ msm_audio_populate_upper_32_bits(cal_block->cal_data.paddr);
+ mem_hdr.mem_map_handle = cal_block->map_data.q6map_handle;
+ payload_size = cal_block->cal_data.size;
+
+ pr_debug("%s: phyaddr lsw = %x msw = %x, maphdl = %x calsize = %d\n",
+ __func__, mem_hdr.data_payload_addr_lsw,
+ mem_hdr.data_payload_addr_msw, mem_hdr.mem_map_handle,
+ payload_size);
+
+ rc = q6asm_set_pp_params(ac, &mem_hdr, NULL, payload_size);
+ if (rc) {
+ pr_err("%s: audio audstrm cal send failed\n", __func__);
goto unlock;
}
- /* asm_stream_cmd_set_pp_params_v2 has no APR header in it */
- q6asm_add_hdr_async(ac, &hdr, (sizeof(struct apr_hdr) +
- sizeof(struct asm_stream_cmd_set_pp_params_v2)), TRUE);
-
- atomic_set(&ac->cmd_state_pp, -1);
- hdr.opcode = ASM_STREAM_CMD_SET_PP_PARAMS_V2;
- payload_params.data_payload_addr_lsw =
- lower_32_bits(cal_block->cal_data.paddr);
- payload_params.data_payload_addr_msw =
- msm_audio_populate_upper_32_bits(
- cal_block->cal_data.paddr);
- payload_params.mem_map_handle = cal_block->map_data.q6map_handle;
- payload_params.data_payload_size = cal_block->cal_data.size;
- memcpy(((u8 *)asm_params), &hdr, sizeof(struct apr_hdr));
- memcpy(((u8 *)asm_params + sizeof(struct apr_hdr)), &payload_params,
- sizeof(struct asm_stream_cmd_set_pp_params_v2));
-
- pr_debug("%s: phyaddr lsw = %x msw = %x, maphdl = %x calsize = %d\n",
- __func__, payload_params.data_payload_addr_lsw,
- payload_params.data_payload_addr_msw,
- payload_params.mem_map_handle,
- payload_params.data_payload_size);
-
- rc = apr_send_pkt(ac->apr, (uint32_t *) asm_params);
- if (rc < 0) {
- pr_err("%s: audio audstrm cal send failed\n", __func__);
- rc = -EINVAL;
- goto free;
- }
- rc = wait_event_timeout(ac->cmd_wait,
- (atomic_read(&ac->cmd_state_pp) >= 0), 5 * HZ);
- if (!rc) {
- pr_err("%s: timeout, audio audstrm cal send\n", __func__);
- rc = -ETIMEDOUT;
- goto free;
- }
- if (atomic_read(&ac->cmd_state_pp) > 0) {
- pr_err("%s: DSP returned error[%d] audio audstrm cal send\n",
- __func__, atomic_read(&ac->cmd_state_pp));
- rc = -EINVAL;
- goto free;
- }
-
+ if (cal_block)
+ cal_utils_mark_cal_used(cal_block);
rc = 0;
-free:
- kfree(asm_params);
unlock:
mutex_unlock(&cal_data[ASM_AUDSTRM_CAL]->lock);
done:
diff --git a/dsp/q6common.c b/dsp/q6common.c
new file mode 100644
index 0000000..7a186dc
--- /dev/null
+++ b/dsp/q6common.c
@@ -0,0 +1,113 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <dsp/q6common.h>
+
+struct q6common_ctl {
+ bool instance_id_supported;
+};
+
+static struct q6common_ctl common;
+
+/**
+ * q6common_update_instance_id_support
+ *
+ * Update instance ID support flag to true/false
+ *
+ * @supported: enable/disable for instance ID support
+ */
+void q6common_update_instance_id_support(bool supported)
+{
+ common.instance_id_supported = supported;
+}
+EXPORT_SYMBOL(q6common_update_instance_id_support);
+
+/**
+ * q6common_is_instance_id_supported
+ *
+ * Returns true/false for instance ID support
+ */
+bool q6common_is_instance_id_supported(void)
+{
+ return common.instance_id_supported;
+}
+EXPORT_SYMBOL(q6common_is_instance_id_supported);
+
+/**
+ * q6common_pack_pp_params
+ *
+ * Populate params header based on instance ID support and pack
+ * it with payload.
+ * Instance ID support -
+ * yes - param_hdr_v3 + payload
+ * no - param_hdr_v1 + payload
+ *
+ * @dest: destination data pointer to be packed into
+ * @v3_hdr: param header v3
+ * @param_data: param payload
+ * @total_size: total size of packed data (hdr + payload)
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr,
+ u8 *param_data, u32 *total_size)
+{
+ struct param_hdr_v1 *v1_hdr = NULL;
+ u32 packed_size = 0;
+ u32 param_size = 0;
+ bool iid_supported = q6common_is_instance_id_supported();
+
+ if (dest == NULL) {
+ pr_err("%s: Received NULL pointer for destination\n", __func__);
+ return -EINVAL;
+ } else if (v3_hdr == NULL) {
+ pr_err("%s: Received NULL pointer for header\n", __func__);
+ return -EINVAL;
+ } else if (total_size == NULL) {
+ pr_err("%s: Received NULL pointer for total size\n", __func__);
+ return -EINVAL;
+ }
+
+ param_size = v3_hdr->param_size;
+ packed_size = iid_supported ? sizeof(struct param_hdr_v3) :
+ sizeof(struct param_hdr_v1);
+
+ if (iid_supported) {
+ memcpy(dest, v3_hdr, packed_size);
+ } else {
+ v1_hdr = (struct param_hdr_v1 *) dest;
+ v1_hdr->module_id = v3_hdr->module_id;
+ v1_hdr->param_id = v3_hdr->param_id;
+
+ if (param_size > U16_MAX) {
+ pr_err("%s: Invalid param size for V1 %d\n", __func__,
+ param_size);
+ return -EINVAL;
+ }
+ v1_hdr->param_size = param_size;
+ v1_hdr->reserved = 0;
+ }
+
+ /*
+ * Make param_data optional for cases when there is no data
+ * present as in some set cases and all get cases.
+ */
+ if (param_data != NULL) {
+ memcpy(dest + packed_size, param_data, param_size);
+ packed_size += param_size;
+ }
+
+ *total_size = packed_size;
+
+ return 0;
+}
+EXPORT_SYMBOL(q6common_pack_pp_params);
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index 2a98dc7..108e4be 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017, Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,7 @@
#include <dsp/q6core.h>
#include <dsp/q6lsm.h>
#include <dsp/q6afe-v2.h>
+#include <dsp/q6common.h>
#include <dsp/audio_cal_utils.h>
#include "adsp_err.h"
@@ -73,11 +74,6 @@
struct mutex apr_lock;
};
-struct lsm_module_param_ids {
- uint32_t module_id;
- uint32_t param_id;
-};
-
static struct lsm_common lsm_common;
/*
* mmap_handle_p can point either client->sound_model.mem_map_handle or
@@ -98,38 +94,6 @@
static int q6lsm_memory_unmap_regions(struct lsm_client *client,
uint32_t handle);
-static void q6lsm_set_param_hdr_info(
- struct lsm_set_params_hdr *param_hdr,
- u32 payload_size, u32 addr_lsw, u32 addr_msw,
- u32 mmap_handle)
-{
- param_hdr->data_payload_size = payload_size;
- param_hdr->data_payload_addr_lsw = addr_lsw;
- param_hdr->data_payload_addr_msw = addr_msw;
- param_hdr->mem_map_handle = mmap_handle;
-}
-
-static void q6lsm_set_param_common(
- struct lsm_param_payload_common *common,
- struct lsm_module_param_ids *ids,
- u32 param_size, u32 set_param_version)
-{
- common->module_id = ids->module_id;
- common->param_id = ids->param_id;
-
- switch (set_param_version) {
- case LSM_SESSION_CMD_SET_PARAMS_V2:
- common->p_size.param_size = param_size;
- break;
- case LSM_SESSION_CMD_SET_PARAMS:
- default:
- common->p_size.sr.param_size =
- (u16) param_size;
- common->p_size.sr.reserved = 0;
- break;
- }
-}
-
static int q6lsm_callback(struct apr_client_data *data, void *priv)
{
struct lsm_client *client = (struct lsm_client *)priv;
@@ -204,6 +168,7 @@
case LSM_SESSION_CMD_OPEN_TX_V2:
case LSM_CMD_ADD_TOPOLOGIES:
case LSM_SESSION_CMD_SET_PARAMS_V2:
+ case LSM_SESSION_CMD_SET_PARAMS_V3:
if (token != client->session &&
payload[0] !=
LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL) {
@@ -462,6 +427,184 @@
hdr->token = client->session;
}
+static int q6lsm_pack_params(u8 *dest, struct param_hdr_v3 *param_info,
+ u8 *param_data, size_t *final_length,
+ u32 set_param_opcode)
+{
+ bool iid_supported = q6common_is_instance_id_supported();
+ union param_hdrs *param_hdr = NULL;
+ u32 param_size = param_info->param_size;
+ size_t hdr_size;
+ size_t provided_size = *final_length;
+
+ hdr_size = iid_supported ? sizeof(struct param_hdr_v3) :
+ sizeof(struct param_hdr_v2);
+ if (provided_size < hdr_size) {
+ pr_err("%s: Provided size %zu is not large enough, need %zu\n",
+ __func__, provided_size, hdr_size);
+ return -EINVAL;
+ }
+
+ if (iid_supported) {
+ memcpy(dest, param_info, hdr_size);
+ } else {
+ /* MID, PID and structure size are the same in V1 and V2 */
+ param_hdr = (union param_hdrs *) dest;
+ param_hdr->v2.module_id = param_info->module_id;
+ param_hdr->v2.param_id = param_info->param_id;
+
+ switch (set_param_opcode) {
+ case LSM_SESSION_CMD_SET_PARAMS_V2:
+ param_hdr->v2.param_size = param_size;
+ break;
+ case LSM_SESSION_CMD_SET_PARAMS:
+ default:
+ if (param_size > U16_MAX) {
+ pr_err("%s: Invalid param size %d\n", __func__,
+ param_size);
+ return -EINVAL;
+ }
+
+ param_hdr->v1.param_size = param_size;
+ param_hdr->v1.reserved = 0;
+ break;
+ }
+ }
+
+ *final_length = hdr_size;
+
+ if (param_data != NULL) {
+ if (provided_size < hdr_size + param_size) {
+ pr_err("%s: Provided size %zu is not large enough, need %zu\n",
+ __func__, provided_size, hdr_size + param_size);
+ return -EINVAL;
+ }
+ memcpy(dest + hdr_size, param_data, param_size);
+ *final_length += param_size;
+ }
+ return 0;
+}
+
+static int q6lsm_set_params_v2(struct lsm_client *client,
+ struct mem_mapping_hdr *mem_hdr,
+ uint8_t *param_data, uint32_t param_size,
+ uint32_t set_param_opcode)
+{
+ struct lsm_session_cmd_set_params_v2 *lsm_set_param = NULL;
+ uint32_t pkt_size = 0;
+ int ret;
+
+ pkt_size = sizeof(struct lsm_session_cmd_set_params_v2);
+ /* Only include param size in packet size when inband */
+ if (param_data != NULL)
+ pkt_size += param_size;
+
+ lsm_set_param = kzalloc(pkt_size, GFP_KERNEL);
+ if (!lsm_set_param)
+ return -ENOMEM;
+
+ q6lsm_add_hdr(client, &lsm_set_param->apr_hdr, pkt_size, true);
+ lsm_set_param->apr_hdr.opcode = set_param_opcode;
+ lsm_set_param->payload_size = param_size;
+
+ if (mem_hdr != NULL) {
+ lsm_set_param->mem_hdr = *mem_hdr;
+ } else if (param_data != NULL) {
+ memcpy(lsm_set_param->param_data, param_data, param_size);
+ } else {
+ pr_err("%s: Received NULL pointers for both memory header and data\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = q6lsm_apr_send_pkt(client, client->apr, lsm_set_param, true,
+ NULL);
+done:
+ kfree(lsm_set_param);
+ return ret;
+}
+
+static int q6lsm_set_params_v3(struct lsm_client *client,
+ struct mem_mapping_hdr *mem_hdr,
+ uint8_t *param_data, uint32_t param_size)
+{
+ struct lsm_session_cmd_set_params_v3 *lsm_set_param = NULL;
+ uint16_t pkt_size = 0;
+ int ret = 0;
+
+ pkt_size = sizeof(struct lsm_session_cmd_set_params_v3);
+ /* Only include param size in packet size when inband */
+ if (param_data != NULL)
+ pkt_size += param_size;
+
+ lsm_set_param = kzalloc(pkt_size, GFP_KERNEL);
+ if (!lsm_set_param)
+ return -ENOMEM;
+
+ q6lsm_add_hdr(client, &lsm_set_param->apr_hdr, pkt_size, true);
+ lsm_set_param->apr_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V3;
+ lsm_set_param->payload_size = param_size;
+
+ if (mem_hdr != NULL) {
+ lsm_set_param->mem_hdr = *mem_hdr;
+ } else if (param_data != NULL) {
+ memcpy(lsm_set_param->param_data, param_data, param_size);
+ } else {
+ pr_err("%s: Received NULL pointers for both memory header and data\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = q6lsm_apr_send_pkt(client, client->apr, lsm_set_param, true,
+ NULL);
+done:
+ kfree(lsm_set_param);
+ return ret;
+}
+
+static int q6lsm_set_params(struct lsm_client *client,
+ struct mem_mapping_hdr *mem_hdr,
+ uint8_t *param_data, uint32_t param_size,
+ uint32_t set_param_opcode)
+
+{
+ if (q6common_is_instance_id_supported())
+ return q6lsm_set_params_v3(client, mem_hdr, param_data,
+ param_size);
+ else
+ return q6lsm_set_params_v2(client, mem_hdr, param_data,
+ param_size, set_param_opcode);
+}
+
+static int q6lsm_pack_and_set_params(struct lsm_client *client,
+ struct param_hdr_v3 *param_info,
+ uint8_t *param_data,
+ uint32_t set_param_opcode)
+
+{
+ u8 *packed_data = NULL;
+ size_t total_size = 0;
+ int ret = 0;
+
+ total_size = sizeof(union param_hdrs) + param_info->param_size;
+ packed_data = kzalloc(total_size, GFP_KERNEL);
+ if (!packed_data)
+ return -ENOMEM;
+
+ ret = q6lsm_pack_params(packed_data, param_info, param_data,
+ &total_size, set_param_opcode);
+ if (ret)
+ goto done;
+
+ ret = q6lsm_set_params(client, NULL, packed_data, total_size,
+ set_param_opcode);
+
+done:
+ kfree(packed_data);
+ return ret;
+}
static int q6lsm_send_custom_topologies(struct lsm_client *client)
{
@@ -624,14 +767,20 @@
struct lsm_params_info *p_info,
size_t *offset)
{
- struct lsm_param_payload_common *param;
+ struct param_hdr_v3 param_hdr;
+ int ret = 0;
- param = (struct lsm_param_payload_common *)
- client->sound_model.data;
- param->module_id = p_info->module_id;
- param->param_id = p_info->param_id;
- param->p_size.param_size = client->sound_model.size;
- *offset = sizeof(*param);
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+
+ param_hdr.module_id = p_info->module_id;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = p_info->param_id;
+ param_hdr.param_size = client->sound_model.size;
+
+ ret = q6lsm_pack_params(client->sound_model.data, ¶m_hdr,
+ NULL, offset, LSM_SESSION_CMD_SET_PARAMS_V2);
+ if (ret)
+ pr_err("%s: Failed to pack params, error %d\n", __func__, ret);
}
EXPORT_SYMBOL(q6lsm_sm_set_param_data);
@@ -693,106 +842,65 @@
}
EXPORT_SYMBOL(q6lsm_open);
-static int q6lsm_send_confidence_levels(
- struct lsm_client *client,
- struct lsm_module_param_ids *ids,
- u32 set_param_opcode)
+static int q6lsm_send_confidence_levels(struct lsm_client *client,
+ struct param_hdr_v3 *param_info,
+ uint32_t set_param_opcode)
{
- u8 *packet;
- size_t pkt_size;
- struct lsm_cmd_set_params_conf *conf_params;
- struct apr_hdr *msg_hdr;
- struct lsm_param_min_confidence_levels *cfl;
+ struct lsm_param_confidence_levels *conf_levels = NULL;
+ uint32_t num_conf_levels = client->num_confidence_levels;
uint8_t i = 0;
uint8_t padd_size = 0;
- u8 *conf_levels;
- int rc;
- u32 payload_size, param_size;
+ uint32_t param_size = 0;
+ int rc = 0;
- padd_size = (4 - (client->num_confidence_levels % 4)) - 1;
- pkt_size = sizeof(*conf_params) + padd_size +
- client->num_confidence_levels;
+ /* Data must be 4 byte aligned so add any necessary padding. */
+ padd_size = (4 - (num_conf_levels % 4)) - 1;
+ param_size = (sizeof(uint8_t) + num_conf_levels + padd_size) *
+ sizeof(uint8_t);
+ param_info->param_size = param_size;
+ pr_debug("%s: Set Conf Levels PARAM SIZE = %d\n", __func__, param_size);
- packet = kzalloc(pkt_size, GFP_KERNEL);
- if (!packet)
+ conf_levels = kzalloc(param_size, GFP_KERNEL);
+ if (!conf_levels)
return -ENOMEM;
- conf_params = (struct lsm_cmd_set_params_conf *) packet;
- conf_levels = (u8 *) (packet + sizeof(*conf_params));
- msg_hdr = &conf_params->msg_hdr;
- q6lsm_add_hdr(client, msg_hdr,
- pkt_size, true);
- msg_hdr->opcode = set_param_opcode;
- payload_size = pkt_size - sizeof(*msg_hdr) -
- sizeof(conf_params->params_hdr);
- q6lsm_set_param_hdr_info(&conf_params->params_hdr,
- payload_size, 0, 0, 0);
- cfl = &conf_params->conf_payload;
- param_size = ((sizeof(uint8_t) + padd_size +
- client->num_confidence_levels)) *
- sizeof(uint8_t);
- q6lsm_set_param_common(&cfl->common, ids,
- param_size, set_param_opcode);
- cfl->num_confidence_levels = client->num_confidence_levels;
+ conf_levels->num_confidence_levels = num_conf_levels;
+ pr_debug("%s: Num conf_level = %d\n", __func__, num_conf_levels);
- pr_debug("%s: CMD PARAM SIZE = %d\n",
- __func__, param_size);
- pr_debug("%s: Num conf_level = %d\n",
- __func__, client->num_confidence_levels);
+ memcpy(conf_levels->confidence_levels, client->confidence_levels,
+ num_conf_levels);
+ for (i = 0; i < num_conf_levels; i++)
+ pr_debug("%s: Confidence_level[%d] = %d\n", __func__, i,
+ conf_levels->confidence_levels[i]);
- memcpy(conf_levels, client->confidence_levels,
- client->num_confidence_levels);
- for (i = 0; i < client->num_confidence_levels; i++)
- pr_debug("%s: Confidence_level[%d] = %d\n",
- __func__, i, conf_levels[i]);
-
- rc = q6lsm_apr_send_pkt(client, client->apr,
- packet, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, param_info,
+ (uint8_t *) conf_levels,
+ set_param_opcode);
if (rc)
- pr_err("%s: confidence_levels cmd failed, err = %d\n",
- __func__, rc);
- kfree(packet);
+ pr_err("%s: Send confidence_levels cmd failed, err = %d\n",
+ __func__, rc);
+ kfree(conf_levels);
return rc;
}
static int q6lsm_send_param_opmode(struct lsm_client *client,
- struct lsm_module_param_ids *opmode_ids,
- u32 set_param_opcode)
+ struct param_hdr_v3 *param_info,
+ u32 set_param_opcode)
{
- int rc;
- struct lsm_cmd_set_params_opmode opmode_params;
- struct apr_hdr *msg_hdr;
+ struct lsm_param_op_mode op_mode;
+ int rc = 0;
- struct lsm_param_op_mode *op_mode;
- u32 data_payload_size, param_size;
+ memset(&op_mode, 0, sizeof(op_mode));
+ param_info->param_size = sizeof(op_mode);
- msg_hdr = &opmode_params.msg_hdr;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(opmode_params), true);
- msg_hdr->opcode = set_param_opcode;
- data_payload_size = sizeof(opmode_params) -
- sizeof(*msg_hdr) -
- sizeof(opmode_params.params_hdr);
- q6lsm_set_param_hdr_info(&opmode_params.params_hdr,
- data_payload_size, 0, 0, 0);
- op_mode = &opmode_params.op_mode;
+ op_mode.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ op_mode.mode = client->mode;
+ pr_debug("%s: mode = 0x%x", __func__, op_mode.mode);
-
- param_size = sizeof(struct lsm_param_op_mode) -
- sizeof(op_mode->common);
- q6lsm_set_param_common(&op_mode->common,
- opmode_ids, param_size,
- set_param_opcode);
- op_mode->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
- op_mode->mode = client->mode;
- op_mode->reserved = 0;
- pr_debug("%s: mode = 0x%x", __func__, op_mode->mode);
-
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &opmode_params, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, param_info, (uint8_t *) &op_mode,
+ set_param_opcode);
if (rc)
- pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
- __func__, msg_hdr->opcode, rc);
+ pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
pr_debug("%s: leave %d\n", __func__, rc);
return rc;
@@ -824,92 +932,57 @@
*/
int q6lsm_set_port_connected(struct lsm_client *client)
{
- int rc;
- struct lsm_cmd_set_connectport connectport;
- struct lsm_module_param_ids connectport_ids;
- struct apr_hdr *msg_hdr;
- struct lsm_param_connect_to_port *connect_to_port;
- u32 data_payload_size, param_size, set_param_opcode;
+ struct lsm_param_connect_to_port connect_port;
+ struct param_hdr_v3 connectport_hdr;
+ u32 set_param_opcode = 0;
+ int rc = 0;
+
+ memset(&connect_port, 0, sizeof(connect_port));
+ memset(&connectport_hdr, 0, sizeof(connectport_hdr));
if (client->use_topology) {
set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- connectport_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
- connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
+ connectport_hdr.module_id = LSM_MODULE_ID_FRAMEWORK;
} else {
set_param_opcode = LSM_SESSION_CMD_SET_PARAMS;
- connectport_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
- connectport_ids.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
+ connectport_hdr.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
}
+ connectport_hdr.instance_id = INSTANCE_ID_0;
+ connectport_hdr.param_id = LSM_PARAM_ID_CONNECT_TO_PORT;
+ connectport_hdr.param_size = sizeof(connect_port);
+
client->connect_to_port = get_lsm_port();
+ connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ connect_port.port_id = client->connect_to_port;
- msg_hdr = &connectport.msg_hdr;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(connectport), true);
- msg_hdr->opcode = set_param_opcode;
- data_payload_size = sizeof(connectport) -
- sizeof(*msg_hdr) -
- sizeof(connectport.params_hdr);
- q6lsm_set_param_hdr_info(&connectport.params_hdr,
- data_payload_size, 0, 0, 0);
- connect_to_port = &connectport.connect_to_port;
-
- param_size = (sizeof(struct lsm_param_connect_to_port) -
- sizeof(connect_to_port->common));
- q6lsm_set_param_common(&connect_to_port->common,
- &connectport_ids, param_size,
- set_param_opcode);
- connect_to_port->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
- connect_to_port->port_id = client->connect_to_port;
- connect_to_port->reserved = 0;
- pr_debug("%s: port= %d", __func__, connect_to_port->port_id);
-
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &connectport, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, &connectport_hdr,
+ (uint8_t *) &connect_port,
+ set_param_opcode);
if (rc)
- pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
- __func__, msg_hdr->opcode, rc);
-
+ pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
return rc;
}
EXPORT_SYMBOL(q6lsm_set_port_connected);
static int q6lsm_send_param_polling_enable(struct lsm_client *client,
- bool poll_en,
- struct lsm_module_param_ids *poll_enable_ids,
- u32 set_param_opcode)
+ bool poll_en,
+ struct param_hdr_v3 *param_info,
+ u32 set_param_opcode)
{
+ struct lsm_param_poll_enable polling_enable;
int rc = 0;
- struct lsm_cmd_poll_enable cmd;
- struct apr_hdr *msg_hdr;
- struct lsm_param_poll_enable *poll_enable;
- u32 data_payload_size, param_size;
- msg_hdr = &cmd.msg_hdr;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(struct lsm_cmd_poll_enable), true);
- msg_hdr->opcode = set_param_opcode;
- data_payload_size = sizeof(struct lsm_cmd_poll_enable) -
- sizeof(struct apr_hdr) -
- sizeof(struct lsm_set_params_hdr);
- q6lsm_set_param_hdr_info(&cmd.params_hdr,
- data_payload_size, 0, 0, 0);
- poll_enable = &cmd.poll_enable;
+ memset(&polling_enable, 0, sizeof(polling_enable));
+ param_info->param_size = sizeof(polling_enable);
- param_size = (sizeof(struct lsm_param_poll_enable) -
- sizeof(poll_enable->common));
- q6lsm_set_param_common(&poll_enable->common,
- poll_enable_ids, param_size,
- set_param_opcode);
- poll_enable->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
- poll_enable->polling_enable = (poll_en) ? 1 : 0;
- pr_debug("%s: poll enable= %d", __func__, poll_enable->polling_enable);
+ polling_enable.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ polling_enable.polling_enable = (poll_en) ? 1 : 0;
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &cmd, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, param_info,
+ (uint8_t *) &polling_enable,
+ set_param_opcode);
if (rc)
- pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
- __func__, msg_hdr->opcode, rc);
-
+ pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
return rc;
}
@@ -925,48 +998,32 @@
int q6lsm_set_fwk_mode_cfg(struct lsm_client *client,
uint32_t event_mode)
{
+ struct lsm_param_fwk_mode_cfg fwk_mode_cfg;
+ struct param_hdr_v3 fwk_mode_cfg_hdr;
int rc = 0;
- struct lsm_cmd_set_fwk_mode_cfg cmd;
- struct lsm_module_param_ids fwk_mode_cfg_ids;
- struct apr_hdr *msg_hdr;
- struct lsm_param_fwk_mode_cfg *fwk_mode_cfg;
- u32 data_payload_size, param_size, set_param_opcode;
- if (client->use_topology) {
- set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- fwk_mode_cfg_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
- fwk_mode_cfg_ids.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG;
- } else {
+ memset(&fwk_mode_cfg, 0, sizeof(fwk_mode_cfg));
+ memset(&fwk_mode_cfg_hdr, 0, sizeof(fwk_mode_cfg_hdr));
+
+ if (!client->use_topology) {
pr_debug("%s: Ignore sending event mode\n", __func__);
return rc;
}
- msg_hdr = &cmd.msg_hdr;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(struct lsm_cmd_set_fwk_mode_cfg), true);
- msg_hdr->opcode = set_param_opcode;
- data_payload_size = sizeof(struct lsm_cmd_set_fwk_mode_cfg) -
- sizeof(struct apr_hdr) -
- sizeof(struct lsm_set_params_hdr);
- q6lsm_set_param_hdr_info(&cmd.params_hdr,
- data_payload_size, 0, 0, 0);
- fwk_mode_cfg = &cmd.fwk_mode_cfg;
+ fwk_mode_cfg_hdr.module_id = LSM_MODULE_ID_FRAMEWORK;
+ fwk_mode_cfg_hdr.instance_id = INSTANCE_ID_0;
+ fwk_mode_cfg_hdr.param_id = LSM_PARAM_ID_FWK_MODE_CONFIG;
+ fwk_mode_cfg_hdr.param_size = sizeof(fwk_mode_cfg);
- param_size = (sizeof(struct lsm_param_fwk_mode_cfg) -
- sizeof(fwk_mode_cfg->common));
- q6lsm_set_param_common(&fwk_mode_cfg->common,
- &fwk_mode_cfg_ids, param_size,
- set_param_opcode);
+ fwk_mode_cfg.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ fwk_mode_cfg.mode = event_mode;
+ pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg.mode);
- fwk_mode_cfg->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
- fwk_mode_cfg->mode = event_mode;
- pr_debug("%s: mode = %d\n", __func__, fwk_mode_cfg->mode);
-
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &cmd, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, &fwk_mode_cfg_hdr,
+ (uint8_t *) &fwk_mode_cfg,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
- pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
- __func__, msg_hdr->opcode, rc);
+ pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
return rc;
}
EXPORT_SYMBOL(q6lsm_set_fwk_mode_cfg);
@@ -1015,58 +1072,41 @@
*/
int q6lsm_set_media_fmt_params(struct lsm_client *client)
{
- int rc = 0;
- struct lsm_cmd_set_media_fmt cmd;
- struct lsm_module_param_ids media_fmt_ids;
- struct apr_hdr *msg_hdr;
- struct lsm_param_media_fmt *media_fmt;
- u32 data_payload_size, param_size, set_param_opcode;
+ struct lsm_param_media_fmt media_fmt;
struct lsm_hw_params param = client->hw_params;
+ struct param_hdr_v3 media_fmt_hdr;
+ int rc = 0;
- if (client->use_topology) {
- set_param_opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- media_fmt_ids.module_id = LSM_MODULE_ID_FRAMEWORK;
- media_fmt_ids.param_id = LSM_PARAM_ID_MEDIA_FMT;
- } else {
+ memset(&media_fmt, 0, sizeof(media_fmt));
+ memset(&media_fmt_hdr, 0, sizeof(media_fmt_hdr));
+
+ if (!client->use_topology) {
pr_debug("%s: Ignore sending media format\n", __func__);
goto err_ret;
}
- msg_hdr = &cmd.msg_hdr;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(struct lsm_cmd_set_media_fmt), true);
- msg_hdr->opcode = set_param_opcode;
- data_payload_size = sizeof(struct lsm_cmd_set_media_fmt) -
- sizeof(struct apr_hdr) -
- sizeof(struct lsm_set_params_hdr);
- q6lsm_set_param_hdr_info(&cmd.params_hdr,
- data_payload_size, 0, 0, 0);
- media_fmt = &cmd.media_fmt;
+ media_fmt_hdr.module_id = LSM_MODULE_ID_FRAMEWORK;
+ media_fmt_hdr.instance_id = INSTANCE_ID_0;
+ media_fmt_hdr.param_id = LSM_PARAM_ID_MEDIA_FMT;
+ media_fmt_hdr.param_size = sizeof(media_fmt);
- param_size = (sizeof(struct lsm_param_media_fmt) -
- sizeof(media_fmt->common));
- q6lsm_set_param_common(&media_fmt->common,
- &media_fmt_ids, param_size,
- set_param_opcode);
-
- media_fmt->minor_version = QLSM_PARAM_ID_MINOR_VERSION_2;
- media_fmt->sample_rate = param.sample_rate;
- media_fmt->num_channels = param.num_chs;
- media_fmt->bit_width = param.sample_size;
-
- rc = q6lsm_arrange_mch_map(media_fmt, media_fmt->num_channels);
+ media_fmt.minor_version = QLSM_PARAM_ID_MINOR_VERSION_2;
+ media_fmt.sample_rate = param.sample_rate;
+ media_fmt.num_channels = param.num_chs;
+ media_fmt.bit_width = param.sample_size;
+ rc = q6lsm_arrange_mch_map(&media_fmt, media_fmt.num_channels);
if (rc)
goto err_ret;
- pr_debug("%s: sample rate= %d, channels %d bit width %d\n",
- __func__, media_fmt->sample_rate, media_fmt->num_channels,
- media_fmt->bit_width);
+ pr_debug("%s: sample rate= %d, channels %d bit width %d\n", __func__,
+ media_fmt.sample_rate, media_fmt.num_channels,
+ media_fmt.bit_width);
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &cmd, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, &media_fmt_hdr,
+ (uint8_t *) &media_fmt,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
- pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
- __func__, msg_hdr->opcode, rc);
+ pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
err_ret:
return rc;
}
@@ -1086,9 +1126,10 @@
enum lsm_detection_mode mode,
bool detectfailure)
{
+ struct param_hdr_v3 param_hdr;
int rc = 0;
- struct lsm_module_param_ids opmode_ids;
- struct lsm_module_param_ids conf_levels_ids;
+
+ memset(¶m_hdr, 0, sizeof(param_hdr));
if (!client->confidence_levels) {
/*
@@ -1112,22 +1153,20 @@
}
client->mode |= detectfailure << 2;
- opmode_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
- opmode_ids.param_id = LSM_PARAM_ID_OPERATION_MODE;
-
- rc = q6lsm_send_param_opmode(client, &opmode_ids,
- LSM_SESSION_CMD_SET_PARAMS);
+ param_hdr.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = LSM_PARAM_ID_OPERATION_MODE;
+ rc = q6lsm_send_param_opmode(client, ¶m_hdr,
+ LSM_SESSION_CMD_SET_PARAMS);
if (rc) {
pr_err("%s: Failed to set lsm config params %d\n",
__func__, rc);
goto err_ret;
}
- conf_levels_ids.module_id = LSM_MODULE_ID_VOICE_WAKEUP;
- conf_levels_ids.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS;
-
- rc = q6lsm_send_confidence_levels(client, &conf_levels_ids,
- LSM_SESSION_CMD_SET_PARAMS);
+ param_hdr.param_id = LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS;
+ rc = q6lsm_send_confidence_levels(client, ¶m_hdr,
+ LSM_SESSION_CMD_SET_PARAMS);
if (rc) {
pr_err("%s: Failed to send conf_levels, err = %d\n",
__func__, rc);
@@ -1334,11 +1373,11 @@
u32 set_params_opcode)
{
int rc = 0;
- struct lsm_cmd_set_params params;
- struct lsm_set_params_hdr *params_hdr = ¶ms.param_hdr;
- struct apr_hdr *msg_hdr = ¶ms.msg_hdr;
+ struct mem_mapping_hdr mem_hdr;
struct cal_block_data *cal_block = NULL;
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
+
pr_debug("%s: Session id %d\n", __func__, client->session);
if (CHECK_SESSION(client->session)) {
pr_err("%s: session[%d]", __func__, client->session);
@@ -1366,21 +1405,16 @@
}
/* Cache mmap address, only map once or if new addr */
lsm_common.common_client[client->session].session = client->session;
- q6lsm_add_hdr(client, msg_hdr, sizeof(params), true);
- msg_hdr->opcode = set_params_opcode;
- q6lsm_set_param_hdr_info(params_hdr,
- cal_block->cal_data.size,
- lower_32_bits(client->lsm_cal_phy_addr),
- msm_audio_populate_upper_32_bits(
- client->lsm_cal_phy_addr),
- client->sound_model.mem_map_handle);
+ mem_hdr.data_payload_addr_lsw = lower_32_bits(client->lsm_cal_phy_addr);
+ mem_hdr.data_payload_addr_msw =
+ msm_audio_populate_upper_32_bits(client->lsm_cal_phy_addr);
+ mem_hdr.mem_map_handle = client->sound_model.mem_map_handle;
- pr_debug("%s: Cal Size = %zd", __func__,
- cal_block->cal_data.size);
- rc = q6lsm_apr_send_pkt(client, client->apr, ¶ms, true, NULL);
+ pr_debug("%s: Cal Size = %zd", __func__, cal_block->cal_data.size);
+ rc = q6lsm_set_params(client, &mem_hdr, NULL, cal_block->cal_data.size,
+ set_params_opcode);
if (rc)
- pr_err("%s: Failed set_params opcode 0x%x, rc %d\n",
- __func__, msg_hdr->opcode, rc);
+ pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
unlock:
mutex_unlock(&lsm_common.cal_data[LSM_CAL_IDX]->lock);
done:
@@ -1413,10 +1447,8 @@
__func__, rc);
if (client->sound_model.data) {
- msm_audio_ion_free(client->sound_model.client,
- client->sound_model.handle);
- client->sound_model.client = NULL;
- client->sound_model.handle = NULL;
+ msm_audio_ion_free(client->sound_model.dma_buf);
+ client->sound_model.dma_buf = NULL;
client->sound_model.data = NULL;
client->sound_model.phys = 0;
client->lsm_cal_phy_addr = 0;
@@ -1575,7 +1607,7 @@
* set_param payload as well.
*/
if (allocate_module_data)
- len += sizeof(struct lsm_param_payload_common);
+ len += sizeof(union param_hdrs);
client->sound_model.size = len;
pad_zero = (LSM_ALIGN_BOUNDARY -
@@ -1594,9 +1626,7 @@
cal_block->cal_data.size);
pr_debug("%s: Pad zeros sound model %zd Total mem %zd\n",
__func__, pad_zero, total_mem);
- rc = msm_audio_ion_alloc("lsm_client",
- &client->sound_model.client,
- &client->sound_model.handle,
+ rc = msm_audio_ion_alloc(&client->sound_model.dma_buf,
total_mem,
&client->sound_model.phys,
&len,
@@ -1671,66 +1701,46 @@
return rc;
}
-static int q6lsm_send_param_epd_thres(
- struct lsm_client *client,
- void *data, struct lsm_module_param_ids *ids)
+static int q6lsm_send_param_epd_thres(struct lsm_client *client, void *data,
+ struct param_hdr_v3 *param_info)
{
- struct snd_lsm_ep_det_thres *ep_det_data;
- struct lsm_cmd_set_epd_threshold epd_cmd;
- struct apr_hdr *msg_hdr = &epd_cmd.msg_hdr;
- struct lsm_set_params_hdr *param_hdr =
- &epd_cmd.param_hdr;
- struct lsm_param_epd_thres *epd_thres =
- &epd_cmd.epd_thres;
- int rc;
+ struct snd_lsm_ep_det_thres *ep_det_data = NULL;
+ struct lsm_param_epd_thres epd_thres;
+ int rc = 0;
+
+ memset(&epd_thres, 0, sizeof(epd_thres));
+ param_info->param_size = sizeof(epd_thres);
ep_det_data = (struct snd_lsm_ep_det_thres *) data;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(epd_cmd), true);
- msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- q6lsm_set_param_hdr_info(param_hdr,
- sizeof(*epd_thres), 0, 0, 0);
- q6lsm_set_param_common(&epd_thres->common, ids,
- sizeof(*epd_thres) - sizeof(epd_thres->common),
- LSM_SESSION_CMD_SET_PARAMS_V2);
- epd_thres->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
- epd_thres->epd_begin = ep_det_data->epd_begin;
- epd_thres->epd_end = ep_det_data->epd_end;
+ epd_thres.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ epd_thres.epd_begin = ep_det_data->epd_begin;
+ epd_thres.epd_end = ep_det_data->epd_end;
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &epd_cmd, true, NULL);
+ rc = q6lsm_pack_and_set_params(client, param_info,
+ (uint8_t *) &epd_thres,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (unlikely(rc))
- pr_err("%s: EPD_THRESHOLD failed, rc %d\n",
- __func__, rc);
+ pr_err("%s: EPD_THRESHOLD failed, rc %d\n", __func__, rc);
return rc;
}
-static int q6lsm_send_param_gain(
- struct lsm_client *client,
- u16 gain, struct lsm_module_param_ids *ids)
+static int q6lsm_send_param_gain(struct lsm_client *client, u16 gain,
+ struct param_hdr_v3 *param_info)
{
- struct lsm_cmd_set_gain lsm_cmd_gain;
- struct apr_hdr *msg_hdr = &lsm_cmd_gain.msg_hdr;
- struct lsm_param_gain *lsm_gain = &lsm_cmd_gain.lsm_gain;
- int rc;
+ struct lsm_param_gain lsm_gain;
+ int rc = 0;
- q6lsm_add_hdr(client, msg_hdr,
- sizeof(lsm_cmd_gain), true);
- msg_hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- q6lsm_set_param_hdr_info(&lsm_cmd_gain.param_hdr,
- sizeof(*lsm_gain), 0, 0, 0);
- q6lsm_set_param_common(&lsm_gain->common, ids,
- sizeof(*lsm_gain) - sizeof(lsm_gain->common),
- LSM_SESSION_CMD_SET_PARAMS_V2);
- lsm_gain->minor_version = QLSM_PARAM_ID_MINOR_VERSION;
- lsm_gain->gain = gain;
- lsm_gain->reserved = 0;
+ memset(&lsm_gain, 0, sizeof(lsm_gain));
+ param_info->param_size = sizeof(lsm_gain);
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &lsm_cmd_gain, true, NULL);
+ lsm_gain.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
+ lsm_gain.gain = gain;
+
+ rc = q6lsm_pack_and_set_params(client, param_info,
+ (uint8_t *) &lsm_gain,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (unlikely(rc))
- pr_err("%s: LSM_GAIN CMD send failed, rc %d\n",
- __func__, rc);
+ pr_err("%s: LSM_GAIN CMD send failed, rc %d\n", __func__, rc);
return rc;
}
@@ -1749,23 +1759,25 @@
struct lsm_params_info *p_info, void *data,
uint32_t param_type)
{
- int rc = 0, pkt_sz;
- struct lsm_module_param_ids ids;
- u8 *packet;
+ struct param_hdr_v3 param_info;
+ int rc = 0;
- memset(&ids, 0, sizeof(ids));
+ memset(¶m_info, 0, sizeof(param_info));
+
switch (param_type) {
case LSM_ENDPOINT_DETECT_THRESHOLD: {
- ids.module_id = p_info->module_id;
- ids.param_id = p_info->param_id;
- rc = q6lsm_send_param_epd_thres(client, data,
- &ids);
+ param_info.module_id = p_info->module_id;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = p_info->param_id;
+ rc = q6lsm_send_param_epd_thres(client, data, ¶m_info);
+ if (rc)
+ pr_err("%s: LSM_ENDPOINT_DETECT_THRESHOLD failed, rc %d\n",
+ __func__, rc);
break;
}
case LSM_OPERATION_MODE: {
struct snd_lsm_detect_mode *det_mode = data;
- struct lsm_module_param_ids opmode_ids;
if (det_mode->mode == LSM_MODE_KEYWORD_ONLY_DETECTION) {
client->mode = 0x01;
@@ -1779,11 +1791,12 @@
client->mode |= det_mode->detect_failure << 2;
- opmode_ids.module_id = p_info->module_id;
- opmode_ids.param_id = p_info->param_id;
+ param_info.module_id = p_info->module_id;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = p_info->param_id;
- rc = q6lsm_send_param_opmode(client, &opmode_ids,
- LSM_SESSION_CMD_SET_PARAMS_V2);
+ rc = q6lsm_send_param_opmode(client, ¶m_info,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
pr_err("%s: OPERATION_MODE failed, rc %d\n",
__func__, rc);
@@ -1792,10 +1805,10 @@
case LSM_GAIN: {
struct snd_lsm_gain *lsm_gain = (struct snd_lsm_gain *) data;
-
- ids.module_id = p_info->module_id;
- ids.param_id = p_info->param_id;
- rc = q6lsm_send_param_gain(client, lsm_gain->gain, &ids);
+ param_info.module_id = p_info->module_id;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = p_info->param_id;
+ rc = q6lsm_send_param_gain(client, lsm_gain->gain, ¶m_info);
if (rc)
pr_err("%s: LSM_GAIN command failed, rc %d\n",
__func__, rc);
@@ -1803,10 +1816,11 @@
}
case LSM_MIN_CONFIDENCE_LEVELS:
- ids.module_id = p_info->module_id;
- ids.param_id = p_info->param_id;
- rc = q6lsm_send_confidence_levels(client, &ids,
- LSM_SESSION_CMD_SET_PARAMS_V2);
+ param_info.module_id = p_info->module_id;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = p_info->param_id;
+ rc = q6lsm_send_confidence_levels(
+ client, ¶m_info, LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
pr_err("%s: CONFIDENCE_LEVELS cmd failed, rc %d\n",
__func__, rc);
@@ -1814,11 +1828,12 @@
case LSM_POLLING_ENABLE: {
struct snd_lsm_poll_enable *lsm_poll_enable =
(struct snd_lsm_poll_enable *) data;
- ids.module_id = p_info->module_id;
- ids.param_id = p_info->param_id;
- rc = q6lsm_send_param_polling_enable(client,
- lsm_poll_enable->poll_en, &ids,
- LSM_SESSION_CMD_SET_PARAMS_V2);
+ param_info.module_id = p_info->module_id;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = p_info->param_id;
+ rc = q6lsm_send_param_polling_enable(
+ client, lsm_poll_enable->poll_en, ¶m_info,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
pr_err("%s: POLLING ENABLE cmd failed, rc %d\n",
__func__, rc);
@@ -1826,24 +1841,27 @@
}
case LSM_REG_SND_MODEL: {
- struct lsm_cmd_set_params model_param;
+ struct mem_mapping_hdr mem_hdr;
u32 payload_size;
- memset(&model_param, 0, sizeof(model_param));
- q6lsm_add_hdr(client, &model_param.msg_hdr,
- sizeof(model_param), true);
- model_param.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- payload_size = p_info->param_size +
- sizeof(struct lsm_param_payload_common);
- q6lsm_set_param_hdr_info(&model_param.param_hdr,
- payload_size,
- lower_32_bits(client->sound_model.phys),
- msm_audio_populate_upper_32_bits(
- client->sound_model.phys),
- client->sound_model.mem_map_handle);
+ memset(&mem_hdr, 0, sizeof(mem_hdr));
- rc = q6lsm_apr_send_pkt(client, client->apr,
- &model_param, true, NULL);
+ if (q6common_is_instance_id_supported())
+ payload_size = p_info->param_size +
+ sizeof(struct param_hdr_v3);
+ else
+ payload_size = p_info->param_size +
+ sizeof(struct param_hdr_v2);
+
+ mem_hdr.data_payload_addr_lsw =
+ lower_32_bits(client->sound_model.phys);
+ mem_hdr.data_payload_addr_msw =
+ msm_audio_populate_upper_32_bits(
+ client->sound_model.phys),
+ mem_hdr.mem_map_handle = client->sound_model.mem_map_handle;
+
+ rc = q6lsm_set_params(client, &mem_hdr, NULL, payload_size,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc) {
pr_err("%s: REG_SND_MODEL failed, rc %d\n",
__func__, rc);
@@ -1858,69 +1876,33 @@
}
case LSM_DEREG_SND_MODEL: {
- struct lsm_param_payload_common *common;
- struct lsm_cmd_set_params *param;
-
- pkt_sz = sizeof(*param) + sizeof(*common);
- packet = kzalloc(pkt_sz, GFP_KERNEL);
- if (!packet) {
- pr_err("%s: No memory for DEREG_SND_MODEL pkt, size = %d\n",
- __func__, pkt_sz);
- return -ENOMEM;
- }
-
- param = (struct lsm_cmd_set_params *) packet;
- common = (struct lsm_param_payload_common *)
- (packet + sizeof(*param));
- q6lsm_add_hdr(client, ¶m->msg_hdr, pkt_sz, true);
- param->msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- q6lsm_set_param_hdr_info(¶m->param_hdr,
- sizeof(*common),
- 0, 0, 0);
- ids.module_id = p_info->module_id;
- ids.param_id = p_info->param_id;
- q6lsm_set_param_common(common, &ids, 0,
- LSM_SESSION_CMD_SET_PARAMS_V2);
- rc = q6lsm_apr_send_pkt(client, client->apr,
- packet, true, NULL);
+ param_info.module_id = p_info->module_id;
+ param_info.instance_id = INSTANCE_ID_0;
+ param_info.param_id = p_info->param_id;
+ param_info.param_size = 0;
+ rc = q6lsm_pack_and_set_params(client, ¶m_info, NULL,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
pr_err("%s: DEREG_SND_MODEL failed, rc %d\n",
__func__, rc);
- kfree(packet);
break;
}
case LSM_CUSTOM_PARAMS: {
- struct apr_hdr *hdr;
- u8 *custom_data;
+ u32 param_size = p_info->param_size;
- if (p_info->param_size <
- sizeof(struct lsm_param_payload_common)) {
- pr_err("%s: Invalid param_size %d\n",
- __func__, p_info->param_size);
+ /* Check minimum size, V2 structure is smaller than V3 */
+ if (param_size < sizeof(struct param_hdr_v2)) {
+ pr_err("%s: Invalid param_size %d\n", __func__,
+ param_size);
return -EINVAL;
}
- pkt_sz = p_info->param_size + sizeof(*hdr);
- packet = kzalloc(pkt_sz, GFP_KERNEL);
- if (!packet) {
- pr_err("%s: no memory for CUSTOM_PARAMS, size = %d\n",
- __func__, pkt_sz);
- return -ENOMEM;
- }
-
- hdr = (struct apr_hdr *) packet;
- custom_data = (u8 *) (packet + sizeof(*hdr));
- q6lsm_add_hdr(client, hdr, pkt_sz, true);
- hdr->opcode = LSM_SESSION_CMD_SET_PARAMS_V2;
- memcpy(custom_data, data, p_info->param_size);
-
- rc = q6lsm_apr_send_pkt(client, client->apr,
- packet, true, NULL);
+ rc = q6lsm_set_params(client, NULL, data, param_size,
+ LSM_SESSION_CMD_SET_PARAMS_V2);
if (rc)
pr_err("%s: CUSTOM_PARAMS failed, rc %d\n",
__func__, rc);
- kfree(packet);
break;
}
default:
@@ -1986,60 +1968,56 @@
*/
int q6lsm_lab_control(struct lsm_client *client, u32 enable)
{
+ struct lsm_param_lab_enable lab_enable;
+ struct param_hdr_v3 lab_enable_hdr;
+ struct lsm_param_lab_config lab_config;
+ struct param_hdr_v3 lab_config_hdr;
int rc = 0;
- struct lsm_params_lab_enable lab_enable;
- struct lsm_params_lab_config lab_config;
- struct lsm_module_param_ids lab_ids;
- u32 param_size;
+
+ memset(&lab_enable, 0, sizeof(lab_enable));
+ memset(&lab_enable_hdr, 0, sizeof(lab_enable_hdr));
+ memset(&lab_config, 0, sizeof(lab_config));
+ memset(&lab_config_hdr, 0, sizeof(lab_config_hdr));
if (!client) {
pr_err("%s: invalid param client %pK\n", __func__, client);
return -EINVAL;
}
+
/* enable/disable lab on dsp */
- q6lsm_add_hdr(client, &lab_enable.msg_hdr, sizeof(lab_enable), true);
- lab_enable.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS;
- q6lsm_set_param_hdr_info(&lab_enable.params_hdr,
- sizeof(struct lsm_lab_enable),
- 0, 0, 0);
- param_size = (sizeof(struct lsm_lab_enable) -
- sizeof(struct lsm_param_payload_common));
- lab_ids.module_id = LSM_MODULE_ID_LAB;
- lab_ids.param_id = LSM_PARAM_ID_LAB_ENABLE;
- q6lsm_set_param_common(&lab_enable.lab_enable.common,
- &lab_ids, param_size,
- LSM_SESSION_CMD_SET_PARAMS);
- lab_enable.lab_enable.enable = (enable) ? 1 : 0;
- rc = q6lsm_apr_send_pkt(client, client->apr, &lab_enable, true, NULL);
+ lab_enable_hdr.module_id = LSM_MODULE_ID_LAB;
+ lab_enable_hdr.instance_id = INSTANCE_ID_0;
+ lab_enable_hdr.param_id = LSM_PARAM_ID_LAB_ENABLE;
+ lab_enable_hdr.param_size = sizeof(lab_enable);
+ lab_enable.enable = (enable) ? 1 : 0;
+ rc = q6lsm_pack_and_set_params(client, &lab_enable_hdr,
+ (uint8_t *) &lab_enable,
+ LSM_SESSION_CMD_SET_PARAMS);
if (rc) {
pr_err("%s: Lab enable failed rc %d\n", __func__, rc);
return rc;
}
if (!enable)
goto exit;
+
/* lab session is being enabled set the config values */
- q6lsm_add_hdr(client, &lab_config.msg_hdr, sizeof(lab_config), true);
- lab_config.msg_hdr.opcode = LSM_SESSION_CMD_SET_PARAMS;
- q6lsm_set_param_hdr_info(&lab_config.params_hdr,
- sizeof(struct lsm_lab_config),
- 0, 0, 0);
- lab_ids.module_id = LSM_MODULE_ID_LAB;
- lab_ids.param_id = LSM_PARAM_ID_LAB_CONFIG;
- param_size = (sizeof(struct lsm_lab_config) -
- sizeof(struct lsm_param_payload_common));
- q6lsm_set_param_common(&lab_config.lab_config.common,
- &lab_ids, param_size,
- LSM_SESSION_CMD_SET_PARAMS);
- lab_config.lab_config.minor_version = 1;
- lab_config.lab_config.wake_up_latency_ms = 250;
- rc = q6lsm_apr_send_pkt(client, client->apr, &lab_config, true, NULL);
+ lab_config_hdr.module_id = LSM_MODULE_ID_LAB;
+ lab_config_hdr.instance_id = INSTANCE_ID_0;
+ lab_config_hdr.param_id = LSM_PARAM_ID_LAB_CONFIG;
+ lab_config_hdr.param_size = sizeof(lab_config);
+ lab_config.minor_version = 1;
+ lab_config.wake_up_latency_ms = 250;
+ rc = q6lsm_pack_and_set_params(client, &lab_config_hdr,
+ (uint8_t *) &lab_config,
+ LSM_SESSION_CMD_SET_PARAMS);
if (rc) {
pr_err("%s: Lab config failed rc %d disable lab\n",
__func__, rc);
/* Lab config failed disable lab */
- lab_enable.lab_enable.enable = 0;
- if (q6lsm_apr_send_pkt(client, client->apr,
- &lab_enable, true, NULL))
+ lab_enable.enable = 0;
+ if (q6lsm_pack_and_set_params(client, &lab_enable_hdr,
+ (uint8_t *) &lab_enable,
+ LSM_SESSION_CMD_SET_PARAMS))
pr_err("%s: Lab disable failed\n", __func__);
}
exit:
@@ -2138,9 +2116,7 @@
client->hw_params.period_count);
return -ENOMEM;
}
- ret = msm_audio_ion_alloc("lsm_lab",
- &client->lab_buffer[0].client,
- &client->lab_buffer[0].handle,
+ ret = msm_audio_ion_alloc(&client->lab_buffer[0].dma_buf,
allocate_size, &client->lab_buffer[0].phys,
&len,
&client->lab_buffer[0].data);
@@ -2155,8 +2131,7 @@
pr_err("%s: memory map filed ret %d size %zd\n",
__func__, ret, len);
msm_audio_ion_free(
- client->lab_buffer[0].client,
- client->lab_buffer[0].handle);
+ client->lab_buffer[0].dma_buf);
}
}
if (ret) {
@@ -2187,9 +2162,7 @@
ret = q6lsm_memory_unmap_regions(client,
client->lab_buffer[0].mem_map_handle);
if (!ret)
- msm_audio_ion_free(
- client->lab_buffer[0].client,
- client->lab_buffer[0].handle);
+ msm_audio_ion_free(client->lab_buffer[0].dma_buf);
else
pr_err("%s: unmap failed not freeing memory\n",
__func__);
@@ -2359,6 +2332,8 @@
int i = 0;
pr_debug("%s:\n", __func__);
+
+ memset(&lsm_common, 0, sizeof(lsm_common));
spin_lock_init(&lsm_session_lock);
spin_lock_init(&mmap_lock);
mutex_init(&lsm_common.apr_lock);
diff --git a/dsp/q6usm.c b/dsp/q6usm.c
index 1ed74a9..3c335a8 100644
--- a/dsp/q6usm.c
+++ b/dsp/q6usm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -209,14 +209,13 @@
pr_debug("%s: data[%pK]phys[%llx][%pK]\n", __func__,
(void *)port->data, (u64)port->phys, (void *)&port->phys);
- msm_audio_ion_free(port->client, port->handle);
+ msm_audio_ion_free(port->dma_buf);
port->data = NULL;
port->phys = 0;
port->buf_size = 0;
port->buf_cnt = 0;
- port->client = NULL;
- port->handle = NULL;
+ port->dma_buf = NULL;
mutex_unlock(&usc->cmd_lock);
return rc;
@@ -250,13 +249,12 @@
(void *)port->param_buf, (u64)port->param_phys,
(void *)&port->param_phys);
- msm_audio_ion_free(port->param_client, port->param_handle);
+ msm_audio_ion_free(port->param_dma_buf);
port->param_buf = NULL;
port->param_phys = 0;
port->param_buf_size = 0;
- port->param_client = NULL;
- port->param_handle = NULL;
+ port->param_dma_buf = NULL;
mutex_unlock(&usc->cmd_lock);
return rc;
@@ -398,8 +396,7 @@
/* The size to allocate should be multiple of 4K bytes */
size = PAGE_ALIGN(size);
- rc = msm_audio_ion_alloc("ultrasound_client",
- &port->client, &port->handle,
+ rc = msm_audio_ion_alloc(&port->dma_buf,
size, &port->phys,
&len, &port->data);
@@ -464,8 +461,7 @@
/* The size to allocate should be multiple of 4K bytes */
size = PAGE_ALIGN(size);
- rc = msm_audio_ion_alloc("ultrasound_client",
- &port->param_client, &port->param_handle,
+ rc = msm_audio_ion_alloc(&port->param_dma_buf,
size, &port->param_phys,
&len, &port->param_buf);
@@ -725,8 +721,7 @@
ab.used = 1;
ab.size = size;
ab.actual_size = size;
- ab.handle = port->handle;
- ab.client = port->client;
+ ab.dma_buf = port->dma_buf;
ret = msm_audio_ion_mmap(&ab, vms);
diff --git a/dsp/q6usm.h b/dsp/q6usm.h
index fa2cd62..ba4f9a9 100644
--- a/dsp/q6usm.h
+++ b/dsp/q6usm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2014, 2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -63,10 +63,8 @@
/* read or write locks */
struct mutex lock;
spinlock_t dsp_lock;
- /* ION memory handle */
- struct ion_handle *handle;
- /* ION memory client */
- struct ion_client *client;
+ /* ION dma_buf memory */
+ struct dma_buf *dma_buf;
/* extended parameters, related to q6 variants */
void *ext;
/* physical address of parameter buffer */
@@ -77,10 +75,8 @@
uint32_t param_buf_size;
/* parameter buffer memory handle */
void *param_buf_mem_handle;
- /* ION memory handle for parameter buffer */
- struct ion_handle *param_handle;
- /* ION memory client for parameter buffer */
- struct ion_client *param_client;
+ /* ION dma_buf memory for parameter buffer */
+ struct dma_buf *param_dma_buf;
};
struct us_client {
diff --git a/dsp/q6voice.c b/dsp/q6voice.c
index d5f280e..88b1741 100644
--- a/dsp/q6voice.c
+++ b/dsp/q6voice.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,7 @@
#include <dsp/q6audio-v2.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/q6afe-v2.h>
+#include <dsp/q6common.h>
#include <dsp/audio_cal_utils.h>
#include <dsp/q6core.h>
#include <dsp/q6voice.h>
@@ -105,8 +106,9 @@
static int32_t qdsp_cvs_callback(struct apr_client_data *data, void *priv);
static int32_t qdsp_cvp_callback(struct apr_client_data *data, void *priv);
-static int voice_send_set_pp_enable_cmd(struct voice_data *v,
- uint32_t module_id, int enable);
+static int voice_send_set_pp_enable_cmd(
+ struct voice_data *v, struct module_instance_info mod_inst_info,
+ int enable);
static int is_cal_memory_allocated(void);
static bool is_cvd_version_queried(void);
static int is_voip_memory_allocated(void);
@@ -137,6 +139,12 @@
struct sound_focus_param *soundFocusData);
static int voice_send_get_source_tracking_cmd(struct voice_data *v,
struct source_tracking_param *sourceTrackingData);
+static int voice_pack_and_set_cvp_param(struct voice_data *v,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data);
+static int voice_pack_and_set_cvs_ui_property(struct voice_data *v,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data);
static void voice_itr_init(struct voice_session_itr *itr,
u32 session_id)
@@ -1471,70 +1479,31 @@
return ret;
}
-static int voice_send_set_pp_enable_cmd(struct voice_data *v,
- uint32_t module_id, int enable)
+static int voice_send_set_pp_enable_cmd(
+ struct voice_data *v, struct module_instance_info mod_inst_info,
+ int enable)
{
- struct cvs_set_pp_enable_cmd cvs_set_pp_cmd;
+ struct enable_param enable_param;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- void *apr_cvs;
- u16 cvs_handle;
- if (v == NULL) {
- pr_err("%s: v is NULL\n", __func__);
- return -EINVAL;
- }
- apr_cvs = common.apr_q6_cvs;
+ memset(&enable_param, 0, sizeof(enable_param));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = mod_inst_info.module_id;
+ param_hdr.instance_id = mod_inst_info.instance_id;
+ param_hdr.param_id = VOICE_PARAM_MOD_ENABLE;
+ param_hdr.param_size = sizeof(enable_param);
+ enable_param.enable = enable ? 1 : 0;
- if (!apr_cvs) {
- pr_err("%s: apr_cvs is NULL.\n", __func__);
- return -EINVAL;
- }
- cvs_handle = voice_get_cvs_handle(v);
+ pr_debug("%s: module_id=%d, instance_id=%d, enable=%d\n",
+ __func__, mod_inst_info.module_id, mod_inst_info.instance_id,
+ enable);
- cvs_set_pp_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
- APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- cvs_set_pp_cmd.hdr.pkt_size = APR_PKT_SIZE(APR_HDR_SIZE,
- sizeof(cvs_set_pp_cmd) -
- APR_HDR_SIZE);
- cvs_set_pp_cmd.hdr.src_port = voice_get_idx_for_session(v->session_id);
- cvs_set_pp_cmd.hdr.dest_port = cvs_handle;
- cvs_set_pp_cmd.hdr.token = 0;
- cvs_set_pp_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_UI_PROPERTY;
+ ret = voice_pack_and_set_cvs_ui_property(v, param_hdr,
+ (uint8_t *) &enable_param);
+ if (ret < 0)
+ pr_err("Fail: sending cvs set pp enable\n");
- cvs_set_pp_cmd.vss_set_pp.module_id = module_id;
- cvs_set_pp_cmd.vss_set_pp.param_id = VOICE_PARAM_MOD_ENABLE;
- cvs_set_pp_cmd.vss_set_pp.param_size = MOD_ENABLE_PARAM_LEN;
- cvs_set_pp_cmd.vss_set_pp.reserved = 0;
- cvs_set_pp_cmd.vss_set_pp.enable = enable;
- cvs_set_pp_cmd.vss_set_pp.reserved_field = 0;
- pr_debug("voice_send_set_pp_enable_cmd, module_id=%d, enable=%d\n",
- module_id, enable);
-
- v->cvs_state = CMD_STATUS_FAIL;
- v->async_err = 0;
- ret = apr_send_pkt(apr_cvs, (uint32_t *) &cvs_set_pp_cmd);
- if (ret < 0) {
- pr_err("Fail: sending cvs set pp enable,\n");
- goto fail;
- }
- ret = wait_event_timeout(v->cvs_wait,
- (v->cvs_state == CMD_STATUS_SUCCESS),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- goto fail;
- }
- if (v->async_err > 0) {
- pr_err("%s: DSP returned error[%s]\n",
- __func__, adsp_err_get_err_str(
- v->async_err));
- ret = adsp_err_get_lnx_err_code(
- v->async_err);
- goto fail;
- }
- return 0;
-fail:
return ret;
}
@@ -1944,8 +1913,7 @@
{
bool ret;
- if (common.cal_mem_map_table.client != NULL &&
- common.cal_mem_map_table.handle != NULL)
+ if (common.cal_mem_map_table.dma_buf != NULL)
ret = true;
else
ret = false;
@@ -1958,18 +1926,15 @@
{
int ret = 0;
- if ((common.cal_mem_map_table.client == NULL) ||
- (common.cal_mem_map_table.handle == NULL))
+ if (common.cal_mem_map_table.dma_buf == NULL)
goto done;
- ret = msm_audio_ion_free(common.cal_mem_map_table.client,
- common.cal_mem_map_table.handle);
+ ret = msm_audio_ion_free(common.cal_mem_map_table.dma_buf);
if (ret < 0)
pr_err("%s: msm_audio_ion_free failed:\n", __func__);
done:
- common.cal_mem_map_table.client = NULL;
- common.cal_mem_map_table.handle = NULL;
+ common.cal_mem_map_table.dma_buf = NULL;
return ret;
}
@@ -1977,8 +1942,7 @@
{
bool ret;
- if (common.rtac_mem_map_table.client != NULL &&
- common.rtac_mem_map_table.handle != NULL)
+ if (common.rtac_mem_map_table.dma_buf != NULL)
ret = true;
else
ret = false;
@@ -1990,18 +1954,15 @@
{
int ret = 0;
- if ((common.rtac_mem_map_table.client == NULL) ||
- (common.rtac_mem_map_table.handle == NULL))
+ if (common.rtac_mem_map_table.dma_buf == NULL)
goto done;
- ret = msm_audio_ion_free(common.rtac_mem_map_table.client,
- common.rtac_mem_map_table.handle);
+ ret = msm_audio_ion_free(common.rtac_mem_map_table.dma_buf);
if (ret < 0)
pr_err("%s: msm_audio_ion_free failed:\n", __func__);
done:
- common.rtac_mem_map_table.client = NULL;
- common.rtac_mem_map_table.handle = NULL;
+ common.rtac_mem_map_table.dma_buf = NULL;
return ret;
}
@@ -2021,8 +1982,7 @@
}
mutex_lock(&common.common_lock);
- if (v->shmem_info.sh_buf.client != NULL &&
- v->shmem_info.sh_buf.handle != NULL)
+ if (v->shmem_info.sh_buf.dma_buf != NULL)
ret = true;
else
ret = false;
@@ -3575,7 +3535,7 @@
pr_debug("%s\n", __func__);
- if (cal_block->map_data.ion_client == NULL) {
+ if (cal_block->map_data.dma_buf == NULL) {
pr_err("%s: No ION allocation for session_id %d!\n",
__func__, session_id);
ret = -EINVAL;
@@ -4254,8 +4214,10 @@
static int voice_setup_vocproc(struct voice_data *v)
{
+ struct module_instance_info mod_inst_info;
int ret = 0;
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
ret = voice_send_cvp_create_cmd(v);
if (ret < 0) {
pr_err("%s: CVP create failed err:%d\n", __func__, ret);
@@ -4297,6 +4259,9 @@
}
}
+ mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+
voice_send_cvs_register_cal_cmd(v);
voice_send_cvp_register_dev_cfg_cmd(v);
voice_send_cvp_register_cal_cmd(v);
@@ -4330,9 +4295,7 @@
}
if (v->st_enable && !v->tty_mode)
- voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_ST,
- v->st_enable);
+ voice_send_set_pp_enable_cmd(v, mod_inst_info, v->st_enable);
/* Start in-call music delivery if this feature is enabled */
if (v->music_info.play_enable)
voice_cvs_start_playback(v);
@@ -4476,14 +4439,12 @@
static int voice_send_cvp_media_format_cmd(struct voice_data *v,
uint32_t param_type)
{
+ struct vss_param_endpoint_media_format_info media_fmt_info;
+ struct param_hdr_v3 param_hdr;
int ret = 0;
- struct cvp_set_media_format_cmd cvp_set_media_format_cmd;
- void *apr_cvp;
- u16 cvp_handle;
- struct vss_icommon_param_data_t *media_fmt_param_data =
- &cvp_set_media_format_cmd.cvp_set_media_param_v2.param_data;
- struct vss_param_endpoint_media_format_info_t *media_fmt_info =
- &media_fmt_param_data->media_format_info;
+
+ memset(&media_fmt_info, 0, sizeof(media_fmt_info));
+ memset(¶m_hdr, 0, sizeof(param_hdr));
if (v == NULL) {
pr_err("%s: v is NULL\n", __func__);
@@ -4491,75 +4452,41 @@
goto done;
}
- apr_cvp = common.apr_q6_cvp;
- if (!apr_cvp) {
- pr_err("%s: apr_cvp is NULL.\n", __func__);
- ret = -EINVAL;
- goto done;
- }
+ param_hdr.module_id = VSS_MODULE_CVD_GENERIC;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_size = sizeof(media_fmt_info);
- cvp_handle = voice_get_cvp_handle(v);
- memset(&cvp_set_media_format_cmd, 0, sizeof(cvp_set_media_format_cmd));
-
- /* Fill header data */
- cvp_set_media_format_cmd.hdr.hdr_field =
- APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
- APR_PKT_VER);
- cvp_set_media_format_cmd.hdr.pkt_size =
- APR_PKT_SIZE(APR_HDR_SIZE,
- sizeof(cvp_set_media_format_cmd) - APR_HDR_SIZE);
- cvp_set_media_format_cmd.hdr.src_svc = 0;
- cvp_set_media_format_cmd.hdr.src_domain = APR_DOMAIN_APPS;
- cvp_set_media_format_cmd.hdr.src_port =
- voice_get_idx_for_session(v->session_id);
- cvp_set_media_format_cmd.hdr.dest_svc = 0;
- cvp_set_media_format_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
- cvp_set_media_format_cmd.hdr.dest_port = cvp_handle;
- cvp_set_media_format_cmd.hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN;
- cvp_set_media_format_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
-
- /* Fill param data */
- cvp_set_media_format_cmd.cvp_set_media_param_v2.mem_size =
- sizeof(struct vss_icommon_param_data_t);
- media_fmt_param_data->module_id = VSS_MODULE_CVD_GENERIC;
- media_fmt_param_data->param_size =
- sizeof(struct vss_param_endpoint_media_format_info_t);
-
- /* Fill device specific data */
switch (param_type) {
case RX_PATH:
- media_fmt_param_data->param_id =
- VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO;
- media_fmt_info->port_id = v->dev_rx.port_id;
- media_fmt_info->num_channels = v->dev_rx.no_of_channels;
- media_fmt_info->bits_per_sample = v->dev_rx.bits_per_sample;
- media_fmt_info->sample_rate = v->dev_rx.sample_rate;
- memcpy(&media_fmt_info->channel_mapping,
+ param_hdr.param_id = VSS_PARAM_RX_PORT_ENDPOINT_MEDIA_INFO;
+ media_fmt_info.port_id = v->dev_rx.port_id;
+ media_fmt_info.num_channels = v->dev_rx.no_of_channels;
+ media_fmt_info.bits_per_sample = v->dev_rx.bits_per_sample;
+ media_fmt_info.sample_rate = v->dev_rx.sample_rate;
+ memcpy(&media_fmt_info.channel_mapping,
&v->dev_rx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
break;
case TX_PATH:
- media_fmt_param_data->param_id =
- VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO;
- media_fmt_info->port_id = v->dev_tx.port_id;
- media_fmt_info->num_channels = v->dev_tx.no_of_channels;
- media_fmt_info->bits_per_sample = v->dev_tx.bits_per_sample;
- media_fmt_info->sample_rate = v->dev_tx.sample_rate;
- memcpy(&media_fmt_info->channel_mapping,
+ param_hdr.param_id = VSS_PARAM_TX_PORT_ENDPOINT_MEDIA_INFO;
+ media_fmt_info.port_id = v->dev_tx.port_id;
+ media_fmt_info.num_channels = v->dev_tx.no_of_channels;
+ media_fmt_info.bits_per_sample = v->dev_tx.bits_per_sample;
+ media_fmt_info.sample_rate = v->dev_tx.sample_rate;
+ memcpy(&media_fmt_info.channel_mapping,
&v->dev_tx.channel_mapping, VSS_CHANNEL_MAPPING_SIZE);
break;
case EC_REF_PATH:
- media_fmt_param_data->param_id =
- VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO;
- media_fmt_info->port_id = common.ec_media_fmt_info.port_id;
- media_fmt_info->num_channels =
+ param_hdr.param_id = VSS_PARAM_EC_REF_PORT_ENDPOINT_MEDIA_INFO;
+ media_fmt_info.port_id = common.ec_media_fmt_info.port_id;
+ media_fmt_info.num_channels =
common.ec_media_fmt_info.num_channels;
- media_fmt_info->bits_per_sample =
+ media_fmt_info.bits_per_sample =
common.ec_media_fmt_info.bits_per_sample;
- media_fmt_info->sample_rate =
+ media_fmt_info.sample_rate =
common.ec_media_fmt_info.sample_rate;
- memcpy(&media_fmt_info->channel_mapping,
+ memcpy(&media_fmt_info.channel_mapping,
&common.ec_media_fmt_info.channel_mapping,
VSS_CHANNEL_MAPPING_SIZE);
break;
@@ -4570,32 +4497,11 @@
goto done;
}
- /* Send command */
- v->cvp_state = CMD_STATUS_FAIL;
- v->async_err = 0;
- ret = apr_send_pkt(apr_cvp, (uint32_t *) &cvp_set_media_format_cmd);
- if (ret < 0) {
- pr_err("%s: Fail in sending VSS_ICOMMON_CMD_SET_PARAM_V2\n",
- __func__);
- ret = -EINVAL;
- goto done;
- }
-
- ret = wait_event_timeout(v->cvp_wait,
- (v->cvp_state == CMD_STATUS_SUCCESS),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- pr_err("%s: wait_event timeout\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (v->async_err > 0) {
- pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
- adsp_err_get_err_str(v->async_err), cvp_handle);
- ret = adsp_err_get_lnx_err_code(v->async_err);
- goto done;
- }
+ ret = voice_pack_and_set_cvp_param(v, param_hdr,
+ (u8 *) &media_fmt_info);
+ if (ret)
+ pr_err("%s: Failed to set media format params on CVP, err %d\n",
+ __func__, ret);
done:
return ret;
@@ -4991,10 +4897,13 @@
{
struct mvm_detach_vocproc_cmd mvm_d_vocproc_cmd;
struct apr_hdr cvp_destroy_session_cmd;
+ struct module_instance_info mod_inst_info;
int ret = 0;
void *apr_mvm, *apr_cvp;
u16 mvm_handle, cvp_handle;
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
+
if (v == NULL) {
pr_err("%s: v is NULL\n", __func__);
return -EINVAL;
@@ -5009,9 +4918,12 @@
mvm_handle = voice_get_mvm_handle(v);
cvp_handle = voice_get_cvp_handle(v);
+ mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+
/* disable slowtalk if st_enable is set */
if (v->st_enable)
- voice_send_set_pp_enable_cmd(v, MODULE_ID_VOICE_MODULE_ST, 0);
+ voice_send_set_pp_enable_cmd(v, mod_inst_info, 0);
/* Disable HD Voice if hd_enable is set */
if (v->hd_enable)
@@ -6333,11 +6245,15 @@
*
* Returns 0 on success or error on failure
*/
-int voc_set_pp_enable(uint32_t session_id, uint32_t module_id, uint32_t enable)
+int voc_set_pp_enable(uint32_t session_id,
+ struct module_instance_info mod_inst_info,
+ uint32_t enable)
{
struct voice_data *v = NULL;
int ret = 0;
struct voice_session_itr itr;
+ int mid = mod_inst_info.module_id;
+ int iid = mod_inst_info.instance_id;
voice_itr_init(&itr, session_id);
while (voice_itr_get_next_session(&itr, &v)) {
@@ -6346,15 +6262,15 @@
continue;
mutex_lock(&v->lock);
- if (module_id == MODULE_ID_VOICE_MODULE_ST)
+ if (mid == MODULE_ID_VOICE_MODULE_ST &&
+ iid == INSTANCE_ID_0)
v->st_enable = enable;
if (v->voc_state == VOC_RUN) {
- if ((module_id == MODULE_ID_VOICE_MODULE_ST) &&
- (!v->tty_mode))
- ret = voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_ST,
- enable);
+ if ((mid == MODULE_ID_VOICE_MODULE_ST) &&
+ iid == INSTANCE_ID_0 && (!v->tty_mode))
+ ret = voice_send_set_pp_enable_cmd(
+ v, mod_inst_info, enable);
}
mutex_unlock(&v->lock);
} else {
@@ -6464,8 +6380,8 @@
return ret;
}
EXPORT_SYMBOL(voc_get_afe_sidetone);
-
-int voc_get_pp_enable(uint32_t session_id, uint32_t module_id)
+int voc_get_pp_enable(uint32_t session_id,
+ struct module_instance_info mod_inst_info)
{
struct voice_data *v = voice_get_session(session_id);
int ret = 0;
@@ -6477,7 +6393,8 @@
}
mutex_lock(&v->lock);
- if (module_id == MODULE_ID_VOICE_MODULE_ST)
+ if (mod_inst_info.module_id == MODULE_ID_VOICE_MODULE_ST &&
+ mod_inst_info.instance_id == INSTANCE_ID_0)
ret = v->st_enable;
mutex_unlock(&v->lock);
@@ -6835,8 +6752,11 @@
int voc_enable_device(uint32_t session_id)
{
struct voice_data *v = voice_get_session(session_id);
+ struct module_instance_info mod_inst_info;
int ret = 0;
+ memset(&mod_inst_info, 0, sizeof(mod_inst_info));
+
if (v == NULL) {
pr_err("%s: v is NULL\n", __func__);
return -EINVAL;
@@ -6852,15 +6772,15 @@
/* Not a critical error, allow voice call to continue */
}
+ mod_inst_info.module_id = MODULE_ID_VOICE_MODULE_ST;
+ mod_inst_info.instance_id = INSTANCE_ID_0;
+
if (v->tty_mode) {
/* disable slowtalk */
- voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_ST,
- 0);
+ voice_send_set_pp_enable_cmd(v, mod_inst_info, 0);
} else {
/* restore slowtalk */
- voice_send_set_pp_enable_cmd(v,
- MODULE_ID_VOICE_MODULE_ST,
+ voice_send_set_pp_enable_cmd(v, mod_inst_info,
v->st_enable);
}
@@ -7257,12 +7177,9 @@
/* Free the ION memory and clear handles for Source Tracking */
if (is_source_tracking_shared_memomry_allocated()) {
msm_audio_ion_free(
- common.source_tracking_sh_mem.sh_mem_block.client,
- common.source_tracking_sh_mem.sh_mem_block.handle);
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf);
common.source_tracking_sh_mem.mem_handle = 0;
- common.source_tracking_sh_mem.sh_mem_block.client =
- NULL;
- common.source_tracking_sh_mem.sh_mem_block.handle =
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf =
NULL;
}
/* clean up srvcc rec flag */
@@ -7465,12 +7382,9 @@
/* Free the ION memory and clear handles for Source Tracking */
if (is_source_tracking_shared_memomry_allocated()) {
msm_audio_ion_free(
- common.source_tracking_sh_mem.sh_mem_block.client,
- common.source_tracking_sh_mem.sh_mem_block.handle);
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf);
common.source_tracking_sh_mem.mem_handle = 0;
- common.source_tracking_sh_mem.sh_mem_block.client =
- NULL;
- common.source_tracking_sh_mem.sh_mem_block.handle =
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf =
NULL;
}
voc_set_error_state(data->reset_proc);
@@ -7521,6 +7435,7 @@
case VSS_ICOMMON_CMD_MAP_MEMORY:
case VSS_ICOMMON_CMD_UNMAP_MEMORY:
case VSS_ICOMMON_CMD_SET_UI_PROPERTY:
+ case VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2:
case VSS_IPLAYBACK_CMD_START:
case VSS_IPLAYBACK_CMD_STOP:
case VSS_IRECORD_CMD_START:
@@ -7534,12 +7449,14 @@
wake_up(&v->cvs_wait);
break;
case VSS_ICOMMON_CMD_SET_PARAM_V2:
- pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2\n",
+ case VSS_ICOMMON_CMD_SET_PARAM_V3:
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM\n",
__func__);
rtac_make_voice_callback(RTAC_CVS, ptr,
data->payload_size);
break;
case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ case VSS_ICOMMON_CMD_GET_PARAM_V3:
pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
__func__);
/* Should only come here if there is an APR */
@@ -7673,7 +7590,8 @@
pr_debug("Recd VSS_ISTREAM_EVT_NOT_READY\n");
} else if (data->opcode == VSS_ISTREAM_EVT_READY) {
pr_debug("Recd VSS_ISTREAM_EVT_READY\n");
- } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
+ } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM ||
+ VSS_ICOMMON_RSP_GET_PARAM_V3) {
pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
ptr = data->payload;
if (ptr[0] != 0) {
@@ -7743,12 +7661,9 @@
*/
if (is_source_tracking_shared_memomry_allocated()) {
msm_audio_ion_free(
- common.source_tracking_sh_mem.sh_mem_block.client,
- common.source_tracking_sh_mem.sh_mem_block.handle);
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf);
common.source_tracking_sh_mem.mem_handle = 0;
- common.source_tracking_sh_mem.sh_mem_block.client =
- NULL;
- common.source_tracking_sh_mem.sh_mem_block.handle =
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf =
NULL;
}
voc_set_error_state(data->reset_proc);
@@ -7816,29 +7731,31 @@
case VSS_IVPCM_EVT_PUSH_BUFFER_V2:
break;
case VSS_ICOMMON_CMD_SET_PARAM_V2:
+ case VSS_ICOMMON_CMD_SET_PARAM_V3:
switch (data->token) {
case VOC_SET_MEDIA_FORMAT_PARAM_TOKEN:
case VOC_GENERIC_SET_PARAM_TOKEN:
- pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called\n",
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by voice_send_cvp_media_format_cmd\n",
__func__);
v->cvp_state = CMD_STATUS_SUCCESS;
v->async_err = ptr[1];
wake_up(&v->cvp_wait);
break;
case VOC_RTAC_SET_PARAM_TOKEN:
- pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM_V2 called by rtac\n",
+ pr_debug("%s: VSS_ICOMMON_CMD_SET_PARAM called by rtac\n",
__func__);
rtac_make_voice_callback(
RTAC_CVP, ptr,
data->payload_size);
break;
default:
- pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM_V2: %d\n",
+ pr_debug("%s: invalid token for command VSS_ICOMMON_CMD_SET_PARAM: %d\n",
__func__, data->token);
break;
}
break;
case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ case VSS_ICOMMON_CMD_GET_PARAM_V3:
pr_debug("%s: VSS_ICOMMON_CMD_GET_PARAM_V2\n",
__func__);
/* Should only come here if there is an APR */
@@ -7905,7 +7822,8 @@
break;
}
}
- } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM) {
+ } else if (data->opcode == VSS_ICOMMON_RSP_GET_PARAM ||
+ VSS_ICOMMON_RSP_GET_PARAM_V3) {
pr_debug("%s: VSS_ICOMMON_RSP_GET_PARAM\n", __func__);
ptr = data->payload;
if (ptr[0] != 0) {
@@ -7958,10 +7876,8 @@
goto done;
}
- rc = msm_audio_ion_free(v->shmem_info.sh_buf.client,
- v->shmem_info.sh_buf.handle);
- v->shmem_info.sh_buf.client = NULL;
- v->shmem_info.sh_buf.handle = NULL;
+ rc = msm_audio_ion_free(v->shmem_info.sh_buf.dma_buf);
+ v->shmem_info.sh_buf.dma_buf = NULL;
if (rc < 0) {
pr_err("%s: Error:%d freeing memory\n", __func__, rc);
@@ -7975,8 +7891,7 @@
cnt++;
}
- v->shmem_info.sh_buf.client = NULL;
- v->shmem_info.sh_buf.handle = NULL;
+ v->shmem_info.sh_buf.dma_buf = NULL;
done:
mutex_unlock(&common.common_lock);
@@ -8003,9 +7918,8 @@
goto done;
}
- rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.sh_buf.client),
- &(v->shmem_info.sh_buf.handle),
- bufsz*bufcnt,
+ rc = msm_audio_ion_alloc(&(v->shmem_info.sh_buf.dma_buf),
+ bufsz * bufcnt,
&phys, &len,
&mem_addr);
if (rc < 0) {
@@ -8055,8 +7969,7 @@
goto done;
}
- rc = msm_audio_ion_alloc("voip_client", &(v->shmem_info.memtbl.client),
- &(v->shmem_info.memtbl.handle),
+ rc = msm_audio_ion_alloc(&(v->shmem_info.memtbl.dma_buf),
sizeof(struct vss_imemory_table_t),
&v->shmem_info.memtbl.phys,
&len,
@@ -8442,9 +8355,7 @@
int ret = 0;
size_t len;
- ret = msm_audio_ion_alloc("voc_cal",
- &(common.cal_mem_map_table.client),
- &(common.cal_mem_map_table.handle),
+ ret = msm_audio_ion_alloc(&(common.cal_mem_map_table.dma_buf),
sizeof(struct vss_imemory_table_t),
&common.cal_mem_map_table.phys,
&len,
@@ -8469,9 +8380,8 @@
int ret = 0;
size_t len;
- ret = msm_audio_ion_alloc("voc_rtac_cal",
- &(common.rtac_mem_map_table.client),
- &(common.rtac_mem_map_table.handle),
+ ret = msm_audio_ion_alloc(
+ &(common.rtac_mem_map_table.dma_buf),
sizeof(struct vss_imemory_table_t),
&common.rtac_mem_map_table.phys,
&len,
@@ -8536,7 +8446,7 @@
if (topology_idx == CVP_VOC_RX_TOPOLOGY_CAL) {
topology = VSS_IVOCPROC_TOPOLOGY_ID_RX_DEFAULT;
} else if (topology_idx == CVP_VOC_TX_TOPOLOGY_CAL) {
- topology = VSS_IVOCPROC_TOPOLOGY_ID_TX_SM_ECNS_V2;
+ topology = VSS_IVOCPROC_TOPOLOGY_ID_NONE;
} else {
pr_err("%s: cal index %x is invalid!\n",
__func__, topology_idx);
@@ -9181,8 +9091,7 @@
pr_debug("%s: Enter\n", __func__);
- if (common.source_tracking_sh_mem.sh_mem_block.client != NULL &&
- common.source_tracking_sh_mem.sh_mem_block.handle != NULL)
+ if (common.source_tracking_sh_mem.sh_mem_block.dma_buf != NULL)
ret = true;
else
ret = false;
@@ -9198,9 +9107,8 @@
pr_debug("%s: Enter\n", __func__);
- ret = msm_audio_ion_alloc("source_tracking_sh_mem_block",
- &(common.source_tracking_sh_mem.sh_mem_block.client),
- &(common.source_tracking_sh_mem.sh_mem_block.handle),
+ ret = msm_audio_ion_alloc(
+ &(common.source_tracking_sh_mem.sh_mem_block.dma_buf),
BUFFER_BLOCK_SIZE,
&(common.source_tracking_sh_mem.sh_mem_block.phys),
(size_t *)&(common.source_tracking_sh_mem.sh_mem_block.size),
@@ -9221,9 +9129,8 @@
(void *)(common.source_tracking_sh_mem.sh_mem_block.data),
(size_t)(common.source_tracking_sh_mem.sh_mem_block.size));
- ret = msm_audio_ion_alloc("source_tracking_sh_mem_table",
- &(common.source_tracking_sh_mem.sh_mem_table.client),
- &(common.source_tracking_sh_mem.sh_mem_table.handle),
+ ret = msm_audio_ion_alloc(
+ &(common.source_tracking_sh_mem.sh_mem_table.dma_buf),
sizeof(struct vss_imemory_table_t),
&(common.source_tracking_sh_mem.sh_mem_table.phys),
(size_t *)&(common.source_tracking_sh_mem.sh_mem_table.size),
@@ -9233,10 +9140,8 @@
__func__, ret);
ret = msm_audio_ion_free(
- common.source_tracking_sh_mem.sh_mem_block.client,
- common.source_tracking_sh_mem.sh_mem_block.handle);
- common.source_tracking_sh_mem.sh_mem_block.client = NULL;
- common.source_tracking_sh_mem.sh_mem_block.handle = NULL;
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf);
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL;
if (ret < 0)
pr_err("%s: Error:%d freeing memory\n", __func__, ret);
@@ -9312,13 +9217,11 @@
}
}
- if ((common.source_tracking_sh_mem.sh_mem_block.client == NULL) ||
- (common.source_tracking_sh_mem.sh_mem_block.handle == NULL))
+ if (common.source_tracking_sh_mem.sh_mem_block.dma_buf == NULL)
goto done;
ret = msm_audio_ion_free(
- common.source_tracking_sh_mem.sh_mem_block.client,
- common.source_tracking_sh_mem.sh_mem_block.handle);
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf);
if (ret < 0) {
pr_err("%s: Error:%d freeing memory\n", __func__, ret);
@@ -9328,8 +9231,7 @@
done:
common.source_tracking_sh_mem.mem_handle = 0;
- common.source_tracking_sh_mem.sh_mem_block.client = NULL;
- common.source_tracking_sh_mem.sh_mem_block.handle = NULL;
+ common.source_tracking_sh_mem.sh_mem_block.dma_buf = NULL;
pr_debug("%s: Exit, ret=%d\n", __func__, ret);
return ret;
@@ -9502,6 +9404,199 @@
}
EXPORT_SYMBOL(voc_get_source_tracking);
+static int voice_set_cvp_param(struct voice_data *v,
+ struct vss_icommon_mem_mapping_hdr *mem_hdr,
+ u32 *param_data, u32 param_size)
+{
+ struct vss_icommon_cmd_set_param *set_param = NULL;
+ uint32_t pkt_size = sizeof(struct vss_icommon_cmd_set_param);
+ void *apr_cvp;
+ int ret = 0;
+
+ apr_cvp = common.apr_q6_cvp;
+ if (!apr_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ if (param_data != NULL)
+ pkt_size += param_size;
+ set_param = kzalloc(pkt_size, GFP_KERNEL);
+ if (!set_param)
+ return -ENOMEM;
+
+ set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ set_param->apr_hdr.pkt_size =
+ APR_PKT_SIZE(APR_HDR_SIZE, pkt_size - APR_HDR_SIZE);
+ set_param->apr_hdr.src_svc = 0;
+ set_param->apr_hdr.src_domain = APR_DOMAIN_APPS;
+ set_param->apr_hdr.src_port = voice_get_idx_for_session(v->session_id);
+ set_param->apr_hdr.dest_svc = 0;
+ set_param->apr_hdr.dest_domain = APR_DOMAIN_ADSP;
+ set_param->apr_hdr.dest_port = voice_get_cvp_handle(v);
+ set_param->apr_hdr.token = VOC_SET_MEDIA_FORMAT_PARAM_TOKEN;
+ set_param->apr_hdr.opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_SET_PARAM_V3 :
+ VSS_ICOMMON_CMD_SET_PARAM_V2;
+
+ set_param->payload_size = param_size;
+
+ if (mem_hdr != NULL) {
+ set_param->mem_hdr = *mem_hdr;
+ } else if (param_data != NULL) {
+ memcpy(set_param->param_data, param_data, param_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ v->async_err = 0;
+ ret = apr_send_pkt(apr_cvp, (u32 *) set_param);
+ if (ret < 0) {
+ pr_err("%s: Failed to send apr packet, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+
+ ret = wait_event_timeout(v->cvp_wait,
+ v->cvp_state == CMD_STATUS_SUCCESS,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (v->async_err > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(v->async_err));
+ ret = adsp_err_get_lnx_err_code(v->async_err);
+ goto done;
+ }
+ ret = 0;
+
+done:
+ kfree(set_param);
+ return ret;
+}
+
+static int voice_pack_and_set_cvp_param(struct voice_data *v,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data)
+{
+ u8 *packed_data = NULL;
+ u32 total_size = 0;
+ int ret = 0;
+
+ total_size = sizeof(union param_hdrs) + param_hdr.param_size;
+ packed_data = kzalloc(total_size, GFP_KERNEL);
+ if (!packed_data)
+ return -ENOMEM;
+
+ ret = q6common_pack_pp_params(packed_data, ¶m_hdr, param_data,
+ &total_size);
+ if (ret) {
+ pr_err("%s: Failed to pack params, error %d", __func__, ret);
+ goto done;
+ }
+
+ ret = voice_set_cvp_param(v, NULL, (u32 *) packed_data, total_size);
+
+done:
+ kfree(packed_data);
+ return ret;
+}
+
+/*
+ * Out of band is not supported and there are currently no pre-packed cases,
+ * so pack and set in the same function. When needed, split up.
+ */
+static int voice_pack_and_set_cvs_ui_property(struct voice_data *v,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data)
+{
+ struct vss_icommon_cmd_set_ui_property *set_ui_property = NULL;
+ u32 total_size = 0;
+ bool iid_supported = q6common_is_instance_id_supported();
+ void *apr_cvs;
+ int ret = 0;
+
+ apr_cvs = common.apr_q6_cvs;
+ if (!apr_cvs) {
+ pr_err("%s: apr_cvs is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ total_size = sizeof(struct vss_icommon_cmd_set_ui_property) +
+ sizeof(union param_hdrs) + param_hdr.param_size;
+ set_ui_property = kzalloc(total_size, GFP_KERNEL);
+ if (!set_ui_property)
+ return -ENOMEM;
+
+ ret = q6common_pack_pp_params(set_ui_property->param_data, ¶m_hdr,
+ param_data, &total_size);
+ if (ret) {
+ pr_err("%s: Failed to pack params, error %d", __func__, ret);
+ goto done;
+ }
+
+ /*
+ * Pack the APR header after packing the data so we have the actual
+ * total size of the payload
+ */
+ set_ui_property->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ set_ui_property->apr_hdr.pkt_size =
+ APR_PKT_SIZE(APR_HDR_SIZE, total_size - APR_HDR_SIZE);
+ set_ui_property->apr_hdr.src_svc = 0;
+ set_ui_property->apr_hdr.src_domain = APR_DOMAIN_APPS;
+ set_ui_property->apr_hdr.src_port =
+ voice_get_idx_for_session(v->session_id);
+ set_ui_property->apr_hdr.dest_svc = 0;
+ set_ui_property->apr_hdr.dest_domain = APR_DOMAIN_ADSP;
+ set_ui_property->apr_hdr.dest_port = voice_get_cvs_handle(v);
+ set_ui_property->apr_hdr.token = 0;
+
+ set_ui_property->apr_hdr.opcode =
+ iid_supported ? VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 :
+ VSS_ICOMMON_CMD_SET_UI_PROPERTY;
+
+ v->cvs_state = CMD_STATUS_FAIL;
+ v->async_err = 0;
+ ret = apr_send_pkt(apr_cvs, (u32 *) set_ui_property);
+ if (ret < 0) {
+ pr_err("%s: Failed to send apr packet, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+
+ ret = wait_event_timeout(v->cvs_wait,
+ v->cvs_state == CMD_STATUS_SUCCESS,
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (v->async_err > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(v->async_err));
+ ret = adsp_err_get_lnx_err_code(v->async_err);
+ goto done;
+ }
+ ret = 0;
+done:
+ kfree(set_ui_property);
+ return ret;
+}
+
/**
* is_voc_initialized:
*
diff --git a/dsp/rtac.c b/dsp/rtac.c
index 43c69cc..d233635 100644
--- a/dsp/rtac.c
+++ b/dsp/rtac.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -27,6 +27,7 @@
#include <dsp/q6afe-v2.h>
#include <dsp/q6adm-v2.h>
#include <dsp/apr_audio-v2.h>
+#include <dsp/q6common.h>
#include <dsp/q6voice.h>
#include "adsp_err.h"
@@ -41,13 +42,13 @@
struct rtac_cal_block_data rtac_cal[MAX_RTAC_BLOCKS] = {
/* ADM_RTAC_CAL */
- {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} },
+ {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} },
/* ASM_RTAC_CAL */
- {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} },
+ {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} },
/* VOICE_RTAC_CAL */
- {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} },
+ {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} },
/* AFE_RTAC_CAL */
- {{RTAC_BUF_SIZE, 0, 0, 0}, {0, 0, 0} }
+ {{RTAC_BUF_SIZE, 0, 0}, {0, 0, 0} }
};
struct rtac_common_data {
@@ -103,14 +104,10 @@
uint32_t cmd_size;
uint32_t port_id;
union {
- struct rtac_afe_set {
- struct afe_port_cmd_set_param_v2 cmd;
- struct afe_port_param_data_v2 data;
- } rtac_afe_set;
- struct rtac_afe_get {
- struct afe_port_cmd_get_param_v2 cmd;
- struct afe_port_param_data_v2 data;
- } rtac_afe_get;
+ struct afe_rtac_user_data_set_v2 v2_set;
+ struct afe_rtac_user_data_set_v3 v3_set;
+ struct afe_rtac_user_data_get_v2 v2_get;
+ struct afe_rtac_user_data_get_v3 v3_get;
};
} __packed;
@@ -164,9 +161,7 @@
goto done;
}
- result = msm_audio_ion_alloc("rtac_client",
- &rtac_cal[cal_type].map_data.ion_client,
- &rtac_cal[cal_type].map_data.ion_handle,
+ result = msm_audio_ion_alloc(&rtac_cal[cal_type].map_data.dma_buf,
rtac_cal[cal_type].map_data.map_size,
&rtac_cal[cal_type].cal_data.paddr,
&len,
@@ -199,14 +194,13 @@
goto done;
}
- if (rtac_cal[cal_type].map_data.ion_client == NULL) {
+ if (rtac_cal[cal_type].map_data.dma_buf == NULL) {
pr_debug("%s: cal_type %d not allocated!\n",
__func__, cal_type);
goto done;
}
- result = msm_audio_ion_free(rtac_cal[cal_type].map_data.ion_client,
- rtac_cal[cal_type].map_data.ion_handle);
+ result = msm_audio_ion_free(rtac_cal[cal_type].map_data.dma_buf);
if (result < 0) {
pr_err("%s: ION free for RTAC failed! cal_type %d, paddr 0x%pK\n",
__func__, cal_type, &rtac_cal[cal_type].cal_data.paddr);
@@ -214,8 +208,7 @@
}
rtac_cal[cal_type].map_data.map_handle = 0;
- rtac_cal[cal_type].map_data.ion_client = NULL;
- rtac_cal[cal_type].map_data.ion_handle = NULL;
+ rtac_cal[cal_type].map_data.dma_buf = NULL;
rtac_cal[cal_type].cal_data.size = 0;
rtac_cal[cal_type].cal_data.kvaddr = 0;
rtac_cal[cal_type].cal_data.paddr = 0;
@@ -754,7 +747,7 @@
pr_debug("%s\n", __func__);
- if (rtac_cal[ADM_RTAC_CAL].map_data.ion_handle == NULL) {
+ if (rtac_cal[ADM_RTAC_CAL].map_data.dma_buf == NULL) {
result = rtac_allocate_cal_buffer(ADM_RTAC_CAL);
if (result < 0) {
pr_err("%s: allocate buffer failed!",
@@ -808,7 +801,9 @@
goto err;
}
- if (opcode == ADM_CMD_SET_PP_PARAMS_V5) {
+ switch (opcode) {
+ case ADM_CMD_SET_PP_PARAMS_V5:
+ case ADM_CMD_SET_PP_PARAMS_V6:
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -826,12 +821,15 @@
buf + 7 * sizeof(u32), data_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+
/* set payload size in packet */
rtac_adm_buffer[8] = data_size;
- } else {
+ break;
+ case ADM_CMD_GET_PP_PARAMS_V5:
+ case ADM_CMD_GET_PP_PARAMS_V6:
if (payload_size > MAX_PAYLOAD_SIZE) {
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
@@ -845,9 +843,14 @@
buf + 3 * sizeof(u32), payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
/* Pack header */
@@ -908,33 +911,39 @@
if (opcode == ADM_CMD_GET_PP_PARAMS_V5) {
bytes_returned = ((u32 *)rtac_cal[ADM_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
-
- if (bytes_returned > rtac_cal[ADM_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (bytes_returned > user_buf_size) {
- pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
- __func__, user_buf_size, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (copy_to_user(buf, (void *)
- rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user,size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ } else if (opcode == ADM_CMD_GET_PP_PARAMS_V6) {
+ bytes_returned =
+ ((u32 *) rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr)[3] +
+ 4 * sizeof(u32);
} else {
bytes_returned = data_size;
+ goto unlock;
}
+
+ if (bytes_returned > rtac_cal[ADM_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (bytes_returned > user_buf_size) {
+ pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
+ __func__, user_buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[ADM_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user,size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
+ }
+
+unlock:
mutex_unlock(&rtac_adm_apr_mutex);
done:
return bytes_returned;
@@ -983,7 +992,7 @@
pr_debug("%s\n", __func__);
- if (rtac_cal[ASM_RTAC_CAL].map_data.ion_handle == NULL) {
+ if (rtac_cal[ASM_RTAC_CAL].map_data.dma_buf == NULL) {
result = rtac_allocate_cal_buffer(ASM_RTAC_CAL);
if (result < 0) {
pr_err("%s: allocate buffer failed!",
@@ -1036,7 +1045,9 @@
goto err;
}
- if (opcode == ASM_STREAM_CMD_SET_PP_PARAMS_V2) {
+ switch (opcode) {
+ case ASM_STREAM_CMD_SET_PP_PARAMS_V2:
+ case ASM_STREAM_CMD_SET_PP_PARAMS_V3:
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -1054,13 +1065,14 @@
buf + 7 * sizeof(u32), data_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
/* set payload size in packet */
rtac_asm_buffer[8] = data_size;
-
- } else {
+ break;
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V2:
+ case ASM_STREAM_CMD_GET_PP_PARAMS_V3:
if (payload_size > MAX_PAYLOAD_SIZE) {
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
@@ -1074,9 +1086,15 @@
buf + 3 * sizeof(u32), payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
/* Pack header */
@@ -1139,33 +1157,39 @@
if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V2) {
bytes_returned = ((u32 *)rtac_cal[ASM_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
-
- if (bytes_returned > rtac_cal[ASM_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (bytes_returned > user_buf_size) {
- pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
- __func__, user_buf_size, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (copy_to_user(buf, (void *)
- rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user,size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ } else if (opcode == ASM_STREAM_CMD_GET_PP_PARAMS_V3) {
+ bytes_returned =
+ ((u32 *) rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr)[3] +
+ 4 * sizeof(u32);
} else {
bytes_returned = data_size;
+ goto unlock;
}
+
+ if (bytes_returned > rtac_cal[ASM_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (bytes_returned > user_buf_size) {
+ pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
+ __func__, user_buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[ASM_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user,size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
+ }
+
+unlock:
mutex_unlock(&rtac_asm_apr_mutex);
done:
return bytes_returned;
@@ -1222,17 +1246,22 @@
return 0;
}
-static int send_rtac_afe_apr(void *buf, uint32_t opcode)
+static int send_rtac_afe_apr(void __user *buf, uint32_t opcode)
{
int32_t result;
uint32_t bytes_returned = 0;
+ uint32_t payload_size = 0;
uint32_t port_index = 0;
+ uint32_t *afe_cmd = NULL;
uint32_t apr_msg_size = 0;
struct rtac_afe_user_data user_afe_buf;
+ struct mem_mapping_hdr *mem_hdr = NULL;
+ struct param_hdr_v1 *get_resp_v2;
+ struct param_hdr_v3 *get_resp_v3;
pr_debug("%s\n", __func__);
- if (rtac_cal[AFE_RTAC_CAL].map_data.ion_handle == NULL) {
+ if (rtac_cal[AFE_RTAC_CAL].map_data.dma_buf == NULL) {
result = rtac_allocate_cal_buffer(AFE_RTAC_CAL);
if (result < 0) {
pr_err("%s: allocate buffer failed! ret = %d\n",
@@ -1276,93 +1305,126 @@
result = -EINVAL;
goto err;
}
- if (opcode == AFE_PORT_CMD_SET_PARAM_V2) {
- struct afe_port_cmd_set_param_v2 *afe_set_apr_msg;
- /* set data size to actual out of band payload size */
- if (user_afe_buf.rtac_afe_set.cmd.payload_size >
- rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__,
- user_afe_buf.rtac_afe_set.cmd.payload_size);
+ afe_cmd =
+ (u32 *) rtac_afe_buffer + sizeof(struct apr_hdr) / sizeof(u32);
+
+ switch (opcode) {
+ case AFE_PORT_CMD_SET_PARAM_V2:
+ apr_msg_size = sizeof(struct afe_port_cmd_set_param_v2);
+ payload_size = user_afe_buf.v2_set.payload_size;
+ if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ payload_size);
result = -EINVAL;
goto err;
}
- /* Copy buffer to out-of-band payload */
- if (copy_from_user((void *)
- rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
- buf+offsetof(struct rtac_afe_user_data,
- rtac_afe_set.data),
- user_afe_buf.rtac_afe_set.cmd.payload_size)) {
+ /* Copy the command to the rtac buffer */
+ memcpy(afe_cmd, &user_afe_buf.v2_set,
+ sizeof(user_afe_buf.v2_set));
+
+ /* Copy the param data to the out-of-band location */
+ if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
+ (void __user *) buf +
+ offsetof(struct rtac_afe_user_data,
+ v2_set.param_hdr),
+ payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
+ result = -EFAULT;
+ goto err;
+ }
+ break;
+ case AFE_PORT_CMD_SET_PARAM_V3:
+ apr_msg_size = sizeof(struct afe_port_cmd_set_param_v3);
+ payload_size = user_afe_buf.v3_set.payload_size;
+ if (payload_size > rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ payload_size);
result = -EINVAL;
goto err;
}
- /* Copy AFE APR Message */
- afe_set_apr_msg = (struct afe_port_cmd_set_param_v2 *)
- ((u8 *)rtac_afe_buffer +
- sizeof(struct apr_hdr));
- if (copy_from_user((void *)
- afe_set_apr_msg,
- buf + offsetof(struct rtac_afe_user_data,
- rtac_afe_set.cmd),
- sizeof(struct afe_port_cmd_set_param_v2))) {
+ /* Copy the command to the rtac buffer */
+ memcpy(afe_cmd, &user_afe_buf.v3_set,
+ sizeof(user_afe_buf.v3_set));
+
+ /* Copy the param data to the out-of-band location */
+ if (copy_from_user(rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
+ (void __user *) buf +
+ offsetof(struct rtac_afe_user_data,
+ v3_get.param_hdr),
+ payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
-
- afe_set_apr_msg->payload_address_lsw =
- lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_set_apr_msg->payload_address_msw =
- msm_audio_populate_upper_32_bits(
- rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_set_apr_msg->mem_map_handle =
- rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
-
- apr_msg_size = sizeof(struct apr_hdr) +
- sizeof(struct afe_port_cmd_set_param_v2);
-
- } else {
- struct afe_port_cmd_get_param_v2 *afe_get_apr_msg;
+ break;
+ case AFE_PORT_CMD_GET_PARAM_V2:
+ apr_msg_size = sizeof(struct afe_port_cmd_get_param_v2);
if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) {
- pr_err("%s: Invalid payload size = %d\n",
- __func__, user_afe_buf.cmd_size);
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ user_afe_buf.cmd_size);
result = -EINVAL;
goto err;
}
- /* Copy buffer to in-band payload */
- afe_get_apr_msg = (struct afe_port_cmd_get_param_v2 *)
- ((u8 *) rtac_afe_buffer +
- sizeof(struct apr_hdr));
- if (copy_from_user((void *)afe_get_apr_msg,
- buf+offsetof(struct rtac_afe_user_data,
- rtac_afe_get.cmd),
- sizeof(struct afe_port_cmd_get_param_v2))) {
+ /* Copy the command and param data in-band */
+ if (copy_from_user(afe_cmd,
+ (void __user *) buf +
+ offsetof(struct rtac_afe_user_data,
+ v2_get),
+ user_afe_buf.cmd_size)) {
+ pr_err("%s: Could not copy payload from user buffer\n",
+ __func__);
+ result = -EFAULT;
+ goto err;
+ }
+ break;
+ case AFE_PORT_CMD_GET_PARAM_V3:
+ apr_msg_size = sizeof(struct afe_port_cmd_get_param_v3);
+
+ if (user_afe_buf.cmd_size > MAX_PAYLOAD_SIZE) {
+ pr_err("%s: Invalid payload size = %d\n", __func__,
+ user_afe_buf.cmd_size);
+ result = -EINVAL;
+ goto err;
+ }
+
+ /* Copy the command and param data in-band */
+ if (copy_from_user(afe_cmd,
+ (void __user *) buf +
+ offsetof(struct rtac_afe_user_data,
+ v3_get),
+ user_afe_buf.cmd_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
-
- afe_get_apr_msg->payload_address_lsw =
- lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_get_apr_msg->payload_address_msw =
- msm_audio_populate_upper_32_bits(
- rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
- afe_get_apr_msg->mem_map_handle =
- rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
- afe_get_apr_msg->payload_size -= sizeof(struct apr_hdr);
- apr_msg_size = sizeof(struct apr_hdr) +
- sizeof(struct afe_port_cmd_get_param_v2);
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
+ /*
+ * The memory header is in the same location in all commands. Therefore,
+ * it doesn't matter what command the buffer is cast into.
+ */
+ mem_hdr = &((struct afe_port_cmd_set_param_v3 *) rtac_afe_buffer)
+ ->mem_hdr;
+ mem_hdr->data_payload_addr_lsw =
+ lower_32_bits(rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
+ mem_hdr->data_payload_addr_msw = msm_audio_populate_upper_32_bits(
+ rtac_cal[AFE_RTAC_CAL].cal_data.paddr);
+ mem_hdr->mem_map_handle = rtac_cal[AFE_RTAC_CAL].map_data.map_handle;
+
+ /* Fill the APR header at the end so we have the correct message size */
fill_afe_apr_hdr((struct apr_hdr *) rtac_afe_buffer,
port_index, opcode, apr_msg_size);
@@ -1400,41 +1462,44 @@
}
if (opcode == AFE_PORT_CMD_GET_PARAM_V2) {
- struct afe_port_param_data_v2 *get_resp;
-
- get_resp = (struct afe_port_param_data_v2 *)
- rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr;
-
- bytes_returned = get_resp->param_size +
- sizeof(struct afe_port_param_data_v2);
-
- if (bytes_returned > rtac_cal[AFE_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (bytes_returned > user_afe_buf.buf_size) {
- pr_err("%s: user size = 0x%x, returned size = 0x%x\n",
- __func__, user_afe_buf.buf_size,
- bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (copy_to_user(buf, (void *)
- rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user,size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ get_resp_v2 = (struct param_hdr_v1 *) rtac_cal[AFE_RTAC_CAL]
+ .cal_data.kvaddr;
+ bytes_returned =
+ get_resp_v2->param_size + sizeof(struct param_hdr_v1);
+ } else if (opcode == AFE_PORT_CMD_GET_PARAM_V3) {
+ get_resp_v3 = (struct param_hdr_v3 *) rtac_cal[AFE_RTAC_CAL]
+ .cal_data.kvaddr;
+ bytes_returned =
+ get_resp_v3->param_size + sizeof(struct param_hdr_v3);
} else {
- bytes_returned = user_afe_buf.rtac_afe_set.cmd.payload_size;
+ bytes_returned = payload_size;
+ goto unlock;
}
+
+ if (bytes_returned > rtac_cal[AFE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (bytes_returned > user_afe_buf.buf_size) {
+ pr_err("%s: user size = 0x%x, returned size = 0x%x\n", __func__,
+ user_afe_buf.buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[AFE_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user,size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
+ }
+
+unlock:
mutex_unlock(&rtac_afe_apr_mutex);
done:
return bytes_returned;
@@ -1482,7 +1547,7 @@
pr_debug("%s\n", __func__);
- if (rtac_cal[VOICE_RTAC_CAL].map_data.ion_handle == NULL) {
+ if (rtac_cal[VOICE_RTAC_CAL].map_data.dma_buf == NULL) {
result = rtac_allocate_cal_buffer(VOICE_RTAC_CAL);
if (result < 0) {
pr_err("%s: allocate buffer failed!",
@@ -1537,7 +1602,9 @@
goto err;
}
- if (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) {
+ switch (opcode) {
+ case VSS_ICOMMON_CMD_SET_PARAM_V2:
+ case VSS_ICOMMON_CMD_SET_PARAM_V3:
/* set payload size to in-band payload */
/* set data size to actual out of band payload size */
data_size = payload_size - 4 * sizeof(u32);
@@ -1555,12 +1622,16 @@
buf + 7 * sizeof(u32), data_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
/* set payload size in packet */
rtac_voice_buffer[8] = data_size;
- } else {
+ /* set token for set param case */
+ voice_params.token = VOC_RTAC_SET_PARAM_TOKEN;
+ break;
+ case VSS_ICOMMON_CMD_GET_PARAM_V2:
+ case VSS_ICOMMON_CMD_GET_PARAM_V3:
if (payload_size > MAX_PAYLOAD_SIZE) {
pr_err("%s: Invalid payload size = %d\n",
__func__, payload_size);
@@ -1574,9 +1645,16 @@
buf + 3 * sizeof(u32), payload_size)) {
pr_err("%s: Could not copy payload from user buffer\n",
__func__);
- result = -EINVAL;
+ result = -EFAULT;
goto err;
}
+ /* set token for get param case */
+ voice_params.token = 0;
+ break;
+ default:
+ pr_err("%s: Invalid opcode %d\n", __func__, opcode);
+ result = -EINVAL;
+ goto err;
}
/* Pack header */
@@ -1590,18 +1668,14 @@
voice_params.dest_svc = 0;
voice_params.dest_domain = APR_DOMAIN_MODEM;
voice_params.dest_port = (u16)dest_port;
- voice_params.token = (opcode == VSS_ICOMMON_CMD_SET_PARAM_V2) ?
- VOC_RTAC_SET_PARAM_TOKEN :
- 0;
voice_params.opcode = opcode;
/* fill for out-of-band */
rtac_voice_buffer[5] = rtac_cal[VOICE_RTAC_CAL].map_data.map_handle;
rtac_voice_buffer[6] =
lower_32_bits(rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
- rtac_voice_buffer[7] =
- msm_audio_populate_upper_32_bits(
- rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
+ rtac_voice_buffer[7] = msm_audio_populate_upper_32_bits(
+ rtac_cal[VOICE_RTAC_CAL].cal_data.paddr);
memcpy(rtac_voice_buffer, &voice_params, sizeof(voice_params));
atomic_set(&rtac_voice_apr_data[mode].cmd_state, 1);
@@ -1640,33 +1714,39 @@
if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V2) {
bytes_returned = ((u32 *)rtac_cal[VOICE_RTAC_CAL].cal_data.
kvaddr)[2] + 3 * sizeof(u32);
-
- if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].
- map_data.map_size) {
- pr_err("%s: Invalid data size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (bytes_returned > user_buf_size) {
- pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
- __func__, user_buf_size, bytes_returned);
- result = -EINVAL;
- goto err;
- }
-
- if (copy_to_user(buf, (void *)
- rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
- bytes_returned)) {
- pr_err("%s: Could not copy buffer to user, size = %d\n",
- __func__, bytes_returned);
- result = -EINVAL;
- goto err;
- }
+ } else if (opcode == VSS_ICOMMON_CMD_GET_PARAM_V3) {
+ bytes_returned =
+ ((u32 *) rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr)[3] +
+ 4 * sizeof(u32);
} else {
bytes_returned = data_size;
+ goto unlock;
}
+
+ if (bytes_returned > rtac_cal[VOICE_RTAC_CAL].map_data.map_size) {
+ pr_err("%s: Invalid data size = %d\n", __func__,
+ bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (bytes_returned > user_buf_size) {
+ pr_err("%s: User buf not big enough, size = 0x%x, returned size = 0x%x\n",
+ __func__, user_buf_size, bytes_returned);
+ result = -EINVAL;
+ goto err;
+ }
+
+ if (copy_to_user((void __user *) buf,
+ rtac_cal[VOICE_RTAC_CAL].cal_data.kvaddr,
+ bytes_returned)) {
+ pr_err("%s: Could not copy buffer to user, size = %d\n",
+ __func__, bytes_returned);
+ result = -EFAULT;
+ goto err;
+ }
+
+unlock:
mutex_unlock(&rtac_voice_apr_mutex);
done:
return bytes_returned;
@@ -1686,8 +1766,8 @@
static long rtac_ioctl_shared(struct file *f,
unsigned int cmd, void *arg)
{
+ u32 opcode;
int result = 0;
-
if (!arg) {
pr_err("%s: No data sent to driver!\n", __func__);
result = -EFAULT;
@@ -1723,42 +1803,64 @@
}
case AUDIO_GET_RTAC_ADM_CAL:
- result = send_adm_apr((void *)arg, ADM_CMD_GET_PP_PARAMS_V5);
+ opcode = q6common_is_instance_id_supported() ?
+ ADM_CMD_GET_PP_PARAMS_V6 :
+ ADM_CMD_GET_PP_PARAMS_V5;
+ result = send_adm_apr((void *) arg, opcode);
break;
case AUDIO_SET_RTAC_ADM_CAL:
- result = send_adm_apr((void *)arg, ADM_CMD_SET_PP_PARAMS_V5);
+ opcode = q6common_is_instance_id_supported() ?
+ ADM_CMD_SET_PP_PARAMS_V6 :
+ ADM_CMD_SET_PP_PARAMS_V5;
+ result = send_adm_apr((void *) arg, opcode);
break;
case AUDIO_GET_RTAC_ASM_CAL:
- result = send_rtac_asm_apr((void *)arg,
- ASM_STREAM_CMD_GET_PP_PARAMS_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ ASM_STREAM_CMD_GET_PP_PARAMS_V3 :
+ ASM_STREAM_CMD_GET_PP_PARAMS_V2;
+ result = send_rtac_asm_apr((void *) arg, opcode);
break;
case AUDIO_SET_RTAC_ASM_CAL:
- result = send_rtac_asm_apr((void *)arg,
- ASM_STREAM_CMD_SET_PP_PARAMS_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ ASM_STREAM_CMD_SET_PP_PARAMS_V3 :
+ ASM_STREAM_CMD_SET_PP_PARAMS_V2;
+ result = send_rtac_asm_apr((void *) arg, opcode);
break;
case AUDIO_GET_RTAC_CVS_CAL:
- result = send_voice_apr(RTAC_CVS, (void *) arg,
- VSS_ICOMMON_CMD_GET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_GET_PARAM_V3 :
+ VSS_ICOMMON_CMD_GET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVS, (void *) arg, opcode);
break;
case AUDIO_SET_RTAC_CVS_CAL:
- result = send_voice_apr(RTAC_CVS, (void *) arg,
- VSS_ICOMMON_CMD_SET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_SET_PARAM_V3 :
+ VSS_ICOMMON_CMD_SET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVS, (void *) arg, opcode);
break;
case AUDIO_GET_RTAC_CVP_CAL:
- result = send_voice_apr(RTAC_CVP, (void *) arg,
- VSS_ICOMMON_CMD_GET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_GET_PARAM_V3 :
+ VSS_ICOMMON_CMD_GET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVP, (void *) arg, opcode);
break;
case AUDIO_SET_RTAC_CVP_CAL:
- result = send_voice_apr(RTAC_CVP, (void *) arg,
- VSS_ICOMMON_CMD_SET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ VSS_ICOMMON_CMD_SET_PARAM_V3 :
+ VSS_ICOMMON_CMD_SET_PARAM_V2;
+ result = send_voice_apr(RTAC_CVP, (void *) arg, opcode);
break;
case AUDIO_GET_RTAC_AFE_CAL:
- result = send_rtac_afe_apr((void *)arg,
- AFE_PORT_CMD_GET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ AFE_PORT_CMD_GET_PARAM_V3 :
+ AFE_PORT_CMD_GET_PARAM_V2;
+ result = send_rtac_afe_apr((void __user *) arg, opcode);
break;
case AUDIO_SET_RTAC_AFE_CAL:
- result = send_rtac_afe_apr((void *)arg,
- AFE_PORT_CMD_SET_PARAM_V2);
+ opcode = q6common_is_instance_id_supported() ?
+ AFE_PORT_CMD_SET_PARAM_V3 :
+ AFE_PORT_CMD_SET_PARAM_V2;
+ result = send_rtac_afe_apr((void __user *) arg, opcode);
break;
default:
pr_err("%s: Invalid IOCTL, command = %d!\n",
diff --git a/include/asoc/wcd9360-registers.h b/include/asoc/wcd9360-registers.h
new file mode 100644
index 0000000..bca9de3
--- /dev/null
+++ b/include/asoc/wcd9360-registers.h
@@ -0,0 +1,1158 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _WCD9360_REGISTERS_H
+#define _WCD9360_REGISTERS_H
+
+#define WCD9360_PAGE_SIZE 256
+#define WCD9360_NUM_PAGES 256
+
+enum {
+ WCD9360_PAGE_0 = 0,
+ WCD9360_PAGE_1,
+ WCD9360_PAGE_2,
+ WCD9360_PAGE_4 = 4,
+ WCD9360_PAGE_6 = 6,
+ WCD9360_PAGE_7,
+ WCD9360_PAGE_10 = 10,
+ WCD9360_PAGE_11,
+ WCD9360_PAGE_12,
+ WCD9360_PAGE_13,
+ WCD9360_PAGE_14,
+ WCD9360_PAGE_80,
+ WCD9360_PAGE_128,
+ WCD9360_PAGE_MAX,
+};
+
+enum {
+ WCD9360_WO = 0,
+ WCD9360_RO,
+ WCD9360_RW,
+};
+
+extern const u8 * const wcd9360_reg[WCD9360_PAGE_MAX];
+
+/* Page-0 Registers */
+#define WCD9360_PAGE0_PAGE_REGISTER (0x00000000)
+#define WCD9360_CODEC_RPM_CLK_BYPASS (0x00000001)
+#define WCD9360_CODEC_RPM_CLK_GATE (0x00000002)
+#define WCD9360_CODEC_RPM_CLK_MCLK_CFG (0x00000003)
+#define WCD9360_CODEC_RPM_CLK_MCLK2_CFG (0x00000004)
+#define WCD9360_CODEC_RPM_I2S_DSD_CLK_SEL (0x00000005)
+#define WCD9360_CODEC_RPM_RST_CTL (0x00000009)
+#define WCD9360_CODEC_RPM_PWR_CDC_DIG_HM_CTL (0x00000011)
+#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE0 (0x00000021)
+#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE1 (0x00000022)
+#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE2 (0x00000023)
+#define WCD9360_CHIP_TIER_CTRL_CHIP_ID_BYTE3 (0x00000024)
+#define WCD9360_CHIP_TIER_CTRL_EFUSE_CTL (0x00000025)
+#define WCD9360_CHIP_TIER_CTRL_EFUSE_TEST0 (0x00000026)
+#define WCD9360_CHIP_TIER_CTRL_EFUSE_TEST1 (0x00000027)
+#define WCD9360_CHIP_TIER_CTRL_EFUSE_STATUS (0x00000039)
+#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_NONNEGO (0x0000003A)
+#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_1 (0x0000003B)
+#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_2 (0x0000003C)
+#define WCD9360_CHIP_TIER_CTRL_I2C_SLAVE_ID_3 (0x0000003D)
+#define WCD9360_CHIP_TIER_CTRL_ANA_WAIT_STATE_CTL (0x0000003E)
+#define WCD9360_CHIP_TIER_CTRL_I2C_ACTIVE (0x00000040)
+#define WCD9360_CHIP_TIER_CTRL_ALT_FUNC_EN (0x00000041)
+#define WCD9360_CHIP_TIER_CTRL_GPIO_CTL_OE (0x00000042)
+#define WCD9360_CHIP_TIER_CTRL_GPIO_CTL_DATA (0x00000043)
+#define WCD9360_DATA_HUB_RX0_CFG (0x00000051)
+#define WCD9360_DATA_HUB_RX1_CFG (0x00000052)
+#define WCD9360_DATA_HUB_RX2_CFG (0x00000053)
+#define WCD9360_DATA_HUB_RX3_CFG (0x00000054)
+#define WCD9360_DATA_HUB_RX4_CFG (0x00000055)
+#define WCD9360_DATA_HUB_RX5_CFG (0x00000056)
+#define WCD9360_DATA_HUB_RX6_CFG (0x00000057)
+#define WCD9360_DATA_HUB_RX7_CFG (0x00000058)
+#define WCD9360_DATA_HUB_SB_TX0_INP_CFG (0x00000061)
+#define WCD9360_DATA_HUB_SB_TX1_INP_CFG (0x00000062)
+#define WCD9360_DATA_HUB_SB_TX2_INP_CFG (0x00000063)
+#define WCD9360_DATA_HUB_SB_TX3_INP_CFG (0x00000064)
+#define WCD9360_DATA_HUB_SB_TX4_INP_CFG (0x00000065)
+#define WCD9360_DATA_HUB_SB_TX5_INP_CFG (0x00000066)
+#define WCD9360_DATA_HUB_SB_TX6_INP_CFG (0x00000067)
+#define WCD9360_DATA_HUB_SB_TX7_INP_CFG (0x00000068)
+#define WCD9360_DATA_HUB_SB_TX8_INP_CFG (0x00000069)
+#define WCD9360_DATA_HUB_SB_TX9_INP_CFG (0x0000006A)
+#define WCD9360_DATA_HUB_SB_TX10_INP_CFG (0x0000006B)
+#define WCD9360_DATA_HUB_SB_TX11_INP_CFG (0x0000006C)
+#define WCD9360_DATA_HUB_SB_TX12_INP_CFG (0x0000006D)
+#define WCD9360_DATA_HUB_SB_TX13_INP_CFG (0x0000006E)
+#define WCD9360_DATA_HUB_SB_TX14_INP_CFG (0x0000006F)
+#define WCD9360_DATA_HUB_SB_TX15_INP_CFG (0x00000070)
+#define WCD9360_DATA_HUB_I2S_TX0_CFG (0x00000071)
+#define WCD9360_DATA_HUB_I2S_TX0_CFG2 (0x00000072)
+#define WCD9360_DATA_HUB_I2S_TX1_0_CFG (0x00000073)
+#define WCD9360_DATA_HUB_I2S_TX1_1_CFG (0x00000074)
+#define WCD9360_DATA_HUB_DATA_HUB_CFG (0x00000079)
+#define WCD9360_DATA_HUB_I2S_0_CTL (0x00000081)
+#define WCD9360_DATA_HUB_I2S_1_CTL (0x00000082)
+#define WCD9360_DATA_HUB_I2S_0_CTL2 (0x00000083)
+#define WCD9360_DATA_HUB_I2S_1_CTL2 (0x00000084)
+#define WCD9360_DATA_HUB_I2S_CLKSRC_CTL (0x00000085)
+#define WCD9360_DATA_HUB_I2S_COMMON_CTL (0x00000086)
+#define WCD9360_DATA_HUB_I2S_0_TDM_CTL (0x00000087)
+#define WCD9360_DATA_HUB_I2S_0_TDM_CTL2 (0x00000089)
+#define WCD9360_DATA_HUB_I2S_0_TDM_CH_RX (0x0000008A)
+#define WCD9360_DATA_HUB_I2S_0_TDM_CH_TX (0x0000008B)
+#define WCD9360_DATA_HUB_I2S_0_TDM_CFG (0x0000008C)
+#define WCD9360_DATA_HUB_I2S_0_TDM_STRETCH (0x0000008D)
+#define WCD9360_DATA_HUB_I2S_RESET_CTL (0x00000090)
+#define WCD9360_DMA_RDMA_CTL_0 (0x00000091)
+#define WCD9360_DMA_CH_2_3_CFG_RDMA_0 (0x00000092)
+#define WCD9360_DMA_CH_0_1_CFG_RDMA_0 (0x00000093)
+#define WCD9360_DMA_RDMA_CTL_1 (0x00000094)
+#define WCD9360_DMA_CH_2_3_CFG_RDMA_1 (0x00000095)
+#define WCD9360_DMA_CH_0_1_CFG_RDMA_1 (0x00000096)
+#define WCD9360_DMA_RDMA_CTL_2 (0x00000097)
+#define WCD9360_DMA_CH_2_3_CFG_RDMA_2 (0x00000098)
+#define WCD9360_DMA_CH_0_1_CFG_RDMA_2 (0x00000099)
+#define WCD9360_DMA_RDMA_CTL_3 (0x0000009A)
+#define WCD9360_DMA_CH_2_3_CFG_RDMA_3 (0x0000009B)
+#define WCD9360_DMA_CH_0_1_CFG_RDMA_3 (0x0000009C)
+#define WCD9360_DMA_RDMA_CTL_4 (0x0000009D)
+#define WCD9360_DMA_CH_2_3_CFG_RDMA_4 (0x0000009E)
+#define WCD9360_DMA_CH_0_1_CFG_RDMA_4 (0x0000009F)
+#define WCD9360_DMA_RDMA4_PRT_CFG (0x000000B1)
+#define WCD9360_DMA_RDMA_SBTX0_7_CFG (0x000000B9)
+#define WCD9360_DMA_RDMA_SBTX8_10_CFG (0x000000BA)
+#define WCD9360_DMA_WDMA_CTL_0 (0x000000C1)
+#define WCD9360_DMA_WDMA_CTL_1 (0x000000C6)
+#define WCD9360_DMA_WDMA_CTL_2 (0x000000CB)
+#define WCD9360_DMA_WDMA_CTL_3 (0x000000D0)
+#define WCD9360_DMA_WDMA_CTL_4 (0x000000D5)
+#define WCD9360_DMA_CH_4_5_CFG_WDMA_0 (0x000000C2)
+#define WCD9360_DMA_CH_4_5_CFG_WDMA_1 (0x000000C7)
+#define WCD9360_DMA_CH_4_5_CFG_WDMA_2 (0x000000CC)
+#define WCD9360_DMA_CH_4_5_CFG_WDMA_3 (0x000000D1)
+#define WCD9360_DMA_CH_4_5_CFG_WDMA_4 (0x000000D6)
+#define WCD9360_DMA_CH_2_3_CFG_WDMA_0 (0x000000C3)
+#define WCD9360_DMA_CH_2_3_CFG_WDMA_1 (0x000000C8)
+#define WCD9360_DMA_CH_2_3_CFG_WDMA_2 (0x000000CD)
+#define WCD9360_DMA_CH_2_3_CFG_WDMA_3 (0x000000D2)
+#define WCD9360_DMA_CH_2_3_CFG_WDMA_4 (0x000000D7)
+#define WCD9360_DMA_CH_0_1_CFG_WDMA_0 (0x000000C4)
+#define WCD9360_DMA_CH_0_1_CFG_WDMA_1 (0x000000C9)
+#define WCD9360_DMA_CH_0_1_CFG_WDMA_2 (0x000000CE)
+#define WCD9360_DMA_CH_0_1_CFG_WDMA_3 (0x000000D3)
+#define WCD9360_DMA_CH_0_1_CFG_WDMA_4 (0x000000D8)
+#define WCD9360_DMA_WDMA0_PRT_CFG (0x000000E1)
+#define WCD9360_DMA_WDMA3_PRT_CFG (0x000000E2)
+#define WCD9360_DMA_WDMA4_PRT0_3_CFG (0x000000E3)
+#define WCD9360_DMA_WDMA4_PRT4_7_CFG (0x000000E4)
+#define WCD9360_PAGE1_PAGE_REGISTER (0x00000100)
+#define WCD9360_CPE_FLL_USER_CTL_0 (0x00000101)
+#define WCD9360_CPE_FLL_USER_CTL_1 (0x00000102)
+#define WCD9360_CPE_FLL_USER_CTL_2 (0x00000103)
+#define WCD9360_CPE_FLL_USER_CTL_3 (0x00000104)
+#define WCD9360_CPE_FLL_USER_CTL_4 (0x00000105)
+#define WCD9360_CPE_FLL_USER_CTL_5 (0x00000106)
+#define WCD9360_CPE_FLL_USER_CTL_6 (0x00000107)
+#define WCD9360_CPE_FLL_USER_CTL_7 (0x00000108)
+#define WCD9360_CPE_FLL_USER_CTL_8 (0x00000109)
+#define WCD9360_CPE_FLL_USER_CTL_9 (0x0000010A)
+#define WCD9360_CPE_FLL_L_VAL_CTL_0 (0x0000010B)
+#define WCD9360_CPE_FLL_L_VAL_CTL_1 (0x0000010C)
+#define WCD9360_CPE_FLL_DSM_FRAC_CTL_0 (0x0000010D)
+#define WCD9360_CPE_FLL_DSM_FRAC_CTL_1 (0x0000010E)
+#define WCD9360_CPE_FLL_CONFIG_CTL_0 (0x0000010F)
+#define WCD9360_CPE_FLL_CONFIG_CTL_1 (0x00000110)
+#define WCD9360_CPE_FLL_CONFIG_CTL_2 (0x00000111)
+#define WCD9360_CPE_FLL_CONFIG_CTL_3 (0x00000112)
+#define WCD9360_CPE_FLL_CONFIG_CTL_4 (0x00000113)
+#define WCD9360_CPE_FLL_TEST_CTL_0 (0x00000114)
+#define WCD9360_CPE_FLL_TEST_CTL_1 (0x00000115)
+#define WCD9360_CPE_FLL_TEST_CTL_2 (0x00000116)
+#define WCD9360_CPE_FLL_TEST_CTL_3 (0x00000117)
+#define WCD9360_CPE_FLL_TEST_CTL_4 (0x00000118)
+#define WCD9360_CPE_FLL_TEST_CTL_5 (0x00000119)
+#define WCD9360_CPE_FLL_TEST_CTL_6 (0x0000011A)
+#define WCD9360_CPE_FLL_TEST_CTL_7 (0x0000011B)
+#define WCD9360_CPE_FLL_FREQ_CTL_0 (0x0000011C)
+#define WCD9360_CPE_FLL_FREQ_CTL_1 (0x0000011D)
+#define WCD9360_CPE_FLL_FREQ_CTL_2 (0x0000011E)
+#define WCD9360_CPE_FLL_FREQ_CTL_3 (0x0000011F)
+#define WCD9360_CPE_FLL_SSC_CTL_0 (0x00000120)
+#define WCD9360_CPE_FLL_SSC_CTL_1 (0x00000121)
+#define WCD9360_CPE_FLL_SSC_CTL_2 (0x00000122)
+#define WCD9360_CPE_FLL_SSC_CTL_3 (0x00000123)
+#define WCD9360_CPE_FLL_FLL_MODE (0x00000124)
+#define WCD9360_CPE_FLL_STATUS_0 (0x00000125)
+#define WCD9360_CPE_FLL_STATUS_1 (0x00000126)
+#define WCD9360_CPE_FLL_STATUS_2 (0x00000127)
+#define WCD9360_CPE_FLL_STATUS_3 (0x00000128)
+#define WCD9360_I2S_FLL_USER_CTL_0 (0x00000141)
+#define WCD9360_I2S_FLL_USER_CTL_1 (0x00000142)
+#define WCD9360_I2S_FLL_USER_CTL_2 (0x00000143)
+#define WCD9360_I2S_FLL_USER_CTL_3 (0x00000144)
+#define WCD9360_I2S_FLL_USER_CTL_4 (0x00000145)
+#define WCD9360_I2S_FLL_USER_CTL_5 (0x00000146)
+#define WCD9360_I2S_FLL_USER_CTL_6 (0x00000147)
+#define WCD9360_I2S_FLL_USER_CTL_7 (0x00000148)
+#define WCD9360_I2S_FLL_USER_CTL_8 (0x00000149)
+#define WCD9360_I2S_FLL_USER_CTL_9 (0x0000014A)
+#define WCD9360_I2S_FLL_L_VAL_CTL_0 (0x0000014B)
+#define WCD9360_I2S_FLL_L_VAL_CTL_1 (0x0000014C)
+#define WCD9360_I2S_FLL_DSM_FRAC_CTL_0 (0x0000014D)
+#define WCD9360_I2S_FLL_DSM_FRAC_CTL_1 (0x0000014E)
+#define WCD9360_I2S_FLL_CONFIG_CTL_0 (0x0000014F)
+#define WCD9360_I2S_FLL_CONFIG_CTL_1 (0x00000150)
+#define WCD9360_I2S_FLL_CONFIG_CTL_2 (0x00000151)
+#define WCD9360_I2S_FLL_CONFIG_CTL_3 (0x00000152)
+#define WCD9360_I2S_FLL_CONFIG_CTL_4 (0x00000153)
+#define WCD9360_I2S_FLL_TEST_CTL_0 (0x00000154)
+#define WCD9360_I2S_FLL_TEST_CTL_1 (0x00000155)
+#define WCD9360_I2S_FLL_TEST_CTL_2 (0x00000156)
+#define WCD9360_I2S_FLL_TEST_CTL_3 (0x00000157)
+#define WCD9360_I2S_FLL_TEST_CTL_4 (0x00000158)
+#define WCD9360_I2S_FLL_TEST_CTL_5 (0x00000159)
+#define WCD9360_I2S_FLL_TEST_CTL_6 (0x0000015A)
+#define WCD9360_I2S_FLL_TEST_CTL_7 (0x0000015B)
+#define WCD9360_I2S_FLL_FREQ_CTL_0 (0x0000015C)
+#define WCD9360_I2S_FLL_FREQ_CTL_1 (0x0000015D)
+#define WCD9360_I2S_FLL_FREQ_CTL_2 (0x0000015E)
+#define WCD9360_I2S_FLL_FREQ_CTL_3 (0x0000015F)
+#define WCD9360_I2S_FLL_SSC_CTL_0 (0x00000160)
+#define WCD9360_I2S_FLL_SSC_CTL_1 (0x00000161)
+#define WCD9360_I2S_FLL_SSC_CTL_2 (0x00000162)
+#define WCD9360_I2S_FLL_SSC_CTL_3 (0x00000163)
+#define WCD9360_I2S_FLL_FLL_MODE (0x00000164)
+#define WCD9360_I2S_FLL_STATUS_0 (0x00000165)
+#define WCD9360_I2S_FLL_STATUS_1 (0x00000166)
+#define WCD9360_I2S_FLL_STATUS_2 (0x00000167)
+#define WCD9360_I2S_FLL_STATUS_3 (0x00000168)
+#define WCD9360_PAGE2_PAGE_REGISTER (0x00000200)
+#define WCD9360_CPE_SS_CPE_CTL (0x00000201)
+#define WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_0 (0x00000202)
+#define WCD9360_CPE_SS_PWR_SYS_PSTATE_CTL_1 (0x00000203)
+#define WCD9360_CPE_SS_PWR_CPEFLL_CTL (0x00000204)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_0 (0x00000205)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_DEEPSLP_1 (0x00000206)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_0 (0x00000208)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_1 (0x00000209)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_2 (0x0000020A)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_3 (0x0000020B)
+#define WCD9360_CPE_SS_PWR_CPE_SYSMEM_SHUTDOWN_4 (0x0000020C)
+#define WCD9360_CPE_SS_PWR_CPE_DRAM1_SHUTDOWN (0x0000020E)
+#define WCD9360_CPE_SS_US_BUF_INT_PERIOD (0x00000212)
+#define WCD9360_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD (0x00000213)
+#define WCD9360_CPE_SS_SVA_CFG (0x00000214)
+#define WCD9360_CPE_SS_US_CFG (0x00000215)
+#define WCD9360_CPE_SS_MAD_CTL (0x00000216)
+#define WCD9360_CPE_SS_CPAR_CTL (0x00000217)
+#define WCD9360_CPE_SS_DMIC0_CTL (0x00000218)
+#define WCD9360_CPE_SS_DMIC1_CTL (0x00000219)
+#define WCD9360_CPE_SS_DMIC2_CTL (0x0000021A)
+#define WCD9360_CPE_SS_DMIC_CFG (0x0000021B)
+#define WCD9360_CPE_SS_CPAR_CFG (0x0000021C)
+#define WCD9360_CPE_SS_WDOG_CFG (0x0000021D)
+#define WCD9360_CPE_SS_BACKUP_INT (0x0000021E)
+#define WCD9360_CPE_SS_STATUS (0x0000021F)
+#define WCD9360_CPE_SS_CPE_OCD_CFG (0x00000220)
+#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_0A (0x00000221)
+#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_0B (0x00000222)
+#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_1A (0x00000223)
+#define WCD9360_CPE_SS_SS_ERROR_INT_MASK_1B (0x00000224)
+#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0A (0x00000225)
+#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_0B (0x00000226)
+#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1A (0x00000227)
+#define WCD9360_CPE_SS_SS_ERROR_INT_STATUS_1B (0x00000228)
+#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0A (0x00000229)
+#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_0B (0x0000022A)
+#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1A (0x0000022B)
+#define WCD9360_CPE_SS_SS_ERROR_INT_CLEAR_1B (0x0000022C)
+#define WCD9360_CPE_SS_DMIC3_CTL (0x00000231)
+#define WCD9360_CPE_SS_WDOG_RESET (0x00000239)
+#define WCD9360_CPE_SS_LPASS_MCLK_PRG (0x00000240)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_0 (0x00000241)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_1 (0x00000242)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_2 (0x00000243)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_3 (0x00000244)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_4 (0x00000245)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_5 (0x00000246)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_6 (0x00000247)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_7 (0x00000248)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_8 (0x00000249)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_9 (0x0000024A)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_10 (0x0000024B)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_11 (0x0000024C)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_12 (0x0000024D)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_13 (0x0000024E)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_14 (0x0000024F)
+#define WCD9360_CPE_SS_LPASS_IPC_IN_15 (0x00000250)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_0 (0x00000251)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_1 (0x00000252)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_2 (0x00000253)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_3 (0x00000254)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_4 (0x00000255)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_5 (0x00000256)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_6 (0x00000257)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_7 (0x00000258)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_8 (0x00000259)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_9 (0x0000025A)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_10 (0x0000025B)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_11 (0x0000025C)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_12 (0x0000025D)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_13 (0x0000025E)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_14 (0x0000025F)
+#define WCD9360_CPE_SS_LPASS_IPC_OUT_15 (0x00000260)
+#define WCD9360_CPE_SS_LPASS_ARB_CTL (0x00000261)
+#define WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_0 (0x00000271)
+#define WCD9360_CPE_SS_MEM_DEEPSLEEP_RD_1 (0x00000272)
+#define WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_0 (0x00000273)
+#define WCD9360_CPE_SS_MEM_DEEPSLEEP_BYPASS_1 (0x00000274)
+#define WCD9360_SOC_MAD_MAIN_CTL_1 (0x00000281)
+#define WCD9360_SOC_MAD_MAIN_CTL_2 (0x00000282)
+#define WCD9360_SOC_MAD_AUDIO_CTL_1 (0x00000283)
+#define WCD9360_SOC_MAD_AUDIO_CTL_2 (0x00000284)
+#define WCD9360_SOC_MAD_AUDIO_CTL_3 (0x00000285)
+#define WCD9360_SOC_MAD_AUDIO_CTL_4 (0x00000286)
+#define WCD9360_SOC_MAD_AUDIO_CTL_5 (0x00000287)
+#define WCD9360_SOC_MAD_AUDIO_CTL_6 (0x00000288)
+#define WCD9360_SOC_MAD_AUDIO_CTL_7 (0x00000289)
+#define WCD9360_SOC_MAD_AUDIO_CTL_8 (0x0000028A)
+#define WCD9360_SOC_MAD_AUDIO_IIR_CTL_PTR (0x0000028B)
+#define WCD9360_SOC_MAD_AUDIO_IIR_CTL_VAL (0x0000028C)
+#define WCD9360_SOC_MAD_ULTR_CTL_1 (0x0000028D)
+#define WCD9360_SOC_MAD_ULTR_CTL_2 (0x0000028E)
+#define WCD9360_SOC_MAD_ULTR_CTL_3 (0x0000028F)
+#define WCD9360_SOC_MAD_ULTR_CTL_4 (0x00000290)
+#define WCD9360_SOC_MAD_ULTR_CTL_5 (0x00000291)
+#define WCD9360_SOC_MAD_ULTR_CTL_6 (0x00000292)
+#define WCD9360_SOC_MAD_ULTR_CTL_7 (0x00000293)
+#define WCD9360_SOC_MAD_BEACON_CTL_1 (0x00000294)
+#define WCD9360_SOC_MAD_BEACON_CTL_2 (0x00000295)
+#define WCD9360_SOC_MAD_BEACON_CTL_3 (0x00000296)
+#define WCD9360_SOC_MAD_BEACON_CTL_4 (0x00000297)
+#define WCD9360_SOC_MAD_BEACON_CTL_5 (0x00000298)
+#define WCD9360_SOC_MAD_BEACON_CTL_6 (0x00000299)
+#define WCD9360_SOC_MAD_BEACON_CTL_7 (0x0000029A)
+#define WCD9360_SOC_MAD_BEACON_CTL_8 (0x0000029B)
+#define WCD9360_SOC_MAD_BEACON_IIR_CTL_PTR (0x0000029C)
+#define WCD9360_SOC_MAD_BEACON_IIR_CTL_VAL (0x0000029D)
+#define WCD9360_SOC_MAD_INP_SEL (0x0000029E)
+#define WCD9360_SOC_MAD_MAD2_INP_SEL (0x0000029F)
+#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_CTRL (0x000002B1)
+#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_STATUS (0x000002B2)
+#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_FS (0x000002B3)
+#define WCD9360_SWR_SAMPLE_PACK_SWR_SAMPLE_PACK_IN_SEL (0x000002B4)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT0 (0x000002C1)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT1 (0x000002C2)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT2 (0x000002C3)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT3 (0x000002C4)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT4 (0x000002C5)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT5 (0x000002C6)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT6 (0x000002C7)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT7 (0x000002C8)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT8 (0x000002C9)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT9 (0x000002CA)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT10 (0x000002CB)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT11 (0x000002CC)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT12 (0x000002CD)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT13 (0x000002CE)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT14 (0x000002CF)
+#define WCD9360_EFUSE_VALUE_EFUSE_VAL_OUT15 (0x000002D0)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT0 (0x000002D1)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT1 (0x000002D2)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT2 (0x000002D3)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT3 (0x000002D4)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT4 (0x000002D5)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT5 (0x000002D6)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT6 (0x000002D7)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT7 (0x000002D8)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT8 (0x000002D9)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT9 (0x000002DA)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT10 (0x000002DB)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT11 (0x000002DC)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT12 (0x000002DD)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT13 (0x000002DE)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT14 (0x000002DF)
+#define WCD9360_EFUSE_VALUE_EFUSE2_VAL_OUT15 (0x000002E0)
+#define WCD9360_PAGE4_PAGE_REGISTER (0x00000400)
+#define WCD9360_INTR_CFG (0x00000401)
+#define WCD9360_INTR_CLR_COMMIT (0x00000402)
+#define WCD9360_INTR_PIN1_MASK0 (0x00000409)
+#define WCD9360_INTR_PIN1_MASK1 (0x0000040A)
+#define WCD9360_INTR_PIN1_MASK2 (0x0000040B)
+#define WCD9360_INTR_PIN1_MASK3 (0x0000040C)
+#define WCD9360_INTR_PIN1_STATUS0 (0x00000411)
+#define WCD9360_INTR_PIN1_STATUS1 (0x00000412)
+#define WCD9360_INTR_PIN1_STATUS2 (0x00000413)
+#define WCD9360_INTR_PIN1_STATUS3 (0x00000414)
+#define WCD9360_INTR_PIN1_CLEAR0 (0x00000419)
+#define WCD9360_INTR_PIN1_CLEAR1 (0x0000041A)
+#define WCD9360_INTR_PIN1_CLEAR2 (0x0000041B)
+#define WCD9360_INTR_PIN1_CLEAR3 (0x0000041C)
+#define WCD9360_INTR_PIN2_MASK3 (0x00000424)
+#define WCD9360_INTR_PIN2_STATUS3 (0x0000042C)
+#define WCD9360_INTR_PIN2_CLEAR3 (0x00000434)
+#define WCD9360_INTR_CPESS_SUMRY_MASK2 (0x0000043B)
+#define WCD9360_INTR_CPESS_SUMRY_MASK3 (0x0000043C)
+#define WCD9360_INTR_CPESS_SUMRY_STATUS2 (0x00000443)
+#define WCD9360_INTR_CPESS_SUMRY_STATUS3 (0x00000444)
+#define WCD9360_INTR_CPESS_SUMRY_CLEAR2 (0x0000044B)
+#define WCD9360_INTR_CPESS_SUMRY_CLEAR3 (0x0000044C)
+#define WCD9360_INTR_LEVEL0 (0x00000461)
+#define WCD9360_INTR_LEVEL1 (0x00000462)
+#define WCD9360_INTR_LEVEL2 (0x00000463)
+#define WCD9360_INTR_LEVEL3 (0x00000464)
+#define WCD9360_INTR_BYPASS0 (0x00000469)
+#define WCD9360_INTR_BYPASS1 (0x0000046A)
+#define WCD9360_INTR_BYPASS2 (0x0000046B)
+#define WCD9360_INTR_BYPASS3 (0x0000046C)
+#define WCD9360_INTR_SET0 (0x00000471)
+#define WCD9360_INTR_SET1 (0x00000472)
+#define WCD9360_INTR_SET2 (0x00000473)
+#define WCD9360_INTR_SET3 (0x00000474)
+#define WCD9360_INTR_CODEC_MISC_MASK (0x000004B1)
+#define WCD9360_INTR_CODEC_MISC_STATUS (0x000004B2)
+#define WCD9360_INTR_CODEC_MISC_CLEAR (0x000004B3)
+#define WCD9360_ANA_PAGE_REGISTER (0x00000600)
+#define WCD9360_ANA_BIAS (0x00000601)
+#define WCD9360_ANA_AMIC_INPUT_SWITCH_CTL (0x00000602)
+#define WCD9360_ANA_RCO (0x00000603)
+#define WCD9360_ANA_BUCK_CTL (0x00000606)
+#define WCD9360_ANA_BUCK_STATUS (0x00000607)
+#define WCD9360_ANA_EAR (0x0000060A)
+#define WCD9360_ANA_MAD_SETUP (0x0000060D)
+#define WCD9360_ANA_AMIC1 (0x0000060E)
+#define WCD9360_ANA_AMIC2 (0x0000060F)
+#define WCD9360_ANA_AMIC3 (0x00000610)
+#define WCD9360_ANA_AMIC4 (0x00000611)
+#define WCD9360_ANA_MICB1 (0x00000622)
+#define WCD9360_ANA_MICB2 (0x00000623)
+#define WCD9360_ANA_MICB3 (0x00000625)
+#define WCD9360_ANA_MICB4 (0x00000626)
+#define WCD9360_BIAS_CTL (0x00000628)
+#define WCD9360_BIAS_VBG_FINE_ADJ (0x00000629)
+#define WCD9360_RCO_CTRL_1 (0x0000062E)
+#define WCD9360_RCO_CTRL_2 (0x0000062F)
+#define WCD9360_RCO_CAL (0x00000630)
+#define WCD9360_RCO_CAL_1 (0x00000631)
+#define WCD9360_RCO_CAL_2 (0x00000632)
+#define WCD9360_RCO_TEST_CTRL (0x00000633)
+#define WCD9360_RCO_CAL_OUT_1 (0x00000634)
+#define WCD9360_RCO_CAL_OUT_2 (0x00000635)
+#define WCD9360_RCO_CAL_OUT_3 (0x00000636)
+#define WCD9360_RCO_CAL_OUT_4 (0x00000637)
+#define WCD9360_RCO_CAL_OUT_5 (0x00000638)
+#define WCD9360_SIDO_MODE_1 (0x0000063A)
+#define WCD9360_SIDO_MODE_2 (0x0000063B)
+#define WCD9360_SIDO_MODE_3 (0x0000063C)
+#define WCD9360_SIDO_MODE_4 (0x0000063D)
+#define WCD9360_SIDO_VCL_1 (0x0000063E)
+#define WCD9360_SIDO_VCL_2 (0x0000063F)
+#define WCD9360_SIDO_VCL_3 (0x00000640)
+#define WCD9360_SIDO_CCL_1 (0x00000641)
+#define WCD9360_SIDO_CCL_2 (0x00000642)
+#define WCD9360_SIDO_CCL_3 (0x00000643)
+#define WCD9360_SIDO_CCL_4 (0x00000644)
+#define WCD9360_SIDO_CCL_5 (0x00000645)
+#define WCD9360_SIDO_CCL_6 (0x00000646)
+#define WCD9360_SIDO_CCL_7 (0x00000647)
+#define WCD9360_SIDO_CCL_8 (0x00000648)
+#define WCD9360_SIDO_CCL_9 (0x00000649)
+#define WCD9360_SIDO_CCL_10 (0x0000064A)
+#define WCD9360_SIDO_FILTER_1 (0x0000064B)
+#define WCD9360_SIDO_FILTER_2 (0x0000064C)
+#define WCD9360_SIDO_DRIVER_1 (0x0000064D)
+#define WCD9360_SIDO_DRIVER_2 (0x0000064E)
+#define WCD9360_SIDO_DRIVER_3 (0x0000064F)
+#define WCD9360_SIDO_CAL_CODE_EXT_1 (0x00000650)
+#define WCD9360_SIDO_CAL_CODE_EXT_2 (0x00000651)
+#define WCD9360_SIDO_CAL_CODE_OUT_1 (0x00000652)
+#define WCD9360_SIDO_CAL_CODE_OUT_2 (0x00000653)
+#define WCD9360_SIDO_TEST_1 (0x00000654)
+#define WCD9360_SIDO_TEST_2 (0x00000655)
+#define WCD9360_LDOH_MODE (0x00000667)
+#define WCD9360_LDOH_BIAS (0x00000668)
+#define WCD9360_LDOH_STB_LOADS (0x00000669)
+#define WCD9360_LDOH_SLOWRAMP (0x0000066A)
+#define WCD9360_MICB1_TEST_CTL_1 (0x0000066B)
+#define WCD9360_MICB1_TEST_CTL_2 (0x0000066C)
+#define WCD9360_MICB1_TEST_CTL_3 (0x0000066D)
+#define WCD9360_MICB2_TEST_CTL_1 (0x0000066E)
+#define WCD9360_MICB2_TEST_CTL_2 (0x0000066F)
+#define WCD9360_MICB2_TEST_CTL_3 (0x00000670)
+#define WCD9360_MICB3_TEST_CTL_1 (0x00000671)
+#define WCD9360_MICB3_TEST_CTL_2 (0x00000672)
+#define WCD9360_MICB3_TEST_CTL_3 (0x00000673)
+#define WCD9360_MICB4_TEST_CTL_1 (0x00000674)
+#define WCD9360_MICB4_TEST_CTL_2 (0x00000675)
+#define WCD9360_MICB4_TEST_CTL_3 (0x00000676)
+#define WCD9360_TX_COM_ADC_VCM (0x00000677)
+#define WCD9360_TX_COM_BIAS_ATEST (0x00000678)
+#define WCD9360_TX_COM_ADC_INT1_IB (0x00000679)
+#define WCD9360_TX_COM_ADC_INT2_IB (0x0000067A)
+#define WCD9360_TX_COM_TXFE_DIV_CTL (0x0000067B)
+#define WCD9360_TX_COM_TXFE_DIV_START (0x0000067C)
+#define WCD9360_TX_COM_TXFE_DIV_STOP_9P6M (0x0000067D)
+#define WCD9360_TX_COM_TXFE_DIV_STOP_12P288M (0x0000067E)
+#define WCD9360_TX_1_2_TEST_EN (0x0000067F)
+#define WCD9360_TX_1_2_ADC_IB (0x00000680)
+#define WCD9360_TX_1_2_ATEST_REFCTL (0x00000681)
+#define WCD9360_TX_1_2_TEST_CTL (0x00000682)
+#define WCD9360_TX_1_2_TEST_BLK_EN (0x00000683)
+#define WCD9360_TX_1_2_TXFE_CLKDIV (0x00000684)
+#define WCD9360_TX_1_2_SAR1_ERR (0x00000685)
+#define WCD9360_TX_1_2_SAR2_ERR (0x00000686)
+#define WCD9360_TX_3_4_TEST_EN (0x00000687)
+#define WCD9360_TX_3_4_ADC_IB (0x00000688)
+#define WCD9360_TX_3_4_ATEST_REFCTL (0x00000689)
+#define WCD9360_TX_3_4_TEST_CTL (0x0000068A)
+#define WCD9360_TX_3_4_TEST_BLK_EN (0x0000068B)
+#define WCD9360_TX_3_4_TXFE_CLKDIV (0x0000068C)
+#define WCD9360_TX_3_4_SAR1_ERR (0x0000068D)
+#define WCD9360_TX_3_4_SAR2_ERR (0x0000068E)
+#define WCD9360_RX_RX_EAR_BIAS_CON_1 (0x000006B3)
+#define WCD9360_RX_RX_EAR_BIAS_CON_2 (0x000006B4)
+#define WCD9360_RX_RX_AUX_BIAS_CON_1 (0x000006B5)
+#define WCD9360_RX_RX_AUX_BIAS_CON_2 (0x000006B6)
+#define WCD9360_RX_RX_BIAS_ATEST (0x000006B7)
+#define WCD9360_RX_RXTOP_RESERVED (0x000006B8)
+#define WCD9360_EAR_EAR_EN_REG (0x000006E1)
+#define WCD9360_EAR_EAR_PA_CON (0x000006E2)
+#define WCD9360_EAR_EAR_SP_CON (0x000006E3)
+#define WCD9360_EAR_EAR_DAC_CON (0x000006E4)
+#define WCD9360_EAR_EAR_CNP_FSM_CON (0x000006E5)
+#define WCD9360_EAR_DAC_CTL_TEST (0x000006E6)
+#define WCD9360_EAR_STATUS_REG (0x000006E7)
+#define WCD9360_EAR_EAR_COMPANDER_CON (0x000006E8)
+#define WCD9360_ANA_NEW_PAGE_REGISTER (0x00000700)
+#define WCD9360_CLK_SYS_PLL_ENABLES (0x0000070E)
+#define WCD9360_CLK_SYS_PLL_PRESET (0x0000070F)
+#define WCD9360_CLK_SYS_PLL_STATUS (0x00000710)
+#define WCD9360_CLK_SYS_MCLK_PRG (0x00000711)
+#define WCD9360_CLK_SYS_MCLK2_PRG1 (0x00000712)
+#define WCD9360_CLK_SYS_MCLK_MISC (0x00000713)
+#define WCD9360_SIDO_NEW_VOUT_A_STARTUP (0x0000071B)
+#define WCD9360_SIDO_NEW_VOUT_D_STARTUP (0x0000071C)
+#define WCD9360_SIDO_NEW_VOUT_D_FREQ1 (0x0000071D)
+#define WCD9360_SIDO_NEW_VOUT_D_FREQ2 (0x0000071E)
+#define WCD9360_AUX_ANA_EAR (0x00000728)
+#define WCD9360_LDORXTX_LDORXTX (0x00000729)
+#define WCD9360_DIE_CRACK_CTL (0x0000072A)
+#define WCD9360_DIE_CRACK_OUT (0x0000072B)
+#define WCD9360_LOOP_BACK_EN (0x0000072C)
+#define WCD9360_CLK_SYS_INT_POST_DIV_REG0 (0x0000076C)
+#define WCD9360_CLK_SYS_INT_POST_DIV_REG1 (0x0000076D)
+#define WCD9360_CLK_SYS_INT_REF_DIV_REG0 (0x0000076E)
+#define WCD9360_CLK_SYS_INT_REF_DIV_REG1 (0x0000076F)
+#define WCD9360_CLK_SYS_INT_FILTER_REG0 (0x00000770)
+#define WCD9360_CLK_SYS_INT_FILTER_REG1 (0x00000771)
+#define WCD9360_CLK_SYS_INT_PLL_L_VAL (0x00000772)
+#define WCD9360_CLK_SYS_INT_PLL_M_VAL (0x00000773)
+#define WCD9360_CLK_SYS_INT_PLL_N_VAL (0x00000774)
+#define WCD9360_CLK_SYS_INT_TEST_REG0 (0x00000775)
+#define WCD9360_CLK_SYS_INT_PFD_CP_DSM_PROG (0x00000776)
+#define WCD9360_CLK_SYS_INT_VCO_PROG (0x00000777)
+#define WCD9360_CLK_SYS_INT_TEST_REG1 (0x00000778)
+#define WCD9360_CLK_SYS_INT_LDO_LOCK_CFG (0x00000779)
+#define WCD9360_CLK_SYS_INT_DIG_LOCK_DET_CFG (0x0000077A)
+#define WCD9360_CLK_SYS_INT_CLK_TEST1 (0x0000077B)
+#define WCD9360_CLK_SYS_INT_CLK_TEST2 (0x0000077C)
+#define WCD9360_CLK_SYS_INT_CLK_TEST3 (0x0000077D)
+#define WCD9360_SIDO_NEW_INT_RAMP_STATUS (0x00000796)
+#define WCD9360_SIDO_NEW_INT_SPARE_1 (0x00000797)
+#define WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_A (0x00000798)
+#define WCD9360_SIDO_NEW_INT_DEBUG_VOUT_SETTING_D (0x00000799)
+#define WCD9360_SIDO_NEW_INT_RAMP_INC_WAIT (0x0000079A)
+#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_CTL (0x0000079B)
+#define WCD9360_SIDO_NEW_INT_RAMP_IBLEED_CTL (0x0000079C)
+#define WCD9360_SIDO_NEW_INT_DEBUG_CPROVR_TEST (0x0000079D)
+#define WCD9360_SIDO_NEW_INT_RAMP_CTL_A (0x0000079E)
+#define WCD9360_SIDO_NEW_INT_RAMP_CTL_D (0x0000079F)
+#define WCD9360_SIDO_NEW_INT_RAMP_TIMEOUT_PERIOD (0x000007A0)
+#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING1 (0x000007A1)
+#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING2 (0x000007A2)
+#define WCD9360_SIDO_NEW_INT_DYNAMIC_IPEAK_SETTING3 (0x000007A3)
+#define WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL1 (0x000007A4)
+#define WCD9360_SIDO_NEW_INT_HIGH_ACCU_MODE_SEL2 (0x000007A5)
+#define WCD9360_EAR_INT_NEW_EAR_CHOPPER_CON (0x000007B7)
+#define WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON1 (0x000007B8)
+#define WCD9360_EAR_INT_NEW_EAR_VCM_GEN_CON2 (0x000007B9)
+#define WCD9360_EAR_INT_NEW_EAR_DYNAMIC_BIAS (0x000007BA)
+#define WCD9360_AUX_INT_AUX_EN_REG (0x000007BD)
+#define WCD9360_AUX_INT_AUX_PA_CON (0x000007BE)
+#define WCD9360_AUX_INT_AUX_SP_CON (0x000007BF)
+#define WCD9360_AUX_INT_AUX_DAC_CON (0x000007C0)
+#define WCD9360_AUX_INT_AUX_CNP_FSM_CON (0x000007C1)
+#define WCD9360_AUX_INT_AUX_TEST (0x000007C2)
+#define WCD9360_AUX_INT_STATUS_REG (0x000007C3)
+#define WCD9360_AUX_INT_AUX_MISC (0x000007C4)
+#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL1 (0x000007C5)
+#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL2 (0x000007C6)
+#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL3 (0x000007C7)
+#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL4 (0x000007C8)
+#define WCD9360_LDORXTX_INT_ANA_LDORXTX_CTRL5 (0x000007C9)
+#define WCD9360_LDORXTX_INT_ANA_LDORXTX_STATUS (0x000007CA)
+#define WCD9360_DIE_CRACK_INT_INT1 (0x000007CC)
+#define WCD9360_DIE_CRACK_INT_INT2 (0x000007CD)
+#define WCD9360_LOOP_BACK_INT_SPARE (0x000007CE)
+#define WCD9360_PAGE10_PAGE_REGISTER (0x00000A00)
+#define WCD9360_CDC_ANC0_CLK_RESET_CTL (0x00000A01)
+#define WCD9360_CDC_ANC0_MODE_1_CTL (0x00000A02)
+#define WCD9360_CDC_ANC0_MODE_2_CTL (0x00000A03)
+#define WCD9360_CDC_ANC0_FF_SHIFT (0x00000A04)
+#define WCD9360_CDC_ANC0_FB_SHIFT (0x00000A05)
+#define WCD9360_CDC_ANC0_LPF_FF_A_CTL (0x00000A06)
+#define WCD9360_CDC_ANC0_LPF_FF_B_CTL (0x00000A07)
+#define WCD9360_CDC_ANC0_LPF_FB_CTL (0x00000A08)
+#define WCD9360_CDC_ANC0_SMLPF_CTL (0x00000A09)
+#define WCD9360_CDC_ANC0_DCFLT_SHIFT_CTL (0x00000A0A)
+#define WCD9360_CDC_ANC0_IIR_ADAPT_CTL (0x00000A0B)
+#define WCD9360_CDC_ANC0_IIR_COEFF_1_CTL (0x00000A0C)
+#define WCD9360_CDC_ANC0_IIR_COEFF_2_CTL (0x00000A0D)
+#define WCD9360_CDC_ANC0_FF_A_GAIN_CTL (0x00000A0E)
+#define WCD9360_CDC_ANC0_FF_B_GAIN_CTL (0x00000A0F)
+#define WCD9360_CDC_ANC0_FB_GAIN_CTL (0x00000A10)
+#define WCD9360_CDC_TX0_TX_PATH_CTL (0x00000A31)
+#define WCD9360_CDC_TX0_TX_PATH_CFG0 (0x00000A32)
+#define WCD9360_CDC_TX0_TX_PATH_CFG1 (0x00000A33)
+#define WCD9360_CDC_TX0_TX_VOL_CTL (0x00000A34)
+#define WCD9360_CDC_TX0_TX_PATH_192_CTL (0x00000A35)
+#define WCD9360_CDC_TX0_TX_PATH_192_CFG (0x00000A36)
+#define WCD9360_CDC_TX0_TX_PATH_SEC0 (0x00000A37)
+#define WCD9360_CDC_TX0_TX_PATH_SEC1 (0x00000A38)
+#define WCD9360_CDC_TX0_TX_PATH_SEC2 (0x00000A39)
+#define WCD9360_CDC_TX0_TX_PATH_SEC3 (0x00000A3A)
+#define WCD9360_CDC_TX0_TX_PATH_SEC4 (0x00000A3B)
+#define WCD9360_CDC_TX0_TX_PATH_SEC5 (0x00000A3C)
+#define WCD9360_CDC_TX0_TX_PATH_SEC6 (0x00000A3D)
+#define WCD9360_CDC_TX1_TX_PATH_CTL (0x00000A41)
+#define WCD9360_CDC_TX1_TX_PATH_CFG0 (0x00000A42)
+#define WCD9360_CDC_TX1_TX_PATH_CFG1 (0x00000A43)
+#define WCD9360_CDC_TX1_TX_VOL_CTL (0x00000A44)
+#define WCD9360_CDC_TX1_TX_PATH_192_CTL (0x00000A45)
+#define WCD9360_CDC_TX1_TX_PATH_192_CFG (0x00000A46)
+#define WCD9360_CDC_TX1_TX_PATH_SEC0 (0x00000A47)
+#define WCD9360_CDC_TX1_TX_PATH_SEC1 (0x00000A48)
+#define WCD9360_CDC_TX1_TX_PATH_SEC2 (0x00000A49)
+#define WCD9360_CDC_TX1_TX_PATH_SEC3 (0x00000A4A)
+#define WCD9360_CDC_TX1_TX_PATH_SEC4 (0x00000A4B)
+#define WCD9360_CDC_TX1_TX_PATH_SEC5 (0x00000A4C)
+#define WCD9360_CDC_TX1_TX_PATH_SEC6 (0x00000A4D)
+#define WCD9360_CDC_TX2_TX_PATH_CTL (0x00000A51)
+#define WCD9360_CDC_TX2_TX_PATH_CFG0 (0x00000A52)
+#define WCD9360_CDC_TX2_TX_PATH_CFG1 (0x00000A53)
+#define WCD9360_CDC_TX2_TX_VOL_CTL (0x00000A54)
+#define WCD9360_CDC_TX2_TX_PATH_192_CTL (0x00000A55)
+#define WCD9360_CDC_TX2_TX_PATH_192_CFG (0x00000A56)
+#define WCD9360_CDC_TX2_TX_PATH_SEC0 (0x00000A57)
+#define WCD9360_CDC_TX2_TX_PATH_SEC1 (0x00000A58)
+#define WCD9360_CDC_TX2_TX_PATH_SEC2 (0x00000A59)
+#define WCD9360_CDC_TX2_TX_PATH_SEC3 (0x00000A5A)
+#define WCD9360_CDC_TX2_TX_PATH_SEC4 (0x00000A5B)
+#define WCD9360_CDC_TX2_TX_PATH_SEC5 (0x00000A5C)
+#define WCD9360_CDC_TX2_TX_PATH_SEC6 (0x00000A5D)
+#define WCD9360_CDC_TX3_TX_PATH_CTL (0x00000A61)
+#define WCD9360_CDC_TX3_TX_PATH_CFG0 (0x00000A62)
+#define WCD9360_CDC_TX3_TX_PATH_CFG1 (0x00000A63)
+#define WCD9360_CDC_TX3_TX_VOL_CTL (0x00000A64)
+#define WCD9360_CDC_TX3_TX_PATH_192_CTL (0x00000A65)
+#define WCD9360_CDC_TX3_TX_PATH_192_CFG (0x00000A66)
+#define WCD9360_CDC_TX3_TX_PATH_SEC0 (0x00000A67)
+#define WCD9360_CDC_TX3_TX_PATH_SEC1 (0x00000A68)
+#define WCD9360_CDC_TX3_TX_PATH_SEC2 (0x00000A69)
+#define WCD9360_CDC_TX3_TX_PATH_SEC3 (0x00000A6A)
+#define WCD9360_CDC_TX3_TX_PATH_SEC4 (0x00000A6B)
+#define WCD9360_CDC_TX3_TX_PATH_SEC5 (0x00000A6C)
+#define WCD9360_CDC_TX3_TX_PATH_SEC6 (0x00000A6D)
+#define WCD9360_CDC_TX4_TX_PATH_CTL (0x00000A71)
+#define WCD9360_CDC_TX4_TX_PATH_CFG0 (0x00000A72)
+#define WCD9360_CDC_TX4_TX_PATH_CFG1 (0x00000A73)
+#define WCD9360_CDC_TX4_TX_VOL_CTL (0x00000A74)
+#define WCD9360_CDC_TX4_TX_PATH_192_CTL (0x00000A75)
+#define WCD9360_CDC_TX4_TX_PATH_192_CFG (0x00000A76)
+#define WCD9360_CDC_TX4_TX_PATH_SEC0 (0x00000A77)
+#define WCD9360_CDC_TX4_TX_PATH_SEC1 (0x00000A78)
+#define WCD9360_CDC_TX4_TX_PATH_SEC2 (0x00000A79)
+#define WCD9360_CDC_TX4_TX_PATH_SEC3 (0x00000A7A)
+#define WCD9360_CDC_TX4_TX_PATH_SEC4 (0x00000A7B)
+#define WCD9360_CDC_TX4_TX_PATH_SEC5 (0x00000A7C)
+#define WCD9360_CDC_TX4_TX_PATH_SEC6 (0x00000A7D)
+#define WCD9360_CDC_TX5_TX_PATH_CTL (0x00000A81)
+#define WCD9360_CDC_TX5_TX_PATH_CFG0 (0x00000A82)
+#define WCD9360_CDC_TX5_TX_PATH_CFG1 (0x00000A83)
+#define WCD9360_CDC_TX5_TX_VOL_CTL (0x00000A84)
+#define WCD9360_CDC_TX5_TX_PATH_192_CTL (0x00000A85)
+#define WCD9360_CDC_TX5_TX_PATH_192_CFG (0x00000A86)
+#define WCD9360_CDC_TX5_TX_PATH_SEC0 (0x00000A87)
+#define WCD9360_CDC_TX5_TX_PATH_SEC1 (0x00000A88)
+#define WCD9360_CDC_TX5_TX_PATH_SEC2 (0x00000A89)
+#define WCD9360_CDC_TX5_TX_PATH_SEC3 (0x00000A8A)
+#define WCD9360_CDC_TX5_TX_PATH_SEC4 (0x00000A8B)
+#define WCD9360_CDC_TX5_TX_PATH_SEC5 (0x00000A8C)
+#define WCD9360_CDC_TX5_TX_PATH_SEC6 (0x00000A8D)
+#define WCD9360_CDC_TX6_TX_PATH_CTL (0x00000A91)
+#define WCD9360_CDC_TX6_TX_PATH_CFG0 (0x00000A92)
+#define WCD9360_CDC_TX6_TX_PATH_CFG1 (0x00000A93)
+#define WCD9360_CDC_TX6_TX_VOL_CTL (0x00000A94)
+#define WCD9360_CDC_TX6_TX_PATH_192_CTL (0x00000A95)
+#define WCD9360_CDC_TX6_TX_PATH_192_CFG (0x00000A96)
+#define WCD9360_CDC_TX6_TX_PATH_SEC0 (0x00000A97)
+#define WCD9360_CDC_TX6_TX_PATH_SEC1 (0x00000A98)
+#define WCD9360_CDC_TX6_TX_PATH_SEC2 (0x00000A99)
+#define WCD9360_CDC_TX6_TX_PATH_SEC3 (0x00000A9A)
+#define WCD9360_CDC_TX6_TX_PATH_SEC4 (0x00000A9B)
+#define WCD9360_CDC_TX6_TX_PATH_SEC5 (0x00000A9C)
+#define WCD9360_CDC_TX6_TX_PATH_SEC6 (0x00000A9D)
+#define WCD9360_CDC_TX7_TX_PATH_CTL (0x00000AA1)
+#define WCD9360_CDC_TX7_TX_PATH_CFG0 (0x00000AA2)
+#define WCD9360_CDC_TX7_TX_PATH_CFG1 (0x00000AA3)
+#define WCD9360_CDC_TX7_TX_VOL_CTL (0x00000AA4)
+#define WCD9360_CDC_TX7_TX_PATH_192_CTL (0x00000AA5)
+#define WCD9360_CDC_TX7_TX_PATH_192_CFG (0x00000AA6)
+#define WCD9360_CDC_TX7_TX_PATH_SEC0 (0x00000AA7)
+#define WCD9360_CDC_TX7_TX_PATH_SEC1 (0x00000AA8)
+#define WCD9360_CDC_TX7_TX_PATH_SEC2 (0x00000AA9)
+#define WCD9360_CDC_TX7_TX_PATH_SEC3 (0x00000AAA)
+#define WCD9360_CDC_TX7_TX_PATH_SEC4 (0x00000AAB)
+#define WCD9360_CDC_TX7_TX_PATH_SEC5 (0x00000AAC)
+#define WCD9360_CDC_TX7_TX_PATH_SEC6 (0x00000AAD)
+#define WCD9360_CDC_TX8_TX_PATH_CTL (0x00000AB1)
+#define WCD9360_CDC_TX8_TX_PATH_CFG0 (0x00000AB2)
+#define WCD9360_CDC_TX8_TX_PATH_CFG1 (0x00000AB3)
+#define WCD9360_CDC_TX8_TX_VOL_CTL (0x00000AB4)
+#define WCD9360_CDC_TX8_TX_PATH_192_CTL (0x00000AB5)
+#define WCD9360_CDC_TX8_TX_PATH_192_CFG (0x00000AB6)
+#define WCD9360_CDC_TX8_TX_PATH_SEC0 (0x00000AB7)
+#define WCD9360_CDC_TX8_TX_PATH_SEC1 (0x00000AB8)
+#define WCD9360_CDC_TX8_TX_PATH_SEC2 (0x00000AB9)
+#define WCD9360_CDC_TX8_TX_PATH_SEC3 (0x00000ABA)
+#define WCD9360_CDC_TX8_TX_PATH_SEC4 (0x00000ABB)
+#define WCD9360_CDC_TX8_TX_PATH_SEC5 (0x00000ABC)
+#define WCD9360_CDC_TX8_TX_PATH_SEC6 (0x00000ABD)
+#define WCD9360_CDC_TX9_SPKR_PROT_PATH_CTL (0x00000AC2)
+#define WCD9360_CDC_TX9_SPKR_PROT_PATH_CFG0 (0x00000AC3)
+#define WCD9360_CDC_TX10_SPKR_PROT_PATH_CTL (0x00000AC6)
+#define WCD9360_CDC_TX10_SPKR_PROT_PATH_CFG0 (0x00000AC7)
+#define WCD9360_CDC_TX11_SPKR_PROT_PATH_CTL (0x00000ACA)
+#define WCD9360_CDC_TX11_SPKR_PROT_PATH_CFG0 (0x00000ACB)
+#define WCD9360_CDC_TX12_SPKR_PROT_PATH_CTL (0x00000ACE)
+#define WCD9360_CDC_TX12_SPKR_PROT_PATH_CFG0 (0x00000ACF)
+#define WCD9360_PAGE11_PAGE_REGISTER (0x00000B00)
+#define WCD9360_CDC_COMPANDER0_CTL0 (0x00000B21)
+#define WCD9360_CDC_COMPANDER0_CTL1 (0x00000B22)
+#define WCD9360_CDC_COMPANDER0_CTL2 (0x00000B23)
+#define WCD9360_CDC_COMPANDER0_CTL3 (0x00000B24)
+#define WCD9360_CDC_COMPANDER0_CTL4 (0x00000B25)
+#define WCD9360_CDC_COMPANDER0_CTL5 (0x00000B26)
+#define WCD9360_CDC_COMPANDER0_CTL6 (0x00000B27)
+#define WCD9360_CDC_COMPANDER0_CTL7 (0x00000B28)
+#define WCD9360_CDC_COMPANDER7_CTL0 (0x00000B31)
+#define WCD9360_CDC_COMPANDER7_CTL1 (0x00000B32)
+#define WCD9360_CDC_COMPANDER7_CTL2 (0x00000B33)
+#define WCD9360_CDC_COMPANDER7_CTL3 (0x00000B34)
+#define WCD9360_CDC_COMPANDER7_CTL4 (0x00000B35)
+#define WCD9360_CDC_COMPANDER7_CTL5 (0x00000B36)
+#define WCD9360_CDC_COMPANDER7_CTL6 (0x00000B37)
+#define WCD9360_CDC_COMPANDER7_CTL7 (0x00000B38)
+#define WCD9360_CDC_COMPANDER8_CTL0 (0x00000B39)
+#define WCD9360_CDC_COMPANDER8_CTL1 (0x00000B3A)
+#define WCD9360_CDC_COMPANDER8_CTL2 (0x00000B3B)
+#define WCD9360_CDC_COMPANDER8_CTL3 (0x00000B3C)
+#define WCD9360_CDC_COMPANDER8_CTL4 (0x00000B3D)
+#define WCD9360_CDC_COMPANDER8_CTL5 (0x00000B3E)
+#define WCD9360_CDC_COMPANDER8_CTL6 (0x00000B3F)
+#define WCD9360_CDC_COMPANDER8_CTL7 (0x00000B40)
+#define WCD9360_CDC_RX0_RX_PATH_CTL (0x00000B41)
+#define WCD9360_CDC_RX0_RX_PATH_CFG0 (0x00000B42)
+#define WCD9360_CDC_RX0_RX_PATH_CFG1 (0x00000B43)
+#define WCD9360_CDC_RX0_RX_PATH_CFG2 (0x00000B44)
+#define WCD9360_CDC_RX0_RX_VOL_CTL (0x00000B45)
+#define WCD9360_CDC_RX0_RX_PATH_MIX_CTL (0x00000B46)
+#define WCD9360_CDC_RX0_RX_PATH_MIX_CFG (0x00000B47)
+#define WCD9360_CDC_RX0_RX_VOL_MIX_CTL (0x00000B48)
+#define WCD9360_CDC_RX0_RX_PATH_SEC0 (0x00000B49)
+#define WCD9360_CDC_RX0_RX_PATH_SEC1 (0x00000B4A)
+#define WCD9360_CDC_RX0_RX_PATH_SEC2 (0x00000B4B)
+#define WCD9360_CDC_RX0_RX_PATH_SEC3 (0x00000B4C)
+#define WCD9360_CDC_RX0_RX_PATH_SEC5 (0x00000B4E)
+#define WCD9360_CDC_RX0_RX_PATH_SEC6 (0x00000B4F)
+#define WCD9360_CDC_RX0_RX_PATH_SEC7 (0x00000B50)
+#define WCD9360_CDC_RX0_RX_PATH_MIX_SEC0 (0x00000B51)
+#define WCD9360_CDC_RX0_RX_PATH_MIX_SEC1 (0x00000B52)
+#define WCD9360_CDC_RX0_RX_PATH_DSMDEM_CTL (0x00000B53)
+#define WCD9360_CDC_RX9_RX_PATH_CTL (0x00000BA5)
+#define WCD9360_CDC_RX9_RX_PATH_CFG0 (0x00000BA6)
+#define WCD9360_CDC_RX9_RX_PATH_CFG1 (0x00000BA7)
+#define WCD9360_CDC_RX9_RX_PATH_CFG2 (0x00000BA8)
+#define WCD9360_CDC_RX9_RX_VOL_CTL (0x00000BA9)
+#define WCD9360_CDC_RX9_RX_PATH_MIX_CTL (0x00000BAA)
+#define WCD9360_CDC_RX9_RX_PATH_MIX_CFG (0x00000BAB)
+#define WCD9360_CDC_RX9_RX_VOL_MIX_CTL (0x00000BAC)
+#define WCD9360_CDC_RX9_RX_PATH_SEC0 (0x00000BAD)
+#define WCD9360_CDC_RX9_RX_PATH_SEC1 (0x00000BAE)
+#define WCD9360_CDC_RX9_RX_PATH_SEC2 (0x00000BAF)
+#define WCD9360_CDC_RX9_RX_PATH_SEC3 (0x00000BB0)
+#define WCD9360_CDC_RX9_RX_PATH_SEC5 (0x00000BB2)
+#define WCD9360_CDC_RX9_RX_PATH_SEC6 (0x00000BB3)
+#define WCD9360_CDC_RX9_RX_PATH_SEC7 (0x00000BB4)
+#define WCD9360_CDC_RX9_RX_PATH_MIX_SEC0 (0x00000BB5)
+#define WCD9360_CDC_RX9_RX_PATH_MIX_SEC1 (0x00000BB6)
+#define WCD9360_CDC_RX9_RX_PATH_DSMDEM_CTL (0x00000BB7)
+#define WCD9360_CDC_RX7_RX_PATH_CTL (0x00000BCD)
+#define WCD9360_CDC_RX7_RX_PATH_CFG0 (0x00000BCE)
+#define WCD9360_CDC_RX7_RX_PATH_CFG1 (0x00000BCF)
+#define WCD9360_CDC_RX7_RX_PATH_CFG2 (0x00000BD0)
+#define WCD9360_CDC_RX7_RX_VOL_CTL (0x00000BD1)
+#define WCD9360_CDC_RX7_RX_PATH_MIX_CTL (0x00000BD2)
+#define WCD9360_CDC_RX7_RX_PATH_MIX_CFG (0x00000BD3)
+#define WCD9360_CDC_RX7_RX_VOL_MIX_CTL (0x00000BD4)
+#define WCD9360_CDC_RX7_RX_PATH_SEC0 (0x00000BD5)
+#define WCD9360_CDC_RX7_RX_PATH_SEC1 (0x00000BD6)
+#define WCD9360_CDC_RX7_RX_PATH_SEC2 (0x00000BD7)
+#define WCD9360_CDC_RX7_RX_PATH_SEC3 (0x00000BD8)
+#define WCD9360_CDC_RX7_RX_PATH_SEC5 (0x00000BDA)
+#define WCD9360_CDC_RX7_RX_PATH_SEC6 (0x00000BDB)
+#define WCD9360_CDC_RX7_RX_PATH_SEC7 (0x00000BDC)
+#define WCD9360_CDC_RX7_RX_PATH_MIX_SEC0 (0x00000BDD)
+#define WCD9360_CDC_RX7_RX_PATH_MIX_SEC1 (0x00000BDE)
+#define WCD9360_CDC_RX7_RX_PATH_DSMDEM_CTL (0x00000BDF)
+#define WCD9360_CDC_RX8_RX_PATH_CTL (0x00000BE1)
+#define WCD9360_CDC_RX8_RX_PATH_CFG0 (0x00000BE2)
+#define WCD9360_CDC_RX8_RX_PATH_CFG1 (0x00000BE3)
+#define WCD9360_CDC_RX8_RX_PATH_CFG2 (0x00000BE4)
+#define WCD9360_CDC_RX8_RX_VOL_CTL (0x00000BE5)
+#define WCD9360_CDC_RX8_RX_PATH_MIX_CTL (0x00000BE6)
+#define WCD9360_CDC_RX8_RX_PATH_MIX_CFG (0x00000BE7)
+#define WCD9360_CDC_RX8_RX_VOL_MIX_CTL (0x00000BE8)
+#define WCD9360_CDC_RX8_RX_PATH_SEC0 (0x00000BE9)
+#define WCD9360_CDC_RX8_RX_PATH_SEC1 (0x00000BEA)
+#define WCD9360_CDC_RX8_RX_PATH_SEC2 (0x00000BEB)
+#define WCD9360_CDC_RX8_RX_PATH_SEC3 (0x00000BEC)
+#define WCD9360_CDC_RX8_RX_PATH_SEC5 (0x00000BEE)
+#define WCD9360_CDC_RX8_RX_PATH_SEC6 (0x00000BEF)
+#define WCD9360_CDC_RX8_RX_PATH_SEC7 (0x00000BF0)
+#define WCD9360_CDC_RX8_RX_PATH_MIX_SEC0 (0x00000BF1)
+#define WCD9360_CDC_RX8_RX_PATH_MIX_SEC1 (0x00000BF2)
+#define WCD9360_CDC_RX8_RX_PATH_DSMDEM_CTL (0x00000BF3)
+#define WCD9360_PAGE12_PAGE_REGISTER (0x00000C00)
+#define WCD9360_CDC_BOOST0_BOOST_PATH_CTL (0x00000C19)
+#define WCD9360_CDC_BOOST0_BOOST_CTL (0x00000C1A)
+#define WCD9360_CDC_BOOST0_BOOST_CFG1 (0x00000C1B)
+#define WCD9360_CDC_BOOST0_BOOST_CFG2 (0x00000C1C)
+#define WCD9360_CDC_BOOST1_BOOST_PATH_CTL (0x00000C21)
+#define WCD9360_CDC_BOOST1_BOOST_CTL (0x00000C22)
+#define WCD9360_CDC_BOOST1_BOOST_CFG1 (0x00000C23)
+#define WCD9360_CDC_BOOST1_BOOST_CFG2 (0x00000C24)
+#define WCD9360_MIXING_ASRC2_CLK_RST_CTL (0x00000C6D)
+#define WCD9360_MIXING_ASRC2_CTL0 (0x00000C6E)
+#define WCD9360_MIXING_ASRC2_CTL1 (0x00000C6F)
+#define WCD9360_MIXING_ASRC2_FIFO_CTL (0x00000C70)
+#define WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_LSB (0x00000C71)
+#define WCD9360_MIXING_ASRC2_STATUS_FMIN_CNTR_MSB (0x00000C72)
+#define WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_LSB (0x00000C73)
+#define WCD9360_MIXING_ASRC2_STATUS_FMAX_CNTR_MSB (0x00000C74)
+#define WCD9360_MIXING_ASRC2_STATUS_FIFO (0x00000C75)
+#define WCD9360_MIXING_ASRC3_CLK_RST_CTL (0x00000C79)
+#define WCD9360_MIXING_ASRC3_CTL0 (0x00000C7A)
+#define WCD9360_MIXING_ASRC3_CTL1 (0x00000C7B)
+#define WCD9360_MIXING_ASRC3_FIFO_CTL (0x00000C7C)
+#define WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_LSB (0x00000C7D)
+#define WCD9360_MIXING_ASRC3_STATUS_FMIN_CNTR_MSB (0x00000C7E)
+#define WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_LSB (0x00000C7F)
+#define WCD9360_MIXING_ASRC3_STATUS_FMAX_CNTR_MSB (0x00000C80)
+#define WCD9360_MIXING_ASRC3_STATUS_FIFO (0x00000C81)
+#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_0 (0x00000C85)
+#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_1 (0x00000C86)
+#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_2 (0x00000C87)
+#define WCD9360_SWR_AHB_BRIDGE_WR_DATA_3 (0x00000C88)
+#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_0 (0x00000C89)
+#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_1 (0x00000C8A)
+#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_2 (0x00000C8B)
+#define WCD9360_SWR_AHB_BRIDGE_WR_ADDR_3 (0x00000C8C)
+#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_0 (0x00000C8D)
+#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_1 (0x00000C8E)
+#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_2 (0x00000C8F)
+#define WCD9360_SWR_AHB_BRIDGE_RD_ADDR_3 (0x00000C90)
+#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_0 (0x00000C91)
+#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_1 (0x00000C92)
+#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_2 (0x00000C93)
+#define WCD9360_SWR_AHB_BRIDGE_RD_DATA_3 (0x00000C94)
+#define WCD9360_SWR_AHB_BRIDGE_ACCESS_CFG (0x00000C95)
+#define WCD9360_SWR_AHB_BRIDGE_ACCESS_STATUS (0x00000C96)
+#define WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL (0x00000CB5)
+#define WCD9360_CDC_SIDETONE_SRC0_ST_SRC_PATH_CFG1 (0x00000CB6)
+#define WCD9360_SIDETONE_ASRC0_CLK_RST_CTL (0x00000CBD)
+#define WCD9360_SIDETONE_ASRC0_CTL0 (0x00000CBE)
+#define WCD9360_SIDETONE_ASRC0_CTL1 (0x00000CBF)
+#define WCD9360_SIDETONE_ASRC0_FIFO_CTL (0x00000CC0)
+#define WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CC1)
+#define WCD9360_SIDETONE_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CC2)
+#define WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CC3)
+#define WCD9360_SIDETONE_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CC4)
+#define WCD9360_SIDETONE_ASRC0_STATUS_FIFO (0x00000CC5)
+#define WCD9360_EC_REF_HQ0_EC_REF_HQ_PATH_CTL (0x00000CD5)
+#define WCD9360_EC_REF_HQ0_EC_REF_HQ_CFG0 (0x00000CD6)
+#define WCD9360_EC_REF_HQ1_EC_REF_HQ_PATH_CTL (0x00000CDD)
+#define WCD9360_EC_REF_HQ1_EC_REF_HQ_CFG0 (0x00000CDE)
+#define WCD9360_EC_ASRC0_CLK_RST_CTL (0x00000CE5)
+#define WCD9360_EC_ASRC0_CTL0 (0x00000CE6)
+#define WCD9360_EC_ASRC0_CTL1 (0x00000CE7)
+#define WCD9360_EC_ASRC0_FIFO_CTL (0x00000CE8)
+#define WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_LSB (0x00000CE9)
+#define WCD9360_EC_ASRC0_STATUS_FMIN_CNTR_MSB (0x00000CEA)
+#define WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_LSB (0x00000CEB)
+#define WCD9360_EC_ASRC0_STATUS_FMAX_CNTR_MSB (0x00000CEC)
+#define WCD9360_EC_ASRC0_STATUS_FIFO (0x00000CED)
+#define WCD9360_EC_ASRC1_CLK_RST_CTL (0x00000CF1)
+#define WCD9360_EC_ASRC1_CTL0 (0x00000CF2)
+#define WCD9360_EC_ASRC1_CTL1 (0x00000CF3)
+#define WCD9360_EC_ASRC1_FIFO_CTL (0x00000CF4)
+#define WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_LSB (0x00000CF5)
+#define WCD9360_EC_ASRC1_STATUS_FMIN_CNTR_MSB (0x00000CF6)
+#define WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_LSB (0x00000CF7)
+#define WCD9360_EC_ASRC1_STATUS_FMAX_CNTR_MSB (0x00000CF8)
+#define WCD9360_EC_ASRC1_STATUS_FIFO (0x00000CF9)
+#define WCD9360_PAGE13_PAGE_REGISTER (0x00000D00)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG0 (0x00000D01)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT0_CFG1 (0x00000D02)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG0 (0x00000D0B)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT9_CFG1 (0x00000D0C)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG0 (0x00000D0F)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT7_CFG1 (0x00000D10)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG0 (0x00000D11)
+#define WCD9360_CDC_RX_INP_MUX_RX_INT8_CFG1 (0x00000D12)
+#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG0 (0x00000D13)
+#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG1 (0x00000D14)
+#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG2 (0x00000D15)
+#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG3 (0x00000D16)
+#define WCD9360_CDC_RX_INP_MUX_RX_MIX_CFG4 (0x00000D17)
+#define WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (0x00000D18)
+#define WCD9360_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1 (0x00000D19)
+#define WCD9360_CDC_RX_INP_MUX_ANC_CFG0 (0x00000D1A)
+#define WCD9360_CDC_RX_INP_MUX_SPLINE_ASRC_CFG0 (0x00000D1B)
+#define WCD9360_CDC_RX_INP_MUX_EC_REF_HQ_CFG0 (0x00000D1C)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (0x00000D1D)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (0x00000D1E)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (0x00000D1F)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (0x00000D20)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (0x00000D21)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (0x00000D22)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG0 (0x00000D23)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX3_CFG1 (0x00000D25)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX4_CFG0 (0x00000D26)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX5_CFG0 (0x00000D27)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX6_CFG0 (0x00000D28)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX7_CFG0 (0x00000D29)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX8_CFG0 (0x00000D2A)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX10_CFG0 (0x00000D2B)
+#define WCD9360_CDC_TX_INP_MUX_ADC_MUX11_CFG0 (0x00000D2C)
+#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0 (0x00000D31)
+#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1 (0x00000D32)
+#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2 (0x00000D33)
+#define WCD9360_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3 (0x00000D34)
+#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG0 (0x00000D3A)
+#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG1 (0x00000D3B)
+#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG2 (0x00000D3C)
+#define WCD9360_CDC_IF_ROUTER_TX_MUX_CFG3 (0x00000D3D)
+#define WCD9360_CDC_CLK_RST_CTRL_MCLK_CONTROL (0x00000D41)
+#define WCD9360_CDC_CLK_RST_CTRL_FS_CNT_CONTROL (0x00000D42)
+#define WCD9360_CDC_CLK_RST_CTRL_SWR_CONTROL (0x00000D43)
+#define WCD9360_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL (0x00000D45)
+#define WCD9360_CDC_PROX_DETECT_PROX_CTL (0x00000D49)
+#define WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD0 (0x00000D4A)
+#define WCD9360_CDC_PROX_DETECT_PROX_POLL_PERIOD1 (0x00000D4B)
+#define WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_LSB (0x00000D4C)
+#define WCD9360_CDC_PROX_DETECT_PROX_SIG_PATTERN_MSB (0x00000D4D)
+#define WCD9360_CDC_PROX_DETECT_PROX_STATUS (0x00000D4E)
+#define WCD9360_CDC_PROX_DETECT_PROX_TEST_CTRL (0x00000D4F)
+#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB (0x00000D50)
+#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB (0x00000D51)
+#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_LSB_RD (0x00000D52)
+#define WCD9360_CDC_PROX_DETECT_PROX_TEST_BUFF_MSB_RD (0x00000D53)
+#define WCD9360_CDC_PROX_DETECT_PROX_CTL_REPEAT_PAT (0x00000D54)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_PATH_CTL (0x00000D55)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL (0x00000D56)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL (0x00000D57)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL (0x00000D58)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL (0x00000D59)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL (0x00000D5A)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL (0x00000D5B)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL (0x00000D5C)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL (0x00000D5D)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_CTL (0x00000D5E)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL (0x00000D5F)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL (0x00000D60)
+#define WCD9360_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL (0x00000D61)
+#define WCD9360_CDC_TOP_TOP_CFG0 (0x00000D81)
+#define WCD9360_CDC_TOP_TOP_CFG1 (0x00000D82)
+#define WCD9360_CDC_TOP_TOP_CFG7 (0x00000D88)
+#define WCD9360_CDC_TOP_EAR_COMP_WR_LSB (0x00000DA9)
+#define WCD9360_CDC_TOP_EAR_COMP_WR_MSB (0x00000DAA)
+#define WCD9360_CDC_TOP_EAR_COMP_LUT (0x00000DAB)
+#define WCD9360_CDC_TOP_EAR_COMP_RD_LSB (0x00000DAC)
+#define WCD9360_CDC_TOP_EAR_COMP_RD_MSB (0x00000DAD)
+#define WCD9360_CDC_TOP_TOP_DEBUG (0x00000DAE)
+#define WCD9360_PAGE80_PAGE_REGISTER (0x00005000)
+#define WCD9360_CODEC_CPR_WR_DATA_0 (0x00005001)
+#define WCD9360_CODEC_CPR_WR_DATA_1 (0x00005002)
+#define WCD9360_CODEC_CPR_WR_DATA_2 (0x00005003)
+#define WCD9360_CODEC_CPR_WR_DATA_3 (0x00005004)
+#define WCD9360_CODEC_CPR_WR_ADDR_0 (0x00005005)
+#define WCD9360_CODEC_CPR_WR_ADDR_1 (0x00005006)
+#define WCD9360_CODEC_CPR_WR_ADDR_2 (0x00005007)
+#define WCD9360_CODEC_CPR_WR_ADDR_3 (0x00005008)
+#define WCD9360_CODEC_CPR_RD_ADDR_0 (0x00005009)
+#define WCD9360_CODEC_CPR_RD_ADDR_1 (0x0000500A)
+#define WCD9360_CODEC_CPR_RD_ADDR_2 (0x0000500B)
+#define WCD9360_CODEC_CPR_RD_ADDR_3 (0x0000500C)
+#define WCD9360_CODEC_CPR_RD_DATA_0 (0x0000500D)
+#define WCD9360_CODEC_CPR_RD_DATA_1 (0x0000500E)
+#define WCD9360_CODEC_CPR_RD_DATA_2 (0x0000500F)
+#define WCD9360_CODEC_CPR_RD_DATA_3 (0x00005010)
+#define WCD9360_CODEC_CPR_ACCESS_CFG (0x00005011)
+#define WCD9360_CODEC_CPR_ACCESS_STATUS (0x00005012)
+#define WCD9360_CODEC_CPR_NOM_CX_VDD (0x00005021)
+#define WCD9360_CODEC_CPR_SVS_CX_VDD (0x00005022)
+#define WCD9360_CODEC_CPR_SVS2_CX_VDD (0x00005023)
+#define WCD9360_CODEC_CPR_NOM_MX_VDD (0x00005024)
+#define WCD9360_CODEC_CPR_SVS_MX_VDD (0x00005025)
+#define WCD9360_CODEC_CPR_SVS2_MX_VDD (0x00005026)
+#define WCD9360_CODEC_CPR_SVS2_MIN_CX_VDD (0x00005027)
+#define WCD9360_CODEC_CPR_MAX_SVS2_STEP (0x00005028)
+#define WCD9360_CODEC_CPR_CTL (0x00005029)
+#define WCD9360_CODEC_CPR_SW_MODECHNG_STATUS (0x0000502A)
+#define WCD9360_CODEC_CPR_SW_MODECHNG_START (0x0000502B)
+#define WCD9360_CODEC_CPR_CPR_STATUS (0x0000502C)
+#define WCD9360_PAGE128_PAGE_REGISTER (0x00008000)
+#define WCD9360_TLMM_JTCK_PINCFG (0x00008001)
+#define WCD9360_TLMM_INTR1_PINCFG (0x00008002)
+#define WCD9360_TLMM_INTR2_PINCFG (0x00008003)
+#define WCD9360_TLMM_SWR_DATA_PINCFG (0x00008004)
+#define WCD9360_TLMM_SWR_CLK_PINCFG (0x00008005)
+#define WCD9360_TLMM_SLIMBUS_DATA1_PINCFG (0x00008006)
+#define WCD9360_TLMM_SLIMBUS_DATA2_PINCFG (0x00008007)
+#define WCD9360_TLMM_SLIMBUS_CLK_PINCFG (0x00008008)
+#define WCD9360_TLMM_I2C_CLK_PINCFG (0x00008009)
+#define WCD9360_TLMM_I2C_DATA_PINCFG (0x0000800A)
+#define WCD9360_TLMM_I2S_0_RX_PINCFG (0x0000800B)
+#define WCD9360_TLMM_I2S_0_TX_PINCFG (0x0000800C)
+#define WCD9360_TLMM_I2S_0_SCK_PINCFG (0x0000800D)
+#define WCD9360_TLMM_I2S_0_WS_PINCFG (0x0000800E)
+#define WCD9360_TLMM_I2S_1_RX_PINCFG (0x0000800F)
+#define WCD9360_TLMM_I2S_1_TX_PINCFG (0x00008010)
+#define WCD9360_TLMM_I2S_1_SCK_PINCFG (0x00008011)
+#define WCD9360_TLMM_I2S_1_WS_PINCFG (0x00008012)
+#define WCD9360_TLMM_DMIC1_CLK_PINCFG (0x00008013)
+#define WCD9360_TLMM_DMIC1_DATA_PINCFG (0x00008014)
+#define WCD9360_TLMM_DMIC2_CLK_PINCFG (0x00008015)
+#define WCD9360_TLMM_DMIC2_DATA_PINCFG (0x00008016)
+#define WCD9360_TLMM_GPIO1_PINCFG (0x00008017)
+#define WCD9360_TLMM_GPIO2_PINCFG (0x00008018)
+#define WCD9360_TLMM_GPIO3_PINCFG (0x00008019)
+#define WCD9360_TLMM_GPIO4_PINCFG (0x0000801A)
+#define WCD9360_TLMM_SPI_S_CSN_PINCFG (0x0000801B)
+#define WCD9360_TLMM_SPI_S_CLK_PINCFG (0x0000801C)
+#define WCD9360_TLMM_SPI_S_DOUT_PINCFG (0x0000801D)
+#define WCD9360_TLMM_SPI_S_DIN_PINCFG (0x0000801E)
+#define WCD9360_TLMM_GPIO0_PINCFG (0x0000801F)
+#define WCD9360_TLMM_DMIC3_CLK_PINCFG (0x00008020)
+#define WCD9360_TLMM_DMIC3_DATA_PINCFG (0x00008021)
+#define WCD9360_TLMM_DMIC4_CLK_PINCFG (0x00008022)
+#define WCD9360_TLMM_DMIC4_DATA_PINCFG (0x00008023)
+#define WCD9360_TEST_DEBUG_PIN_CTL_OE_0 (0x00008031)
+#define WCD9360_TEST_DEBUG_PIN_CTL_OE_1 (0x00008032)
+#define WCD9360_TEST_DEBUG_PIN_CTL_OE_2 (0x00008033)
+#define WCD9360_TEST_DEBUG_PIN_CTL_OE_3 (0x00008034)
+#define WCD9360_TEST_DEBUG_PIN_CTL_OE_4 (0x00008035)
+#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_0 (0x00008036)
+#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_1 (0x00008037)
+#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_2 (0x00008038)
+#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_3 (0x00008039)
+#define WCD9360_TEST_DEBUG_PIN_CTL_DATA_4 (0x0000803A)
+#define WCD9360_TEST_DEBUG_PAD_DRVCTL_0 (0x0000803B)
+#define WCD9360_TEST_DEBUG_PAD_DRVCTL_1 (0x0000803C)
+#define WCD9360_TEST_DEBUG_PIN_STATUS (0x0000803D)
+#define WCD9360_TEST_DEBUG_NPL_DLY_TEST_1 (0x0000803E)
+#define WCD9360_TEST_DEBUG_NPL_DLY_TEST_2 (0x0000803F)
+#define WCD9360_TEST_DEBUG_MEM_CTRL (0x00008040)
+#define WCD9360_TEST_DEBUG_DEBUG_BUS_SEL (0x00008041)
+#define WCD9360_TEST_DEBUG_DEBUG_JTAG (0x00008042)
+#define WCD9360_TEST_DEBUG_DEBUG_EN_1 (0x00008043)
+#define WCD9360_TEST_DEBUG_DEBUG_EN_2 (0x00008044)
+#define WCD9360_TEST_DEBUG_DEBUG_EN_3 (0x00008045)
+#define WCD9360_TEST_DEBUG_DEBUG_EN_4 (0x00008046)
+#define WCD9360_TEST_DEBUG_DEBUG_EN_5 (0x00008047)
+#define WCD9360_TEST_DEBUG_ANA_DTEST_DIR (0x0000804A)
+#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_0 (0x0000804B)
+#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_1 (0x0000804C)
+#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_2 (0x0000804D)
+#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_3 (0x0000804E)
+#define WCD9360_TEST_DEBUG_PAD_INP_DISABLE_4 (0x0000804F)
+#define WCD9360_TEST_DEBUG_SYSMEM_CTRL (0x00008050)
+#define WCD9360_TEST_DEBUG_LVAL_NOM_LOW (0x00008052)
+#define WCD9360_TEST_DEBUG_LVAL_NOM_HIGH (0x00008053)
+#define WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_LOW (0x00008054)
+#define WCD9360_TEST_DEBUG_LVAL_SVS_SVS2_HIGH (0x00008055)
+#define WCD9360_TEST_DEBUG_SPI_SLAVE_CHAR (0x00008056)
+#define WCD9360_TEST_DEBUG_CODEC_DIAGS (0x00008057)
+#define WCD9360_TEST_DEBUG_PAD_TEST (0x00008058)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_0 (0x00008061)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_1 (0x00008062)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_2 (0x00008063)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_3 (0x00008064)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_4 (0x00008065)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_5 (0x00008066)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_6 (0x00008067)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_7 (0x00008068)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_8 (0x00008069)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_9 (0x0000806A)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_10 (0x0000806B)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_11 (0x0000806C)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_12 (0x0000806D)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_13 (0x0000806E)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_14 (0x0000806F)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_15 (0x00008070)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_16 (0x00008071)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_17 (0x00008072)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_18 (0x00008073)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_19 (0x00008074)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_20 (0x00008075)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_21 (0x00008076)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_22 (0x00008077)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_23 (0x00008078)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_24 (0x00008079)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_25 (0x0000807A)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_26 (0x0000807B)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_27 (0x0000807C)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_28 (0x0000807D)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_29 (0x0000807E)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_30 (0x0000807F)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_BIT_31 (0x00008080)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_CTRL (0x00008081)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_7_0 (0x00008082)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_15_8 (0x00008083)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_23_16 (0x00008084)
+#define WCD9360_TEST_DEBUG_DEBUG_MUX_RD_31_24 (0x00008085)
+#define WCD9360_MAX_REGISTER 0x80FF
+
+/* SLIMBUS Slave Registers */
+#define WCD9360_SLIM_PGD_PORT_INT_RX_EN0 (0x30)
+#define WCD9360_SLIM_PGD_PORT_INT_TX_EN0 (0x32)
+#define WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34)
+#define WCD9360_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35)
+#define WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36)
+#define WCD9360_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37)
+#define WCD9360_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38)
+#define WCD9360_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39)
+#define WCD9360_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A)
+#define WCD9360_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B)
+#define WCD9360_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60)
+#define WCD9360_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70)
+
+#endif
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index 4cef82e..ae096e6 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -29,6 +29,107 @@
phys_addr_t paddr;
};
+/* Common structures and definitions used for instance ID support */
+/* Instance ID definitions */
+#define INSTANCE_ID_0 0x0000
+
+struct mem_mapping_hdr {
+ /*
+ * LSW of parameter data payload address. Supported values: any.
+ * - Must be set to zero for in-band data.
+ */
+ u32 data_payload_addr_lsw;
+
+ /*
+ * MSW of Parameter data payload address. Supported values: any.
+ * - Must be set to zero for in-band data.
+ * - In the case of 32 bit Shared memory address, MSW field must be
+ * set to zero.
+ * - In the case of 36 bit shared memory address, bit 31 to bit 4 of
+ * MSW must be set to zero.
+ */
+ u32 data_payload_addr_msw;
+
+ /*
+ * Memory map handle returned by DSP through
+ * ASM_CMD_SHARED_MEM_MAP_REGIONS command.
+ * Supported Values: Any.
+ * If memory map handle is NULL, the parameter data payloads are
+ * within the message payload (in-band).
+ * If memory map handle is non-NULL, the parameter data payloads begin
+ * at the address specified in the address MSW and LSW (out-of-band).
+ */
+ u32 mem_map_handle;
+
+} __packed;
+
+/*
+ * Payload format for parameter data.
+ * Immediately following these structures are param_size bytes of parameter
+ * data.
+ */
+struct param_hdr_v1 {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+
+ /* The size of the parameter specified by the module/param ID combo */
+ uint16_t param_size;
+
+ /* This field must be set to zero. */
+ uint16_t reserved;
+} __packed;
+
+struct param_hdr_v2 {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+
+ /* The size of the parameter specified by the module/param ID combo */
+ uint32_t param_size;
+} __packed;
+
+struct param_hdr_v3 {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+
+ /* Instance of the module. */
+ uint16_t instance_id;
+
+ /* This field must be set to zero. */
+ uint16_t reserved;
+
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+
+ /* The size of the parameter specified by the module/param ID combo */
+ uint32_t param_size;
+} __packed;
+
+/* A union of all param_hdr versions for versitility and max size */
+union param_hdrs {
+ struct param_hdr_v1 v1;
+ struct param_hdr_v2 v2;
+ struct param_hdr_v3 v3;
+};
+
+struct module_instance_info {
+ /* Module ID. */
+ u32 module_id;
+
+ /* Instance of the module */
+ u16 instance_id;
+
+ /* Reserved. This field must be set to zero. */
+ u16 reserved;
+} __packed;
+
+/* Begin service specific definitions and structures */
+
#define ADSP_ADM_VERSION 0x00070000
#define ADM_CMD_SHARED_MEM_MAP_REGIONS 0x00010322
@@ -397,55 +498,40 @@
/* Sets one or more parameters to a COPP. */
#define ADM_CMD_SET_PP_PARAMS_V5 0x00010328
+#define ADM_CMD_SET_PP_PARAMS_V6 0x0001035D
-/* Payload of the #ADM_CMD_SET_PP_PARAMS_V5 command.
- * If the data_payload_addr_lsw and data_payload_addr_msw element
- * are NULL, a series of adm_param_datastructures immediately
- * follows, whose total size is data_payload_size bytes.
+/*
+ * Structure of the ADM Set PP Params command. Parameter data must be
+ * pre-packed with correct header for either V2 or V3 when sent in-band.
+ * Use q6core_pack_pp_params to pack the header and data correctly depending on
+ * Instance ID support.
*/
-struct adm_cmd_set_pp_params_v5 {
- struct apr_hdr hdr;
- u32 payload_addr_lsw;
-/* LSW of parameter data payload address. */
- u32 payload_addr_msw;
-/* MSW of parameter data payload address. */
+struct adm_cmd_set_pp_params {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
- u32 mem_map_handle;
-/* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS
- * command
- *
- * If mem_map_handle is zero implies the message is in
- * the payload
- */
+ /* The memory mapping header to be used when sending out of band */
+ struct mem_mapping_hdr mem_hdr;
- u32 payload_size;
-/* Size in bytes of the variable payload accompanying this
- * message or
- * in shared memory. This is used for parsing the parameter
- * payload.
- */
+ /*
+ * Size in bytes of the variable payload accompanying this
+ * message or
+ * in shared memory. This is used for parsing the parameter
+ * payload.
+ */
+ u32 payload_size;
+
+ /*
+ * Parameter data for in band payload. This should be structured as the
+ * parameter header immediately followed by the parameter data. Multiple
+ * parameters can be set in one command by repeating the header followed
+ * by the data for as many parameters as need to be set.
+ * Use q6core_pack_pp_params to pack the header and data correctly
+ * depending on Instance ID support.
+ */
+ u8 param_data[0];
} __packed;
-/* Payload format for COPP parameter data.
- * Immediately following this structure are param_size bytes
- * of parameter
- * data.
- */
-struct adm_param_data_v5 {
- u32 module_id;
- /* Unique ID of the module. */
- u32 param_id;
- /* Unique ID of the parameter. */
- u16 param_size;
- /* Data size of the param_id/module_id combination.
- * This value is a
- * multiple of 4 bytes.
- */
- u16 reserved;
- /* Reserved for future enhancements.
- * This field must be set to zero.
- */
-} __packed;
#define ASM_STREAM_CMD_REGISTER_PP_EVENTS 0x00013213
#define ASM_STREAM_PP_EVENT 0x00013214
@@ -489,25 +575,6 @@
u16 reserved;
} __packed;
-/* Defined specifically for in-band use, includes params */
-struct adm_cmd_set_pp_params_inband_v5 {
- struct apr_hdr hdr;
- /* LSW of parameter data payload address.*/
- u32 payload_addr_lsw;
- /* MSW of parameter data payload address.*/
- u32 payload_addr_msw;
- /* Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS */
- /* command. If mem_map_handle is zero implies the message is in */
- /* the payload */
- u32 mem_map_handle;
- /* Size in bytes of the variable payload accompanying this */
- /* message or in shared memory. This is used for parsing the */
- /* parameter payload. */
- u32 payload_size;
- /* Parameters passed for in band payload */
- struct adm_param_data_v5 params;
-} __packed;
-
/* Returns the status and COPP ID to an #ADM_CMD_DEVICE_OPEN_V5 command.
*/
#define ADM_CMDRSP_DEVICE_OPEN_V5 0x00010329
@@ -538,43 +605,21 @@
/* This command allows a query of one COPP parameter. */
#define ADM_CMD_GET_PP_PARAMS_V5 0x0001032A
+#define ADM_CMD_GET_PP_PARAMS_V6 0x0001035E
-/* Payload an #ADM_CMD_GET_PP_PARAMS_V5 command. */
-struct adm_cmd_get_pp_params_v5 {
- struct apr_hdr hdr;
- u32 data_payload_addr_lsw;
- /* LSW of parameter data payload address.*/
+/*
+ * Structure of the ADM Get PP Params command. Parameter header must be
+ * packed correctly for either V2 or V3. Use q6core_pack_pp_params to pack the
+ * header correctly depending on Instance ID support.
+ */
+struct adm_cmd_get_pp_params {
+ struct apr_hdr apr_hdr;
- u32 data_payload_addr_msw;
- /* MSW of parameter data payload address.*/
+ /* The memory mapping header to be used when requesting outband */
+ struct mem_mapping_hdr mem_hdr;
- /* If the mem_map_handle is non zero,
- * on ACK, the ParamData payloads begin at
- * the address specified (out-of-band).
- */
-
- u32 mem_map_handle;
- /* Memory map handle returned
- * by ADM_CMD_SHARED_MEM_MAP_REGIONS command.
- * If the mem_map_handle is 0, it implies that
- * the ACK's payload will contain the ParamData (in-band).
- */
-
- u32 module_id;
- /* Unique ID of the module. */
-
- u32 param_id;
- /* Unique ID of the parameter. */
-
- u16 param_max_size;
- /* Maximum data size of the parameter
- *ID/module ID combination. This
- * field is a multiple of 4 bytes.
- */
- u16 reserved;
- /* Reserved for future enhancements.
- * This field must be set to zero.
- */
+ /* Parameter header for in band payload. */
+ union param_hdrs param_hdr;
} __packed;
/* Returns parameter values
@@ -586,15 +631,49 @@
* which returns parameter values in response
* to an #ADM_CMD_GET_PP_PARAMS_V5 command.
* Immediately following this
- * structure is the adm_param_data_v5
+ * structure is the param_hdr_v1
* structure containing the pre/postprocessing
* parameter data. For an in-band
* scenario, the variable payload depends
* on the size of the parameter.
*/
struct adm_cmd_rsp_get_pp_params_v5 {
- u32 status;
/* Status message (error code).*/
+ u32 status;
+
+ /* The header that identifies the subsequent parameter data */
+ struct param_hdr_v1 param_hdr;
+
+ /* The parameter data returned */
+ u32 param_data[0];
+} __packed;
+
+/*
+ * Returns parameter values in response to an #ADM_CMD_GET_PP_PARAMS_V5/6
+ * command.
+ */
+#define ADM_CMDRSP_GET_PP_PARAMS_V6 0x0001035F
+
+/*
+ * Payload of the #ADM_CMDRSP_GET_PP_PARAMS_V6 message,
+ * which returns parameter values in response
+ * to an #ADM_CMD_GET_PP_PARAMS_V6 command.
+ * Immediately following this
+ * structure is the param_hdr_v3
+ * structure containing the pre/postprocessing
+ * parameter data. For an in-band
+ * scenario, the variable payload depends
+ * on the size of the parameter.
+ */
+struct adm_cmd_rsp_get_pp_params_v6 {
+ /* Status message (error code).*/
+ u32 status;
+
+ /* The header that identifies the subsequent parameter data */
+ struct param_hdr_v3 param_hdr;
+
+ /* The parameter data returned */
+ u32 param_data[0];
} __packed;
/* Structure for holding soft stepping volume parameters. */
@@ -627,9 +706,31 @@
#define AUDPROC_CHMIXER_PARAM_ID_COEFF 0x00010342
-struct audproc_mfc_output_media_fmt {
- struct adm_cmd_set_pp_params_v5 params;
- struct adm_param_data_v5 data;
+struct adm_cmd_set_pp_params_v5 {
+ struct apr_hdr hdr;
+ u32 payload_addr_lsw;
+ /* LSW of parameter data payload address.*/
+ u32 payload_addr_msw;
+ /* MSW of parameter data payload address.*/
+
+ u32 mem_map_handle;
+ /*
+ * Memory map handle returned by ADM_CMD_SHARED_MEM_MAP_REGIONS
+ * command.
+ * If mem_map_handle is zero implies the message is in
+ * the payload
+ */
+
+ u32 payload_size;
+ /*
+ * Size in bytes of the variable payload accompanying this
+ * message or
+ * in shared memory. This is used for parsing the parameter
+ * payload.
+ */
+} __packed;
+
+struct audproc_mfc_param_media_fmt {
uint32_t sampling_rate;
uint16_t bits_per_sample;
uint16_t num_channels;
@@ -637,8 +738,6 @@
} __packed;
struct audproc_volume_ctrl_master_gain {
- struct adm_cmd_set_pp_params_v5 params;
- struct adm_param_data_v5 data;
/* Linear gain in Q13 format. */
uint16_t master_gain;
/* Clients must set this field to zero. */
@@ -646,8 +745,6 @@
} __packed;
struct audproc_soft_step_volume_params {
- struct adm_cmd_set_pp_params_v5 params;
- struct adm_param_data_v5 data;
/*
* Period in milliseconds.
* Supported values: 0 to 15000
@@ -669,7 +766,6 @@
} __packed;
struct audproc_enable_param_t {
- struct adm_cmd_set_pp_params_inband_v5 pp_params;
/*
* Specifies whether the Audio processing module is enabled.
* This parameter is generic/common parameter to configure or
@@ -1432,86 +1528,137 @@
#define AFE_MODULE_LOOPBACK 0x00010205
#define AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH 0x00010206
+/* Used by RTAC */
+struct afe_rtac_user_data_set_v2 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+
+ /* Actual size of the payload in bytes.
+ * This is used for parsing the parameter payload.
+ * Supported values: > 0
+ */
+ u16 payload_size;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The parameter header for the parameter data to set */
+ struct param_hdr_v1 param_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u32 *param_data;
+} __packed;
+
+struct afe_rtac_user_data_set_v3 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+ /* Reserved for future enhancements. Must be 0. */
+ u16 reserved;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The size of the parameter header and parameter data */
+ u32 payload_size;
+
+ /* The parameter header for the parameter data to set */
+ struct param_hdr_v3 param_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u32 *param_data;
+} __packed;
+
+struct afe_rtac_user_data_get_v2 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+
+ /* Actual size of the payload in bytes.
+ * This is used for parsing the parameter payload.
+ * Supported values: > 0
+ */
+ u16 payload_size;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The module ID of the parameter to get */
+ u32 module_id;
+
+ /* The parameter ID of the parameter to get */
+ u32 param_id;
+
+ /* The parameter data to be filled when sent inband */
+ struct param_hdr_v1 param_hdr;
+} __packed;
+
+struct afe_rtac_user_data_get_v3 {
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+ /* Reserved for future enhancements. Must be 0. */
+ u16 reserved;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ struct param_hdr_v3 param_hdr;
+} __packed;
+
+#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF
+struct afe_port_cmd_set_param_v2 {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+
+ /*
+ * Actual size of the payload in bytes.
+ * This is used for parsing the parameter payload.
+ * Supported values: > 0
+ */
+ u16 payload_size;
+
+ /* The header detailing the memory mapping for out of band. */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u8 param_data[0];
+} __packed;
+
+#define AFE_PORT_CMD_SET_PARAM_V3 0x000100FA
+struct afe_port_cmd_set_param_v3 {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* Port ID of the AFE port to configure. Port interface and direction
+ * (Rx or Tx) to configure. An even number represents the Rx direction,
+ * and an odd number represents the Tx direction.
+ */
+ u16 port_id;
+
+ /* Reserved. This field must be set to zero. */
+ u16 reserved;
+
+ /* The memory mapping header to be used when sending outband */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The total size of the payload, including param_hdr_v3 */
+ u32 payload_size;
+
+ /*
+ * The parameter data to be filled when sent inband.
+ * Must include param_hdr packed correctly.
+ */
+ u8 param_data[0];
+} __packed;
+
/* Payload of the #AFE_PARAM_ID_LOOPBACK_GAIN_PER_PATH parameter,
* which gets/sets loopback gain of a port to an Rx port.
* The Tx port ID of the loopback is part of the set_param command.
*/
-/* Payload of the #AFE_PORT_CMD_SET_PARAM_V2 command's
- * configuration/calibration settings for the AFE port.
- */
-struct afe_port_cmd_set_param_v2 {
- u16 port_id;
-/* Port interface and direction (Rx or Tx) to start. */
-
- u16 payload_size;
-/* Actual size of the payload in bytes.
- * This is used for parsing the parameter payload.
- * Supported values: > 0
- */
-
-u32 payload_address_lsw;
-/* LSW of 64 bit Payload address.
- * Address should be 32-byte,
- * 4kbyte aligned and must be contiguous memory.
- */
-
-u32 payload_address_msw;
-/* MSW of 64 bit Payload address.
- * In case of 32-bit shared memory address,
- * this field must be set to zero.
- * In case of 36-bit shared memory address,
- * bit-4 to bit-31 must be set to zero.
- * Address should be 32-byte, 4kbyte aligned
- * and must be contiguous memory.
- */
-
-u32 mem_map_handle;
-/* Memory map handle returned by
- * AFE_SERVICE_CMD_SHARED_MEM_MAP_REGIONS commands.
- * Supported Values:
- * - NULL -- Message. The parameter data is in-band.
- * - Non-NULL -- The parameter data is Out-band.Pointer to
- * the physical address
- * in shared memory of the payload data.
- * An optional field is available if parameter
- * data is in-band:
- * afe_param_data_v2 param_data[...].
- * For detailed payload content, see the
- * afe_port_param_data_v2 structure.
- */
-} __packed;
-
-#define AFE_PORT_CMD_SET_PARAM_V2 0x000100EF
-
-struct afe_port_param_data_v2 {
- u32 module_id;
-/* ID of the module to be configured.
- * Supported values: Valid module ID
- */
-
-u32 param_id;
-/* ID of the parameter corresponding to the supported parameters
- * for the module ID.
- * Supported values: Valid parameter ID
- */
-
-u16 param_size;
-/* Actual size of the data for the
- * module_id/param_id pair. The size is a
- * multiple of four bytes.
- * Supported values: > 0
- */
-
-u16 reserved;
-/* This field must be set to zero.
- */
-} __packed;
-
struct afe_loopback_gain_per_path_param {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
u16 rx_port_id;
/* Rx port of the loopback. */
@@ -1547,9 +1694,6 @@
* which enables/disables one AFE loopback.
*/
struct afe_loopback_cfg_v1 {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
u32 loopback_cfg_minor_version;
/* Minor version used for tracking the version of the RMC module
* configuration interface.
@@ -1611,19 +1755,19 @@
struct afe_st_loopback_cfg_v1 {
struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 gain_pdata;
+ struct mem_mapping_hdr mem_hdr;
+ struct param_hdr_v1 gain_pdata;
struct afe_loopback_sidetone_gain gain_data;
- struct afe_port_param_data_v2 cfg_pdata;
+ struct param_hdr_v1 cfg_pdata;
struct loopback_cfg_data cfg_data;
} __packed;
struct afe_loopback_iir_cfg_v2 {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 st_iir_enable_pdata;
- struct afe_mod_enable_param st_iir_mode_enable_data;
- struct afe_port_param_data_v2 st_iir_filter_config_pdata;
+ struct apr_hdr hdr;
+ struct mem_mapping_hdr param;
+ struct param_hdr_v1 st_iir_enable_pdata;
+ struct afe_mod_enable_param st_iir_mode_enable_data;
+ struct param_hdr_v1 st_iir_filter_config_pdata;
struct afe_sidetone_iir_filter_config_params st_iir_filter_config_data;
} __packed;
#define AFE_MODULE_SPEAKER_PROTECTION 0x00010209
@@ -2076,20 +2220,6 @@
*/
} __packed;
-struct afe_spdif_clk_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_spdif_clk_cfg clk_cfg;
-} __packed;
-
-struct afe_spdif_chstatus_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_spdif_ch_status_cfg ch_status;
-} __packed;
-
struct afe_spdif_port_config {
struct afe_param_id_spdif_cfg cfg;
struct afe_param_id_spdif_ch_status_cfg ch_status;
@@ -2608,16 +2738,6 @@
u32 endian;
} __packed;
-struct afe_usb_audio_dev_param_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- union {
- struct afe_param_id_usb_audio_dev_params usb_dev;
- struct afe_param_id_usb_audio_dev_lpcm_fmt lpcm_fmt;
- };
-} __packed;
-
/* This param id is used to configure Real Time Proxy interface. */
#define AFE_PARAM_ID_RT_PROXY_CONFIG 0x00010213
@@ -3030,20 +3150,6 @@
*/
} __packed;
-struct afe_slot_mapping_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_slot_mapping_cfg slot_mapping;
-} __packed;
-
-struct afe_custom_tdm_header_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_custom_tdm_header_cfg custom_tdm_header;
-} __packed;
-
struct afe_tdm_port_config {
struct afe_param_id_tdm_cfg tdm;
struct afe_param_id_slot_mapping_cfg slot_mapping;
@@ -3559,18 +3665,6 @@
struct avs_enc_set_scrambler_param_t enc_set_scrambler_param;
} __packed;
-struct afe_audioif_config_command_no_payload {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
-} __packed;
-
-struct afe_audioif_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- union afe_port_config port;
-} __packed;
-
#define AFE_PORT_CMD_DEVICE_START 0x000100E5
/* Payload of the #AFE_PORT_CMD_DEVICE_START.*/
@@ -3732,13 +3826,8 @@
*/
} __packed;
-#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0
-
-/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command,
- * which queries for one post/preprocessing parameter of a
- * stream.
- */
-struct afe_port_cmd_get_param_v2 {
+/* Used by RTAC */
+struct afe_rtac_get_param_v2 {
u16 port_id;
/* Port interface and direction (Rx or Tx) to start. */
@@ -3784,6 +3873,37 @@
*/
} __packed;
+#define AFE_PORT_CMD_GET_PARAM_V2 0x000100F0
+
+/* Payload of the #AFE_PORT_CMD_GET_PARAM_V2 command,
+ * which queries for one post/preprocessing parameter of a
+ * stream.
+ */
+struct afe_port_cmd_get_param_v2 {
+ struct apr_hdr apr_hdr;
+
+ /* Port interface and direction (Rx or Tx) to start. */
+ u16 port_id;
+
+ /* Maximum data size of the parameter ID/module ID combination.
+ * This is a multiple of four bytes
+ * Supported values: > 0
+ */
+ u16 payload_size;
+
+ /* The memory mapping header to be used when requesting outband */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The module ID of the parameter data requested */
+ u32 module_id;
+
+ /* The parameter ID of the parameter data requested */
+ u32 param_id;
+
+ /* The header information for the parameter data */
+ struct param_hdr_v1 param_hdr;
+} __packed;
+
#define AFE_PORT_CMDRSP_GET_PARAM_V2 0x00010106
/* Payload of the #AFE_PORT_CMDRSP_GET_PARAM_V2 message, which
@@ -3799,6 +3919,41 @@
struct afe_port_cmdrsp_get_param_v2 {
u32 status;
+ struct param_hdr_v1 param_hdr;
+ u8 param_data[0];
+} __packed;
+
+#define AFE_PORT_CMD_GET_PARAM_V3 0x000100FB
+struct afe_port_cmd_get_param_v3 {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* Port ID of the AFE port to configure. Port interface and direction
+ * (Rx or Tx) to configure. An even number represents the Rx direction,
+ * and an odd number represents the Tx direction.
+ */
+ u16 port_id;
+
+ /* Reserved. This field must be set to zero. */
+ u16 reserved;
+
+ /* The memory mapping header to be used when requesting outband */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The header information for the parameter data */
+ struct param_hdr_v3 param_hdr;
+} __packed;
+
+#define AFE_PORT_CMDRSP_GET_PARAM_V3 0x00010108
+struct afe_port_cmdrsp_get_param_v3 {
+ /* The status of the command */
+ uint32_t status;
+
+ /* The header information for the parameter data */
+ struct param_hdr_v3 param_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u8 param_data[0];
} __packed;
#define AFE_PARAM_ID_LPASS_CORE_SHARED_CLOCK_CONFIG 0x0001028C
@@ -3820,13 +3975,6 @@
*/
} __packed;
-struct afe_lpass_core_shared_clk_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg;
-} __packed;
-
/* adsp_afe_service_commands.h */
#define ADSP_MEMORY_MAP_EBI_POOL 0
@@ -6451,59 +6599,33 @@
#define ASM_STREAM_CMD_FLUSH_READBUFS 0x00010C09
#define ASM_STREAM_CMD_SET_PP_PARAMS_V2 0x00010DA1
+#define ASM_STREAM_CMD_SET_PP_PARAMS_V3 0x0001320D
-struct asm_stream_cmd_set_pp_params_v2 {
- u32 data_payload_addr_lsw;
-/* LSW of parameter data payload address. Supported values: any. */
- u32 data_payload_addr_msw;
-/* MSW of Parameter data payload address. Supported values: any.
- * - Must be set to zero for in-band data.
- * - In the case of 32 bit Shared memory address, msw field must be
- * - set to zero.
- * - In the case of 36 bit shared memory address, bit 31 to bit 4 of
- * msw
- *
- * - must be set to zero.
+/*
+ * Structure for the ASM Stream Set PP Params command. Parameter data must be
+ * pre-packed with the correct header for either V2 or V3 when sent in-band.
+ * Use q6core_pack_pp_params to pack the header and data correctly depending on
+ * Instance ID support.
*/
- u32 mem_map_handle;
-/* Supported Values: Any.
- * memory map handle returned by DSP through
- * ASM_CMD_SHARED_MEM_MAP_REGIONS
- * command.
- * if mmhandle is NULL, the ParamData payloads are within the
- * message payload (in-band).
- * If mmhandle is non-NULL, the ParamData payloads begin at the
- * address specified in the address msw and lsw (out-of-band).
- */
+struct asm_stream_cmd_set_pp_params {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
- u32 data_payload_size;
-/* Size in bytes of the variable payload accompanying the
- * message, or in shared memory. This field is used for parsing the
- * parameter payload.
- */
-} __packed;
+ /* The memory mapping header to be used when sending out of band */
+ struct mem_mapping_hdr mem_hdr;
+ /* The total size of the payload, including the parameter header */
+ u32 payload_size;
-struct asm_stream_param_data_v2 {
- u32 module_id;
- /* Unique module ID. */
-
- u32 param_id;
- /* Unique parameter ID. */
-
- u16 param_size;
-/* Data size of the param_id/module_id combination. This is
- * a multiple of 4 bytes.
- */
-
- u16 reserved;
-/* Reserved for future enhancements. This field must be set to
- * zero.
- */
-
+ /* The parameter data to be filled when sent inband. Parameter data
+ * must be pre-packed with parameter header and then copied here. Use
+ * q6core_pack_pp_params to pack the header and param data correctly.
+ */
+ u32 param_data[0];
} __packed;
#define ASM_STREAM_CMD_GET_PP_PARAMS_V2 0x00010DA2
+#define ASM_STREAM_CMD_GET_PP_PARAMS_V3 0x0001320E
struct asm_stream_cmd_get_pp_params_v2 {
u32 data_payload_addr_lsw;
@@ -6681,6 +6803,7 @@
} __packed;
#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V2 0x00010DA4
+#define ASM_STREAM_CMDRSP_GET_PP_PARAMS_V3 0x0001320F
struct asm_stream_cmdrsp_get_pp_params_v2 {
u32 status;
@@ -7456,12 +7579,6 @@
/*< Clients must set this field to zero. */
} __packed;
-struct adm_set_mic_gain_params {
- struct adm_cmd_set_pp_params_v5 params;
- struct adm_param_data_v5 data;
- struct admx_mic_gain mic_gain_data;
-} __packed;
-
/* end_addtogroup audio_pp_param_ids */
/* @ingroup audio_pp_module_ids
@@ -7819,56 +7936,23 @@
#define ADM_CMD_GET_PP_TOPO_MODULE_LIST 0x00010349
#define ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST 0x00010350
+#define ADM_CMD_GET_PP_TOPO_MODULE_LIST_V2 0x00010360
+#define ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST_V2 0x00010361
#define AUDPROC_PARAM_ID_ENABLE 0x00010904
- /*
- * Payload of the ADM_CMD_GET_PP_TOPO_MODULE_LIST command.
- */
-struct adm_cmd_get_pp_topo_module_list_t {
- struct apr_hdr hdr;
- /* Lower 32 bits of the 64-bit parameter data payload address. */
- uint32_t data_payload_addr_lsw;
- /*
- * Upper 32 bits of the 64-bit parameter data payload address.
- *
- *
- * The size of the shared memory, if specified, must be large enough to
- * contain the entire parameter data payload, including the module ID,
- * parameter ID, parameter size, and parameter values.
- */
- uint32_t data_payload_addr_msw;
- /*
- * Unique identifier for an address.
- *
- * This memory map handle is returned by the aDSP through the
- * #ADM_CMD_SHARED_MEM_MAP_REGIONS command.
- *
- * @values
- * - Non-NULL -- On acknowledgment, the parameter data payloads begin at
- * the address specified (out-of-band)
- * - NULL -- The acknowledgment's payload contains the parameter data
- * (in-band) @tablebulletend
- */
- uint32_t mem_map_handle;
+/*
+ * Payload of the ADM_CMD_GET_PP_TOPO_MODULE_LIST command.
+ */
+struct adm_cmd_get_pp_topo_module_list {
+ struct apr_hdr apr_hdr;
+
+ /* The memory mapping header to be used when requesting out of band */
+ struct mem_mapping_hdr mem_hdr;
+
/*
* Maximum data size of the list of modules. This
* field is a multiple of 4 bytes.
*/
- uint16_t param_max_size;
- /* This field must be set to zero. */
- uint16_t reserved;
-} __packed;
-
-/*
- * Payload of the ADM_CMDRSP_GET_PP_TOPO_MODULE_LIST message, which returns
- * module ids in response to an ADM_CMD_GET_PP_TOPO_MODULE_LIST command.
- * Immediately following this structure is the acknowledgment <b>module id
- * data variable payload</b> containing the pre/postprocessing module id
- * values. For an in-band scenario, the variable payload depends on the size
- * of the parameter.
- */
-struct adm_cmd_rsp_get_pp_topo_module_list_t {
- /* Status message (error code). */
- uint32_t status;
+ uint32_t param_max_size;
} __packed;
struct audproc_topology_module_id_info_t {
@@ -7961,9 +8045,6 @@
struct asm_volume_ctrl_master_gain {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint16_t master_gain;
/* Linear gain in Q13 format. */
@@ -7973,10 +8054,6 @@
struct asm_volume_ctrl_lr_chan_gain {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
-
uint16_t l_chan_gain;
/*< Linear gain in Q13 format for the left channel. */
@@ -7996,9 +8073,6 @@
struct asm_volume_ctrl_mute_config {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint32_t mute_flag;
/*< Specifies whether mute is disabled (0) or enabled (nonzero).*/
@@ -8026,9 +8100,6 @@
* parameters used by the Volume Control module.
*/
struct asm_soft_step_volume_params {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint32_t period;
/*< Period in milliseconds.
* Supported values: 0 to 15000
@@ -8058,9 +8129,6 @@
struct asm_soft_pause_params {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint32_t enable_flag;
/*< Specifies whether soft pause is disabled (0) or enabled
* (nonzero).
@@ -8150,10 +8218,7 @@
struct asm_volume_ctrl_multichannel_gain {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
- uint32_t num_channels;
+ uint32_t num_channels;
/*
* Number of channels for which gain values are provided. Any
* channels present in the data for which gain is not provided are
@@ -8178,9 +8243,6 @@
struct asm_volume_ctrl_channelype_mute_pair {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint8_t channelype;
/*< Channel type for which the mute setting is to be applied.
* Supported values:
@@ -8229,9 +8291,6 @@
struct asm_volume_ctrl_multichannel_mute {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint32_t num_channels;
/*< Number of channels for which mute configuration is
* provided. Any channels present in the data for which mute
@@ -8676,9 +8735,6 @@
} __packed;
struct asm_eq_params {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
uint32_t enable_flag;
/*< Specifies whether the equalizer module is disabled (0) or enabled
* (nonzero).
@@ -8717,6 +8773,9 @@
#define VSS_ICOMMON_CMD_SET_PARAM_V2 0x0001133D
#define VSS_ICOMMON_CMD_GET_PARAM_V2 0x0001133E
#define VSS_ICOMMON_RSP_GET_PARAM 0x00011008
+#define VSS_ICOMMON_CMD_SET_PARAM_V3 0x00013245
+#define VSS_ICOMMON_CMD_GET_PARAM_V3 0x00013246
+#define VSS_ICOMMON_RSP_GET_PARAM_V3 0x00013247
#define VSS_MAX_AVCS_NUM_SERVICES 25
@@ -9102,15 +9161,13 @@
} __packed;
struct afe_sp_th_vi_get_param {
- struct apr_hdr hdr;
- struct afe_port_cmd_get_param_v2 get_param;
- struct afe_port_param_data_v2 pdata;
+ struct param_hdr_v3 pdata;
struct afe_sp_th_vi_ftm_params param;
} __packed;
struct afe_sp_th_vi_get_param_resp {
uint32_t status;
- struct afe_port_param_data_v2 pdata;
+ struct param_hdr_v3 pdata;
struct afe_sp_th_vi_ftm_params param;
} __packed;
@@ -9176,15 +9233,13 @@
} __packed;
struct afe_sp_ex_vi_get_param {
- struct apr_hdr hdr;
- struct afe_port_cmd_get_param_v2 get_param;
- struct afe_port_param_data_v2 pdata;
+ struct param_hdr_v3 pdata;
struct afe_sp_ex_vi_ftm_params param;
} __packed;
struct afe_sp_ex_vi_get_param_resp {
uint32_t status;
- struct afe_port_param_data_v2 pdata;
+ struct param_hdr_v3 pdata;
struct afe_sp_ex_vi_ftm_params param;
} __packed;
@@ -9205,23 +9260,16 @@
struct afe_sp_rx_limiter_th_param limiter_th_cfg;
} __packed;
-struct afe_spkr_prot_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- union afe_spkr_prot_config prot_config;
-} __packed;
-
struct afe_spkr_prot_get_vi_calib {
struct apr_hdr hdr;
- struct afe_port_cmd_get_param_v2 get_param;
- struct afe_port_param_data_v2 pdata;
+ struct mem_mapping_hdr mem_hdr;
+ struct param_hdr_v3 pdata;
struct asm_calib_res_cfg res_cfg;
} __packed;
struct afe_spkr_prot_calib_get_resp {
uint32_t status;
- struct afe_port_param_data_v2 pdata;
+ struct param_hdr_v3 pdata;
struct asm_calib_res_cfg res_cfg;
} __packed;
@@ -9350,16 +9398,6 @@
#define ASM_STREAM_POSTPROC_TOPO_ID_DTS_HPX 0x00010DED
#define ASM_STREAM_POSTPROC_TOPO_ID_HPX_PLUS 0x10015000
#define ASM_STREAM_POSTPROC_TOPO_ID_HPX_MASTER 0x10015001
-struct asm_dts_eagle_param {
- struct apr_hdr hdr;
- struct asm_stream_cmd_set_pp_params_v2 param;
- struct asm_stream_param_data_v2 data;
-} __packed;
-
-struct asm_dts_eagle_param_get {
- struct apr_hdr hdr;
- struct asm_stream_cmd_get_pp_params_v2 param;
-} __packed;
/* Opcode to set BT address and license for aptx decoder */
#define APTX_DECODER_BT_ADDRESS 0x00013201
@@ -9468,6 +9506,7 @@
#define LSM_SESSION_CMD_CLOSE_TX (0x00012A88)
#define LSM_SESSION_CMD_SET_PARAMS (0x00012A83)
#define LSM_SESSION_CMD_SET_PARAMS_V2 (0x00012A8F)
+#define LSM_SESSION_CMD_SET_PARAMS_V3 (0x00012A92)
#define LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x00012A84)
#define LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x00012A85)
#define LSM_SESSION_CMD_START (0x00012A86)
@@ -9514,6 +9553,7 @@
/* Commands/Params to pass the codec/slimbus data to DSP */
#define AFE_SVC_CMD_SET_PARAM (0x000100f3)
+#define AFE_SVC_CMD_SET_PARAM_V2 (0x000100fc)
#define AFE_MODULE_CDC_DEV_CFG (0x00010234)
#define AFE_PARAM_ID_CDC_SLIMBUS_SLAVE_CFG (0x00010235)
#define AFE_PARAM_ID_CDC_REG_CFG (0x00010236)
@@ -9913,13 +9953,6 @@
#define AFE_MODULE_CLOCK_SET 0x0001028F
#define AFE_PARAM_ID_CLOCK_SET 0x00010290
-struct afe_lpass_clk_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_clk_cfg clk_cfg;
-} __packed;
-
enum afe_lpass_digital_clk_src {
Q6AFE_LPASS_DIGITAL_ROOT_INVALID,
Q6AFE_LPASS_DIGITAL_ROOT_PRI_MI2S_OSR,
@@ -9955,14 +9988,6 @@
u16 reserved;
} __packed;
-
-struct afe_lpass_digital_clk_config_command {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_digital_clk_cfg clk_cfg;
-} __packed;
-
/*
* Opcode for AFE to start DTMF.
*/
@@ -10071,18 +10096,32 @@
struct afe_param_cdc_reg_cfg *reg_data;
} __packed;
-struct afe_svc_cmd_set_param {
+struct afe_svc_cmd_set_param_v1 {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* The total size of the payload, including param_hdr_v3 */
uint32_t payload_size;
- uint32_t payload_address_lsw;
- uint32_t payload_address_msw;
- uint32_t mem_map_handle;
+
+ /* The memory mapping header to be used when sending outband */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u32 param_data[0];
} __packed;
-struct afe_svc_param_data {
- uint32_t module_id;
- uint32_t param_id;
- uint16_t param_size;
- uint16_t reserved;
+struct afe_svc_cmd_set_param_v2 {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* The memory mapping header to be used when sending outband */
+ struct mem_mapping_hdr mem_hdr;
+
+ /* The total size of the payload, including param_hdr_v3 */
+ u32 payload_size;
+
+ /* The parameter data to be filled when sent inband */
+ u32 param_data[0];
} __packed;
struct afe_param_hw_mad_ctrl {
@@ -10091,87 +10130,9 @@
uint16_t mad_enable;
} __packed;
-struct afe_cmd_hw_mad_ctrl {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_hw_mad_ctrl payload;
-} __packed;
-
-struct afe_cmd_hw_mad_slimbus_slave_port_cfg {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_slimbus_slave_port_cfg sb_port_cfg;
-} __packed;
-
-struct afe_cmd_sw_mad_enable {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
-} __packed;
-
-struct afe_param_cdc_reg_cfg_payload {
- struct afe_svc_param_data common;
- struct afe_param_cdc_reg_cfg reg_cfg;
-} __packed;
-
-struct afe_lpass_clk_config_command_v2 {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_svc_param_data pdata;
- struct afe_clk_set clk_cfg;
-} __packed;
-
-/*
- * reg_data's size can be up to AFE_MAX_CDC_REGISTERS_TO_CONFIG
- */
-struct afe_svc_cmd_cdc_reg_cfg {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_param_cdc_reg_cfg_payload reg_data[0];
-} __packed;
-
-struct afe_svc_cmd_init_cdc_reg_cfg {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_port_param_data_v2 init;
-} __packed;
-
-struct afe_svc_cmd_sb_slave_cfg {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_cdc_slimbus_slave_cfg sb_slave_cfg;
-} __packed;
-
-struct afe_svc_cmd_cdc_reg_page_cfg {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_cdc_reg_page_cfg cdc_reg_page_cfg;
-} __packed;
-
-struct afe_svc_cmd_cdc_aanc_version {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_cdc_aanc_version version;
-} __packed;
-
-struct afe_port_cmd_set_aanc_param {
- struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
- struct afe_port_param_data_v2 pdata;
- union {
- struct afe_param_aanc_port_cfg aanc_port_cfg;
- struct afe_mod_enable_param mod_enable;
- } __packed data;
-} __packed;
-
struct afe_port_cmd_set_aanc_acdb_table {
struct apr_hdr hdr;
- struct afe_port_cmd_set_param_v2 param;
+ struct mem_mapping_hdr mem_hdr;
} __packed;
/* Dolby DAP topology */
@@ -10194,13 +10155,6 @@
#define Q14_GAIN_ZERO_POINT_FIVE 0x2000
#define Q14_GAIN_UNITY 0x4000
-struct afe_svc_cmd_set_clip_bank_selection {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_clip_bank_sel bank_sel;
-} __packed;
-
/* Ultrasound supported formats */
#define US_POINT_EPOS_FORMAT_V2 0x0001272D
#define US_RAW_FORMAT_V2 0x0001272C
@@ -10427,13 +10381,6 @@
struct afe_param_id_group_device_tdm_cfg tdm_cfg;
} __packed;
-struct afe_port_group_create {
- struct apr_hdr hdr;
- struct afe_svc_cmd_set_param param;
- struct afe_port_param_data_v2 pdata;
- union afe_port_group_config data;
-} __packed;
-
/* ID of the parameter used by #AFE_MODULE_AUDIO_DEV_INTERFACE to specify
* the timing statistics of the corresponding device interface.
* Client can periodically query for the device time statistics to help adjust
@@ -10523,16 +10470,9 @@
u32 ref_timer_abs_ts_msw;
} __packed;
-struct afe_av_dev_drift_get_param {
- struct apr_hdr hdr;
- struct afe_port_cmd_get_param_v2 get_param;
- struct afe_port_param_data_v2 pdata;
- struct afe_param_id_dev_timing_stats timing_stats;
-} __packed;
-
struct afe_av_dev_drift_get_param_resp {
uint32_t status;
- struct afe_port_param_data_v2 pdata;
+ struct param_hdr_v3 pdata;
struct afe_param_id_dev_timing_stats timing_stats;
} __packed;
@@ -10744,7 +10684,7 @@
struct asm_mtmx_strtr_params {
struct apr_hdr hdr;
struct asm_session_cmd_set_mtmx_strstr_params_v2 param;
- struct asm_stream_param_data_v2 data;
+ struct param_hdr_v1 data;
union asm_session_mtmx_strtr_param_config config;
} __packed;
@@ -10854,7 +10794,7 @@
struct asm_mtmx_strtr_get_params_cmdrsp {
uint32_t err_code;
- struct asm_stream_param_data_v2 param_info;
+ struct param_hdr_v1 param_info;
union asm_session_mtmx_strtr_data_type param_data;
} __packed;
@@ -10874,18 +10814,14 @@
#define AUDPROC_PARAM_ID_COMPRESSED_MUTE 0x00010771
struct adm_set_compressed_device_mute {
- struct adm_cmd_set_pp_params_v5 command;
- struct adm_param_data_v5 params;
- u32 mute_on;
+ u32 mute_on;
} __packed;
#define AUDPROC_MODULE_ID_COMPRESSED_LATENCY 0x0001076E
#define AUDPROC_PARAM_ID_COMPRESSED_LATENCY 0x0001076F
struct adm_set_compressed_device_latency {
- struct adm_cmd_set_pp_params_v5 command;
- struct adm_param_data_v5 params;
- u32 latency;
+ u32 latency;
} __packed;
#define VOICEPROC_MODULE_ID_GENERIC_TX 0x00010EF6
@@ -10915,12 +10851,6 @@
uint16_t reserved;
} __packed;
-struct adm_set_fluence_soundfocus_param {
- struct adm_cmd_set_pp_params_v5 params;
- struct adm_param_data_v5 data;
- struct adm_param_fluence_soundfocus_t soundfocus_data;
-} __packed;
-
struct adm_param_fluence_sourcetracking_t {
uint8_t vad[MAX_SECTORS];
uint16_t doa_speech;
@@ -10950,10 +10880,4 @@
uint16_t reserved1;
} __packed;
-
-struct adm_set_sec_primary_ch_params {
- struct adm_cmd_set_pp_params_v5 params;
- struct adm_param_data_v5 data;
- struct admx_sec_primary_mic_ch sec_primary_mic_ch_data;
-} __packed;
#endif /*_APR_AUDIO_V2_H_ */
diff --git a/include/dsp/audio_cal_utils.h b/include/dsp/audio_cal_utils.h
index e12d8c1..614ef23 100644
--- a/include/dsp/audio_cal_utils.h
+++ b/include/dsp/audio_cal_utils.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014, 2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -28,8 +28,7 @@
size_t map_size;
int32_t q6map_handle;
int32_t ion_map_handle;
- struct ion_client *ion_client;
- struct ion_handle *ion_handle;
+ struct dma_buf *dma_buf;
};
struct cal_block_data {
@@ -38,6 +37,7 @@
void *cal_info;
struct list_head list;
struct cal_data cal_data;
+ bool cal_stale;
struct mem_map_data map_data;
int32_t buffer_number;
};
@@ -99,4 +99,8 @@
/* Version of the cal type*/
int32_t cal_utils_get_cal_type_version(void *cal_type_data);
+
+void cal_utils_mark_cal_used(struct cal_block_data *cal_block);
+
+bool cal_utils_is_cal_stale(struct cal_block_data *cal_block);
#endif
diff --git a/include/dsp/msm_audio_ion.h b/include/dsp/msm_audio_ion.h
index 8a2fb6e..dae1d1d 100644
--- a/include/dsp/msm_audio_ion.h
+++ b/include/dsp/msm_audio_ion.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -17,29 +17,20 @@
#include <sound/pcm.h>
#include <linux/msm_ion.h>
+enum {
+ MSM_AUDIO_ION_INV_CACHES = 0,
+ MSM_AUDIO_ION_CLEAN_CACHES,
+};
-int msm_audio_ion_alloc(const char *name, struct ion_client **client,
- struct ion_handle **handle, size_t bufsz,
- ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr);
+int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
+ dma_addr_t *paddr, size_t *pa_len, void **vaddr);
-int msm_audio_ion_import(const char *name, struct ion_client **client,
- struct ion_handle **handle, int fd,
+int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
unsigned long *ionflag, size_t bufsz,
- ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr);
-int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle);
-int msm_audio_ion_mmap(struct audio_buffer *substream,
- struct vm_area_struct *vma);
-
-bool msm_audio_ion_is_smmu_available(void);
+ dma_addr_t *paddr, size_t *pa_len, void **vaddr);
+int msm_audio_ion_free(struct dma_buf *dma_buf);
+int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma);
int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op);
-struct ion_client *msm_audio_ion_client_create(const char *name);
-void msm_audio_ion_client_destroy(struct ion_client *client);
-int msm_audio_ion_import_legacy(const char *name, struct ion_client *client,
- struct ion_handle **handle, int fd,
- unsigned long *ionflag, size_t bufsz,
- ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr);
-int msm_audio_ion_free_legacy(struct ion_client *client,
- struct ion_handle *handle);
-u32 msm_audio_populate_upper_32_bits(ion_phys_addr_t pa);
+u32 msm_audio_populate_upper_32_bits(dma_addr_t pa);
#endif /* _LINUX_MSM_AUDIO_ION_H */
diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h
index 19a844c..bc3fdcf 100644
--- a/include/dsp/q6adm-v2.h
+++ b/include/dsp/q6adm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,8 @@
#define MAX_MODULES_IN_TOPO 16
#define ADM_GET_TOPO_MODULE_LIST_LENGTH\
((MAX_MODULES_IN_TOPO + 1) * sizeof(uint32_t))
+#define ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH \
+ ((MAX_MODULES_IN_TOPO + 1) * 2 * sizeof(uint32_t))
#define AUD_PROC_BLOCK_SIZE 4096
#define AUD_VOL_BLOCK_SIZE 4096
#define AUDIO_RX_CALIBRATION_SIZE (AUD_PROC_BLOCK_SIZE + \
@@ -91,14 +93,20 @@
void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate);
-int adm_get_params(int port_id, int copp_idx, uint32_t module_id,
- uint32_t param_id, uint32_t params_length, char *params);
+int adm_get_pp_params(int port_id, int copp_idx, uint32_t client_id,
+ struct mem_mapping_hdr *mem_hdr,
+ struct param_hdr_v3 *param_hdr, u8 *returned_param_data);
int adm_send_params_v5(int port_id, int copp_idx, char *params,
uint32_t params_length);
-int adm_dolby_dap_send_params(int port_id, int copp_idx, char *params,
- uint32_t params_length);
+int adm_set_pp_params(int port_id, int copp_idx,
+ struct mem_mapping_hdr *mem_hdr, u8 *param_data,
+ u32 params_size);
+
+int adm_pack_and_set_one_pp_param(int port_id, int copp_idx,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data);
int adm_open(int port, int path, int rate, int mode, int topology,
int perf_mode, uint16_t bits_per_sample,
@@ -146,6 +154,10 @@
int adm_get_pp_topo_module_list(int port_id, int copp_idx, int32_t param_length,
char *params);
+int adm_get_pp_topo_module_list_v2(int port_id, int copp_idx,
+ int32_t param_length,
+ int32_t *returned_params);
+
int adm_set_volume(int port_id, int copp_idx, int volume);
int adm_set_softvolume(int port_id, int copp_idx,
@@ -158,6 +170,9 @@
int adm_param_enable(int port_id, int copp_idx, int module_id, int enable);
+int adm_param_enable_v2(int port_id, int copp_idx,
+ struct module_instance_info mod_inst_info, int enable);
+
int adm_send_calibration(int port_id, int copp_idx, int path, int perf_mode,
int cal_type, char *params, int size);
@@ -187,5 +202,4 @@
int channel_index);
void msm_dts_srs_acquire_lock(void);
void msm_dts_srs_release_lock(void);
-void adm_set_lsm_port_id(int port_id);
#endif /* __Q6_ADM_V2_H__ */
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 6fb9c44..ade1249 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -246,8 +246,7 @@
uint32_t used;
uint32_t size;/* size of buffer */
uint32_t actual_size; /* actual number of bytes read by DSP */
- struct ion_handle *handle;
- struct ion_client *client;
+ struct dma_buf *dma_buf;
};
struct afe_audio_port_data {
diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h
index 157c243..ba35779 100644
--- a/include/dsp/q6asm-v2.h
+++ b/include/dsp/q6asm-v2.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -165,8 +165,7 @@
uint32_t used;
uint32_t size;/* size of buffer */
uint32_t actual_size; /* actual number of bytes read by DSP */
- struct ion_handle *handle;
- struct ion_client *client;
+ struct dma_buf *dma_buf;
};
struct audio_aio_write_param {
@@ -246,6 +245,11 @@
struct shared_io_config config;
};
+struct q6asm_cal_info {
+ int topology_id;
+ int app_type;
+};
+
void q6asm_audio_client_free(struct audio_client *ac);
struct audio_client *q6asm_audio_client_alloc(app_cb cb, void *priv);
@@ -265,6 +269,17 @@
int q6asm_audio_client_buf_free_contiguous(unsigned int dir,
struct audio_client *ac);
+int q6asm_set_pp_params(struct audio_client *ac,
+ struct mem_mapping_hdr *mem_hdr, u8 *param_data,
+ u32 param_size);
+
+int q6asm_pack_and_set_pp_param_in_band(struct audio_client *ac,
+ struct param_hdr_v3 param_hdr,
+ u8 *param_data);
+
+int q6asm_set_soft_volume_module_instance_ids(int instance,
+ struct param_hdr_v3 *param_hdr);
+
int q6asm_open_read(struct audio_client *ac, uint32_t format
/*, uint16_t bits_per_sample*/);
@@ -625,9 +640,6 @@
int q6asm_get_session_time_legacy(struct audio_client *ac, uint64_t *tstamp);
-int q6asm_send_audio_effects_params(struct audio_client *ac, char *params,
- uint32_t params_length);
-
int q6asm_send_stream_cmd(struct audio_client *ac,
struct msm_adsp_event_data *data);
diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h
new file mode 100644
index 0000000..552f976
--- /dev/null
+++ b/include/dsp/q6common.h
@@ -0,0 +1,23 @@
+/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __Q6COMMON_H__
+#define __Q6COMMON_H__
+
+#include <dsp/apr_audio-v2.h>
+
+void q6common_update_instance_id_support(bool supported);
+bool q6common_is_instance_id_supported(void);
+int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr,
+ u8 *param_data, u32 *total_size);
+
+#endif /* __Q6COMMON_H__ */
diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h
index efce3a6..73168d1 100644
--- a/include/dsp/q6lsm.h
+++ b/include/dsp/q6lsm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -33,8 +33,7 @@
void *data;
size_t size; /* size of buffer */
uint32_t actual_size; /* actual number of bytes read by DSP */
- struct ion_handle *handle;
- struct ion_client *client;
+ struct dma_buf *dma_buf;
uint32_t mem_map_handle;
};
@@ -48,8 +47,7 @@
dma_addr_t phys;
void *data;
size_t size;
- struct ion_handle *handle;
- struct ion_client *client;
+ struct dma_buf *dma_buf;
uint32_t mem_map_handle;
};
@@ -112,31 +110,27 @@
uint32_t buffer_size;
} __packed;
-struct lsm_param_size_reserved {
- uint16_t param_size;
- uint16_t reserved;
+struct lsm_session_cmd_set_params_v2 {
+ struct apr_hdr apr_hdr;
+ uint32_t payload_size;
+ struct mem_mapping_hdr mem_hdr;
+ u32 param_data[0];
} __packed;
-union lsm_param_size {
- uint32_t param_size;
- struct lsm_param_size_reserved sr;
-} __packed;
-
-struct lsm_param_payload_common {
- uint32_t module_id;
- uint32_t param_id;
- union lsm_param_size p_size;
+struct lsm_session_cmd_set_params_v3 {
+ struct apr_hdr apr_hdr;
+ struct mem_mapping_hdr mem_hdr;
+ uint32_t payload_size;
+ u32 param_data[0];
} __packed;
struct lsm_param_op_mode {
- struct lsm_param_payload_common common;
uint32_t minor_version;
uint16_t mode;
uint16_t reserved;
} __packed;
struct lsm_param_connect_to_port {
- struct lsm_param_payload_common common;
uint32_t minor_version;
/* AFE port id that receives voice wake up data */
uint16_t port_id;
@@ -144,20 +138,17 @@
} __packed;
struct lsm_param_poll_enable {
- struct lsm_param_payload_common common;
uint32_t minor_version;
/* indicates to voice wakeup that HW MAD/SW polling is enabled or not */
uint32_t polling_enable;
} __packed;
struct lsm_param_fwk_mode_cfg {
- struct lsm_param_payload_common common;
uint32_t minor_version;
uint32_t mode;
} __packed;
struct lsm_param_media_fmt {
- struct lsm_param_payload_common common;
uint32_t minor_version;
uint32_t sample_rate;
uint16_t num_channels;
@@ -165,78 +156,23 @@
uint8_t channel_mapping[LSM_MAX_NUM_CHANNELS];
} __packed;
-/*
- * This param cannot be sent in this format.
- * The actual number of confidence level values
- * need to appended to this param payload.
- */
-struct lsm_param_min_confidence_levels {
- struct lsm_param_payload_common common;
- uint8_t num_confidence_levels;
-} __packed;
-
-struct lsm_set_params_hdr {
- uint32_t data_payload_size;
- uint32_t data_payload_addr_lsw;
- uint32_t data_payload_addr_msw;
- uint32_t mem_map_handle;
-} __packed;
-
-struct lsm_cmd_set_params {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr param_hdr;
-} __packed;
-
-struct lsm_cmd_set_params_conf {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_param_min_confidence_levels conf_payload;
-} __packed;
-
-struct lsm_cmd_set_params_opmode {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_param_op_mode op_mode;
-} __packed;
-
-struct lsm_cmd_set_connectport {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_param_connect_to_port connect_to_port;
-} __packed;
-
-struct lsm_cmd_poll_enable {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_param_poll_enable poll_enable;
+struct lsm_param_confidence_levels {
+ uint8_t num_confidence_levels;
+ uint8_t confidence_levels[0];
} __packed;
struct lsm_param_epd_thres {
- struct lsm_param_payload_common common;
uint32_t minor_version;
uint32_t epd_begin;
uint32_t epd_end;
} __packed;
-struct lsm_cmd_set_epd_threshold {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr param_hdr;
- struct lsm_param_epd_thres epd_thres;
-} __packed;
-
struct lsm_param_gain {
- struct lsm_param_payload_common common;
uint32_t minor_version;
uint16_t gain;
uint16_t reserved;
} __packed;
-struct lsm_cmd_set_gain {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr param_hdr;
- struct lsm_param_gain lsm_gain;
-} __packed;
-
struct lsm_cmd_reg_snd_model {
struct apr_hdr hdr;
uint32_t model_size;
@@ -245,31 +181,16 @@
uint32_t mem_map_handle;
} __packed;
-struct lsm_lab_enable {
- struct lsm_param_payload_common common;
+struct lsm_param_lab_enable {
uint16_t enable;
uint16_t reserved;
} __packed;
-struct lsm_params_lab_enable {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_lab_enable lab_enable;
-} __packed;
-
-struct lsm_lab_config {
- struct lsm_param_payload_common common;
+struct lsm_param_lab_config {
uint32_t minor_version;
uint32_t wake_up_latency_ms;
} __packed;
-
-struct lsm_params_lab_config {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_lab_config lab_config;
-} __packed;
-
struct lsm_cmd_read {
struct apr_hdr hdr;
uint32_t buf_addr_lsw;
@@ -291,19 +212,6 @@
uint32_t flags;
} __packed;
-struct lsm_cmd_set_fwk_mode_cfg {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_param_fwk_mode_cfg fwk_mode_cfg;
-} __packed;
-
-struct lsm_cmd_set_media_fmt {
- struct apr_hdr msg_hdr;
- struct lsm_set_params_hdr params_hdr;
- struct lsm_param_media_fmt media_fmt;
-} __packed;
-
-
struct lsm_client *q6lsm_client_alloc(lsm_app_cb cb, void *priv);
void q6lsm_client_free(struct lsm_client *client);
int q6lsm_open(struct lsm_client *client, uint16_t app_id);
diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h
index a41a2db..be72b72 100644
--- a/include/dsp/q6voice.h
+++ b/include/dsp/q6voice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -156,8 +156,7 @@
};
struct share_mem_buf {
- struct ion_handle *handle;
- struct ion_client *client;
+ struct dma_buf *dma_buf;
struct mem_buffer buf[NUM_OF_BUFFERS];
};
@@ -165,12 +164,12 @@
dma_addr_t phys;
void *data;
size_t size; /* size of buffer */
- struct ion_handle *handle;
- struct ion_client *client;
+ struct dma_buf *dma_buf;
};
/* Common */
#define VSS_ICOMMON_CMD_SET_UI_PROPERTY 0x00011103
+#define VSS_ICOMMON_CMD_SET_UI_PROPERTY_V2 0x00013248
/* Set a UI property */
#define VSS_ICOMMON_CMD_MAP_MEMORY 0x00011025
#define VSS_ICOMMON_CMD_UNMAP_MEMORY 0x00011026
@@ -212,7 +211,7 @@
struct vss_icommon_cmd_unmap_memory_t vss_unmap_mem;
} __packed;
-struct vss_param_endpoint_media_format_info_t {
+struct vss_param_endpoint_media_format_info {
/* AFE port ID to which this media format corresponds to. */
uint32_t port_id;
/*
@@ -262,27 +261,6 @@
uint16_t channel_type[VSS_NUM_CHANNELS_MAX];
} __packed;
-struct vss_icommon_param_data_t {
- /* Valid ID of the module. */
- uint32_t module_id;
- /* Valid ID of the parameter. */
- uint32_t param_id;
- /*
- * Data size of the structure relating to the param_id/module_id
- * combination in uint8_t bytes.
- */
- uint16_t param_size;
- /* This field must be set to zero. */
- uint16_t reserved;
- /*
- * Parameter data payload when inband. Should have size param_size.
- * Bit size of payload must be a multiple of 4.
- */
- union {
- struct vss_param_endpoint_media_format_info_t media_format_info;
- };
-} __packed;
-
struct vss_icommon_param_data_channel_info_v2_t {
/* Valid ID of the module. */
uint32_t module_id;
@@ -406,8 +384,7 @@
struct vss_icommon_param_data_mfc_config_v2_t param_data;
} __packed;
-/* Payload structure for the VSS_ICOMMON_CMD_SET_PARAM_V2 command. */
-struct vss_icommon_cmd_set_param_v2_t {
+struct vss_icommon_mem_mapping_hdr {
/*
* Pointer to the unique identifier for an address (physical/virtual).
*
@@ -427,10 +404,23 @@
* mem_handle is 0, this field is ignored.
*/
uint64_t mem_address;
+} __packed;
+
+struct vss_icommon_cmd_set_param {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* The memory mapping header to be used when sending outband */
+ struct vss_icommon_mem_mapping_hdr mem_hdr;
+
/* Size of the parameter data payload in bytes. */
- uint32_t mem_size;
- /* Parameter data payload when the data is inband. */
- struct vss_icommon_param_data_t param_data;
+ uint32_t payload_size;
+
+ /*
+ * Parameter data payload when inband. Should have size param_size.
+ * Bit size of payload must be a multiple of 4.
+ */
+ uint8_t param_data[0];
} __packed;
/* TO MVM commands */
@@ -783,7 +773,6 @@
#define MODULE_ID_VOICE_MODULE_ST 0x00010EE3
#define VOICE_PARAM_MOD_ENABLE 0x00010E00
-#define MOD_ENABLE_PARAM_LEN 4
#define VSS_IPLAYBACK_CMD_START 0x000112BD
/* Start in-call music delivery on the Tx voice path. */
@@ -1058,20 +1047,20 @@
*/
} __packed;
-struct vss_icommon_cmd_set_ui_property_enable_t {
- uint32_t module_id;
- /* Unique ID of the module. */
- uint32_t param_id;
- /* Unique ID of the parameter. */
- uint16_t param_size;
- /* Size of the parameter in bytes: MOD_ENABLE_PARAM_LEN */
- uint16_t reserved;
- /* Reserved; set to 0. */
+struct enable_param {
uint16_t enable;
uint16_t reserved_field;
/* Reserved, set to 0. */
};
+struct vss_icommon_cmd_set_ui_property {
+ /* APR Header */
+ struct apr_hdr apr_hdr;
+
+ /* The parameter data to be filled when sent inband */
+ u8 param_data[0];
+} __packed;
+
/*
* Event sent by the stream to the client that enables Rx DTMF
* detection whenever DTMF is detected in the Rx path.
@@ -1180,10 +1169,6 @@
struct apr_hdr hdr;
} __packed;
-struct cvs_set_pp_enable_cmd {
- struct apr_hdr hdr;
- struct vss_icommon_cmd_set_ui_property_enable_t vss_set_pp;
-} __packed;
struct cvs_start_record_cmd {
struct apr_hdr hdr;
struct vss_irecord_cmd_start_t rec_mode;
@@ -1256,6 +1241,8 @@
*/
#define VSS_IVOCPROC_CMD_DEREGISTER_DEVICE_CONFIG 0x00011372
+#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V0 0x00000000
+#define CVD_CAL_DATA_FORMAT_MINOR_VERSION_V1 0x00000001
#define VSS_IVOCPROC_CMD_REGISTER_CALIBRATION_DATA_V2 0x00011373
#define VSS_IVOCPROC_CMD_DEREGISTER_CALIBRATION_DATA 0x00011276
@@ -1635,11 +1622,6 @@
struct vss_ivocproc_cmd_topology_set_dev_channels_t cvp_set_channels;
} __packed;
-struct cvp_set_media_format_cmd {
- struct apr_hdr hdr;
- struct vss_icommon_cmd_set_param_v2_t cvp_set_media_param_v2;
-} __packed;
-
struct cvp_set_channel_info_cmd_v2 {
struct apr_hdr hdr;
struct vss_icommon_cmd_set_param_channel_info_v2_t
@@ -1874,12 +1856,6 @@
struct voice_rec_route_state rec_route_state;
};
-struct cal_mem {
- struct ion_handle *handle;
- uint32_t phy;
- void *buf;
-};
-
#define MAX_VOC_SESSIONS 8
struct common_data {
@@ -1909,9 +1885,6 @@
uint32_t voice_host_pcm_mem_handle;
- struct cal_mem cvp_cal;
- struct cal_mem cvs_cal;
-
struct mutex common_lock;
struct mvs_driver_info mvs_info;
@@ -2003,9 +1976,11 @@
#define VSID_MAX ALL_SESSION_VSID
/* called by alsa driver */
-int voc_set_pp_enable(uint32_t session_id, uint32_t module_id,
+int voc_set_pp_enable(uint32_t session_id,
+ struct module_instance_info mod_inst_info,
uint32_t enable);
-int voc_get_pp_enable(uint32_t session_id, uint32_t module_id);
+int voc_get_pp_enable(uint32_t session_id,
+ struct module_instance_info mod_inst_info);
int voc_set_hd_enable(uint32_t session_id, uint32_t enable);
uint8_t voc_get_tty_mode(uint32_t session_id);
int voc_set_tty_mode(uint32_t session_id, uint8_t tty_mode);
diff --git a/include/dsp/rtac.h b/include/dsp/rtac.h
index f8c5556..05dd82a 100644
--- a/include/dsp/rtac.h
+++ b/include/dsp/rtac.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2013-2015, 2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2013-2015, 2017-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,8 +38,7 @@
struct rtac_cal_mem_map_data {
uint32_t map_size;
uint32_t map_handle;
- struct ion_client *ion_client;
- struct ion_handle *ion_handle;
+ struct dma_buf *dma_buf;
};
struct rtac_cal_data {
diff --git a/include/soc/internal.h b/include/soc/internal.h
index 452d9d2..ad0a98d 120000
--- a/include/soc/internal.h
+++ b/include/soc/internal.h
@@ -1 +1 @@
-../../../../../../kernel/msm-4.9/drivers/base/regmap/internal.h
\ No newline at end of file
+../../../../../../kernel/msm-4.14/drivers/base/regmap/internal.h
\ No newline at end of file
diff --git a/include/uapi/Android.mk b/include/uapi/Android.mk
new file mode 100644
index 0000000..36bcfde
--- /dev/null
+++ b/include/uapi/Android.mk
@@ -0,0 +1,28 @@
+# Use this by setting
+# LOCAL_HEADER_LIBRARIES := audio_kernel_headers
+
+LOCAL_PATH := $(call my-dir)
+MYLOCAL_PATH := $(LOCAL_PATH)
+
+UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include
+
+AUDIO_KERNEL_HEADERS := $(call all-named-files-under,*.h,linux) $(call all-named-files-under,*.h,sound)
+
+HEADER_INSTALL_DIR := kernel/msm-$(TARGET_KERNEL_VERSION)/scripts
+
+BUILD_ROOT_RELATIVE := ../../../../../../../
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := audio_kernel_headers
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_PREBUILT_INT_KERNEL)
+
+GEN := $(addprefix $(UAPI_OUT)/,$(AUDIO_KERNEL_HEADERS))
+$(GEN): PRIVATE_PATH := $(MYLOCAL_PATH)
+$(GEN): PRIVATE_CUSTOM_TOOL = $(shell cd $(PRODUCT_OUT)/obj/KERNEL_OBJ; $(BUILD_ROOT_RELATIVE)$(HEADER_INSTALL_DIR)/headers_install.sh $(BUILD_ROOT_RELATIVE)$(dir $@) $(BUILD_ROOT_RELATIVE)$(subst $(UAPI_OUT),$(MYLOCAL_PATH),$(dir $@)) $(notdir $@))
+$(GEN): $(addprefix $(MYLOCAL_PATH)/,$(AUDIO_KERNEL_HEADERS))
+ $(transform-generated-source)
+
+LOCAL_GENERATED_SOURCES := $(GEN)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(UAPI_OUT)
+
+include $(BUILD_HEADER_LIBRARY)
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index 7647f05..f6af2bf 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -17,3 +17,4 @@
header-y += msm_audio_ape.h
header-y += msm_audio_g711.h
header-y += msm_audio_g711_dec.h
+header-y += mfd/
diff --git a/include/uapi/linux/mfd/Kbuild b/include/uapi/linux/mfd/Kbuild
new file mode 100644
index 0000000..9377c98
--- /dev/null
+++ b/include/uapi/linux/mfd/Kbuild
@@ -0,0 +1 @@
+header-y += wcd9xxx/
diff --git a/include/uapi/linux/mfd/wcd9xxx/Kbuild b/include/uapi/linux/mfd/wcd9xxx/Kbuild
new file mode 100644
index 0000000..8e55965
--- /dev/null
+++ b/include/uapi/linux/mfd/wcd9xxx/Kbuild
@@ -0,0 +1,2 @@
+header-y += wcd9xxx_registers.h
+header-y += wcd9320_registers.h
diff --git a/include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h b/include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h
new file mode 100644
index 0000000..63ab624
--- /dev/null
+++ b/include/uapi/linux/mfd/wcd9xxx/wcd9320_registers.h
@@ -0,0 +1,1399 @@
+#ifndef WCD9320_REGISTERS_H
+#define WCD9320_REGISTERS_H
+
+#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
+
+#define TAIKO_A_CHIP_CTL WCD9XXX_A_CHIP_CTL
+#define TAIKO_A_CHIP_CTL__POR WCD9XXX_A_CHIP_CTL__POR
+#define TAIKO_A_CHIP_STATUS WCD9XXX_A_CHIP_STATUS
+#define TAIKO_A_CHIP_STATUS__POR WCD9XXX_A_CHIP_STATUS__POR
+#define TAIKO_A_CHIP_ID_BYTE_0 WCD9XXX_A_CHIP_ID_BYTE_0
+#define TAIKO_A_CHIP_ID_BYTE_0__POR WCD9XXX_A_CHIP_ID_BYTE_0__POR
+#define TAIKO_A_CHIP_ID_BYTE_1 WCD9XXX_A_CHIP_ID_BYTE_1
+#define TAIKO_A_CHIP_ID_BYTE_1__POR WCD9XXX_A_CHIP_ID_BYTE_1__POR
+#define TAIKO_A_CHIP_ID_BYTE_2 WCD9XXX_A_CHIP_ID_BYTE_2
+#define TAIKO_A_CHIP_ID_BYTE_2__POR WCD9XXX_A_CHIP_ID_BYTE_2__POR
+#define TAIKO_A_CHIP_ID_BYTE_3 WCD9XXX_A_CHIP_ID_BYTE_3
+#define TAIKO_A_CHIP_ID_BYTE_3__POR WCD9XXX_A_CHIP_ID_BYTE_3__POR
+#define TAIKO_A_CHIP_VERSION WCD9XXX_A_CHIP_VERSION
+#define TAIKO_A_CHIP_VERSION__POR WCD9XXX_A_CHIP_VERSION__POR
+#define TAIKO_A_SB_VERSION WCD9XXX_A_SB_VERSION
+#define TAIKO_A_SB_VERSION__POR WCD9XXX_A_SB_VERSION__POR
+#define TAIKO_A_SLAVE_ID_1 WCD9XXX_A_SLAVE_ID_1
+#define TAIKO_A_SLAVE_ID_1__POR WCD9XXX_A_SLAVE_ID_1__POR
+#define TAIKO_A_SLAVE_ID_2 WCD9XXX_A_SLAVE_ID_2
+#define TAIKO_A_SLAVE_ID_2__POR WCD9XXX_A_SLAVE_ID_2__POR
+#define TAIKO_A_SLAVE_ID_3 WCD9XXX_A_SLAVE_ID_3
+#define TAIKO_A_SLAVE_ID_3__POR WCD9XXX_A_SLAVE_ID_3__POR
+#define TAIKO_A_PIN_CTL_OE0 (0x010)
+#define TAIKO_A_PIN_CTL_OE0__POR (0x00)
+#define TAIKO_A_PIN_CTL_OE1 (0x011)
+#define TAIKO_A_PIN_CTL_OE1__POR (0x00)
+#define TAIKO_A_PIN_CTL_DATA0 (0x012)
+#define TAIKO_A_PIN_CTL_DATA0__POR (0x00)
+#define TAIKO_A_PIN_CTL_DATA1 (0x013)
+#define TAIKO_A_PIN_CTL_DATA1__POR (0x00)
+#define TAIKO_A_HDRIVE_GENERIC (0x018)
+#define TAIKO_A_HDRIVE_GENERIC__POR (0x00)
+#define TAIKO_A_HDRIVE_OVERRIDE (0x019)
+#define TAIKO_A_HDRIVE_OVERRIDE__POR (0x08)
+#define TAIKO_A_ANA_CSR_WAIT_STATE (0x020)
+#define TAIKO_A_ANA_CSR_WAIT_STATE__POR (0x44)
+#define TAIKO_A_PROCESS_MONITOR_CTL0 (0x040)
+#define TAIKO_A_PROCESS_MONITOR_CTL0__POR (0x80)
+#define TAIKO_A_PROCESS_MONITOR_CTL1 (0x041)
+#define TAIKO_A_PROCESS_MONITOR_CTL1__POR (0x00)
+#define TAIKO_A_PROCESS_MONITOR_CTL2 (0x042)
+#define TAIKO_A_PROCESS_MONITOR_CTL2__POR (0x00)
+#define TAIKO_A_PROCESS_MONITOR_CTL3 (0x043)
+#define TAIKO_A_PROCESS_MONITOR_CTL3__POR (0x01)
+#define TAIKO_A_QFUSE_CTL (0x048)
+#define TAIKO_A_QFUSE_CTL__POR (0x00)
+#define TAIKO_A_QFUSE_STATUS (0x049)
+#define TAIKO_A_QFUSE_STATUS__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT0 (0x04A)
+#define TAIKO_A_QFUSE_DATA_OUT0__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT1 (0x04B)
+#define TAIKO_A_QFUSE_DATA_OUT1__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT2 (0x04C)
+#define TAIKO_A_QFUSE_DATA_OUT2__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT3 (0x04D)
+#define TAIKO_A_QFUSE_DATA_OUT3__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT4 (0x04E)
+#define TAIKO_A_QFUSE_DATA_OUT4__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT5 (0x04F)
+#define TAIKO_A_QFUSE_DATA_OUT5__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT6 (0x050)
+#define TAIKO_A_QFUSE_DATA_OUT6__POR (0x00)
+#define TAIKO_A_QFUSE_DATA_OUT7 (0x051)
+#define TAIKO_A_QFUSE_DATA_OUT7__POR (0x00)
+#define TAIKO_A_CDC_CTL WCD9XXX_A_CDC_CTL
+#define TAIKO_A_CDC_CTL__POR WCD9XXX_A_CDC_CTL__POR
+#define TAIKO_A_LEAKAGE_CTL WCD9XXX_A_LEAKAGE_CTL
+#define TAIKO_A_LEAKAGE_CTL__POR WCD9XXX_A_LEAKAGE_CTL__POR
+#define TAIKO_A_INTR_MODE (0x090)
+#define TAIKO_A_INTR_MODE__POR (0x00)
+#define TAIKO_A_INTR_MASK0 (0x094)
+#define TAIKO_A_INTR_MASK0__POR (0xFF)
+#define TAIKO_A_INTR_MASK1 (0x095)
+#define TAIKO_A_INTR_MASK1__POR (0xFF)
+#define TAIKO_A_INTR_MASK2 (0x096)
+#define TAIKO_A_INTR_MASK2__POR (0x3F)
+#define TAIKO_A_INTR_MASK3 (0x097)
+#define TAIKO_A_INTR_MASK3__POR (0x3F)
+#define TAIKO_A_INTR_STATUS0 (0x098)
+#define TAIKO_A_INTR_STATUS0__POR (0x00)
+#define TAIKO_A_INTR_STATUS1 (0x099)
+#define TAIKO_A_INTR_STATUS1__POR (0x00)
+#define TAIKO_A_INTR_STATUS2 (0x09A)
+#define TAIKO_A_INTR_STATUS2__POR (0x00)
+#define TAIKO_A_INTR_STATUS3 (0x09B)
+#define TAIKO_A_INTR_STATUS3__POR (0x00)
+#define TAIKO_A_INTR_CLEAR0 (0x09C)
+#define TAIKO_A_INTR_CLEAR0__POR (0x00)
+#define TAIKO_A_INTR_CLEAR1 (0x09D)
+#define TAIKO_A_INTR_CLEAR1__POR (0x00)
+#define TAIKO_A_INTR_CLEAR2 (0x09E)
+#define TAIKO_A_INTR_CLEAR2__POR (0x00)
+#define TAIKO_A_INTR_CLEAR3 (0x09F)
+#define TAIKO_A_INTR_CLEAR3__POR (0x00)
+#define TAIKO_A_INTR_LEVEL0 (0x0A0)
+#define TAIKO_A_INTR_LEVEL0__POR (0x01)
+#define TAIKO_A_INTR_LEVEL1 (0x0A1)
+#define TAIKO_A_INTR_LEVEL1__POR (0x00)
+#define TAIKO_A_INTR_LEVEL2 (0x0A2)
+#define TAIKO_A_INTR_LEVEL2__POR (0x00)
+#define TAIKO_A_INTR_LEVEL3 (0x0A3)
+#define TAIKO_A_INTR_LEVEL3__POR (0x00)
+#define TAIKO_A_INTR_TEST0 (0x0A4)
+#define TAIKO_A_INTR_TEST0__POR (0x00)
+#define TAIKO_A_INTR_TEST1 (0x0A5)
+#define TAIKO_A_INTR_TEST1__POR (0x00)
+#define TAIKO_A_INTR_TEST2 (0x0A6)
+#define TAIKO_A_INTR_TEST2__POR (0x00)
+#define TAIKO_A_INTR_TEST3 (0x0A7)
+#define TAIKO_A_INTR_TEST3__POR (0x00)
+#define TAIKO_A_INTR_SET0 (0x0A8)
+#define TAIKO_A_INTR_SET0__POR (0x00)
+#define TAIKO_A_INTR_SET1 (0x0A9)
+#define TAIKO_A_INTR_SET1__POR (0x00)
+#define TAIKO_A_INTR_SET2 (0x0AA)
+#define TAIKO_A_INTR_SET2__POR (0x00)
+#define TAIKO_A_INTR_SET3 (0x0AB)
+#define TAIKO_A_INTR_SET3__POR (0x00)
+#define TAIKO_A_INTR_DESTN0 (0x0AC)
+#define TAIKO_A_INTR_DESTN0__POR (0x00)
+#define TAIKO_A_INTR_DESTN1 (0x0AD)
+#define TAIKO_A_INTR_DESTN1__POR (0x00)
+#define TAIKO_A_INTR_DESTN2 (0x0AE)
+#define TAIKO_A_INTR_DESTN2__POR (0x00)
+#define TAIKO_A_INTR_DESTN3 (0x0AF)
+#define TAIKO_A_INTR_DESTN3__POR (0x00)
+#define TAIKO_A_CDC_TX_I2S_SCK_MODE (0x0C0)
+#define TAIKO_A_CDC_TX_I2S_SCK_MODE__POR (0x00)
+#define TAIKO_A_CDC_TX_I2S_WS_MODE (0x0C1)
+#define TAIKO_A_CDC_TX_I2S_WS_MODE__POR (0x00)
+#define TAIKO_A_CDC_DMIC_DATA0_MODE (0x0C4)
+#define TAIKO_A_CDC_DMIC_DATA0_MODE__POR (0x00)
+#define TAIKO_A_CDC_DMIC_CLK0_MODE (0x0C5)
+#define TAIKO_A_CDC_DMIC_CLK0_MODE__POR (0x00)
+#define TAIKO_A_CDC_DMIC_DATA1_MODE (0x0C6)
+#define TAIKO_A_CDC_DMIC_DATA1_MODE__POR (0x00)
+#define TAIKO_A_CDC_DMIC_CLK1_MODE (0x0C7)
+#define TAIKO_A_CDC_DMIC_CLK1_MODE__POR (0x00)
+#define TAIKO_A_CDC_RX_I2S_SCK_MODE (0x0C8)
+#define TAIKO_A_CDC_RX_I2S_SCK_MODE__POR (0x00)
+#define TAIKO_A_CDC_RX_I2S_WS_MODE (0x0C9)
+#define TAIKO_A_CDC_RX_I2S_WS_MODE__POR (0x00)
+#define TAIKO_A_CDC_DMIC_DATA2_MODE (0x0CA)
+#define TAIKO_A_CDC_DMIC_DATA2_MODE__POR (0x00)
+#define TAIKO_A_CDC_DMIC_CLK2_MODE (0x0CB)
+#define TAIKO_A_CDC_DMIC_CLK2_MODE__POR (0x00)
+#define TAIKO_A_CDC_INTR1_MODE (0x0CC)
+#define TAIKO_A_CDC_INTR1_MODE__POR (0x00)
+#define TAIKO_A_CDC_SB_NRZ_SEL_MODE (0x0CD)
+#define TAIKO_A_CDC_SB_NRZ_SEL_MODE__POR (0x00)
+#define TAIKO_A_CDC_INTR2_MODE (0x0CE)
+#define TAIKO_A_CDC_INTR2_MODE__POR (0x00)
+#define TAIKO_A_CDC_RF_PA_ON_MODE (0x0CF)
+#define TAIKO_A_CDC_RF_PA_ON_MODE__POR (0x00)
+#define TAIKO_A_BIAS_REF_CTL (0x100)
+#define TAIKO_A_BIAS_REF_CTL__POR (0x1C)
+#define TAIKO_A_BIAS_CENTRAL_BG_CTL (0x101)
+#define TAIKO_A_BIAS_CENTRAL_BG_CTL__POR (0x50)
+#define TAIKO_A_BIAS_PRECHRG_CTL (0x102)
+#define TAIKO_A_BIAS_PRECHRG_CTL__POR (0x07)
+#define TAIKO_A_BIAS_CURR_CTL_1 (0x103)
+#define TAIKO_A_BIAS_CURR_CTL_1__POR (0x52)
+#define TAIKO_A_BIAS_CURR_CTL_2 (0x104)
+#define TAIKO_A_BIAS_CURR_CTL_2__POR (0x00)
+#define TAIKO_A_BIAS_OSC_BG_CTL (0x105)
+#define TAIKO_A_BIAS_OSC_BG_CTL__POR (0x16)
+#define TAIKO_A_CLK_BUFF_EN1 (0x108)
+#define TAIKO_A_CLK_BUFF_EN1__POR (0x04)
+#define TAIKO_A_CLK_BUFF_EN2 (0x109)
+#define TAIKO_A_CLK_BUFF_EN2__POR (0x02)
+#define TAIKO_A_LDO_H_MODE_1 (0x110)
+#define TAIKO_A_LDO_H_MODE_1__POR (0x65)
+#define TAIKO_A_LDO_H_MODE_2 (0x111)
+#define TAIKO_A_LDO_H_MODE_2__POR (0xA8)
+#define TAIKO_A_LDO_H_LOOP_CTL (0x112)
+#define TAIKO_A_LDO_H_LOOP_CTL__POR (0x6B)
+#define TAIKO_A_LDO_H_COMP_1 (0x113)
+#define TAIKO_A_LDO_H_COMP_1__POR (0x84)
+#define TAIKO_A_LDO_H_COMP_2 (0x114)
+#define TAIKO_A_LDO_H_COMP_2__POR (0xE0)
+#define TAIKO_A_LDO_H_BIAS_1 (0x115)
+#define TAIKO_A_LDO_H_BIAS_1__POR (0x6D)
+#define TAIKO_A_LDO_H_BIAS_2 (0x116)
+#define TAIKO_A_LDO_H_BIAS_2__POR (0xA5)
+#define TAIKO_A_LDO_H_BIAS_3 (0x117)
+#define TAIKO_A_LDO_H_BIAS_3__POR (0x60)
+#define TAIKO_A_VBAT_CLK (0x118)
+#define TAIKO_A_VBAT_CLK__POR (0x03)
+#define TAIKO_A_VBAT_LOOP (0x119)
+#define TAIKO_A_VBAT_LOOP__POR (0x02)
+#define TAIKO_A_VBAT_REF (0x11A)
+#define TAIKO_A_VBAT_REF__POR (0x20)
+#define TAIKO_A_VBAT_ADC_TEST (0x11B)
+#define TAIKO_A_VBAT_ADC_TEST__POR (0x00)
+#define TAIKO_A_VBAT_FE (0x11C)
+#define TAIKO_A_VBAT_FE__POR (0x48)
+#define TAIKO_A_VBAT_BIAS_1 (0x11D)
+#define TAIKO_A_VBAT_BIAS_1__POR (0x03)
+#define TAIKO_A_VBAT_BIAS_2 (0x11E)
+#define TAIKO_A_VBAT_BIAS_2__POR (0x00)
+#define TAIKO_A_VBAT_ADC_DATA_MSB (0x11F)
+#define TAIKO_A_VBAT_ADC_DATA_MSB__POR (0x00)
+#define TAIKO_A_VBAT_ADC_DATA_LSB (0x120)
+#define TAIKO_A_VBAT_ADC_DATA_LSB__POR (0x00)
+#define TAIKO_A_MICB_CFILT_1_CTL (0x128)
+#define TAIKO_A_MICB_CFILT_1_CTL__POR (0x40)
+#define TAIKO_A_MICB_CFILT_1_VAL (0x129)
+#define TAIKO_A_MICB_CFILT_1_VAL__POR (0x80)
+#define TAIKO_A_MICB_CFILT_1_PRECHRG (0x12A)
+#define TAIKO_A_MICB_CFILT_1_PRECHRG__POR (0x38)
+#define TAIKO_A_MICB_1_CTL (0x12B)
+#define TAIKO_A_MICB_1_CTL__POR (0x16)
+#define TAIKO_A_MICB_1_INT_RBIAS (0x12C)
+#define TAIKO_A_MICB_1_INT_RBIAS__POR (0x24)
+#define TAIKO_A_MICB_1_MBHC (0x12D)
+#define TAIKO_A_MICB_1_MBHC__POR (0x01)
+#define TAIKO_A_MICB_CFILT_2_CTL (0x12E)
+#define TAIKO_A_MICB_CFILT_2_CTL__POR (0x40)
+#define TAIKO_A_MICB_CFILT_2_VAL (0x12F)
+#define TAIKO_A_MICB_CFILT_2_VAL__POR (0x80)
+#define TAIKO_A_MICB_CFILT_2_PRECHRG (0x130)
+#define TAIKO_A_MICB_CFILT_2_PRECHRG__POR (0x38)
+#define TAIKO_A_MICB_2_CTL (0x131)
+#define TAIKO_A_MICB_2_CTL__POR (0x16)
+#define TAIKO_A_MICB_2_INT_RBIAS (0x132)
+#define TAIKO_A_MICB_2_INT_RBIAS__POR (0x24)
+#define TAIKO_A_MICB_2_MBHC (0x133)
+#define TAIKO_A_MICB_2_MBHC__POR (0x02)
+#define TAIKO_A_MICB_CFILT_3_CTL (0x134)
+#define TAIKO_A_MICB_CFILT_3_CTL__POR (0x40)
+#define TAIKO_A_MICB_CFILT_3_VAL (0x135)
+#define TAIKO_A_MICB_CFILT_3_VAL__POR (0x80)
+#define TAIKO_A_MICB_CFILT_3_PRECHRG (0x136)
+#define TAIKO_A_MICB_CFILT_3_PRECHRG__POR (0x38)
+#define TAIKO_A_MICB_3_CTL (0x137)
+#define TAIKO_A_MICB_3_CTL__POR (0x16)
+#define TAIKO_A_MICB_3_INT_RBIAS (0x138)
+#define TAIKO_A_MICB_3_INT_RBIAS__POR (0x24)
+#define TAIKO_A_MICB_3_MBHC (0x139)
+#define TAIKO_A_MICB_3_MBHC__POR (0x00)
+#define TAIKO_A_MICB_4_CTL (0x13D)
+#define TAIKO_A_MICB_4_CTL__POR (0x16)
+#define TAIKO_A_MICB_4_INT_RBIAS (0x13E)
+#define TAIKO_A_MICB_4_INT_RBIAS__POR (0x24)
+#define TAIKO_A_MICB_4_MBHC (0x13F)
+#define TAIKO_A_MICB_4_MBHC__POR (0x01)
+#define TAIKO_A_MBHC_INSERT_DETECT (0x14A)
+#define TAIKO_A_MBHC_INSERT_DETECT__POR (0x00)
+#define TAIKO_A_MBHC_INSERT_DET_STATUS (0x14B)
+#define TAIKO_A_MBHC_INSERT_DET_STATUS__POR (0x00)
+#define TAIKO_A_TX_COM_BIAS (0x14C)
+#define TAIKO_A_TX_COM_BIAS__POR (0xF0)
+#define TAIKO_A_MBHC_SCALING_MUX_1 (0x14E)
+#define TAIKO_A_MBHC_SCALING_MUX_1__POR (0x00)
+#define TAIKO_A_MBHC_SCALING_MUX_2 (0x14F)
+#define TAIKO_A_MBHC_SCALING_MUX_2__POR (0x80)
+#define TAIKO_A_MAD_ANA_CTRL (0x150)
+#define TAIKO_A_MAD_ANA_CTRL__POR (0xF1)
+#define TAIKO_A_TX_SUP_SWITCH_CTRL_1 (0x151)
+#define TAIKO_A_TX_SUP_SWITCH_CTRL_1__POR (0x00)
+#define TAIKO_A_TX_SUP_SWITCH_CTRL_2 (0x152)
+#define TAIKO_A_TX_SUP_SWITCH_CTRL_2__POR (0x80)
+#define TAIKO_A_TX_1_2_EN (0x153)
+#define TAIKO_A_TX_1_2_EN__POR (0x00)
+#define TAIKO_A_TX_1_2_TEST_EN (0x154)
+#define TAIKO_A_TX_1_2_TEST_EN__POR (0xCC)
+#define TAIKO_A_TX_1_2_ADC_CH1 (0x155)
+#define TAIKO_A_TX_1_2_ADC_CH1__POR (0x44)
+#define TAIKO_A_TX_1_2_ADC_CH2 (0x156)
+#define TAIKO_A_TX_1_2_ADC_CH2__POR (0x44)
+#define TAIKO_A_TX_1_2_ATEST_REFCTRL (0x157)
+#define TAIKO_A_TX_1_2_ATEST_REFCTRL__POR (0x00)
+#define TAIKO_A_TX_1_2_TEST_CTL (0x158)
+#define TAIKO_A_TX_1_2_TEST_CTL__POR (0x38)
+#define TAIKO_A_TX_1_2_TEST_BLOCK_EN (0x159)
+#define TAIKO_A_TX_1_2_TEST_BLOCK_EN__POR (0xFC)
+#define TAIKO_A_TX_1_2_TXFE_CLKDIV (0x15A)
+#define TAIKO_A_TX_1_2_TXFE_CLKDIV__POR (0x55)
+#define TAIKO_A_TX_1_2_SAR_ERR_CH1 (0x15B)
+#define TAIKO_A_TX_1_2_SAR_ERR_CH1__POR (0x00)
+#define TAIKO_A_TX_1_2_SAR_ERR_CH2 (0x15C)
+#define TAIKO_A_TX_1_2_SAR_ERR_CH2__POR (0x00)
+#define TAIKO_A_TX_3_4_EN (0x15D)
+#define TAIKO_A_TX_3_4_EN__POR (0x00)
+#define TAIKO_A_TX_3_4_TEST_EN (0x15E)
+#define TAIKO_A_TX_3_4_TEST_EN__POR (0xCC)
+#define TAIKO_A_TX_3_4_ADC_CH3 (0x15F)
+#define TAIKO_A_TX_3_4_ADC_CH3__POR (0x44)
+#define TAIKO_A_TX_3_4_ADC_CH4 (0x160)
+#define TAIKO_A_TX_3_4_ADC_CH4__POR (0x44)
+#define TAIKO_A_TX_3_4_ATEST_REFCTRL (0x161)
+#define TAIKO_A_TX_3_4_ATEST_REFCTRL__POR (0x00)
+#define TAIKO_A_TX_3_4_TEST_CTL (0x162)
+#define TAIKO_A_TX_3_4_TEST_CTL__POR (0x38)
+#define TAIKO_A_TX_3_4_TEST_BLOCK_EN (0x163)
+#define TAIKO_A_TX_3_4_TEST_BLOCK_EN__POR (0xFC)
+#define TAIKO_A_TX_3_4_TXFE_CKDIV (0x164)
+#define TAIKO_A_TX_3_4_TXFE_CKDIV__POR (0x55)
+#define TAIKO_A_TX_3_4_SAR_ERR_CH3 (0x165)
+#define TAIKO_A_TX_3_4_SAR_ERR_CH3__POR (0x00)
+#define TAIKO_A_TX_3_4_SAR_ERR_CH4 (0x166)
+#define TAIKO_A_TX_3_4_SAR_ERR_CH4__POR (0x00)
+#define TAIKO_A_TX_5_6_EN (0x167)
+#define TAIKO_A_TX_5_6_EN__POR (0x11)
+#define TAIKO_A_TX_5_6_TEST_EN (0x168)
+#define TAIKO_A_TX_5_6_TEST_EN__POR (0xCC)
+#define TAIKO_A_TX_5_6_ADC_CH5 (0x169)
+#define TAIKO_A_TX_5_6_ADC_CH5__POR (0x44)
+#define TAIKO_A_TX_5_6_ADC_CH6 (0x16A)
+#define TAIKO_A_TX_5_6_ADC_CH6__POR (0x44)
+#define TAIKO_A_TX_5_6_ATEST_REFCTRL (0x16B)
+#define TAIKO_A_TX_5_6_ATEST_REFCTRL__POR (0x00)
+#define TAIKO_A_TX_5_6_TEST_CTL (0x16C)
+#define TAIKO_A_TX_5_6_TEST_CTL__POR (0x38)
+#define TAIKO_A_TX_5_6_TEST_BLOCK_EN (0x16D)
+#define TAIKO_A_TX_5_6_TEST_BLOCK_EN__POR (0xFC)
+#define TAIKO_A_TX_5_6_TXFE_CKDIV (0x16E)
+#define TAIKO_A_TX_5_6_TXFE_CKDIV__POR (0x55)
+#define TAIKO_A_TX_5_6_SAR_ERR_CH5 (0x16F)
+#define TAIKO_A_TX_5_6_SAR_ERR_CH5__POR (0x00)
+#define TAIKO_A_TX_5_6_SAR_ERR_CH6 (0x170)
+#define TAIKO_A_TX_5_6_SAR_ERR_CH6__POR (0x00)
+#define TAIKO_A_TX_7_MBHC_EN (0x171)
+#define TAIKO_A_TX_7_MBHC_EN__POR (0x0C)
+#define TAIKO_A_TX_7_MBHC_ATEST_REFCTRL (0x172)
+#define TAIKO_A_TX_7_MBHC_ATEST_REFCTRL__POR (0x00)
+#define TAIKO_A_TX_7_MBHC_ADC (0x173)
+#define TAIKO_A_TX_7_MBHC_ADC__POR (0x44)
+#define TAIKO_A_TX_7_MBHC_TEST_CTL (0x174)
+#define TAIKO_A_TX_7_MBHC_TEST_CTL__POR (0x38)
+#define TAIKO_A_TX_7_MBHC_SAR_ERR (0x175)
+#define TAIKO_A_TX_7_MBHC_SAR_ERR__POR (0x00)
+#define TAIKO_A_TX_7_TXFE_CLKDIV (0x176)
+#define TAIKO_A_TX_7_TXFE_CLKDIV__POR (0x0B)
+#define TAIKO_A_BUCK_MODE_1 (0x181)
+#define TAIKO_A_BUCK_MODE_1__POR (0x21)
+#define TAIKO_A_BUCK_MODE_2 (0x182)
+#define TAIKO_A_BUCK_MODE_2__POR (0xFF)
+#define TAIKO_A_BUCK_MODE_3 (0x183)
+#define TAIKO_A_BUCK_MODE_3__POR (0xCC)
+#define TAIKO_A_BUCK_MODE_4 (0x184)
+#define TAIKO_A_BUCK_MODE_4__POR (0x3A)
+#define TAIKO_A_BUCK_MODE_5 (0x185)
+#define TAIKO_A_BUCK_MODE_5__POR (0x00)
+#define TAIKO_A_BUCK_CTRL_VCL_1 (0x186)
+#define TAIKO_A_BUCK_CTRL_VCL_1__POR (0x48)
+#define TAIKO_A_BUCK_CTRL_VCL_2 (0x187)
+#define TAIKO_A_BUCK_CTRL_VCL_2__POR (0xA3)
+#define TAIKO_A_BUCK_CTRL_VCL_3 (0x188)
+#define TAIKO_A_BUCK_CTRL_VCL_3__POR (0x82)
+#define TAIKO_A_BUCK_CTRL_CCL_1 (0x189)
+#define TAIKO_A_BUCK_CTRL_CCL_1__POR (0xAB)
+#define TAIKO_A_BUCK_CTRL_CCL_2 (0x18A)
+#define TAIKO_A_BUCK_CTRL_CCL_2__POR (0xDC)
+#define TAIKO_A_BUCK_CTRL_CCL_3 (0x18B)
+#define TAIKO_A_BUCK_CTRL_CCL_3__POR (0x6A)
+#define TAIKO_A_BUCK_CTRL_CCL_4 (0x18C)
+#define TAIKO_A_BUCK_CTRL_CCL_4__POR (0x58)
+#define TAIKO_A_BUCK_CTRL_PWM_DRVR_1 (0x18D)
+#define TAIKO_A_BUCK_CTRL_PWM_DRVR_1__POR (0x50)
+#define TAIKO_A_BUCK_CTRL_PWM_DRVR_2 (0x18E)
+#define TAIKO_A_BUCK_CTRL_PWM_DRVR_2__POR (0x64)
+#define TAIKO_A_BUCK_CTRL_PWM_DRVR_3 (0x18F)
+#define TAIKO_A_BUCK_CTRL_PWM_DRVR_3__POR (0x77)
+#define TAIKO_A_BUCK_TMUX_A_D (0x190)
+#define TAIKO_A_BUCK_TMUX_A_D__POR (0x00)
+#define TAIKO_A_NCP_BUCKREF (0x191)
+#define TAIKO_A_NCP_BUCKREF__POR (0x00)
+#define TAIKO_A_NCP_EN (0x192)
+#define TAIKO_A_NCP_EN__POR (0xFE)
+#define TAIKO_A_NCP_CLK (0x193)
+#define TAIKO_A_NCP_CLK__POR (0x94)
+#define TAIKO_A_NCP_STATIC (0x194)
+#define TAIKO_A_NCP_STATIC__POR (0x28)
+#define TAIKO_A_NCP_VTH_LOW (0x195)
+#define TAIKO_A_NCP_VTH_LOW__POR (0x88)
+#define TAIKO_A_NCP_VTH_HIGH (0x196)
+#define TAIKO_A_NCP_VTH_HIGH__POR (0xA0)
+#define TAIKO_A_NCP_ATEST (0x197)
+#define TAIKO_A_NCP_ATEST__POR (0x00)
+#define TAIKO_A_NCP_DTEST (0x198)
+#define TAIKO_A_NCP_DTEST__POR (0x00)
+#define TAIKO_A_NCP_DLY1 (0x199)
+#define TAIKO_A_NCP_DLY1__POR (0x06)
+#define TAIKO_A_NCP_DLY2 (0x19A)
+#define TAIKO_A_NCP_DLY2__POR (0x06)
+#define TAIKO_A_RX_AUX_SW_CTL (0x19B)
+#define TAIKO_A_RX_AUX_SW_CTL__POR (0x00)
+#define TAIKO_A_RX_PA_AUX_IN_CONN (0x19C)
+#define TAIKO_A_RX_PA_AUX_IN_CONN__POR (0x00)
+#define TAIKO_A_RX_COM_TIMER_DIV (0x19E)
+#define TAIKO_A_RX_COM_TIMER_DIV__POR (0xE8)
+#define TAIKO_A_RX_COM_OCP_CTL (0x19F)
+#define TAIKO_A_RX_COM_OCP_CTL__POR (0x1F)
+#define TAIKO_A_RX_COM_OCP_COUNT (0x1A0)
+#define TAIKO_A_RX_COM_OCP_COUNT__POR (0x77)
+#define TAIKO_A_RX_COM_DAC_CTL (0x1A1)
+#define TAIKO_A_RX_COM_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_COM_BIAS (0x1A2)
+#define TAIKO_A_RX_COM_BIAS__POR (0x00)
+#define TAIKO_A_RX_HPH_AUTO_CHOP (0x1A4)
+#define TAIKO_A_RX_HPH_AUTO_CHOP__POR (0x38)
+#define TAIKO_A_RX_HPH_CHOP_CTL (0x1A5)
+#define TAIKO_A_RX_HPH_CHOP_CTL__POR (0xB4)
+#define TAIKO_A_RX_HPH_BIAS_PA (0x1A6)
+#define TAIKO_A_RX_HPH_BIAS_PA__POR (0xAA)
+#define TAIKO_A_RX_HPH_BIAS_LDO (0x1A7)
+#define TAIKO_A_RX_HPH_BIAS_LDO__POR (0x87)
+#define TAIKO_A_RX_HPH_BIAS_CNP (0x1A8)
+#define TAIKO_A_RX_HPH_BIAS_CNP__POR (0x8A)
+#define TAIKO_A_RX_HPH_BIAS_WG_OCP (0x1A9)
+#define TAIKO_A_RX_HPH_BIAS_WG_OCP__POR (0x2A)
+#define TAIKO_A_RX_HPH_OCP_CTL (0x1AA)
+#define TAIKO_A_RX_HPH_OCP_CTL__POR (0x68)
+#define TAIKO_A_RX_HPH_CNP_EN (0x1AB)
+#define TAIKO_A_RX_HPH_CNP_EN__POR (0x80)
+#define TAIKO_A_RX_HPH_CNP_WG_CTL (0x1AC)
+#define TAIKO_A_RX_HPH_CNP_WG_CTL__POR (0xDE)
+#define TAIKO_A_RX_HPH_CNP_WG_TIME (0x1AD)
+#define TAIKO_A_RX_HPH_CNP_WG_TIME__POR (0x2A)
+#define TAIKO_A_RX_HPH_L_GAIN (0x1AE)
+#define TAIKO_A_RX_HPH_L_GAIN__POR (0x00)
+#define TAIKO_A_RX_HPH_L_TEST (0x1AF)
+#define TAIKO_A_RX_HPH_L_TEST__POR (0x00)
+#define TAIKO_A_RX_HPH_L_PA_CTL (0x1B0)
+#define TAIKO_A_RX_HPH_L_PA_CTL__POR (0x40)
+#define TAIKO_A_RX_HPH_L_DAC_CTL (0x1B1)
+#define TAIKO_A_RX_HPH_L_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_HPH_L_ATEST (0x1B2)
+#define TAIKO_A_RX_HPH_L_ATEST__POR (0x00)
+#define TAIKO_A_RX_HPH_L_STATUS (0x1B3)
+#define TAIKO_A_RX_HPH_L_STATUS__POR (0x00)
+#define TAIKO_A_RX_HPH_R_GAIN (0x1B4)
+#define TAIKO_A_RX_HPH_R_GAIN__POR (0x00)
+#define TAIKO_A_RX_HPH_R_TEST (0x1B5)
+#define TAIKO_A_RX_HPH_R_TEST__POR (0x00)
+#define TAIKO_A_RX_HPH_R_PA_CTL (0x1B6)
+#define TAIKO_A_RX_HPH_R_PA_CTL__POR (0x40)
+#define TAIKO_A_RX_HPH_R_DAC_CTL (0x1B7)
+#define TAIKO_A_RX_HPH_R_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_HPH_R_ATEST (0x1B8)
+#define TAIKO_A_RX_HPH_R_ATEST__POR (0x00)
+#define TAIKO_A_RX_HPH_R_STATUS (0x1B9)
+#define TAIKO_A_RX_HPH_R_STATUS__POR (0x00)
+#define TAIKO_A_RX_EAR_BIAS_PA (0x1BA)
+#define TAIKO_A_RX_EAR_BIAS_PA__POR (0xA6)
+#define TAIKO_A_RX_EAR_BIAS_CMBUFF (0x1BB)
+#define TAIKO_A_RX_EAR_BIAS_CMBUFF__POR (0xA0)
+#define TAIKO_A_RX_EAR_EN (0x1BC)
+#define TAIKO_A_RX_EAR_EN__POR (0x00)
+#define TAIKO_A_RX_EAR_GAIN (0x1BD)
+#define TAIKO_A_RX_EAR_GAIN__POR (0x02)
+#define TAIKO_A_RX_EAR_CMBUFF (0x1BE)
+#define TAIKO_A_RX_EAR_CMBUFF__POR (0x04)
+#define TAIKO_A_RX_EAR_ICTL (0x1BF)
+#define TAIKO_A_RX_EAR_ICTL__POR (0x40)
+#define TAIKO_A_RX_EAR_CCOMP (0x1C0)
+#define TAIKO_A_RX_EAR_CCOMP__POR (0x08)
+#define TAIKO_A_RX_EAR_VCM (0x1C1)
+#define TAIKO_A_RX_EAR_VCM__POR (0x03)
+#define TAIKO_A_RX_EAR_CNP (0x1C2)
+#define TAIKO_A_RX_EAR_CNP__POR (0xF2)
+#define TAIKO_A_RX_EAR_DAC_CTL_ATEST (0x1C3)
+#define TAIKO_A_RX_EAR_DAC_CTL_ATEST__POR (0x00)
+#define TAIKO_A_RX_EAR_STATUS (0x1C5)
+#define TAIKO_A_RX_EAR_STATUS__POR (0x04)
+#define TAIKO_A_RX_LINE_BIAS_PA (0x1C6)
+#define TAIKO_A_RX_LINE_BIAS_PA__POR (0xA8)
+#define TAIKO_A_RX_BUCK_BIAS1 (0x1C7)
+#define TAIKO_A_RX_BUCK_BIAS1__POR (0x42)
+#define TAIKO_A_RX_BUCK_BIAS2 (0x1C8)
+#define TAIKO_A_RX_BUCK_BIAS2__POR (0x84)
+#define TAIKO_A_RX_LINE_COM (0x1C9)
+#define TAIKO_A_RX_LINE_COM__POR (0x80)
+#define TAIKO_A_RX_LINE_CNP_EN (0x1CA)
+#define TAIKO_A_RX_LINE_CNP_EN__POR (0x00)
+#define TAIKO_A_RX_LINE_CNP_WG_CTL (0x1CB)
+#define TAIKO_A_RX_LINE_CNP_WG_CTL__POR (0x00)
+#define TAIKO_A_RX_LINE_CNP_WG_TIME (0x1CC)
+#define TAIKO_A_RX_LINE_CNP_WG_TIME__POR (0x04)
+#define TAIKO_A_RX_LINE_1_GAIN (0x1CD)
+#define TAIKO_A_RX_LINE_1_GAIN__POR (0x00)
+#define TAIKO_A_RX_LINE_1_TEST (0x1CE)
+#define TAIKO_A_RX_LINE_1_TEST__POR (0x00)
+#define TAIKO_A_RX_LINE_1_DAC_CTL (0x1CF)
+#define TAIKO_A_RX_LINE_1_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_LINE_1_STATUS (0x1D0)
+#define TAIKO_A_RX_LINE_1_STATUS__POR (0x00)
+#define TAIKO_A_RX_LINE_2_GAIN (0x1D1)
+#define TAIKO_A_RX_LINE_2_GAIN__POR (0x00)
+#define TAIKO_A_RX_LINE_2_TEST (0x1D2)
+#define TAIKO_A_RX_LINE_2_TEST__POR (0x00)
+#define TAIKO_A_RX_LINE_2_DAC_CTL (0x1D3)
+#define TAIKO_A_RX_LINE_2_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_LINE_2_STATUS (0x1D4)
+#define TAIKO_A_RX_LINE_2_STATUS__POR (0x00)
+#define TAIKO_A_RX_LINE_3_GAIN (0x1D5)
+#define TAIKO_A_RX_LINE_3_GAIN__POR (0x00)
+#define TAIKO_A_RX_LINE_3_TEST (0x1D6)
+#define TAIKO_A_RX_LINE_3_TEST__POR (0x00)
+#define TAIKO_A_RX_LINE_3_DAC_CTL (0x1D7)
+#define TAIKO_A_RX_LINE_3_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_LINE_3_STATUS (0x1D8)
+#define TAIKO_A_RX_LINE_3_STATUS__POR (0x00)
+#define TAIKO_A_RX_LINE_4_GAIN (0x1D9)
+#define TAIKO_A_RX_LINE_4_GAIN__POR (0x00)
+#define TAIKO_A_RX_LINE_4_TEST (0x1DA)
+#define TAIKO_A_RX_LINE_4_TEST__POR (0x00)
+#define TAIKO_A_RX_LINE_4_DAC_CTL (0x1DB)
+#define TAIKO_A_RX_LINE_4_DAC_CTL__POR (0x00)
+#define TAIKO_A_RX_LINE_4_STATUS (0x1DC)
+#define TAIKO_A_RX_LINE_4_STATUS__POR (0x00)
+#define TAIKO_A_RX_LINE_CNP_DBG (0x1DD)
+#define TAIKO_A_RX_LINE_CNP_DBG__POR (0x00)
+#define TAIKO_A_SPKR_DRV_EN (0x1DF)
+#define TAIKO_A_SPKR_DRV_EN__POR (0x6F)
+#define TAIKO_A_SPKR_DRV_GAIN (0x1E0)
+#define TAIKO_A_SPKR_DRV_GAIN__POR (0x00)
+#define TAIKO_A_SPKR_DRV_DAC_CTL (0x1E1)
+#define TAIKO_A_SPKR_DRV_DAC_CTL__POR (0x04)
+#define TAIKO_A_SPKR_DRV_OCP_CTL (0x1E2)
+#define TAIKO_A_SPKR_DRV_OCP_CTL__POR (0x98)
+#define TAIKO_A_SPKR_DRV_CLIP_DET (0x1E3)
+#define TAIKO_A_SPKR_DRV_CLIP_DET__POR (0x48)
+#define TAIKO_A_SPKR_DRV_IEC (0x1E4)
+#define TAIKO_A_SPKR_DRV_IEC__POR (0x20)
+#define TAIKO_A_SPKR_DRV_DBG_DAC (0x1E5)
+#define TAIKO_A_SPKR_DRV_DBG_DAC__POR (0x05)
+#define TAIKO_A_SPKR_DRV_DBG_PA (0x1E6)
+#define TAIKO_A_SPKR_DRV_DBG_PA__POR (0x18)
+#define TAIKO_A_SPKR_DRV_DBG_PWRSTG (0x1E7)
+#define TAIKO_A_SPKR_DRV_DBG_PWRSTG__POR (0x00)
+#define TAIKO_A_SPKR_DRV_BIAS_LDO (0x1E8)
+#define TAIKO_A_SPKR_DRV_BIAS_LDO__POR (0x45)
+#define TAIKO_A_SPKR_DRV_BIAS_INT (0x1E9)
+#define TAIKO_A_SPKR_DRV_BIAS_INT__POR (0xA5)
+#define TAIKO_A_SPKR_DRV_BIAS_PA (0x1EA)
+#define TAIKO_A_SPKR_DRV_BIAS_PA__POR (0x55)
+#define TAIKO_A_SPKR_DRV_STATUS_OCP (0x1EB)
+#define TAIKO_A_SPKR_DRV_STATUS_OCP__POR (0x00)
+#define TAIKO_A_SPKR_DRV_STATUS_PA (0x1EC)
+#define TAIKO_A_SPKR_DRV_STATUS_PA__POR (0x00)
+#define TAIKO_A_SPKR_PROT_EN (0x1ED)
+#define TAIKO_A_SPKR_PROT_EN__POR (0x00)
+#define TAIKO_A_SPKR_PROT_ADC_EN (0x1EE)
+#define TAIKO_A_SPKR_PROT_ADC_EN__POR (0x44)
+#define TAIKO_A_SPKR_PROT_ISENSE_BIAS (0x1EF)
+#define TAIKO_A_SPKR_PROT_ISENSE_BIAS__POR (0x44)
+#define TAIKO_A_SPKR_PROT_VSENSE_BIAS (0x1F0)
+#define TAIKO_A_SPKR_PROT_VSENSE_BIAS__POR (0x44)
+#define TAIKO_A_SPKR_PROT_ADC_ATEST_REFCTRL (0x1F1)
+#define TAIKO_A_SPKR_PROT_ADC_ATEST_REFCTRL__POR (0x00)
+#define TAIKO_A_SPKR_PROT_ADC_TEST_CTL (0x1F2)
+#define TAIKO_A_SPKR_PROT_ADC_TEST_CTL__POR (0x38)
+#define TAIKO_A_SPKR_PROT_TEST_BLOCK_EN (0x1F3)
+#define TAIKO_A_SPKR_PROT_TEST_BLOCK_EN__POR (0xFC)
+#define TAIKO_A_SPKR_PROT_ATEST (0x1F4)
+#define TAIKO_A_SPKR_PROT_ATEST__POR (0x00)
+#define TAIKO_A_SPKR_PROT_V_SAR_ERR (0x1F5)
+#define TAIKO_A_SPKR_PROT_V_SAR_ERR__POR (0x00)
+#define TAIKO_A_SPKR_PROT_I_SAR_ERR (0x1F6)
+#define TAIKO_A_SPKR_PROT_I_SAR_ERR__POR (0x00)
+#define TAIKO_A_SPKR_PROT_LDO_CTRL (0x1F7)
+#define TAIKO_A_SPKR_PROT_LDO_CTRL__POR (0x00)
+#define TAIKO_A_SPKR_PROT_ISENSE_CTRL (0x1F8)
+#define TAIKO_A_SPKR_PROT_ISENSE_CTRL__POR (0x00)
+#define TAIKO_A_SPKR_PROT_VSENSE_CTRL (0x1F9)
+#define TAIKO_A_SPKR_PROT_VSENSE_CTRL__POR (0x00)
+#define TAIKO_A_RC_OSC_FREQ (0x1FA)
+#define TAIKO_A_RC_OSC_FREQ__POR (0x46)
+#define TAIKO_A_RC_OSC_TEST (0x1FB)
+#define TAIKO_A_RC_OSC_TEST__POR (0x0A)
+#define TAIKO_A_RC_OSC_STATUS (0x1FC)
+#define TAIKO_A_RC_OSC_STATUS__POR (0x18)
+#define TAIKO_A_RC_OSC_TUNER (0x1FD)
+#define TAIKO_A_RC_OSC_TUNER__POR (0x00)
+#define TAIKO_A_MBHC_HPH (0x1FE)
+#define TAIKO_A_MBHC_HPH__POR (0x44)
+#define TAIKO_A_CDC_ANC1_B1_CTL (0x200)
+#define TAIKO_A_CDC_ANC1_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_B1_CTL (0x280)
+#define TAIKO_A_CDC_ANC2_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_SHIFT (0x201)
+#define TAIKO_A_CDC_ANC1_SHIFT__POR (0x00)
+#define TAIKO_A_CDC_ANC2_SHIFT (0x281)
+#define TAIKO_A_CDC_ANC2_SHIFT__POR (0x00)
+#define TAIKO_A_CDC_ANC1_IIR_B1_CTL (0x202)
+#define TAIKO_A_CDC_ANC1_IIR_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_IIR_B1_CTL (0x282)
+#define TAIKO_A_CDC_ANC2_IIR_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_IIR_B2_CTL (0x203)
+#define TAIKO_A_CDC_ANC1_IIR_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_IIR_B2_CTL (0x283)
+#define TAIKO_A_CDC_ANC2_IIR_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_IIR_B3_CTL (0x204)
+#define TAIKO_A_CDC_ANC1_IIR_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_IIR_B3_CTL (0x284)
+#define TAIKO_A_CDC_ANC2_IIR_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_LPF_B1_CTL (0x206)
+#define TAIKO_A_CDC_ANC1_LPF_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_LPF_B1_CTL (0x286)
+#define TAIKO_A_CDC_ANC2_LPF_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_LPF_B2_CTL (0x207)
+#define TAIKO_A_CDC_ANC1_LPF_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_LPF_B2_CTL (0x287)
+#define TAIKO_A_CDC_ANC2_LPF_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_SPARE (0x209)
+#define TAIKO_A_CDC_ANC1_SPARE__POR (0x00)
+#define TAIKO_A_CDC_ANC2_SPARE (0x289)
+#define TAIKO_A_CDC_ANC2_SPARE__POR (0x00)
+#define TAIKO_A_CDC_ANC1_SMLPF_CTL (0x20A)
+#define TAIKO_A_CDC_ANC1_SMLPF_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_SMLPF_CTL (0x28A)
+#define TAIKO_A_CDC_ANC2_SMLPF_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_DCFLT_CTL (0x20B)
+#define TAIKO_A_CDC_ANC1_DCFLT_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_DCFLT_CTL (0x28B)
+#define TAIKO_A_CDC_ANC2_DCFLT_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_GAIN_CTL (0x20C)
+#define TAIKO_A_CDC_ANC1_GAIN_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_GAIN_CTL (0x28C)
+#define TAIKO_A_CDC_ANC2_GAIN_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC1_B2_CTL (0x20D)
+#define TAIKO_A_CDC_ANC1_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_ANC2_B2_CTL (0x28D)
+#define TAIKO_A_CDC_ANC2_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX1_VOL_CTL_TIMER (0x220)
+#define TAIKO_A_CDC_TX1_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX2_VOL_CTL_TIMER (0x228)
+#define TAIKO_A_CDC_TX2_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX3_VOL_CTL_TIMER (0x230)
+#define TAIKO_A_CDC_TX3_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX4_VOL_CTL_TIMER (0x238)
+#define TAIKO_A_CDC_TX4_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX5_VOL_CTL_TIMER (0x240)
+#define TAIKO_A_CDC_TX5_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX6_VOL_CTL_TIMER (0x248)
+#define TAIKO_A_CDC_TX6_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX7_VOL_CTL_TIMER (0x250)
+#define TAIKO_A_CDC_TX7_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX8_VOL_CTL_TIMER (0x258)
+#define TAIKO_A_CDC_TX8_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX9_VOL_CTL_TIMER (0x260)
+#define TAIKO_A_CDC_TX9_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX10_VOL_CTL_TIMER (0x268)
+#define TAIKO_A_CDC_TX10_VOL_CTL_TIMER__POR (0x00)
+#define TAIKO_A_CDC_TX1_VOL_CTL_GAIN (0x221)
+#define TAIKO_A_CDC_TX1_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX2_VOL_CTL_GAIN (0x229)
+#define TAIKO_A_CDC_TX2_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX3_VOL_CTL_GAIN (0x231)
+#define TAIKO_A_CDC_TX3_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX4_VOL_CTL_GAIN (0x239)
+#define TAIKO_A_CDC_TX4_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX5_VOL_CTL_GAIN (0x241)
+#define TAIKO_A_CDC_TX5_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX6_VOL_CTL_GAIN (0x249)
+#define TAIKO_A_CDC_TX6_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX7_VOL_CTL_GAIN (0x251)
+#define TAIKO_A_CDC_TX7_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX8_VOL_CTL_GAIN (0x259)
+#define TAIKO_A_CDC_TX8_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX9_VOL_CTL_GAIN (0x261)
+#define TAIKO_A_CDC_TX9_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX10_VOL_CTL_GAIN (0x269)
+#define TAIKO_A_CDC_TX10_VOL_CTL_GAIN__POR (0x00)
+#define TAIKO_A_CDC_TX1_VOL_CTL_CFG (0x222)
+#define TAIKO_A_CDC_TX1_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX2_VOL_CTL_CFG (0x22A)
+#define TAIKO_A_CDC_TX2_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX3_VOL_CTL_CFG (0x232)
+#define TAIKO_A_CDC_TX3_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX4_VOL_CTL_CFG (0x23A)
+#define TAIKO_A_CDC_TX4_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX5_VOL_CTL_CFG (0x242)
+#define TAIKO_A_CDC_TX5_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX6_VOL_CTL_CFG (0x24A)
+#define TAIKO_A_CDC_TX6_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX7_VOL_CTL_CFG (0x252)
+#define TAIKO_A_CDC_TX7_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX8_VOL_CTL_CFG (0x25A)
+#define TAIKO_A_CDC_TX8_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX9_VOL_CTL_CFG (0x262)
+#define TAIKO_A_CDC_TX9_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX10_VOL_CTL_CFG (0x26A)
+#define TAIKO_A_CDC_TX10_VOL_CTL_CFG__POR (0x00)
+#define TAIKO_A_CDC_TX1_MUX_CTL (0x223)
+#define TAIKO_A_CDC_TX1_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX2_MUX_CTL (0x22B)
+#define TAIKO_A_CDC_TX2_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX3_MUX_CTL (0x233)
+#define TAIKO_A_CDC_TX3_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX4_MUX_CTL (0x23B)
+#define TAIKO_A_CDC_TX4_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX5_MUX_CTL (0x243)
+#define TAIKO_A_CDC_TX5_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX6_MUX_CTL (0x24B)
+#define TAIKO_A_CDC_TX6_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX7_MUX_CTL (0x253)
+#define TAIKO_A_CDC_TX7_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX8_MUX_CTL (0x25B)
+#define TAIKO_A_CDC_TX8_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX9_MUX_CTL (0x263)
+#define TAIKO_A_CDC_TX9_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX10_MUX_CTL (0x26B)
+#define TAIKO_A_CDC_TX10_MUX_CTL__POR (0x08)
+#define TAIKO_A_CDC_TX1_CLK_FS_CTL (0x224)
+#define TAIKO_A_CDC_TX1_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX2_CLK_FS_CTL (0x22C)
+#define TAIKO_A_CDC_TX2_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX3_CLK_FS_CTL (0x234)
+#define TAIKO_A_CDC_TX3_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX4_CLK_FS_CTL (0x23C)
+#define TAIKO_A_CDC_TX4_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX5_CLK_FS_CTL (0x244)
+#define TAIKO_A_CDC_TX5_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX6_CLK_FS_CTL (0x24C)
+#define TAIKO_A_CDC_TX6_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX7_CLK_FS_CTL (0x254)
+#define TAIKO_A_CDC_TX7_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX8_CLK_FS_CTL (0x25C)
+#define TAIKO_A_CDC_TX8_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX9_CLK_FS_CTL (0x264)
+#define TAIKO_A_CDC_TX9_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX10_CLK_FS_CTL (0x26C)
+#define TAIKO_A_CDC_TX10_CLK_FS_CTL__POR (0x03)
+#define TAIKO_A_CDC_TX1_DMIC_CTL (0x225)
+#define TAIKO_A_CDC_TX1_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX2_DMIC_CTL (0x22D)
+#define TAIKO_A_CDC_TX2_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX3_DMIC_CTL (0x235)
+#define TAIKO_A_CDC_TX3_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX4_DMIC_CTL (0x23D)
+#define TAIKO_A_CDC_TX4_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX5_DMIC_CTL (0x245)
+#define TAIKO_A_CDC_TX5_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX6_DMIC_CTL (0x24D)
+#define TAIKO_A_CDC_TX6_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX7_DMIC_CTL (0x255)
+#define TAIKO_A_CDC_TX7_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX8_DMIC_CTL (0x25D)
+#define TAIKO_A_CDC_TX8_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX9_DMIC_CTL (0x265)
+#define TAIKO_A_CDC_TX9_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_TX10_DMIC_CTL (0x26D)
+#define TAIKO_A_CDC_TX10_DMIC_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B1_CTL (0x278)
+#define TAIKO_A_CDC_DEBUG_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B2_CTL (0x279)
+#define TAIKO_A_CDC_DEBUG_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B3_CTL (0x27A)
+#define TAIKO_A_CDC_DEBUG_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B4_CTL (0x27B)
+#define TAIKO_A_CDC_DEBUG_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B5_CTL (0x27C)
+#define TAIKO_A_CDC_DEBUG_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B6_CTL (0x27D)
+#define TAIKO_A_CDC_DEBUG_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_DEBUG_B7_CTL (0x27E)
+#define TAIKO_A_CDC_DEBUG_B7_CTL__POR (0x00)
+#define TAIKO_A_CDC_SRC1_PDA_CFG (0x2A0)
+#define TAIKO_A_CDC_SRC1_PDA_CFG__POR (0x00)
+#define TAIKO_A_CDC_SRC2_PDA_CFG (0x2A8)
+#define TAIKO_A_CDC_SRC2_PDA_CFG__POR (0x00)
+#define TAIKO_A_CDC_SRC1_FS_CTL (0x2A1)
+#define TAIKO_A_CDC_SRC1_FS_CTL__POR (0x1B)
+#define TAIKO_A_CDC_SRC2_FS_CTL (0x2A9)
+#define TAIKO_A_CDC_SRC2_FS_CTL__POR (0x1B)
+#define TAIKO_A_CDC_RX1_B1_CTL (0x2B0)
+#define TAIKO_A_CDC_RX1_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_B1_CTL (0x2B8)
+#define TAIKO_A_CDC_RX2_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_B1_CTL (0x2C0)
+#define TAIKO_A_CDC_RX3_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_B1_CTL (0x2C8)
+#define TAIKO_A_CDC_RX4_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_B1_CTL (0x2D0)
+#define TAIKO_A_CDC_RX5_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_B1_CTL (0x2D8)
+#define TAIKO_A_CDC_RX6_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_B1_CTL (0x2E0)
+#define TAIKO_A_CDC_RX7_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_B2_CTL (0x2B1)
+#define TAIKO_A_CDC_RX1_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_B2_CTL (0x2B9)
+#define TAIKO_A_CDC_RX2_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_B2_CTL (0x2C1)
+#define TAIKO_A_CDC_RX3_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_B2_CTL (0x2C9)
+#define TAIKO_A_CDC_RX4_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_B2_CTL (0x2D1)
+#define TAIKO_A_CDC_RX5_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_B2_CTL (0x2D9)
+#define TAIKO_A_CDC_RX6_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_B2_CTL (0x2E1)
+#define TAIKO_A_CDC_RX7_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_B3_CTL (0x2B2)
+#define TAIKO_A_CDC_RX1_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_B3_CTL (0x2BA)
+#define TAIKO_A_CDC_RX2_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_B3_CTL (0x2C2)
+#define TAIKO_A_CDC_RX3_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_B3_CTL (0x2CA)
+#define TAIKO_A_CDC_RX4_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_B3_CTL (0x2D2)
+#define TAIKO_A_CDC_RX5_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_B3_CTL (0x2DA)
+#define TAIKO_A_CDC_RX6_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_B3_CTL (0x2E2)
+#define TAIKO_A_CDC_RX7_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_B4_CTL (0x2B3)
+#define TAIKO_A_CDC_RX1_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_B4_CTL (0x2BB)
+#define TAIKO_A_CDC_RX2_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_B4_CTL (0x2C3)
+#define TAIKO_A_CDC_RX3_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_B4_CTL (0x2CB)
+#define TAIKO_A_CDC_RX4_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_B4_CTL (0x2D3)
+#define TAIKO_A_CDC_RX5_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_B4_CTL (0x2DB)
+#define TAIKO_A_CDC_RX6_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_B4_CTL (0x2E3)
+#define TAIKO_A_CDC_RX7_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_B5_CTL (0x2B4)
+#define TAIKO_A_CDC_RX1_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX2_B5_CTL (0x2BC)
+#define TAIKO_A_CDC_RX2_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX3_B5_CTL (0x2C4)
+#define TAIKO_A_CDC_RX3_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX4_B5_CTL (0x2CC)
+#define TAIKO_A_CDC_RX4_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX5_B5_CTL (0x2D4)
+#define TAIKO_A_CDC_RX5_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX6_B5_CTL (0x2DC)
+#define TAIKO_A_CDC_RX6_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX7_B5_CTL (0x2E4)
+#define TAIKO_A_CDC_RX7_B5_CTL__POR (0x78)
+#define TAIKO_A_CDC_RX1_B6_CTL (0x2B5)
+#define TAIKO_A_CDC_RX1_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX2_B6_CTL (0x2BD)
+#define TAIKO_A_CDC_RX2_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX3_B6_CTL (0x2C5)
+#define TAIKO_A_CDC_RX3_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX4_B6_CTL (0x2CD)
+#define TAIKO_A_CDC_RX4_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX5_B6_CTL (0x2D5)
+#define TAIKO_A_CDC_RX5_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX6_B6_CTL (0x2DD)
+#define TAIKO_A_CDC_RX6_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX7_B6_CTL (0x2E5)
+#define TAIKO_A_CDC_RX7_B6_CTL__POR (0x80)
+#define TAIKO_A_CDC_RX1_VOL_CTL_B1_CTL (0x2B6)
+#define TAIKO_A_CDC_RX1_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_VOL_CTL_B1_CTL (0x2BE)
+#define TAIKO_A_CDC_RX2_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_VOL_CTL_B1_CTL (0x2C6)
+#define TAIKO_A_CDC_RX3_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_VOL_CTL_B1_CTL (0x2CE)
+#define TAIKO_A_CDC_RX4_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_VOL_CTL_B1_CTL (0x2D6)
+#define TAIKO_A_CDC_RX5_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_VOL_CTL_B1_CTL (0x2DE)
+#define TAIKO_A_CDC_RX6_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_VOL_CTL_B1_CTL (0x2E6)
+#define TAIKO_A_CDC_RX7_VOL_CTL_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL (0x2B7)
+#define TAIKO_A_CDC_RX1_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL (0x2BF)
+#define TAIKO_A_CDC_RX2_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL (0x2C7)
+#define TAIKO_A_CDC_RX3_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL (0x2CF)
+#define TAIKO_A_CDC_RX4_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL (0x2D7)
+#define TAIKO_A_CDC_RX5_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL (0x2DF)
+#define TAIKO_A_CDC_RX6_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL (0x2E7)
+#define TAIKO_A_CDC_RX7_VOL_CTL_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_VBAT_CFG (0x2E8)
+#define TAIKO_A_CDC_VBAT_CFG__POR (0x1A)
+#define TAIKO_A_CDC_VBAT_ADC_CAL1 (0x2E9)
+#define TAIKO_A_CDC_VBAT_ADC_CAL1__POR (0x00)
+#define TAIKO_A_CDC_VBAT_ADC_CAL2 (0x2EA)
+#define TAIKO_A_CDC_VBAT_ADC_CAL2__POR (0x00)
+#define TAIKO_A_CDC_VBAT_ADC_CAL3 (0x2EB)
+#define TAIKO_A_CDC_VBAT_ADC_CAL3__POR (0x04)
+#define TAIKO_A_CDC_VBAT_PK_EST1 (0x2EC)
+#define TAIKO_A_CDC_VBAT_PK_EST1__POR (0xE0)
+#define TAIKO_A_CDC_VBAT_PK_EST2 (0x2ED)
+#define TAIKO_A_CDC_VBAT_PK_EST2__POR (0x01)
+#define TAIKO_A_CDC_VBAT_PK_EST3 (0x2EE)
+#define TAIKO_A_CDC_VBAT_PK_EST3__POR (0x40)
+#define TAIKO_A_CDC_VBAT_RF_PROC1 (0x2EF)
+#define TAIKO_A_CDC_VBAT_RF_PROC1__POR (0x2A)
+#define TAIKO_A_CDC_VBAT_RF_PROC2 (0x2F0)
+#define TAIKO_A_CDC_VBAT_RF_PROC2__POR (0x86)
+#define TAIKO_A_CDC_VBAT_TAC1 (0x2F1)
+#define TAIKO_A_CDC_VBAT_TAC1__POR (0x70)
+#define TAIKO_A_CDC_VBAT_TAC2 (0x2F2)
+#define TAIKO_A_CDC_VBAT_TAC2__POR (0x18)
+#define TAIKO_A_CDC_VBAT_TAC3 (0x2F3)
+#define TAIKO_A_CDC_VBAT_TAC3__POR (0x18)
+#define TAIKO_A_CDC_VBAT_TAC4 (0x2F4)
+#define TAIKO_A_CDC_VBAT_TAC4__POR (0x03)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD1 (0x2F5)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD1__POR (0x01)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD2 (0x2F6)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD2__POR (0x00)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD3 (0x2F7)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD3__POR (0x64)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD4 (0x2F8)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD4__POR (0x01)
+#define TAIKO_A_CDC_VBAT_DEBUG1 (0x2F9)
+#define TAIKO_A_CDC_VBAT_DEBUG1__POR (0x00)
+#define TAIKO_A_CDC_CLK_ANC_RESET_CTL (0x300)
+#define TAIKO_A_CDC_CLK_ANC_RESET_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_RX_RESET_CTL (0x301)
+#define TAIKO_A_CDC_CLK_RX_RESET_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_TX_RESET_B1_CTL (0x302)
+#define TAIKO_A_CDC_CLK_TX_RESET_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_TX_RESET_B2_CTL (0x303)
+#define TAIKO_A_CDC_CLK_TX_RESET_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_DMIC_B1_CTL (0x304)
+#define TAIKO_A_CDC_CLK_DMIC_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_DMIC_B2_CTL (0x305)
+#define TAIKO_A_CDC_CLK_DMIC_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_RX_I2S_CTL (0x306)
+#define TAIKO_A_CDC_CLK_RX_I2S_CTL__POR (0x03)
+#define TAIKO_A_CDC_CLK_TX_I2S_CTL (0x307)
+#define TAIKO_A_CDC_CLK_TX_I2S_CTL__POR (0x03)
+#define TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL (0x308)
+#define TAIKO_A_CDC_CLK_OTHR_RESET_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL (0x309)
+#define TAIKO_A_CDC_CLK_OTHR_RESET_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL (0x30A)
+#define TAIKO_A_CDC_CLK_TX_CLK_EN_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL (0x30B)
+#define TAIKO_A_CDC_CLK_TX_CLK_EN_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_OTHR_CTL (0x30C)
+#define TAIKO_A_CDC_CLK_OTHR_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL (0x30D)
+#define TAIKO_A_CDC_CLK_RDAC_CLK_EN_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL (0x30E)
+#define TAIKO_A_CDC_CLK_ANC_CLK_EN_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_RX_B1_CTL (0x30F)
+#define TAIKO_A_CDC_CLK_RX_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_RX_B2_CTL (0x310)
+#define TAIKO_A_CDC_CLK_RX_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_MCLK_CTL (0x311)
+#define TAIKO_A_CDC_CLK_MCLK_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_PDM_CTL (0x312)
+#define TAIKO_A_CDC_CLK_PDM_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_SD_CTL (0x313)
+#define TAIKO_A_CDC_CLK_SD_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLK_POWER_CTL (0x314)
+#define TAIKO_A_CDC_CLK_POWER_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLSH_B1_CTL (0x320)
+#define TAIKO_A_CDC_CLSH_B1_CTL__POR (0xE4)
+#define TAIKO_A_CDC_CLSH_B2_CTL (0x321)
+#define TAIKO_A_CDC_CLSH_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLSH_B3_CTL (0x322)
+#define TAIKO_A_CDC_CLSH_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CLSH_BUCK_NCP_VARS (0x323)
+#define TAIKO_A_CDC_CLSH_BUCK_NCP_VARS__POR (0x00)
+#define TAIKO_A_CDC_CLSH_IDLE_HPH_THSD (0x324)
+#define TAIKO_A_CDC_CLSH_IDLE_HPH_THSD__POR (0x12)
+#define TAIKO_A_CDC_CLSH_IDLE_EAR_THSD (0x325)
+#define TAIKO_A_CDC_CLSH_IDLE_EAR_THSD__POR (0x0C)
+#define TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD (0x326)
+#define TAIKO_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR (0x18)
+#define TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD (0x327)
+#define TAIKO_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR (0x23)
+#define TAIKO_A_CDC_CLSH_K_ADDR (0x328)
+#define TAIKO_A_CDC_CLSH_K_ADDR__POR (0x00)
+#define TAIKO_A_CDC_CLSH_K_DATA (0x329)
+#define TAIKO_A_CDC_CLSH_K_DATA__POR (0xA4)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L (0x32A)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_L__POR (0xD7)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U (0x32B)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_HPH_U__POR (0x05)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L (0x32C)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_L__POR (0x60)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U (0x32D)
+#define TAIKO_A_CDC_CLSH_I_PA_FACT_EAR_U__POR (0x09)
+#define TAIKO_A_CDC_CLSH_V_PA_HD_EAR (0x32E)
+#define TAIKO_A_CDC_CLSH_V_PA_HD_EAR__POR (0x00)
+#define TAIKO_A_CDC_CLSH_V_PA_HD_HPH (0x32F)
+#define TAIKO_A_CDC_CLSH_V_PA_HD_HPH__POR (0x00)
+#define TAIKO_A_CDC_CLSH_V_PA_MIN_EAR (0x330)
+#define TAIKO_A_CDC_CLSH_V_PA_MIN_EAR__POR (0x00)
+#define TAIKO_A_CDC_CLSH_V_PA_MIN_HPH (0x331)
+#define TAIKO_A_CDC_CLSH_V_PA_MIN_HPH__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B1_CTL (0x340)
+#define TAIKO_A_CDC_IIR1_GAIN_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B1_CTL (0x350)
+#define TAIKO_A_CDC_IIR2_GAIN_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B2_CTL (0x341)
+#define TAIKO_A_CDC_IIR1_GAIN_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B2_CTL (0x351)
+#define TAIKO_A_CDC_IIR2_GAIN_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B3_CTL (0x342)
+#define TAIKO_A_CDC_IIR1_GAIN_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B3_CTL (0x352)
+#define TAIKO_A_CDC_IIR2_GAIN_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B4_CTL (0x343)
+#define TAIKO_A_CDC_IIR1_GAIN_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B4_CTL (0x353)
+#define TAIKO_A_CDC_IIR2_GAIN_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B5_CTL (0x344)
+#define TAIKO_A_CDC_IIR1_GAIN_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B5_CTL (0x354)
+#define TAIKO_A_CDC_IIR2_GAIN_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B6_CTL (0x345)
+#define TAIKO_A_CDC_IIR1_GAIN_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B6_CTL (0x355)
+#define TAIKO_A_CDC_IIR2_GAIN_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B7_CTL (0x346)
+#define TAIKO_A_CDC_IIR1_GAIN_B7_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B7_CTL (0x356)
+#define TAIKO_A_CDC_IIR2_GAIN_B7_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_GAIN_B8_CTL (0x347)
+#define TAIKO_A_CDC_IIR1_GAIN_B8_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_B8_CTL (0x357)
+#define TAIKO_A_CDC_IIR2_GAIN_B8_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_CTL (0x348)
+#define TAIKO_A_CDC_IIR1_CTL__POR (0x40)
+#define TAIKO_A_CDC_IIR2_CTL (0x358)
+#define TAIKO_A_CDC_IIR2_CTL__POR (0x40)
+#define TAIKO_A_CDC_IIR1_GAIN_TIMER_CTL (0x349)
+#define TAIKO_A_CDC_IIR1_GAIN_TIMER_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_GAIN_TIMER_CTL (0x359)
+#define TAIKO_A_CDC_IIR2_GAIN_TIMER_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_COEF_B1_CTL (0x34A)
+#define TAIKO_A_CDC_IIR1_COEF_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_COEF_B1_CTL (0x35A)
+#define TAIKO_A_CDC_IIR2_COEF_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR1_COEF_B2_CTL (0x34B)
+#define TAIKO_A_CDC_IIR1_COEF_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_IIR2_COEF_B2_CTL (0x35B)
+#define TAIKO_A_CDC_IIR2_COEF_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_TOP_GAIN_UPDATE (0x360)
+#define TAIKO_A_CDC_TOP_GAIN_UPDATE__POR (0x00)
+#define TAIKO_A_CDC_COMP0_B1_CTL (0x368)
+#define TAIKO_A_CDC_COMP0_B1_CTL__POR (0x30)
+#define TAIKO_A_CDC_COMP1_B1_CTL (0x370)
+#define TAIKO_A_CDC_COMP1_B1_CTL__POR (0x30)
+#define TAIKO_A_CDC_COMP2_B1_CTL (0x378)
+#define TAIKO_A_CDC_COMP2_B1_CTL__POR (0x30)
+#define TAIKO_A_CDC_COMP0_B2_CTL (0x369)
+#define TAIKO_A_CDC_COMP0_B2_CTL__POR (0xB5)
+#define TAIKO_A_CDC_COMP1_B2_CTL (0x371)
+#define TAIKO_A_CDC_COMP1_B2_CTL__POR (0xB5)
+#define TAIKO_A_CDC_COMP2_B2_CTL (0x379)
+#define TAIKO_A_CDC_COMP2_B2_CTL__POR (0xB5)
+#define TAIKO_A_CDC_COMP0_B3_CTL (0x36A)
+#define TAIKO_A_CDC_COMP0_B3_CTL__POR (0x28)
+#define TAIKO_A_CDC_COMP1_B3_CTL (0x372)
+#define TAIKO_A_CDC_COMP1_B3_CTL__POR (0x28)
+#define TAIKO_A_CDC_COMP2_B3_CTL (0x37A)
+#define TAIKO_A_CDC_COMP2_B3_CTL__POR (0x28)
+#define TAIKO_A_CDC_COMP0_B4_CTL (0x36B)
+#define TAIKO_A_CDC_COMP0_B4_CTL__POR (0x3C)
+#define TAIKO_A_CDC_COMP1_B4_CTL (0x373)
+#define TAIKO_A_CDC_COMP1_B4_CTL__POR (0x3C)
+#define TAIKO_A_CDC_COMP2_B4_CTL (0x37B)
+#define TAIKO_A_CDC_COMP2_B4_CTL__POR (0x3C)
+#define TAIKO_A_CDC_COMP0_B5_CTL (0x36C)
+#define TAIKO_A_CDC_COMP0_B5_CTL__POR (0x1F)
+#define TAIKO_A_CDC_COMP1_B5_CTL (0x374)
+#define TAIKO_A_CDC_COMP1_B5_CTL__POR (0x1F)
+#define TAIKO_A_CDC_COMP2_B5_CTL (0x37C)
+#define TAIKO_A_CDC_COMP2_B5_CTL__POR (0x1F)
+#define TAIKO_A_CDC_COMP0_B6_CTL (0x36D)
+#define TAIKO_A_CDC_COMP0_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP1_B6_CTL (0x375)
+#define TAIKO_A_CDC_COMP1_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP2_B6_CTL (0x37D)
+#define TAIKO_A_CDC_COMP2_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS (0x36E)
+#define TAIKO_A_CDC_COMP0_SHUT_DOWN_STATUS__POR (0x03)
+#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS (0x376)
+#define TAIKO_A_CDC_COMP1_SHUT_DOWN_STATUS__POR (0x03)
+#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS (0x37E)
+#define TAIKO_A_CDC_COMP2_SHUT_DOWN_STATUS__POR (0x03)
+#define TAIKO_A_CDC_COMP0_FS_CFG (0x36F)
+#define TAIKO_A_CDC_COMP0_FS_CFG__POR (0x03)
+#define TAIKO_A_CDC_COMP1_FS_CFG (0x377)
+#define TAIKO_A_CDC_COMP1_FS_CFG__POR (0x03)
+#define TAIKO_A_CDC_COMP2_FS_CFG (0x37F)
+#define TAIKO_A_CDC_COMP2_FS_CFG__POR (0x03)
+#define TAIKO_A_CDC_CONN_RX1_B1_CTL (0x380)
+#define TAIKO_A_CDC_CONN_RX1_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX1_B2_CTL (0x381)
+#define TAIKO_A_CDC_CONN_RX1_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX1_B3_CTL (0x382)
+#define TAIKO_A_CDC_CONN_RX1_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX2_B1_CTL (0x383)
+#define TAIKO_A_CDC_CONN_RX2_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX2_B2_CTL (0x384)
+#define TAIKO_A_CDC_CONN_RX2_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX2_B3_CTL (0x385)
+#define TAIKO_A_CDC_CONN_RX2_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX3_B1_CTL (0x386)
+#define TAIKO_A_CDC_CONN_RX3_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX3_B2_CTL (0x387)
+#define TAIKO_A_CDC_CONN_RX3_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX4_B1_CTL (0x388)
+#define TAIKO_A_CDC_CONN_RX4_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX4_B2_CTL (0x389)
+#define TAIKO_A_CDC_CONN_RX4_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX5_B1_CTL (0x38A)
+#define TAIKO_A_CDC_CONN_RX5_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX5_B2_CTL (0x38B)
+#define TAIKO_A_CDC_CONN_RX5_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX6_B1_CTL (0x38C)
+#define TAIKO_A_CDC_CONN_RX6_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX6_B2_CTL (0x38D)
+#define TAIKO_A_CDC_CONN_RX6_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX7_B1_CTL (0x38E)
+#define TAIKO_A_CDC_CONN_RX7_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX7_B2_CTL (0x38F)
+#define TAIKO_A_CDC_CONN_RX7_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX7_B3_CTL (0x390)
+#define TAIKO_A_CDC_CONN_RX7_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_ANC_B1_CTL (0x391)
+#define TAIKO_A_CDC_CONN_ANC_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_ANC_B2_CTL (0x392)
+#define TAIKO_A_CDC_CONN_ANC_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_B1_CTL (0x393)
+#define TAIKO_A_CDC_CONN_TX_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_B2_CTL (0x394)
+#define TAIKO_A_CDC_CONN_TX_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_B3_CTL (0x395)
+#define TAIKO_A_CDC_CONN_TX_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_B4_CTL (0x396)
+#define TAIKO_A_CDC_CONN_TX_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ1_B1_CTL (0x397)
+#define TAIKO_A_CDC_CONN_EQ1_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ1_B2_CTL (0x398)
+#define TAIKO_A_CDC_CONN_EQ1_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ1_B3_CTL (0x399)
+#define TAIKO_A_CDC_CONN_EQ1_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ1_B4_CTL (0x39A)
+#define TAIKO_A_CDC_CONN_EQ1_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ2_B1_CTL (0x39B)
+#define TAIKO_A_CDC_CONN_EQ2_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ2_B2_CTL (0x39C)
+#define TAIKO_A_CDC_CONN_EQ2_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ2_B3_CTL (0x39D)
+#define TAIKO_A_CDC_CONN_EQ2_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_EQ2_B4_CTL (0x39E)
+#define TAIKO_A_CDC_CONN_EQ2_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_SRC1_B1_CTL (0x39F)
+#define TAIKO_A_CDC_CONN_SRC1_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_SRC1_B2_CTL (0x3A0)
+#define TAIKO_A_CDC_CONN_SRC1_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_SRC2_B1_CTL (0x3A1)
+#define TAIKO_A_CDC_CONN_SRC2_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_SRC2_B2_CTL (0x3A2)
+#define TAIKO_A_CDC_CONN_SRC2_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B1_CTL (0x3A3)
+#define TAIKO_A_CDC_CONN_TX_SB_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B2_CTL (0x3A4)
+#define TAIKO_A_CDC_CONN_TX_SB_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B3_CTL (0x3A5)
+#define TAIKO_A_CDC_CONN_TX_SB_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B4_CTL (0x3A6)
+#define TAIKO_A_CDC_CONN_TX_SB_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B5_CTL (0x3A7)
+#define TAIKO_A_CDC_CONN_TX_SB_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B6_CTL (0x3A8)
+#define TAIKO_A_CDC_CONN_TX_SB_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B7_CTL (0x3A9)
+#define TAIKO_A_CDC_CONN_TX_SB_B7_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B8_CTL (0x3AA)
+#define TAIKO_A_CDC_CONN_TX_SB_B8_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B9_CTL (0x3AB)
+#define TAIKO_A_CDC_CONN_TX_SB_B9_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B10_CTL (0x3AC)
+#define TAIKO_A_CDC_CONN_TX_SB_B10_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_TX_SB_B11_CTL (0x3AD)
+#define TAIKO_A_CDC_CONN_TX_SB_B11_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX_SB_B1_CTL (0x3AE)
+#define TAIKO_A_CDC_CONN_RX_SB_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_RX_SB_B2_CTL (0x3AF)
+#define TAIKO_A_CDC_CONN_RX_SB_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_CLSH_CTL (0x3B0)
+#define TAIKO_A_CDC_CONN_CLSH_CTL__POR (0x00)
+#define TAIKO_A_CDC_CONN_MISC (0x3B1)
+#define TAIKO_A_CDC_CONN_MISC__POR (0x01)
+#define TAIKO_A_CDC_CONN_MAD (0x3B2)
+#define TAIKO_A_CDC_CONN_MAD__POR (0x01)
+#define TAIKO_A_CDC_MBHC_EN_CTL (0x3C0)
+#define TAIKO_A_CDC_MBHC_EN_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_FIR_B1_CFG (0x3C1)
+#define TAIKO_A_CDC_MBHC_FIR_B1_CFG__POR (0x00)
+#define TAIKO_A_CDC_MBHC_FIR_B2_CFG (0x3C2)
+#define TAIKO_A_CDC_MBHC_FIR_B2_CFG__POR (0x06)
+#define TAIKO_A_CDC_MBHC_TIMER_B1_CTL (0x3C3)
+#define TAIKO_A_CDC_MBHC_TIMER_B1_CTL__POR (0x03)
+#define TAIKO_A_CDC_MBHC_TIMER_B2_CTL (0x3C4)
+#define TAIKO_A_CDC_MBHC_TIMER_B2_CTL__POR (0x09)
+#define TAIKO_A_CDC_MBHC_TIMER_B3_CTL (0x3C5)
+#define TAIKO_A_CDC_MBHC_TIMER_B3_CTL__POR (0x1E)
+#define TAIKO_A_CDC_MBHC_TIMER_B4_CTL (0x3C6)
+#define TAIKO_A_CDC_MBHC_TIMER_B4_CTL__POR (0x45)
+#define TAIKO_A_CDC_MBHC_TIMER_B5_CTL (0x3C7)
+#define TAIKO_A_CDC_MBHC_TIMER_B5_CTL__POR (0x04)
+#define TAIKO_A_CDC_MBHC_TIMER_B6_CTL (0x3C8)
+#define TAIKO_A_CDC_MBHC_TIMER_B6_CTL__POR (0x78)
+#define TAIKO_A_CDC_MBHC_B1_STATUS (0x3C9)
+#define TAIKO_A_CDC_MBHC_B1_STATUS__POR (0x00)
+#define TAIKO_A_CDC_MBHC_B2_STATUS (0x3CA)
+#define TAIKO_A_CDC_MBHC_B2_STATUS__POR (0x00)
+#define TAIKO_A_CDC_MBHC_B3_STATUS (0x3CB)
+#define TAIKO_A_CDC_MBHC_B3_STATUS__POR (0x00)
+#define TAIKO_A_CDC_MBHC_B4_STATUS (0x3CC)
+#define TAIKO_A_CDC_MBHC_B4_STATUS__POR (0x00)
+#define TAIKO_A_CDC_MBHC_B5_STATUS (0x3CD)
+#define TAIKO_A_CDC_MBHC_B5_STATUS__POR (0x00)
+#define TAIKO_A_CDC_MBHC_B1_CTL (0x3CE)
+#define TAIKO_A_CDC_MBHC_B1_CTL__POR (0xC0)
+#define TAIKO_A_CDC_MBHC_B2_CTL (0x3CF)
+#define TAIKO_A_CDC_MBHC_B2_CTL__POR (0x5D)
+#define TAIKO_A_CDC_MBHC_VOLT_B1_CTL (0x3D0)
+#define TAIKO_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B2_CTL (0x3D1)
+#define TAIKO_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B3_CTL (0x3D2)
+#define TAIKO_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B4_CTL (0x3D3)
+#define TAIKO_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B5_CTL (0x3D4)
+#define TAIKO_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B6_CTL (0x3D5)
+#define TAIKO_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B7_CTL (0x3D6)
+#define TAIKO_A_CDC_MBHC_VOLT_B7_CTL__POR (0xFF)
+#define TAIKO_A_CDC_MBHC_VOLT_B8_CTL (0x3D7)
+#define TAIKO_A_CDC_MBHC_VOLT_B8_CTL__POR (0x07)
+#define TAIKO_A_CDC_MBHC_VOLT_B9_CTL (0x3D8)
+#define TAIKO_A_CDC_MBHC_VOLT_B9_CTL__POR (0xFF)
+#define TAIKO_A_CDC_MBHC_VOLT_B10_CTL (0x3D9)
+#define TAIKO_A_CDC_MBHC_VOLT_B10_CTL__POR (0x7F)
+#define TAIKO_A_CDC_MBHC_VOLT_B11_CTL (0x3DA)
+#define TAIKO_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_VOLT_B12_CTL (0x3DB)
+#define TAIKO_A_CDC_MBHC_VOLT_B12_CTL__POR (0x80)
+#define TAIKO_A_CDC_MBHC_CLK_CTL (0x3DC)
+#define TAIKO_A_CDC_MBHC_CLK_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_INT_CTL (0x3DD)
+#define TAIKO_A_CDC_MBHC_INT_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_DEBUG_CTL (0x3DE)
+#define TAIKO_A_CDC_MBHC_DEBUG_CTL__POR (0x00)
+#define TAIKO_A_CDC_MBHC_SPARE (0x3DF)
+#define TAIKO_A_CDC_MBHC_SPARE__POR (0x00)
+#define TAIKO_A_CDC_MAD_MAIN_CTL_1 (0x3E0)
+#define TAIKO_A_CDC_MAD_MAIN_CTL_1__POR (0x00)
+#define TAIKO_A_CDC_MAD_MAIN_CTL_2 (0x3E1)
+#define TAIKO_A_CDC_MAD_MAIN_CTL_2__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_1 (0x3E2)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_1__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_2 (0x3E3)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_2__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_3 (0x3E4)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_3__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_4 (0x3E5)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_4__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_5 (0x3E6)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_5__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_6 (0x3E7)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_6__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_7 (0x3E8)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_7__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_8 (0x3E9)
+#define TAIKO_A_CDC_MAD_AUDIO_CTL_8__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR (0x3EA)
+#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_PTR__POR (0x00)
+#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL (0x3EB)
+#define TAIKO_A_CDC_MAD_AUDIO_IIR_CTL_VAL__POR (0x40)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_1 (0x3EC)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_1__POR (0x00)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_2 (0x3ED)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_2__POR (0x00)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_3 (0x3EE)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_3__POR (0x00)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_4 (0x3EF)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_4__POR (0x00)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_5 (0x3F0)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_5__POR (0x00)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_6 (0x3F1)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_6__POR (0x00)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_7 (0x3F2)
+#define TAIKO_A_CDC_MAD_ULTR_CTL_7__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_1 (0x3F3)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_1__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_2 (0x3F4)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_2__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_3 (0x3F5)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_3__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_4 (0x3F6)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_4__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_5 (0x3F7)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_5__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_6 (0x3F8)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_6__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_7 (0x3F9)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_7__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_8 (0x3FA)
+#define TAIKO_A_CDC_MAD_BEACON_CTL_8__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_PTR (0x3FB)
+#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_PTR__POR (0x00)
+#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL (0x3FC)
+#define TAIKO_A_CDC_MAD_BEACON_IIR_CTL_VAL__POR (0x00)
+
+/* Taiko v2+ registers */
+#define TAIKO_A_CDC_TX_1_GAIN (0x153)
+#define TAIKO_A_CDC_TX_1_GAIN__POR (0x02)
+#define TAIKO_A_CDC_TX_2_GAIN (0x155)
+#define TAIKO_A_CDC_TX_2_GAIN__POR (0x02)
+#define TAIKO_A_CDC_TX_1_2_ADC_IB (0x156)
+#define TAIKO_A_CDC_TX_1_2_ADC_IB__POR (0x44)
+#define TAIKO_A_CDC_TX_3_GAIN (0x15D)
+#define TAIKO_A_CDC_TX_3_GAIN__POR (0x02)
+#define TAIKO_A_CDC_TX_4_GAIN (0x15F)
+#define TAIKO_A_CDC_TX_4_GAIN__POR (0x02)
+#define TAIKO_A_CDC_TX_3_4_ADC_IB (0x160)
+#define TAIKO_A_CDC_TX_3_4_ADC_IB__POR (0x44)
+#define TAIKO_A_CDC_TX_5_GAIN (0x167)
+#define TAIKO_A_CDC_TX_5_GAIN__POR (0x02)
+#define TAIKO_A_CDC_TX_6_GAIN (0x169)
+#define TAIKO_A_CDC_TX_6_GAIN__POR (0x02)
+#define TAIKO_A_CDC_TX_5_6_ADC_IB (0x16A)
+#define TAIKO_A_CDC_TX_5_6_ADC_IB__POR (0x44)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL0 (0x270)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL0__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL1 (0x271)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL1__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL2 (0x272)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL2__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL3 (0x273)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL3__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL4 (0x274)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL4__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL5 (0x275)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL5__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL6 (0x276)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL6__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL7 (0x277)
+#define TAIKO_A_CDC_SPKR_CLIPDET_VAL7__POR (0x00)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD_MON (0x2FA)
+#define TAIKO_A_CDC_VBAT_GAIN_UPD_MON__POR (0x00)
+#define TAIKO_A_CDC_VBAT_GAIN_MON_VAL (0x2FB)
+#define TAIKO_A_CDC_VBAT_GAIN_MON_VAL__POR (0x00)
+#define TAIKO_A_CDC_PA_RAMP_B1_CTL (0x361)
+#define TAIKO_A_CDC_PA_RAMP_B1_CTL__POR (0x00)
+#define TAIKO_A_CDC_PA_RAMP_B2_CTL (0x362)
+#define TAIKO_A_CDC_PA_RAMP_B2_CTL__POR (0x00)
+#define TAIKO_A_CDC_PA_RAMP_B3_CTL (0x363)
+#define TAIKO_A_CDC_PA_RAMP_B3_CTL__POR (0x00)
+#define TAIKO_A_CDC_PA_RAMP_B4_CTL (0x364)
+#define TAIKO_A_CDC_PA_RAMP_B4_CTL__POR (0x00)
+#define TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL (0x365)
+#define TAIKO_A_CDC_SPKR_CLIPDET_B1_CTL__POR (0x00)
+
+/* SLIMBUS Slave Registers */
+#define TAIKO_SLIM_PGD_PORT_INT_EN0 (0x30)
+#define TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_0 (0x34)
+#define TAIKO_SLIM_PGD_PORT_INT_STATUS_RX_1 (0x35)
+#define TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_0 (0x36)
+#define TAIKO_SLIM_PGD_PORT_INT_STATUS_TX_1 (0x37)
+#define TAIKO_SLIM_PGD_PORT_INT_CLR_RX_0 (0x38)
+#define TAIKO_SLIM_PGD_PORT_INT_CLR_RX_1 (0x39)
+#define TAIKO_SLIM_PGD_PORT_INT_CLR_TX_0 (0x3A)
+#define TAIKO_SLIM_PGD_PORT_INT_CLR_TX_1 (0x3B)
+#define TAIKO_SLIM_PGD_PORT_INT_RX_SOURCE0 (0x60)
+#define TAIKO_SLIM_PGD_PORT_INT_TX_SOURCE0 (0x70)
+
+/* Macros for Packing Register Writes into a U32 */
+#define TAIKO_PACKED_REG_SIZE sizeof(u32)
+
+#define TAIKO_CODEC_PACK_ENTRY(reg, mask, val) ((val & 0xff)|\
+ ((mask & 0xff) << 8)|((reg & 0xffff) << 16))
+
+#define TAIKO_CODEC_UNPACK_ENTRY(packed, reg, mask, val) \
+ do { \
+ ((reg) = ((packed >> 16) & (0xffff))); \
+ ((mask) = ((packed >> 8) & (0xff))); \
+ ((val) = ((packed) & (0xff))); \
+ } while (0);
+
+#endif
diff --git a/include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h b/include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h
new file mode 100644
index 0000000..7902cfb
--- /dev/null
+++ b/include/uapi/linux/mfd/wcd9xxx/wcd9xxx_registers.h
@@ -0,0 +1,361 @@
+#ifndef WCD9XXX_CODEC_DIGITAL_H
+
+#define WCD9XXX_CODEC_DIGITAL_H
+
+#define WCD9XXX_A_CHIP_CTL (0x00)
+#define WCD9XXX_A_CHIP_CTL__POR (0x00000000)
+#define WCD9XXX_A_CHIP_STATUS (0x01)
+#define WCD9XXX_A_CHIP_STATUS__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_0 (0x04)
+#define WCD9XXX_A_CHIP_ID_BYTE_0__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_1 (0x05)
+#define WCD9XXX_A_CHIP_ID_BYTE_1__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_2 (0x06)
+#define WCD9XXX_A_CHIP_ID_BYTE_2__POR (0x00000000)
+#define WCD9XXX_A_CHIP_ID_BYTE_3 (0x07)
+#define WCD9XXX_A_CHIP_ID_BYTE_3__POR (0x00000001)
+#define WCD9XXX_A_CHIP_VERSION (0x08)
+#define WCD9XXX_A_CHIP_VERSION__POR (0x00000020)
+#define WCD9XXX_A_SB_VERSION (0x09)
+#define WCD9XXX_A_SB_VERSION__POR (0x00000010)
+#define WCD9XXX_A_SLAVE_ID_1 (0x0C)
+#define WCD9XXX_A_SLAVE_ID_1__POR (0x00000077)
+#define WCD9XXX_A_SLAVE_ID_2 (0x0D)
+#define WCD9XXX_A_SLAVE_ID_2__POR (0x00000066)
+#define WCD9XXX_A_SLAVE_ID_3 (0x0E)
+#define WCD9XXX_A_SLAVE_ID_3__POR (0x00000055)
+#define WCD9XXX_A_CDC_CTL (0x80)
+#define WCD9XXX_A_CDC_CTL__POR (0x00000000)
+#define WCD9XXX_A_LEAKAGE_CTL (0x88)
+#define WCD9XXX_A_LEAKAGE_CTL__POR (0x00000004)
+#define WCD9XXX_A_INTR_MODE (0x90)
+#define WCD9XXX_A_INTR_MASK0 (0x94)
+#define WCD9XXX_A_INTR_STATUS0 (0x98)
+#define WCD9XXX_A_INTR_CLEAR0 (0x9C)
+#define WCD9XXX_A_INTR_LEVEL0 (0xA0)
+#define WCD9XXX_A_INTR_LEVEL1 (0xA1)
+#define WCD9XXX_A_INTR_LEVEL2 (0xA2)
+#define WCD9XXX_A_RX_HPH_CNP_EN (0x1AB)
+#define WCD9XXX_A_RX_HPH_CNP_EN__POR (0x80)
+#define WCD9XXX_A_RX_HPH_CNP_EN (0x1AB)
+#define WCD9XXX_A_RX_HPH_CNP_EN__POR (0x80)
+#define WCD9XXX_A_BIAS_CENTRAL_BG_CTL (0x101)
+#define WCD9XXX_A_BIAS_CENTRAL_BG_CTL__POR (0x50)
+#define WCD9XXX_A_CLK_BUFF_EN1 (0x108)
+#define WCD9XXX_A_CLK_BUFF_EN1__POR (0x04)
+#define WCD9XXX_A_CLK_BUFF_EN2 (0x109)
+#define WCD9XXX_A_CLK_BUFF_EN2__POR (0x02)
+#define WCD9XXX_A_RX_COM_BIAS (0x1A2)
+#define WCD9XXX_A_RX_COM_BIAS__POR (0x00)
+#define WCD9XXX_A_RC_OSC_FREQ (0x1FA)
+#define WCD9XXX_A_RC_OSC_FREQ__POR (0x46)
+#define WCD9XXX_A_BIAS_OSC_BG_CTL (0x105)
+#define WCD9XXX_A_BIAS_OSC_BG_CTL__POR (0x16)
+#define WCD9XXX_A_RC_OSC_TEST (0x1FB)
+#define WCD9XXX_A_RC_OSC_TEST__POR (0x0A)
+#define WCD9XXX_A_CDC_CLK_MCLK_CTL (0x311)
+#define WCD9XXX_A_CDC_CLK_MCLK_CTL__POR (0x00)
+
+#define WCD9XXX_A_CDC_MBHC_EN_CTL (0x3C0)
+#define WCD9XXX_A_CDC_MBHC_EN_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_FIR_B1_CFG (0x3C1)
+#define WCD9XXX_A_CDC_MBHC_FIR_B1_CFG__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_FIR_B2_CFG (0x3C2)
+#define WCD9XXX_A_CDC_MBHC_FIR_B2_CFG__POR (0x06)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B1_CTL (0x3C3)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B1_CTL__POR (0x03)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B2_CTL (0x3C4)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B2_CTL__POR (0x09)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B3_CTL (0x3C5)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B3_CTL__POR (0x1E)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL (0x3C6)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B4_CTL__POR (0x45)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL (0x3C7)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B5_CTL__POR (0x04)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B6_CTL (0x3C8)
+#define WCD9XXX_A_CDC_MBHC_TIMER_B6_CTL__POR (0x78)
+#define WCD9XXX_A_CDC_MBHC_B1_STATUS (0x3C9)
+#define WCD9XXX_A_CDC_MBHC_B1_STATUS__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_B2_STATUS (0x3CA)
+#define WCD9XXX_A_CDC_MBHC_B2_STATUS__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_B3_STATUS (0x3CB)
+#define WCD9XXX_A_CDC_MBHC_B3_STATUS__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_B4_STATUS (0x3CC)
+#define WCD9XXX_A_CDC_MBHC_B4_STATUS__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_B5_STATUS (0x3CD)
+#define WCD9XXX_A_CDC_MBHC_B5_STATUS__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_B1_CTL (0x3CE)
+#define WCD9XXX_A_CDC_MBHC_B1_CTL__POR (0xC0)
+#define WCD9XXX_A_CDC_MBHC_B2_CTL (0x3CF)
+#define WCD9XXX_A_CDC_MBHC_B2_CTL__POR (0x5D)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL (0x3D0)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B1_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL (0x3D1)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B2_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL (0x3D2)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B3_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL (0x3D3)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B4_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL (0x3D4)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B5_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL (0x3D5)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B6_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B7_CTL (0x3D6)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B7_CTL__POR (0xFF)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B8_CTL (0x3D7)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B8_CTL__POR (0x07)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL (0x3D8)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B9_CTL__POR (0xFF)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL (0x3D9)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B10_CTL__POR (0x7F)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL (0x3DA)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B11_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL (0x3DB)
+#define WCD9XXX_A_CDC_MBHC_VOLT_B12_CTL__POR (0x80)
+#define WCD9XXX_A_CDC_MBHC_CLK_CTL (0x3DC)
+#define WCD9XXX_A_CDC_MBHC_CLK_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_INT_CTL (0x3DD)
+#define WCD9XXX_A_CDC_MBHC_INT_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_DEBUG_CTL (0x3DE)
+#define WCD9XXX_A_CDC_MBHC_DEBUG_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_MBHC_SPARE (0x3DF)
+#define WCD9XXX_A_CDC_MBHC_SPARE__POR (0x00)
+#define WCD9XXX_A_MBHC_SCALING_MUX_1 (0x14E)
+#define WCD9XXX_A_MBHC_SCALING_MUX_1__POR (0x00)
+#define WCD9XXX_A_RX_HPH_OCP_CTL (0x1AA)
+#define WCD9XXX_A_RX_HPH_OCP_CTL__POR (0x68)
+#define WCD9XXX_A_MICB_1_CTL (0x12B)
+#define WCD9XXX_A_MICB_1_CTL__POR (0x16)
+#define WCD9XXX_A_MICB_1_INT_RBIAS (0x12C)
+#define WCD9XXX_A_MICB_1_INT_RBIAS__POR (0x24)
+#define WCD9XXX_A_MICB_1_MBHC (0x12D)
+#define WCD9XXX_A_MICB_1_MBHC__POR (0x01)
+#define WCD9XXX_A_MICB_CFILT_2_CTL (0x12E)
+#define WCD9XXX_A_MICB_CFILT_2_CTL__POR (0x40)
+#define WCD9XXX_A_MICB_CFILT_2_VAL (0x12F)
+#define WCD9XXX_A_MICB_CFILT_2_VAL__POR (0x80)
+#define WCD9XXX_A_MICB_CFILT_2_PRECHRG (0x130)
+#define WCD9XXX_A_MICB_CFILT_2_PRECHRG__POR (0x38)
+#define WCD9XXX_A_MICB_2_CTL (0x131)
+#define WCD9XXX_A_MICB_2_CTL__POR (0x16)
+#define WCD9XXX_A_MICB_2_INT_RBIAS (0x132)
+#define WCD9XXX_A_MICB_2_INT_RBIAS__POR (0x24)
+#define WCD9XXX_A_MICB_2_MBHC (0x133)
+#define WCD9XXX_A_MICB_2_MBHC__POR (0x02)
+#define WCD9XXX_A_MICB_CFILT_3_CTL (0x134)
+#define WCD9XXX_A_MICB_CFILT_3_CTL__POR (0x40)
+#define WCD9XXX_A_MICB_CFILT_3_VAL (0x135)
+#define WCD9XXX_A_MICB_CFILT_3_VAL__POR (0x80)
+#define WCD9XXX_A_MICB_CFILT_3_PRECHRG (0x136)
+#define WCD9XXX_A_MICB_CFILT_3_PRECHRG__POR (0x38)
+#define WCD9XXX_A_MICB_3_CTL (0x137)
+#define WCD9XXX_A_MICB_3_CTL__POR (0x16)
+#define WCD9XXX_A_MICB_3_INT_RBIAS (0x138)
+#define WCD9XXX_A_MICB_3_INT_RBIAS__POR (0x24)
+#define WCD9XXX_A_MICB_3_MBHC (0x139)
+#define WCD9XXX_A_MICB_3_MBHC__POR (0x00)
+#define WCD9XXX_A_MICB_4_CTL (0x13D)
+#define WCD9XXX_A_MICB_4_CTL__POR (0x16)
+#define WCD9XXX_A_MICB_4_INT_RBIAS (0x13E)
+#define WCD9XXX_A_MICB_4_INT_RBIAS__POR (0x24)
+#define WCD9XXX_A_MICB_4_MBHC (0x13F)
+#define WCD9XXX_A_MICB_4_MBHC__POR (0x01)
+#define WCD9XXX_A_MICB_CFILT_1_VAL (0x129)
+#define WCD9XXX_A_MICB_CFILT_1_VAL__POR (0x80)
+#define WCD9XXX_A_RX_HPH_L_STATUS (0x1B3)
+#define WCD9XXX_A_RX_HPH_L_STATUS__POR (0x00)
+#define WCD9XXX_A_MBHC_HPH (0x1FE)
+#define WCD9XXX_A_MBHC_HPH__POR (0x44)
+#define WCD9XXX_A_RX_HPH_CNP_WG_TIME (0x1AD)
+#define WCD9XXX_A_RX_HPH_CNP_WG_TIME__POR (0x2A)
+#define WCD9XXX_A_RX_HPH_R_DAC_CTL (0x1B7)
+#define WCD9XXX_A_RX_HPH_R_DAC_CTL__POR (0x00)
+#define WCD9XXX_A_RX_HPH_L_DAC_CTL (0x1B1)
+#define WCD9XXX_A_RX_HPH_L_DAC_CTL__POR (0x00)
+#define WCD9XXX_A_TX_7_MBHC_EN (0x171)
+#define WCD9XXX_A_TX_7_MBHC_EN__POR (0x0C)
+#define WCD9XXX_A_PIN_CTL_OE0 (0x010)
+#define WCD9XXX_A_PIN_CTL_OE0__POR (0x00)
+#define WCD9XXX_A_PIN_CTL_OE1 (0x011)
+#define WCD9XXX_A_PIN_CTL_OE1__POR (0x00)
+#define WCD9XXX_A_MICB_CFILT_1_CTL (0x128)
+#define WCD9XXX_A_LDO_H_MODE_1 (0x110)
+#define WCD9XXX_A_LDO_H_MODE_1__POR (0x65)
+#define WCD9XXX_A_MICB_CFILT_1_CTL__POR (0x40)
+#define WCD9XXX_A_TX_7_MBHC_TEST_CTL (0x174)
+#define WCD9XXX_A_TX_7_MBHC_TEST_CTL__POR (0x38)
+#define WCD9XXX_A_MBHC_SCALING_MUX_2 (0x14F)
+#define WCD9XXX_A_MBHC_SCALING_MUX_2__POR (0x80)
+#define WCD9XXX_A_TX_COM_BIAS (0x14C)
+#define WCD9XXX_A_TX_COM_BIAS__POR (0xF0)
+
+#define WCD9XXX_A_MBHC_INSERT_DETECT (0x14A) /* TAIKO and later */
+#define WCD9XXX_A_MBHC_INSERT_DETECT__POR (0x00)
+#define WCD9XXX_A_MBHC_INSERT_DET_STATUS (0x14B) /* TAIKO and later */
+#define WCD9XXX_A_MBHC_INSERT_DET_STATUS__POR (0x00)
+#define WCD9XXX_A_MAD_ANA_CTRL (0x150)
+#define WCD9XXX_A_MAD_ANA_CTRL__POR (0xF1)
+
+
+#define WCD9XXX_A_CDC_CLK_OTHR_CTL (0x30C)
+#define WCD9XXX_A_CDC_CLK_OTHR_CTL__POR (0x00)
+
+/* Class H related common registers */
+#define WCD9XXX_A_BUCK_MODE_1 (0x181)
+#define WCD9XXX_A_BUCK_MODE_1__POR (0x21)
+#define WCD9XXX_A_BUCK_MODE_2 (0x182)
+#define WCD9XXX_A_BUCK_MODE_2__POR (0xFF)
+#define WCD9XXX_A_BUCK_MODE_3 (0x183)
+#define WCD9XXX_A_BUCK_MODE_3__POR (0xCC)
+#define WCD9XXX_A_BUCK_MODE_4 (0x184)
+#define WCD9XXX_A_BUCK_MODE_4__POR (0x3A)
+#define WCD9XXX_A_BUCK_MODE_5 (0x185)
+#define WCD9XXX_A_BUCK_MODE_5__POR (0x00)
+#define WCD9XXX_A_BUCK_CTRL_VCL_1 (0x186)
+#define WCD9XXX_A_BUCK_CTRL_VCL_1__POR (0x48)
+#define WCD9XXX_A_BUCK_CTRL_VCL_2 (0x187)
+#define WCD9XXX_A_BUCK_CTRL_VCL_2__POR (0xA3)
+#define WCD9XXX_A_BUCK_CTRL_VCL_3 (0x188)
+#define WCD9XXX_A_BUCK_CTRL_VCL_3__POR (0x82)
+#define WCD9XXX_A_BUCK_CTRL_CCL_1 (0x189)
+#define WCD9XXX_A_BUCK_CTRL_CCL_1__POR (0xAB)
+#define WCD9XXX_A_BUCK_CTRL_CCL_2 (0x18A)
+#define WCD9XXX_A_BUCK_CTRL_CCL_2__POR (0xDC)
+#define WCD9XXX_A_BUCK_CTRL_CCL_3 (0x18B)
+#define WCD9XXX_A_BUCK_CTRL_CCL_3__POR (0x6A)
+#define WCD9XXX_A_BUCK_CTRL_CCL_4 (0x18C)
+#define WCD9XXX_A_BUCK_CTRL_CCL_4__POR (0x58)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_1 (0x18D)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_1__POR (0x50)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_2 (0x18E)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_2__POR (0x64)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_3 (0x18F)
+#define WCD9XXX_A_BUCK_CTRL_PWM_DRVR_3__POR (0x77)
+#define WCD9XXX_A_BUCK_TMUX_A_D (0x190)
+#define WCD9XXX_A_BUCK_TMUX_A_D__POR (0x00)
+#define WCD9XXX_A_NCP_EN (0x192)
+#define WCD9XXX_A_NCP_EN__POR (0xFE)
+#define WCD9XXX_A_NCP_STATIC (0x194)
+#define WCD9XXX_A_NCP_STATIC__POR (0x28)
+#define WCD9XXX_A_NCP_BUCKREF (0x191)
+#define WCD9XXX_A_NCP_BUCKREF__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_B1_CTL (0x320)
+#define WCD9XXX_A_CDC_CLSH_B1_CTL__POR (0xE4)
+#define WCD9XXX_A_CDC_CLSH_B2_CTL (0x321)
+#define WCD9XXX_A_CDC_CLSH_B2_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_B3_CTL (0x322)
+#define WCD9XXX_A_CDC_CLSH_B3_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS (0x323)
+#define WCD9XXX_A_CDC_CLSH_BUCK_NCP_VARS__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD (0x324)
+#define WCD9XXX_A_CDC_CLSH_IDLE_HPH_THSD__POR (0x12)
+#define WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD (0x325)
+#define WCD9XXX_A_CDC_CLSH_IDLE_EAR_THSD__POR (0x0C)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD (0x326)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_HPH_THSD__POR (0x18)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD (0x327)
+#define WCD9XXX_A_CDC_CLSH_FCLKONLY_EAR_THSD__POR (0x23)
+#define WCD9XXX_A_CDC_CLSH_K_ADDR (0x328)
+#define WCD9XXX_A_CDC_CLSH_K_ADDR__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_K_DATA (0x329)
+#define WCD9XXX_A_CDC_CLSH_K_DATA__POR (0xA4)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L (0x32A)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_L__POR (0xD7)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U (0x32B)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_HPH_U__POR (0x05)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L (0x32C)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_L__POR (0x60)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U (0x32D)
+#define WCD9XXX_A_CDC_CLSH_I_PA_FACT_EAR_U__POR (0x09)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR (0x32E)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_EAR__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH (0x32F)
+#define WCD9XXX_A_CDC_CLSH_V_PA_HD_HPH__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR (0x330)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_EAR__POR (0x00)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH (0x331)
+#define WCD9XXX_A_CDC_CLSH_V_PA_MIN_HPH__POR (0x00)
+
+#define WCD9XXX_A_CDC_RX1_B6_CTL (0x2B5)
+#define WCD9XXX_A_CDC_RX1_B6_CTL__POR (0x80)
+#define WCD9XXX_A_CDC_RX2_B6_CTL (0x2BD)
+#define WCD9XXX_A_CDC_RX2_B6_CTL__POR (0x80)
+#define WCD9XXX_A_RX_HPH_L_GAIN (0x1AE)
+#define WCD9XXX_A_RX_HPH_L_GAIN__POR (0x00)
+#define WCD9XXX_A_RX_HPH_R_GAIN (0x1B4)
+#define WCD9XXX_A_RX_HPH_R_GAIN__POR (0x00)
+#define WCD9XXX_A_RX_HPH_CHOP_CTL (0x1A5)
+#define WCD9XXX_A_RX_HPH_CHOP_CTL__POR (0xB4)
+#define WCD9XXX_A_RX_HPH_BIAS_PA (0x1A6)
+#define WCD9XXX_A_RX_HPH_BIAS_PA__POR (0x7A)
+#define WCD9XXX_A_RX_HPH_L_TEST (0x1AF)
+#define WCD9XXX_A_RX_HPH_L_TEST__POR (0x00)
+#define WCD9XXX_A_RX_HPH_R_TEST (0x1B5)
+#define WCD9XXX_A_RX_HPH_R_TEST__POR (0x00)
+#define WCD9XXX_A_CDC_CLK_RX_B1_CTL (0x30F)
+#define WCD9XXX_A_CDC_CLK_RX_B1_CTL__POR (0x00)
+#define WCD9XXX_A_NCP_CLK (0x193)
+#define WCD9XXX_A_NCP_CLK__POR (0x94)
+#define WCD9XXX_A_RX_HPH_BIAS_WG_OCP (0x1A9)
+#define WCD9XXX_A_RX_HPH_BIAS_WG_OCP__POR (0x2A)
+#define WCD9XXX_A_RX_HPH_CNP_WG_CTL (0x1AC)
+#define WCD9XXX_A_RX_HPH_CNP_WG_CTL__POR (0xDE)
+#define WCD9XXX_A_RX_HPH_L_PA_CTL (0x1B0)
+#define WCD9XXX_A_RX_HPH_L_PA_CTL__POR (0x42)
+#define WCD9XXX_A_RX_HPH_R_PA_CTL (0x1B6)
+#define WCD9XXX_A_RX_HPH_R_PA_CTL__POR (0x42)
+#define WCD9XXX_A_CDC_CONN_RX2_B1_CTL (0x383)
+#define WCD9XXX_A_CDC_CONN_RX2_B1_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_PA_RAMP_B1_CTL (0x361)
+#define WCD9XXX_A_CDC_PA_RAMP_B1_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_PA_RAMP_B2_CTL (0x362)
+#define WCD9XXX_A_CDC_PA_RAMP_B2_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_PA_RAMP_B3_CTL (0x363)
+#define WCD9XXX_A_CDC_PA_RAMP_B3_CTL__POR (0x00)
+#define WCD9XXX_A_CDC_PA_RAMP_B4_CTL (0x364)
+#define WCD9XXX_A_CDC_PA_RAMP_B4_CTL__POR (0x00)
+
+#define WCD9330_A_LEAKAGE_CTL (0x03C)
+#define WCD9330_A_LEAKAGE_CTL__POR (0x04)
+#define WCD9330_A_CDC_CTL (0x034)
+#define WCD9330_A_CDC_CTL__POR (0x00)
+
+/* Class-H registers for codecs from and above WCD9335 */
+#define WCD9XXX_A_CDC_RX0_RX_PATH_CFG0 (0xB42)
+#define WCD9XXX_A_CDC_RX1_RX_PATH_CFG0 (0xB56)
+#define WCD9XXX_A_CDC_RX2_RX_PATH_CFG0 (0xB6A)
+#define WCD9XXX_A_CDC_CLSH_K1_MSB (0xC08)
+#define WCD9XXX_A_CDC_CLSH_K1_LSB (0xC09)
+#define WCD9XXX_A_ANA_RX_SUPPLIES (0x608)
+#define WCD9XXX_A_ANA_HPH (0x609)
+#define WCD9XXX_A_CDC_CLSH_CRC (0xC01)
+#define WCD9XXX_FLYBACK_EN (0x6A4)
+#define WCD9XXX_FLYBACK_VNEG_CTRL_1 (0x6A5)
+#define WCD9XXX_FLYBACK_VNEGDAC_CTRL_2 (0x6AF)
+#define WCD9XXX_RX_BIAS_FLYB_BUFF (0x6C7)
+#define WCD9XXX_HPH_L_EN (0x6D3)
+#define WCD9XXX_HPH_R_EN (0x6D6)
+#define WCD9XXX_HPH_REFBUFF_UHQA_CTL (0x6DD)
+#define WCD9XXX_CLASSH_CTRL_VCL_2 (0x69B)
+#define WCD9XXX_CDC_CLSH_HPH_V_PA (0xC04)
+#define WCD9XXX_CDC_RX0_RX_PATH_SEC0 (0xB49)
+#define WCD9XXX_CDC_RX1_RX_PATH_CTL (0xB55)
+#define WCD9XXX_CDC_RX2_RX_PATH_CTL (0xB69)
+#define WCD9XXX_CDC_CLK_RST_CTRL_MCLK_CONTROL (0xD41)
+#define WCD9XXX_CLASSH_CTRL_CCL_1 (0x69C)
+
+/* RX Gain control registers of codecs from and above WCD9335 */
+#define WCD9XXX_CDC_RX1_RX_VOL_CTL (0xB59)
+#define WCD9XXX_CDC_RX1_RX_VOL_MIX_CTL (0xB5C)
+#define WCD9XXX_CDC_RX1_RX_PATH_SEC1 (0xB5E)
+#define WCD9XXX_CDC_RX2_RX_VOL_CTL (0xB6D)
+#define WCD9XXX_CDC_RX2_RX_VOL_MIX_CTL (0xB70)
+#define WCD9XXX_CDC_RX2_RX_PATH_SEC1 (0xB72)
+
+/* Class-H registers for codecs from and above WCD934X */
+#define WCD9XXX_HPH_CNP_WG_CTL (0x06cc)
+#define WCD9XXX_FLYBACK_VNEG_CTRL_4 (0x06a8)
+#define WCD9XXX_HPH_NEW_INT_PA_MISC2 (0x0738)
+#define WCD9XXX_RX_BIAS_HPH_LOWPOWER (0x06bf)
+#define WCD9XXX_HPH_PA_CTL1 (0x06d1)
+#endif
diff --git a/include/uapi/sound/audio_effects.h b/include/uapi/sound/audio_effects.h
index 7964c34..f38b212 100644
--- a/include/uapi/sound/audio_effects.h
+++ b/include/uapi/sound/audio_effects.h
@@ -145,8 +145,12 @@
#define PBE_ENABLE_PARAM_LEN 1
#define PBE_CONFIG_PARAM_LEN 28
+/* Command Payload length and size for Non-IID commands */
#define COMMAND_PAYLOAD_LEN 3
#define COMMAND_PAYLOAD_SZ (COMMAND_PAYLOAD_LEN * sizeof(uint32_t))
+/* Command Payload length and size for IID commands */
+#define COMMAND_IID_PAYLOAD_LEN 4
+#define COMMAND_IID_PAYLOAD_SZ (COMMAND_IID_PAYLOAD_LEN * sizeof(uint32_t))
#define MAX_INBAND_PARAM_SZ 4096
#define Q27_UNITY (1 << 27)
#define Q8_UNITY (1 << 8)
diff --git a/include/uapi/sound/msmcal-hwdep.h b/include/uapi/sound/msmcal-hwdep.h
index 49f15de..2f6d37a 100644
--- a/include/uapi/sound/msmcal-hwdep.h
+++ b/include/uapi/sound/msmcal-hwdep.h
@@ -2,6 +2,7 @@
#define _CALIB_HWDEP_H
#define WCD9XXX_CODEC_HWDEP_NODE 1000
+#define AQT1000_CODEC_HWDEP_NODE 1001
enum wcd_cal_type {
WCD9XXX_MIN_CAL,
WCD9XXX_ANC_CAL = WCD9XXX_MIN_CAL,
diff --git a/ipc/Android.mk b/ipc/Android.mk
index b7908dc..e6ad346 100644
--- a/ipc/Android.mk
+++ b/ipc/Android.mk
@@ -11,9 +11,13 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/ipc/Kbuild b/ipc/Kbuild
index 8730156..3cc021c 100644
--- a/ipc/Kbuild
+++ b/ipc/Kbuild
@@ -16,6 +16,9 @@
ifeq ($(CONFIG_ARCH_SDM670), y)
TARGET_KERNEL_VERSION := 4.9
endif
+ifeq ($(CONFIG_ARCH_SDM855), y)
+ TARGET_KERNEL_VERSION := 4.14
+endif
KDIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)
@@ -39,6 +42,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
# As per target team, build is done as follows:
@@ -104,38 +112,7 @@
KBUILD_CPPFLAGS += $(CDEFINES)
ifeq ($(KERNEL_BUILD), 0)
-
-HEADER_INSTALL_DIR := $(TOP)/kernel/msm-$(TARGET_KERNEL_VERSION)/scripts
-UAPI_OUT := $(OUT)/obj/vendor/qcom/opensource/audio-kernel/include
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ avtimer.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_aac.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_ac3.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_alac.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrnb.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrwb.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_amrwbplus.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_ape.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_calibration.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_g711_dec.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_g711.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_mvs.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_qcp.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_sbc.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_voicememo.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_wma.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/linux/ $(AUDIO_ROOT)/include/uapi/linux/ msm_audio_wmapro.h;)
-
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ audio_effects.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ audio_slimslave.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ devdep_params.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ lsm_params.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ msmcal-hwdep.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ voice_params.h;)
-$(shell $(HEADER_INSTALL_DIR)/headers_install.sh $(UAPI_OUT)/sound/ $(AUDIO_ROOT)/include/uapi/sound/ wcd-dsp-glink.h;)
-
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
-
endif
# Currently, for versions of gcc which support it, the kernel Makefile
diff --git a/ipc/apr_tal_glink.c b/ipc/apr_tal_glink.c
deleted file mode 100644
index 6683348..0000000
--- a/ipc/apr_tal_glink.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/uaccess.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/wait.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/debugfs.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <soc/qcom/glink.h>
-#include <ipc/apr_tal.h>
-
-#define APR_MAXIMUM_NUM_OF_RETRIES 2
-
-struct apr_tx_buf {
- struct apr_pkt_priv pkt_priv;
- char buf[APR_MAX_BUF];
-};
-
-struct link_state {
- uint32_t dest;
- void *handle;
- enum glink_link_state link_state;
- wait_queue_head_t wait;
-};
-
-static struct link_state link_state[APR_DEST_MAX];
-
-static char *svc_names[APR_DEST_MAX][APR_CLIENT_MAX] = {
- {
- "apr_audio_svc",
- "apr_voice_svc",
- },
- {
- "apr_audio_svc",
- "apr_voice_svc",
- },
-};
-
-static struct apr_svc_ch_dev
- apr_svc_ch[APR_DL_MAX][APR_DEST_MAX][APR_CLIENT_MAX];
-
-static struct apr_tx_buf *apr_alloc_buf(int len)
-{
-
- if (len > APR_MAX_BUF) {
- pr_err("%s: buf too large [%d]\n", __func__, len);
- return ERR_PTR(-EINVAL);
- }
-
- return kzalloc(sizeof(struct apr_tx_buf), GFP_ATOMIC);
-}
-
-static void apr_free_buf(const void *ptr)
-{
-
- struct apr_pkt_priv *apr_pkt_priv = (struct apr_pkt_priv *)ptr;
- struct apr_tx_buf *tx_buf;
-
- if (!apr_pkt_priv) {
- pr_err("%s: Invalid apr_pkt_priv\n", __func__);
- return;
- }
-
- if (apr_pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) {
- tx_buf = container_of((void *)apr_pkt_priv,
- struct apr_tx_buf, pkt_priv);
- pr_debug("%s: Freeing buffer %pK", __func__, tx_buf);
- kfree(tx_buf);
- }
-}
-
-
-static int __apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
- struct apr_pkt_priv *pkt_priv, int len)
-{
- int rc = 0;
- unsigned long flags;
-
- spin_lock_irqsave(&apr_ch->w_lock, flags);
- rc = glink_tx(apr_ch->handle, pkt_priv, data, len, GLINK_TX_ATOMIC);
- spin_unlock_irqrestore(&apr_ch->w_lock, flags);
-
- if (rc)
- pr_err("%s: glink_tx failed, rc[%d]\n", __func__, rc);
- else
- rc = len;
-
- return rc;
-}
-
-int apr_tal_write(struct apr_svc_ch_dev *apr_ch, void *data,
- struct apr_pkt_priv *pkt_priv, int len)
-{
- int rc = 0, retries = 0;
- void *pkt_data = NULL;
- struct apr_tx_buf *tx_buf = NULL;
- struct apr_pkt_priv *pkt_priv_ptr = pkt_priv;
-
- if (!apr_ch->handle || !pkt_priv)
- return -EINVAL;
-
- if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER) {
- tx_buf = apr_alloc_buf(len);
- if (IS_ERR_OR_NULL(tx_buf)) {
- rc = -EINVAL;
- goto exit;
- }
- memcpy(tx_buf->buf, data, len);
- memcpy(&tx_buf->pkt_priv, pkt_priv, sizeof(tx_buf->pkt_priv));
- pkt_priv_ptr = &tx_buf->pkt_priv;
- pkt_data = tx_buf->buf;
- } else {
- pkt_data = data;
- }
-
- do {
- if (rc == -EAGAIN)
- udelay(50);
-
- rc = __apr_tal_write(apr_ch, pkt_data, pkt_priv_ptr, len);
- } while (rc == -EAGAIN && retries++ < APR_MAXIMUM_NUM_OF_RETRIES);
-
- if (rc < 0) {
- pr_err("%s: Unable to send the packet, rc:%d\n", __func__, rc);
- if (pkt_priv->pkt_owner == APR_PKT_OWNER_DRIVER)
- kfree(tx_buf);
- }
-exit:
- return rc;
-}
-
-void apr_tal_notify_rx(void *handle, const void *priv, const void *pkt_priv,
- const void *ptr, size_t size)
-{
- struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
- unsigned long flags;
-
- if (!apr_ch || !ptr) {
- pr_err("%s: Invalid apr_ch or ptr\n", __func__);
- return;
- }
-
- pr_debug("%s: Rx packet received\n", __func__);
-
- spin_lock_irqsave(&apr_ch->r_lock, flags);
- if (apr_ch->func)
- apr_ch->func((void *)ptr, size, (void *)pkt_priv);
- spin_unlock_irqrestore(&apr_ch->r_lock, flags);
- glink_rx_done(apr_ch->handle, ptr, true);
-}
-
-static void apr_tal_notify_tx_abort(void *handle, const void *priv,
- const void *pkt_priv)
-{
- pr_debug("%s: tx_abort received for pkt_priv:%pK\n",
- __func__, pkt_priv);
- apr_free_buf(pkt_priv);
-}
-
-void apr_tal_notify_tx_done(void *handle, const void *priv,
- const void *pkt_priv, const void *ptr)
-{
- pr_debug("%s: tx_done received for pkt_priv:%pK\n",
- __func__, pkt_priv);
- apr_free_buf(pkt_priv);
-}
-
-bool apr_tal_notify_rx_intent_req(void *handle, const void *priv,
- size_t req_size)
-{
- struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
-
- if (!apr_ch) {
- pr_err("%s: Invalid apr_ch\n", __func__);
- return false;
- }
-
- pr_err("%s: No rx intents queued, unable to receive\n", __func__);
- return false;
-}
-
-static void apr_tal_notify_remote_rx_intent(void *handle, const void *priv,
- size_t size)
-{
- struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
-
- if (!apr_ch) {
- pr_err("%s: Invalid apr_ch\n", __func__);
- return;
- }
- /*
- * This is to make sure that the far end has queued at least one intent
- * before we attmpt any IPC. A simple bool flag is used here instead of
- * a counter, as the far end is required to guarantee intent
- * availability for all use cases once the channel is fully opened.
- */
- pr_debug("%s: remote queued an intent\n", __func__);
- apr_ch->if_remote_intent_ready = true;
- wake_up(&apr_ch->wait);
-}
-
-void apr_tal_notify_state(void *handle, const void *priv, unsigned int event)
-{
- struct apr_svc_ch_dev *apr_ch = (struct apr_svc_ch_dev *)priv;
-
- if (!apr_ch) {
- pr_err("%s: Invalid apr_ch\n", __func__);
- return;
- }
-
- apr_ch->channel_state = event;
- pr_info("%s: Channel state[%d]\n", __func__, event);
-
- if (event == GLINK_CONNECTED)
- wake_up(&apr_ch->wait);
-}
-
-int apr_tal_rx_intents_config(struct apr_svc_ch_dev *apr_ch,
- int num_of_intents, uint32_t size)
-{
- int i;
- int rc = 0;
-
- if (!apr_ch || !num_of_intents || !size) {
- pr_err("%s: Invalid parameter\n", __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < num_of_intents; i++) {
- rc = glink_queue_rx_intent(apr_ch->handle, apr_ch, size);
- if (rc) {
- pr_err("%s: Failed to queue rx intent, iteration[%d]\n",
- __func__, i);
- break;
- }
- }
-
- return rc;
-}
-
-struct apr_svc_ch_dev *apr_tal_open(uint32_t clnt, uint32_t dest, uint32_t dl,
- apr_svc_cb_fn func, void *priv)
-{
- int rc;
- struct glink_open_config open_cfg;
- struct apr_svc_ch_dev *apr_ch;
-
- if ((clnt >= APR_CLIENT_MAX) || (dest >= APR_DEST_MAX) ||
- (dl >= APR_DL_MAX)) {
- pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n",
- __func__, clnt, dest, dl);
- return NULL;
- }
-
- apr_ch = &apr_svc_ch[dl][dest][clnt];
- mutex_lock(&apr_ch->m_lock);
- if (apr_ch->handle) {
- pr_err("%s: This channel is already opened\n", __func__);
- rc = -EBUSY;
- goto unlock;
- }
-
- if (link_state[dest].link_state != GLINK_LINK_STATE_UP) {
- rc = wait_event_timeout(link_state[dest].wait,
- link_state[dest].link_state == GLINK_LINK_STATE_UP,
- msecs_to_jiffies(APR_OPEN_TIMEOUT_MS));
- if (rc == 0) {
- pr_err("%s: Open timeout, dest:%d\n", __func__, dest);
- rc = -ETIMEDOUT;
- goto unlock;
- }
- pr_debug("%s: Wakeup done, dest:%d\n", __func__, dest);
- }
-
- memset(&open_cfg, 0, sizeof(struct glink_open_config));
- open_cfg.options = GLINK_OPT_INITIAL_XPORT;
- if (dest == APR_DEST_MODEM)
- open_cfg.edge = "mpss";
- else
- open_cfg.edge = "lpass";
-
- open_cfg.name = svc_names[dest][clnt];
- open_cfg.notify_rx = apr_tal_notify_rx;
- open_cfg.notify_tx_done = apr_tal_notify_tx_done;
- open_cfg.notify_state = apr_tal_notify_state;
- open_cfg.notify_rx_intent_req = apr_tal_notify_rx_intent_req;
- open_cfg.notify_remote_rx_intent = apr_tal_notify_remote_rx_intent;
- open_cfg.notify_tx_abort = apr_tal_notify_tx_abort;
- open_cfg.priv = apr_ch;
- open_cfg.transport = "smem";
-
- apr_ch->channel_state = GLINK_REMOTE_DISCONNECTED;
- apr_ch->handle = glink_open(&open_cfg);
- if (IS_ERR_OR_NULL(apr_ch->handle)) {
- pr_err("%s: glink_open failed %s\n", __func__,
- svc_names[dest][clnt]);
- apr_ch->handle = NULL;
- rc = -EINVAL;
- goto unlock;
- }
-
- rc = wait_event_timeout(apr_ch->wait,
- (apr_ch->channel_state == GLINK_CONNECTED), 5 * HZ);
- if (rc == 0) {
- pr_err("%s: TIMEOUT for OPEN event\n", __func__);
- rc = -ETIMEDOUT;
- goto close_link;
- }
-
- /*
- * Remote intent is not required for GLINK <--> SMD IPC, so this is
- * designed not to fail the open call.
- */
- rc = wait_event_timeout(apr_ch->wait,
- apr_ch->if_remote_intent_ready, 5 * HZ);
- if (rc == 0)
- pr_err("%s: TIMEOUT for remote intent readiness\n", __func__);
-
- rc = apr_tal_rx_intents_config(apr_ch, APR_DEFAULT_NUM_OF_INTENTS,
- APR_MAX_BUF);
- if (rc) {
- pr_err("%s: Unable to queue intents\n", __func__);
- goto close_link;
- }
-
- apr_ch->func = func;
- apr_ch->priv = priv;
-
-close_link:
- if (rc) {
- glink_close(apr_ch->handle);
- apr_ch->handle = NULL;
- }
-unlock:
- mutex_unlock(&apr_ch->m_lock);
-
- return rc ? NULL : apr_ch;
-}
-
-int apr_tal_start_rx_rt(struct apr_svc_ch_dev *apr_ch)
-{
- int rc = 0;
-
- if (!apr_ch || !apr_ch->handle) {
- rc = -EINVAL;
- goto exit;
- }
-
- mutex_lock(&apr_ch->m_lock);
- rc = glink_start_rx_rt(apr_ch->handle);
- mutex_unlock(&apr_ch->m_lock);
-exit:
- return rc;
-}
-
-int apr_tal_end_rx_rt(struct apr_svc_ch_dev *apr_ch)
-{
- int rc = 0;
-
- if (!apr_ch || !apr_ch->handle) {
- rc = -EINVAL;
- goto exit;
- }
-
- mutex_lock(&apr_ch->m_lock);
- rc = glink_end_rx_rt(apr_ch->handle);
- mutex_unlock(&apr_ch->m_lock);
-exit:
- return rc;
-}
-
-int apr_tal_close(struct apr_svc_ch_dev *apr_ch)
-{
- int rc;
-
- if (!apr_ch || !apr_ch->handle) {
- rc = -EINVAL;
- goto exit;
- }
-
- mutex_lock(&apr_ch->m_lock);
- rc = glink_close(apr_ch->handle);
- apr_ch->handle = NULL;
- apr_ch->func = NULL;
- apr_ch->priv = NULL;
- apr_ch->if_remote_intent_ready = false;
- mutex_unlock(&apr_ch->m_lock);
-exit:
- return rc;
-}
-
-static void apr_tal_link_state_cb(struct glink_link_state_cb_info *cb_info,
- void *priv)
-{
- uint32_t dest;
-
- if (!cb_info) {
- pr_err("%s: Invalid cb_info\n", __func__);
- return;
- }
-
- if (!strcmp(cb_info->edge, "mpss"))
- dest = APR_DEST_MODEM;
- else if (!strcmp(cb_info->edge, "lpass"))
- dest = APR_DEST_QDSP6;
- else {
- pr_err("%s:Unknown edge[%s]\n", __func__, cb_info->edge);
- return;
- }
-
- pr_info("%s: edge[%s] link state[%d]\n", __func__, cb_info->edge,
- cb_info->link_state);
-
- link_state[dest].link_state = cb_info->link_state;
- if (link_state[dest].link_state == GLINK_LINK_STATE_UP)
- wake_up(&link_state[dest].wait);
-}
-
-static struct glink_link_info mpss_link_info = {
- .transport = "smem",
- .edge = "mpss",
- .glink_link_state_notif_cb = apr_tal_link_state_cb,
-};
-
-static struct glink_link_info lpass_link_info = {
- .transport = "smem",
- .edge = "lpass",
- .glink_link_state_notif_cb = apr_tal_link_state_cb,
-};
-
-int apr_tal_init(void)
-{
- int i, j, k;
-
- for (i = 0; i < APR_DL_MAX; i++) {
- for (j = 0; j < APR_DEST_MAX; j++) {
- for (k = 0; k < APR_CLIENT_MAX; k++) {
- init_waitqueue_head(&apr_svc_ch[i][j][k].wait);
- spin_lock_init(&apr_svc_ch[i][j][k].w_lock);
- spin_lock_init(&apr_svc_ch[i][j][k].r_lock);
- mutex_init(&apr_svc_ch[i][j][k].m_lock);
- }
- }
- }
-
- for (i = 0; i < APR_DEST_MAX; i++)
- init_waitqueue_head(&link_state[i].wait);
-
- link_state[APR_DEST_MODEM].link_state = GLINK_LINK_STATE_DOWN;
- link_state[APR_DEST_MODEM].handle =
- glink_register_link_state_cb(&mpss_link_info, NULL);
- if (!link_state[APR_DEST_MODEM].handle)
- pr_err("%s: Unable to register mpss link state\n", __func__);
-
- link_state[APR_DEST_QDSP6].link_state = GLINK_LINK_STATE_DOWN;
- link_state[APR_DEST_QDSP6].handle =
- glink_register_link_state_cb(&lpass_link_info, NULL);
- if (!link_state[APR_DEST_QDSP6].handle)
- pr_err("%s: Unable to register lpass link state\n", __func__);
-
- return 0;
-}
diff --git a/ipc/wcd-dsp-glink.c b/ipc/wcd-dsp-glink.c
index 400fd06..8e1d8a2 100644
--- a/ipc/wcd-dsp-glink.c
+++ b/ipc/wcd-dsp-glink.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,34 +13,33 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
-#include <linux/list.h>
#include <linux/cdev.h>
#include <linux/platform_device.h>
+#include <linux/of_device.h>
#include <linux/vmalloc.h>
-#include <soc/qcom/glink.h>
+#include <linux/rpmsg.h>
#include "sound/wcd-dsp-glink.h"
#define WDSP_GLINK_DRIVER_NAME "wcd-dsp-glink"
#define WDSP_MAX_WRITE_SIZE (256 * 1024)
#define WDSP_MAX_READ_SIZE (4 * 1024)
-#define WDSP_MAX_NO_OF_INTENTS (20)
-#define WDSP_MAX_NO_OF_CHANNELS (10)
#define WDSP_WRITE_PKT_SIZE (sizeof(struct wdsp_write_pkt))
-#define WDSP_REG_PKT_SIZE (sizeof(struct wdsp_reg_pkt))
#define WDSP_CMD_PKT_SIZE (sizeof(struct wdsp_cmd_pkt))
-#define WDSP_CH_CFG_SIZE (sizeof(struct wdsp_glink_ch_cfg))
#define MINOR_NUMBER_COUNT 1
-#define WDSP_EDGE "wdsp"
#define RESP_QUEUE_SIZE 3
-#define QOS_PKT_SIZE 1024
#define TIMEOUT_MS 1000
+enum wdsp_ch_state {
+ WDSP_CH_DISCONNECTED,
+ WDSP_CH_CONNECTED,
+};
+
struct wdsp_glink_dev {
struct class *cls;
struct device *dev;
@@ -48,7 +47,7 @@
dev_t dev_num;
};
-struct wdsp_glink_rsp_que {
+struct wdsp_rsp_que {
/* Size of valid data in buffer */
u32 buf_size;
@@ -56,687 +55,230 @@
u8 buf[WDSP_MAX_READ_SIZE];
};
-struct wdsp_glink_tx_buf {
+struct wdsp_ch {
+ struct wdsp_glink_priv *wpriv;
+ /* rpmsg handle */
+ void *handle;
+ /* Channel states like connect, disconnect */
+ int ch_state;
+ char ch_name[RPMSG_NAME_SIZE];
+ spinlock_t ch_lock;
+};
+
+struct wdsp_tx_buf {
struct work_struct tx_work;
- struct work_struct free_tx_work;
/* Glink channel information */
- struct wdsp_glink_ch *ch;
+ struct wdsp_ch *ch;
/* Tx buffer to send to glink */
u8 buf[0];
};
-struct wdsp_glink_ch {
- struct wdsp_glink_priv *wpriv;
-
- /* Glink channel handle */
- void *handle;
-
- /* Channel states like connect, disconnect */
- int channel_state;
- struct mutex mutex;
-
- /* To free up the channel memory */
- bool free_mem;
-
- /* Glink local channel open work */
- struct work_struct lcl_ch_open_wrk;
-
- /* Glink local channel close work */
- struct work_struct lcl_ch_cls_wrk;
-
- /* Wait for ch connect state before sending any command */
- wait_queue_head_t ch_connect_wait;
-
- /*
- * Glink channel configuration. This has to be the last
- * member of the strucuture as it has variable size
- */
- struct wdsp_glink_ch_cfg ch_cfg;
-};
-
-struct wdsp_glink_state {
- /* Glink link state information */
- enum glink_link_state link_state;
- void *handle;
-};
-
struct wdsp_glink_priv {
/* Respone buffer related */
u8 rsp_cnt;
- struct wdsp_glink_rsp_que rsp[RESP_QUEUE_SIZE];
+ struct wdsp_rsp_que rsp[RESP_QUEUE_SIZE];
struct completion rsp_complete;
- struct mutex rsp_mutex;
+ spinlock_t rsp_lock;
/* Glink channel related */
- struct mutex glink_mutex;
- struct wdsp_glink_state glink_state;
- struct wdsp_glink_ch **ch;
- u8 no_of_channels;
- struct work_struct ch_open_cls_wrk;
+ int no_of_channels;
+ struct wdsp_ch **ch;
struct workqueue_struct *work_queue;
+ /* Wait for all channels state before sending any command */
+ wait_queue_head_t ch_state_wait;
- wait_queue_head_t link_state_wait;
-
+ struct wdsp_glink_dev *wdev;
struct device *dev;
};
+static struct wdsp_glink_priv *wpriv;
-static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch);
-static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch);
-
-/*
- * wdsp_glink_free_tx_buf_work - Work function to free tx pkt
- * work: Work structure
- */
-static void wdsp_glink_free_tx_buf_work(struct work_struct *work)
-{
- struct wdsp_glink_tx_buf *tx_buf;
-
- tx_buf = container_of(work, struct wdsp_glink_tx_buf,
- free_tx_work);
- vfree(tx_buf);
-}
-
-/*
- * wdsp_glink_free_tx_buf - Function to free tx buffer
- * priv: Pointer to the channel
- * pkt_priv: Pointer to the tx buffer
- */
-static void wdsp_glink_free_tx_buf(const void *priv, const void *pkt_priv)
-{
- struct wdsp_glink_tx_buf *tx_buf = (struct wdsp_glink_tx_buf *)pkt_priv;
- struct wdsp_glink_priv *wpriv;
- struct wdsp_glink_ch *ch;
-
- if (!priv) {
- pr_err("%s: Invalid priv\n", __func__);
- return;
- }
- if (!tx_buf) {
- pr_err("%s: Invalid tx_buf\n", __func__);
- return;
- }
-
- ch = (struct wdsp_glink_ch *)priv;
- wpriv = ch->wpriv;
- /* Work queue to free tx pkt */
- INIT_WORK(&tx_buf->free_tx_work, wdsp_glink_free_tx_buf_work);
- queue_work(wpriv->work_queue, &tx_buf->free_tx_work);
-}
-
-/*
- * wdsp_glink_notify_rx - Glink notify rx callback for responses
- * handle: Opaque Channel handle returned by GLink
- * priv: Private pointer to the channel
- * pkt_priv: Private pointer to the packet
- * ptr: Pointer to the Rx data
- * size: Size of the Rx data
- */
-static void wdsp_glink_notify_rx(void *handle, const void *priv,
- const void *pkt_priv, const void *ptr,
- size_t size)
-{
- u8 *rx_buf;
- u8 rsp_cnt;
- struct wdsp_glink_ch *ch;
- struct wdsp_glink_priv *wpriv;
-
- if (!ptr || !priv) {
- pr_err("%s: Invalid parameters\n", __func__);
- return;
- }
-
- ch = (struct wdsp_glink_ch *)priv;
- wpriv = ch->wpriv;
- rx_buf = (u8 *)ptr;
- if (size > WDSP_MAX_READ_SIZE) {
- dev_err(wpriv->dev, "%s: Size %zd is greater than allowed %d\n",
- __func__, size, WDSP_MAX_READ_SIZE);
- size = WDSP_MAX_READ_SIZE;
- }
-
- mutex_lock(&wpriv->rsp_mutex);
- rsp_cnt = wpriv->rsp_cnt;
- if (rsp_cnt >= RESP_QUEUE_SIZE) {
- dev_err(wpriv->dev, "%s: Resp Queue is Full\n", __func__);
- rsp_cnt = 0;
- }
- dev_dbg(wpriv->dev, "%s: copy into buffer %d\n", __func__, rsp_cnt);
-
- memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, size);
- wpriv->rsp[rsp_cnt].buf_size = size;
- wpriv->rsp_cnt = ++rsp_cnt;
- mutex_unlock(&wpriv->rsp_mutex);
-
- glink_rx_done(handle, ptr, true);
- complete(&wpriv->rsp_complete);
-}
-
-/*
- * wdsp_glink_notify_tx_done - Glink notify tx done callback to
- * free tx buffer
- * handle: Opaque Channel handle returned by GLink
- * priv: Private pointer to the channel
- * pkt_priv: Private pointer to the packet
- * ptr: Pointer to the Tx data
- */
-static void wdsp_glink_notify_tx_done(void *handle, const void *priv,
- const void *pkt_priv, const void *ptr)
-{
- wdsp_glink_free_tx_buf(priv, pkt_priv);
-}
-/*
- * wdsp_glink_notify_tx_abort - Glink notify tx abort callback to
- * free tx buffer
- * handle: Opaque Channel handle returned by GLink
- * priv: Private pointer to the channel
- * pkt_priv: Private pointer to the packet
- */
-static void wdsp_glink_notify_tx_abort(void *handle, const void *priv,
- const void *pkt_priv)
-{
- wdsp_glink_free_tx_buf(priv, pkt_priv);
-}
-
-/*
- * wdsp_glink_notify_rx_intent_req - Glink notify rx intent request callback
- * to queue buffer to receive from remote client
- * handle: Opaque channel handle returned by GLink
- * priv: Private pointer to the channel
- * req_size: Size of intent to be queued
- */
-static bool wdsp_glink_notify_rx_intent_req(void *handle, const void *priv,
- size_t req_size)
-{
- struct wdsp_glink_priv *wpriv;
- struct wdsp_glink_ch *ch;
- int rc = 0;
- bool ret = false;
-
- if (!priv) {
- pr_err("%s: Invalid priv\n", __func__);
- goto done;
- }
- if (req_size > WDSP_MAX_READ_SIZE) {
- pr_err("%s: Invalid req_size %zd\n", __func__, req_size);
- goto done;
- }
-
- ch = (struct wdsp_glink_ch *)priv;
- wpriv = ch->wpriv;
-
- dev_dbg(wpriv->dev, "%s: intent size %zd requested for ch name %s",
- __func__, req_size, ch->ch_cfg.name);
-
- mutex_lock(&ch->mutex);
- rc = glink_queue_rx_intent(ch->handle, ch, req_size);
- if (rc < 0) {
- dev_err(wpriv->dev, "%s: Failed to queue rx intent, rc = %d\n",
- __func__, rc);
- mutex_unlock(&ch->mutex);
- goto done;
- }
- mutex_unlock(&ch->mutex);
- ret = true;
-
-done:
- return ret;
-}
-
-/*
- * wdsp_glink_lcl_ch_open_wrk - Work function to open channel again
- * when local disconnect event happens
- * work: Work structure
- */
-static void wdsp_glink_lcl_ch_open_wrk(struct work_struct *work)
-{
- struct wdsp_glink_ch *ch;
-
- ch = container_of(work, struct wdsp_glink_ch,
- lcl_ch_open_wrk);
-
- wdsp_glink_open_ch(ch);
-}
-
-/*
- * wdsp_glink_lcl_ch_cls_wrk - Work function to close channel locally
- * when remote disconnect event happens
- * work: Work structure
- */
-static void wdsp_glink_lcl_ch_cls_wrk(struct work_struct *work)
-{
- struct wdsp_glink_ch *ch;
-
- ch = container_of(work, struct wdsp_glink_ch,
- lcl_ch_cls_wrk);
-
- wdsp_glink_close_ch(ch);
-}
-
-/*
- * wdsp_glink_notify_state - Glink channel state information event callback
- * handle: Opaque Channel handle returned by GLink
- * priv: Private pointer to the channel
- * event: channel state event
- */
-static void wdsp_glink_notify_state(void *handle, const void *priv,
- unsigned int event)
-{
- struct wdsp_glink_priv *wpriv;
- struct wdsp_glink_ch *ch;
- int i, ret = 0;
-
- if (!priv) {
- pr_err("%s: Invalid priv\n", __func__);
- return;
- }
-
- ch = (struct wdsp_glink_ch *)priv;
- wpriv = ch->wpriv;
-
- mutex_lock(&ch->mutex);
- ch->channel_state = event;
- if (event == GLINK_CONNECTED) {
- dev_dbg(wpriv->dev, "%s: glink channel: %s connected\n",
- __func__, ch->ch_cfg.name);
-
- for (i = 0; i < ch->ch_cfg.no_of_intents; i++) {
- dev_dbg(wpriv->dev, "%s: intent_size = %d\n", __func__,
- ch->ch_cfg.intents_size[i]);
- ret = glink_queue_rx_intent(ch->handle, ch,
- ch->ch_cfg.intents_size[i]);
- if (ret < 0)
- dev_warn(wpriv->dev, "%s: Failed to queue intent %d of size %d\n",
- __func__, i,
- ch->ch_cfg.intents_size[i]);
- }
-
- ret = glink_qos_latency(ch->handle, ch->ch_cfg.latency_in_us,
- QOS_PKT_SIZE);
- if (ret < 0)
- dev_warn(wpriv->dev, "%s: Failed to request qos %d for ch %s\n",
- __func__, ch->ch_cfg.latency_in_us,
- ch->ch_cfg.name);
-
- wake_up(&ch->ch_connect_wait);
- mutex_unlock(&ch->mutex);
- } else if (event == GLINK_LOCAL_DISCONNECTED) {
- /*
- * Don't use dev_dbg here as dev may not be valid if channel
- * closed from driver close.
- */
- pr_debug("%s: channel: %s disconnected locally\n",
- __func__, ch->ch_cfg.name);
- mutex_unlock(&ch->mutex);
-
- if (ch->free_mem) {
- kfree(ch);
- ch = NULL;
- }
- } else if (event == GLINK_REMOTE_DISCONNECTED) {
- dev_dbg(wpriv->dev, "%s: remote channel: %s disconnected remotely\n",
- __func__, ch->ch_cfg.name);
- mutex_unlock(&ch->mutex);
- /*
- * If remote disconnect happens, local side also has
- * to close the channel as per glink design in a
- * separate work_queue.
- */
- queue_work(wpriv->work_queue, &ch->lcl_ch_cls_wrk);
- }
-}
-
-/*
- * wdsp_glink_close_ch - Internal function to close glink channel
- * ch: Glink Channel structure.
- */
-static int wdsp_glink_close_ch(struct wdsp_glink_ch *ch)
-{
- struct wdsp_glink_priv *wpriv = ch->wpriv;
- int ret = 0;
-
- mutex_lock(&wpriv->glink_mutex);
- if (ch->handle) {
- ret = glink_close(ch->handle);
- if (ret < 0) {
- dev_err(wpriv->dev, "%s: glink_close is failed, ret = %d\n",
- __func__, ret);
- } else {
- ch->handle = NULL;
- dev_dbg(wpriv->dev, "%s: ch %s is closed\n", __func__,
- ch->ch_cfg.name);
- }
- } else {
- dev_dbg(wpriv->dev, "%s: ch %s is already closed\n", __func__,
- ch->ch_cfg.name);
- }
- mutex_unlock(&wpriv->glink_mutex);
-
-
- return ret;
-}
-
-/*
- * wdsp_glink_open_ch - Internal function to open glink channel
- * ch: Glink Channel structure.
- */
-static int wdsp_glink_open_ch(struct wdsp_glink_ch *ch)
-{
- struct wdsp_glink_priv *wpriv = ch->wpriv;
- struct glink_open_config open_cfg;
- int ret = 0;
-
- mutex_lock(&wpriv->glink_mutex);
- if (!ch->handle) {
- memset(&open_cfg, 0, sizeof(open_cfg));
- open_cfg.options = GLINK_OPT_INITIAL_XPORT;
- open_cfg.edge = WDSP_EDGE;
- open_cfg.notify_rx = wdsp_glink_notify_rx;
- open_cfg.notify_tx_done = wdsp_glink_notify_tx_done;
- open_cfg.notify_tx_abort = wdsp_glink_notify_tx_abort;
- open_cfg.notify_state = wdsp_glink_notify_state;
- open_cfg.notify_rx_intent_req = wdsp_glink_notify_rx_intent_req;
- open_cfg.priv = ch;
- open_cfg.name = ch->ch_cfg.name;
-
- dev_dbg(wpriv->dev, "%s: ch->ch_cfg.name = %s, latency_in_us = %d, intents = %d\n",
- __func__, ch->ch_cfg.name, ch->ch_cfg.latency_in_us,
- ch->ch_cfg.no_of_intents);
-
- ch->handle = glink_open(&open_cfg);
- if (IS_ERR_OR_NULL(ch->handle)) {
- dev_err(wpriv->dev, "%s: glink_open failed for ch %s\n",
- __func__, ch->ch_cfg.name);
- ch->handle = NULL;
- ret = -EINVAL;
- }
- } else {
- dev_err(wpriv->dev, "%s: ch %s is already opened\n", __func__,
- ch->ch_cfg.name);
- }
- mutex_unlock(&wpriv->glink_mutex);
-
- return ret;
-}
-
-/*
- * wdsp_glink_close_all_ch - Internal function to close all glink channels
- * wpriv: Wdsp_glink private structure
- */
-static void wdsp_glink_close_all_ch(struct wdsp_glink_priv *wpriv)
+static struct wdsp_ch *wdsp_get_ch(char *ch_name)
{
int i;
- for (i = 0; i < wpriv->no_of_channels; i++)
- if (wpriv->ch && wpriv->ch[i])
- wdsp_glink_close_ch(wpriv->ch[i]);
-}
-
-/*
- * wdsp_glink_open_all_ch - Internal function to open all glink channels
- * wpriv: Wdsp_glink private structure
- */
-static int wdsp_glink_open_all_ch(struct wdsp_glink_priv *wpriv)
-{
- int ret = 0, i, j;
-
for (i = 0; i < wpriv->no_of_channels; i++) {
- if (wpriv->ch && wpriv->ch[i]) {
- ret = wdsp_glink_open_ch(wpriv->ch[i]);
- if (ret < 0)
- goto err_open;
- }
+ if (!strcmp(ch_name, wpriv->ch[i]->ch_name))
+ return wpriv->ch[i];
}
- goto done;
-
-err_open:
- for (j = 0; j < i; j++)
- if (wpriv->ch[i])
- wdsp_glink_close_ch(wpriv->ch[j]);
-
-done:
- return ret;
+ return NULL;
}
/*
- * wdsp_glink_ch_open_wq - Work function to open glink channels
- * work: Work structure
+ * wdsp_rpmsg_callback - Rpmsg callback for responses
+ * rpdev: Rpmsg device structure
+ * data: Pointer to the Rx data
+ * len: Size of the Rx data
+ * priv: Private pointer to the channel
+ * addr: Address variable
+ * Returns 0 on success and an appropriate error value on failure
*/
-static void wdsp_glink_ch_open_cls_wrk(struct work_struct *work)
+static int wdsp_rpmsg_callback(struct rpmsg_device *rpdev, void *data,
+ int len, void *priv, u32 addr__unused)
{
+ struct wdsp_ch *ch = dev_get_drvdata(&rpdev->dev);
struct wdsp_glink_priv *wpriv;
+ unsigned long flags;
+ u8 *rx_buf;
+ u8 rsp_cnt = 0;
- wpriv = container_of(work, struct wdsp_glink_priv,
- ch_open_cls_wrk);
-
- if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) {
- dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_DOWN\n",
- __func__);
-
- wdsp_glink_close_all_ch(wpriv);
- } else if (wpriv->glink_state.link_state == GLINK_LINK_STATE_UP) {
- dev_info(wpriv->dev, "%s: GLINK_LINK_STATE_UP\n",
- __func__);
-
- wdsp_glink_open_all_ch(wpriv);
+ if (!ch || !data) {
+ pr_err("%s: Invalid ch or data\n", __func__);
+ return -EINVAL;
}
+
+ wpriv = ch->wpriv;
+ rx_buf = (u8 *)data;
+ if (len > WDSP_MAX_READ_SIZE) {
+ dev_info_ratelimited(wpriv->dev, "%s: Size %d is greater than allowed %d\n",
+ __func__, len, WDSP_MAX_READ_SIZE);
+ len = WDSP_MAX_READ_SIZE;
+ }
+ dev_dbg_ratelimited(wpriv->dev, "%s: copy into buffer %d\n", __func__,
+ wpriv->rsp_cnt);
+
+ if (wpriv->rsp_cnt >= RESP_QUEUE_SIZE) {
+ dev_info_ratelimited(wpriv->dev, "%s: Resp Queue is Full\n",
+ __func__);
+ rsp_cnt = 0;
+ }
+ spin_lock_irqsave(&wpriv->rsp_lock, flags);
+ rsp_cnt = wpriv->rsp_cnt;
+ memcpy(wpriv->rsp[rsp_cnt].buf, rx_buf, len);
+ wpriv->rsp[rsp_cnt].buf_size = len;
+ wpriv->rsp_cnt = ++rsp_cnt;
+ spin_unlock_irqrestore(&wpriv->rsp_lock, flags);
+
+ complete(&wpriv->rsp_complete);
+
+ return 0;
}
/*
- * wdsp_glink_link_state_cb - Glink link state callback to inform
- * about link states
- * cb_info: Glink link state callback information structure
- * priv: Private structure of link state passed while register
+ * wdsp_rpmsg_probe - Rpmsg channel probe function
+ * rpdev: Rpmsg device structure
+ * Returns 0 on success and an appropriate error value on failure
*/
-static void wdsp_glink_link_state_cb(struct glink_link_state_cb_info *cb_info,
- void *priv)
+static int wdsp_rpmsg_probe(struct rpmsg_device *rpdev)
{
- struct wdsp_glink_priv *wpriv;
+ struct wdsp_ch *ch;
- if (!cb_info || !priv) {
- pr_err("%s: Invalid parameters\n", __func__);
+ ch = wdsp_get_ch(rpdev->id.name);
+ if (!ch) {
+ dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n",
+ __func__, rpdev->id.name);
+ return -EINVAL;
+ }
+
+ dev_dbg(&rpdev->dev, "%s: Channel[%s] state[Up]\n",
+ __func__, rpdev->id.name);
+
+ spin_lock(&ch->ch_lock);
+ ch->handle = rpdev;
+ ch->ch_state = WDSP_CH_CONNECTED;
+ spin_unlock(&ch->ch_lock);
+ dev_set_drvdata(&rpdev->dev, ch);
+ wake_up(&wpriv->ch_state_wait);
+
+ return 0;
+}
+
+/*
+ * wdsp_rpmsg_remove - Rpmsg channel remove function
+ * rpdev: Rpmsg device structure
+ */
+static void wdsp_rpmsg_remove(struct rpmsg_device *rpdev)
+{
+ struct wdsp_ch *ch = dev_get_drvdata(&rpdev->dev);
+
+ if (!ch) {
+ dev_err(&rpdev->dev, "%s: Invalid ch\n", __func__);
return;
}
- wpriv = (struct wdsp_glink_priv *)priv;
-
- mutex_lock(&wpriv->glink_mutex);
- wpriv->glink_state.link_state = cb_info->link_state;
- wake_up(&wpriv->link_state_wait);
- mutex_unlock(&wpriv->glink_mutex);
-
- queue_work(wpriv->work_queue, &wpriv->ch_open_cls_wrk);
+ dev_dbg(&rpdev->dev, "%s: Channel[%s] state[Down]\n",
+ __func__, rpdev->id.name);
+ spin_lock(&ch->ch_lock);
+ ch->handle = NULL;
+ ch->ch_state = WDSP_CH_DISCONNECTED;
+ spin_unlock(&ch->ch_lock);
+ dev_set_drvdata(&rpdev->dev, NULL);
}
-/*
- * wdsp_glink_ch_info_init- Internal function to allocate channel memory
- * and register with glink
- * wpriv: Wdsp_glink private structure.
- * pkt: Glink registration packet contains glink channel information.
- * pkt_size: Size of the pkt.
- */
-static int wdsp_glink_ch_info_init(struct wdsp_glink_priv *wpriv,
- struct wdsp_reg_pkt *pkt, size_t pkt_size)
+static bool wdsp_is_ch_connected(struct wdsp_glink_priv *wpriv)
{
- int ret = 0, i, j;
- struct glink_link_info link_info;
- struct wdsp_glink_ch_cfg *ch_cfg;
- struct wdsp_glink_ch **ch;
- u8 no_of_channels;
- u8 *payload;
- u32 ch_size, ch_cfg_size;
- size_t size = WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE;
+ int i;
- mutex_lock(&wpriv->glink_mutex);
- if (wpriv->ch) {
- dev_err_ratelimited(wpriv->dev, "%s: glink ch memory is already allocated\n",
- __func__);
- ret = -EINVAL;
- goto done;
- }
- payload = (u8 *)pkt->payload;
- no_of_channels = pkt->no_of_channels;
-
- if (no_of_channels > WDSP_MAX_NO_OF_CHANNELS) {
- dev_err_ratelimited(wpriv->dev, "%s: no_of_channels: %d but max allowed are %d\n",
- __func__, no_of_channels, WDSP_MAX_NO_OF_CHANNELS);
- ret = -EINVAL;
- goto done;
- }
- ch = kcalloc(no_of_channels, sizeof(struct wdsp_glink_ch *),
- GFP_ATOMIC);
- if (!ch) {
- ret = -ENOMEM;
- goto done;
- }
- wpriv->ch = ch;
- wpriv->no_of_channels = no_of_channels;
-
- for (i = 0; i < no_of_channels; i++) {
- ch_cfg = (struct wdsp_glink_ch_cfg *)payload;
-
- size += WDSP_CH_CFG_SIZE;
- if (size > pkt_size) {
- dev_err_ratelimited(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n",
- __func__, size, pkt_size);
- ret = -EINVAL;
- goto err_ch_mem;
+ for (i = 0; i < wpriv->no_of_channels; i++) {
+ spin_lock(&wpriv->ch[i]->ch_lock);
+ if (wpriv->ch[i]->ch_state != WDSP_CH_CONNECTED) {
+ spin_unlock(&wpriv->ch[i]->ch_lock);
+ return false;
}
- if (ch_cfg->no_of_intents > WDSP_MAX_NO_OF_INTENTS) {
- dev_err_ratelimited(wpriv->dev, "%s: Invalid no_of_intents = %d\n",
- __func__, ch_cfg->no_of_intents);
- ret = -EINVAL;
- goto err_ch_mem;
- }
- size += (sizeof(u32) * ch_cfg->no_of_intents);
- if (size > pkt_size) {
- dev_err_ratelimited(wpriv->dev, "%s: Invalid size = %zd, pkt_size = %zd\n",
- __func__, size, pkt_size);
- ret = -EINVAL;
- goto err_ch_mem;
- }
-
- ch_cfg_size = sizeof(struct wdsp_glink_ch_cfg) +
- (sizeof(u32) * ch_cfg->no_of_intents);
- ch_size = sizeof(struct wdsp_glink_ch) +
- (sizeof(u32) * ch_cfg->no_of_intents);
-
- dev_dbg(wpriv->dev, "%s: channels: %d ch_cfg_size: %d, size: %zd, pkt_size: %zd",
- __func__, no_of_channels, ch_cfg_size, size, pkt_size);
-
- ch[i] = kzalloc(ch_size, GFP_KERNEL);
- if (!ch[i]) {
- ret = -ENOMEM;
- goto err_ch_mem;
- }
- ch[i]->channel_state = GLINK_LOCAL_DISCONNECTED;
- memcpy(&ch[i]->ch_cfg, payload, ch_cfg_size);
- payload += ch_cfg_size;
-
- /* check ch name is valid string or not */
- for (j = 0; j < WDSP_CH_NAME_MAX_LEN; j++) {
- if (ch[i]->ch_cfg.name[j] == '\0')
- break;
- }
-
- if (j == WDSP_CH_NAME_MAX_LEN) {
- dev_err_ratelimited(wpriv->dev, "%s: Wrong channel name\n",
- __func__);
- kfree(ch[i]);
- ch[i] = NULL;
- ret = -EINVAL;
- goto err_ch_mem;
- }
-
- mutex_init(&ch[i]->mutex);
- ch[i]->wpriv = wpriv;
- INIT_WORK(&ch[i]->lcl_ch_open_wrk, wdsp_glink_lcl_ch_open_wrk);
- INIT_WORK(&ch[i]->lcl_ch_cls_wrk, wdsp_glink_lcl_ch_cls_wrk);
- init_waitqueue_head(&ch[i]->ch_connect_wait);
+ spin_unlock(&wpriv->ch[i]->ch_lock);
}
+ return true;
+}
- INIT_WORK(&wpriv->ch_open_cls_wrk, wdsp_glink_ch_open_cls_wrk);
+static int wdsp_wait_for_all_ch_connect(struct wdsp_glink_priv *wpriv)
+{
+ int ret;
- /* Register glink link_state notification */
- link_info.glink_link_state_notif_cb = wdsp_glink_link_state_cb;
- link_info.transport = NULL;
- link_info.edge = WDSP_EDGE;
-
- wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN;
- wpriv->glink_state.handle = glink_register_link_state_cb(&link_info,
- wpriv);
- if (!wpriv->glink_state.handle) {
- dev_err(wpriv->dev, "%s: Unable to register wdsp link state\n",
- __func__);
- ret = -EINVAL;
- goto err_ch_mem;
+ ret = wait_event_timeout(wpriv->ch_state_wait,
+ wdsp_is_ch_connected(wpriv),
+ msecs_to_jiffies(TIMEOUT_MS));
+ if (!ret) {
+ dev_err_ratelimited(wpriv->dev, "%s: All channels are not connected\n",
+ __func__);
+ ret = -ETIMEDOUT;
+ goto err;
}
- goto done;
+ ret = 0;
-err_ch_mem:
- for (j = 0; j < i; j++) {
- mutex_destroy(&ch[j]->mutex);
- kfree(wpriv->ch[j]);
- wpriv->ch[j] = NULL;
- }
- kfree(wpriv->ch);
- wpriv->ch = NULL;
- wpriv->no_of_channels = 0;
-
-done:
- mutex_unlock(&wpriv->glink_mutex);
+err:
return ret;
}
/*
- * wdsp_glink_tx_buf_work - Work queue function to send tx buffer to glink
+ * wdsp_tx_buf_work - Work queue function to send tx buffer to glink
* work: Work structure
*/
-static void wdsp_glink_tx_buf_work(struct work_struct *work)
+static void wdsp_tx_buf_work(struct work_struct *work)
{
struct wdsp_glink_priv *wpriv;
- struct wdsp_glink_ch *ch;
- struct wdsp_glink_tx_buf *tx_buf;
+ struct wdsp_ch *ch;
+ struct wdsp_tx_buf *tx_buf;
struct wdsp_write_pkt *wpkt;
struct wdsp_cmd_pkt *cpkt;
int ret = 0;
+ struct rpmsg_device *rpdev = NULL;
- tx_buf = container_of(work, struct wdsp_glink_tx_buf,
+ tx_buf = container_of(work, struct wdsp_tx_buf,
tx_work);
ch = tx_buf->ch;
wpriv = ch->wpriv;
wpkt = (struct wdsp_write_pkt *)tx_buf->buf;
cpkt = (struct wdsp_cmd_pkt *)wpkt->payload;
+
dev_dbg(wpriv->dev, "%s: ch name = %s, payload size = %d\n",
__func__, cpkt->ch_name, cpkt->payload_size);
- mutex_lock(&tx_buf->ch->mutex);
- if (ch->channel_state == GLINK_CONNECTED) {
- mutex_unlock(&tx_buf->ch->mutex);
- ret = glink_tx(ch->handle, tx_buf,
- cpkt->payload, cpkt->payload_size,
- GLINK_TX_REQ_INTENT);
- if (ret < 0) {
- dev_err(wpriv->dev, "%s: glink tx failed, ret = %d\n",
+ spin_lock(&ch->ch_lock);
+ rpdev = ch->handle;
+ if (rpdev || ch->ch_state == WDSP_CH_CONNECTED) {
+ spin_unlock(&ch->ch_lock);
+ ret = rpmsg_send(rpdev->ept, cpkt->payload,
+ cpkt->payload_size);
+ if (ret < 0)
+ dev_err(wpriv->dev, "%s: rpmsg send failed, ret = %d\n",
__func__, ret);
- /*
- * If glink_tx() is failed then free tx_buf here as
- * there won't be any tx_done notification to
- * free the buffer.
- */
- vfree(tx_buf);
- }
} else {
- mutex_unlock(&tx_buf->ch->mutex);
+ spin_unlock(&ch->ch_lock);
dev_err(wpriv->dev, "%s: channel %s is not in connected state\n",
- __func__, ch->ch_cfg.name);
- /*
- * Free tx_buf here as there won't be any tx_done
- * notification in this case also.
- */
- vfree(tx_buf);
+ __func__, ch->ch_name);
}
+ vfree(tx_buf);
}
/*
@@ -745,19 +287,20 @@
* buf: Pointer to the userspace buffer
* count: Number bytes to read from the file
* ppos: Pointer to the position into the file
+ * Returns 0 on success and an appropriate error value on failure
*/
static ssize_t wdsp_glink_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
{
int ret = 0, ret1 = 0;
- struct wdsp_glink_rsp_que *rsp;
+ struct wdsp_rsp_que *read_rsp = NULL;
struct wdsp_glink_priv *wpriv;
+ unsigned long flags;
wpriv = (struct wdsp_glink_priv *)file->private_data;
if (!wpriv) {
pr_err("%s: Invalid private data\n", __func__);
- ret = -EINVAL;
- goto done;
+ return -EINVAL;
}
if (count > WDSP_MAX_READ_SIZE) {
@@ -766,35 +309,42 @@
count = WDSP_MAX_READ_SIZE;
}
/*
- * Complete signal has given from glink rx notification callback
+ * Complete signal has given from gwdsp_rpmsg_callback()
* or from flush API. Also use interruptible wait_for_completion API
* to allow the system to go in suspend.
*/
ret = wait_for_completion_interruptible(&wpriv->rsp_complete);
- if (ret)
- goto done;
+ if (ret < 0)
+ return ret;
- mutex_lock(&wpriv->rsp_mutex);
+ read_rsp = kzalloc(sizeof(struct wdsp_rsp_que), GFP_KERNEL);
+ if (!read_rsp)
+ return -ENOMEM;
+
+ spin_lock_irqsave(&wpriv->rsp_lock, flags);
if (wpriv->rsp_cnt) {
wpriv->rsp_cnt--;
dev_dbg(wpriv->dev, "%s: read from buffer %d\n",
__func__, wpriv->rsp_cnt);
- rsp = &wpriv->rsp[wpriv->rsp_cnt];
- if (count < rsp->buf_size) {
- ret1 = copy_to_user(buf, &rsp->buf, count);
+ memcpy(read_rsp, &wpriv->rsp[wpriv->rsp_cnt],
+ sizeof(struct wdsp_rsp_que));
+ spin_unlock_irqrestore(&wpriv->rsp_lock, flags);
+
+ if (count < read_rsp->buf_size) {
+ ret1 = copy_to_user(buf, read_rsp->buf, count);
/* Return the number of bytes copied */
ret = count;
} else {
- ret1 = copy_to_user(buf, &rsp->buf, rsp->buf_size);
+ ret1 = copy_to_user(buf, read_rsp->buf,
+ read_rsp->buf_size);
/* Return the number of bytes copied */
- ret = rsp->buf_size;
+ ret = read_rsp->buf_size;
}
if (ret1) {
- mutex_unlock(&wpriv->rsp_mutex);
dev_err_ratelimited(wpriv->dev, "%s: copy_to_user failed %d\n",
- __func__, ret);
+ __func__, ret);
ret = -EFAULT;
goto done;
}
@@ -805,11 +355,12 @@
*/
dev_dbg(wpriv->dev, "%s: resp count = %d\n", __func__,
wpriv->rsp_cnt);
+ spin_unlock_irqrestore(&wpriv->rsp_lock, flags);
ret = -EINVAL;
}
- mutex_unlock(&wpriv->rsp_mutex);
done:
+ kfree(read_rsp);
return ret;
}
@@ -819,6 +370,7 @@
* buf: Pointer to the userspace buffer
* count: Number bytes to read from the file
* ppos: Pointer to the position into the file
+ * Returns 0 on success and an appropriate error value on failure
*/
static ssize_t wdsp_glink_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
@@ -826,7 +378,7 @@
int ret = 0, i, tx_buf_size;
struct wdsp_write_pkt *wpkt;
struct wdsp_cmd_pkt *cpkt;
- struct wdsp_glink_tx_buf *tx_buf;
+ struct wdsp_tx_buf *tx_buf;
struct wdsp_glink_priv *wpriv;
size_t pkt_max_size;
@@ -847,7 +399,7 @@
dev_dbg(wpriv->dev, "%s: count = %zd\n", __func__, count);
- tx_buf_size = count + sizeof(struct wdsp_glink_tx_buf);
+ tx_buf_size = count + sizeof(struct wdsp_tx_buf);
tx_buf = vzalloc(tx_buf_size);
if (!tx_buf) {
ret = -ENOMEM;
@@ -865,33 +417,14 @@
wpkt = (struct wdsp_write_pkt *)tx_buf->buf;
switch (wpkt->pkt_type) {
case WDSP_REG_PKT:
- if (count < (WDSP_WRITE_PKT_SIZE + WDSP_REG_PKT_SIZE +
- WDSP_CH_CFG_SIZE)) {
- dev_err_ratelimited(wpriv->dev, "%s: Invalid reg pkt size = %zd\n",
- __func__, count);
- ret = -EINVAL;
- goto free_buf;
- }
- ret = wdsp_glink_ch_info_init(wpriv,
- (struct wdsp_reg_pkt *)wpkt->payload,
- count);
- if (ret < 0)
- dev_err_ratelimited(wpriv->dev, "%s: glink register failed, ret = %d\n",
- __func__, ret);
+ /* Keep this case to support backward compatibility */
vfree(tx_buf);
break;
case WDSP_READY_PKT:
- ret = wait_event_timeout(wpriv->link_state_wait,
- (wpriv->glink_state.link_state ==
- GLINK_LINK_STATE_UP),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- dev_err_ratelimited(wpriv->dev, "%s: Link state wait timeout\n",
- __func__);
- ret = -ETIMEDOUT;
- goto free_buf;
- }
- ret = 0;
+ ret = wdsp_wait_for_all_ch_connect(wpriv);
+ if (ret < 0)
+ dev_err_ratelimited(wpriv->dev, "%s: Channels not in connected state\n",
+ __func__);
vfree(tx_buf);
break;
case WDSP_CMD_PKT:
@@ -901,16 +434,6 @@
ret = -EINVAL;
goto free_buf;
}
- mutex_lock(&wpriv->glink_mutex);
- if (wpriv->glink_state.link_state == GLINK_LINK_STATE_DOWN) {
- mutex_unlock(&wpriv->glink_mutex);
- dev_err_ratelimited(wpriv->dev, "%s: Link state is Down\n",
- __func__);
-
- ret = -ENETRESET;
- goto free_buf;
- }
- mutex_unlock(&wpriv->glink_mutex);
cpkt = (struct wdsp_cmd_pkt *)wpkt->payload;
pkt_max_size = sizeof(struct wdsp_write_pkt) +
sizeof(struct wdsp_cmd_pkt) +
@@ -922,15 +445,13 @@
goto free_buf;
}
for (i = 0; i < wpriv->no_of_channels; i++) {
- if (wpriv->ch && wpriv->ch[i] &&
- (!strcmp(cpkt->ch_name,
- wpriv->ch[i]->ch_cfg.name))) {
+ if (!strcmp(cpkt->ch_name, wpriv->ch[i]->ch_name)) {
tx_buf->ch = wpriv->ch[i];
break;
}
}
if (!tx_buf->ch) {
- dev_err_ratelimited(wpriv->dev, "%s: Failed to get glink channel\n",
+ dev_err_ratelimited(wpriv->dev, "%s: Failed to get channel\n",
__func__);
ret = -EINVAL;
goto free_buf;
@@ -938,20 +459,17 @@
dev_dbg(wpriv->dev, "%s: requested ch_name: %s, pkt_size: %zd\n",
__func__, cpkt->ch_name, pkt_max_size);
- ret = wait_event_timeout(tx_buf->ch->ch_connect_wait,
- (tx_buf->ch->channel_state ==
- GLINK_CONNECTED),
- msecs_to_jiffies(TIMEOUT_MS));
- if (!ret) {
- dev_err_ratelimited(wpriv->dev, "%s: glink channel %s is not in connected state %d\n",
- __func__, tx_buf->ch->ch_cfg.name,
- tx_buf->ch->channel_state);
- ret = -ETIMEDOUT;
+ spin_lock(&tx_buf->ch->ch_lock);
+ if (tx_buf->ch->ch_state != WDSP_CH_CONNECTED) {
+ spin_unlock(&tx_buf->ch->ch_lock);
+ ret = -ENETRESET;
+ dev_err_ratelimited(wpriv->dev, "%s: Channels are not in connected state\n",
+ __func__);
goto free_buf;
}
- ret = 0;
+ spin_unlock(&tx_buf->ch->ch_lock);
- INIT_WORK(&tx_buf->tx_work, wdsp_glink_tx_buf_work);
+ INIT_WORK(&tx_buf->tx_work, wdsp_tx_buf_work);
queue_work(wpriv->work_queue, &tx_buf->tx_work);
break;
default:
@@ -974,54 +492,22 @@
* wdsp_glink_open - Open API to initialize private data
* inode: Pointer to the inode structure
* file: Pointer to the file structure
+ * Returns 0 on success and an appropriate error value on failure
*/
static int wdsp_glink_open(struct inode *inode, struct file *file)
{
- int ret = 0;
- struct wdsp_glink_priv *wpriv;
- struct wdsp_glink_dev *wdev;
- if (!inode->i_cdev) {
- pr_err("%s: cdev is NULL\n", __func__);
- ret = -EINVAL;
- goto done;
- }
- wdev = container_of(inode->i_cdev, struct wdsp_glink_dev, cdev);
-
- wpriv = kzalloc(sizeof(struct wdsp_glink_priv), GFP_KERNEL);
- if (!wpriv) {
- ret = -ENOMEM;
- goto done;
- }
- wpriv->dev = wdev->dev;
- wpriv->work_queue = create_singlethread_workqueue("wdsp_glink_wq");
- if (!wpriv->work_queue) {
- dev_err(wpriv->dev, "%s: Error creating wdsp_glink_wq\n",
- __func__);
- ret = -EINVAL;
- goto err_wq;
- }
-
- wpriv->glink_state.link_state = GLINK_LINK_STATE_DOWN;
- init_completion(&wpriv->rsp_complete);
- init_waitqueue_head(&wpriv->link_state_wait);
- mutex_init(&wpriv->rsp_mutex);
- mutex_init(&wpriv->glink_mutex);
+ pr_debug("%s: wpriv = %pK\n", __func__, wpriv);
file->private_data = wpriv;
- goto done;
-
-err_wq:
- kfree(wpriv);
-
-done:
- return ret;
+ return 0;
}
/*
* wdsp_glink_flush - Flush API to unblock read.
* file: Pointer to the file structure
* id: Lock owner ID
+ * Returns 0 on success and an appropriate error value on failure
*/
static int wdsp_glink_flush(struct file *file, fl_owner_t id)
{
@@ -1047,56 +533,115 @@
*
* inode: Pointer to the inode structure
* file: Pointer to the file structure
+ * Returns 0 on success and an appropriate error value on failure
*/
static int wdsp_glink_release(struct inode *inode, struct file *file)
{
- int i, ret = 0;
- struct wdsp_glink_priv *wpriv;
-
- wpriv = (struct wdsp_glink_priv *)file->private_data;
- if (!wpriv) {
- pr_err("%s: Invalid private data\n", __func__);
- ret = -EINVAL;
- goto done;
- }
-
- if (wpriv->glink_state.handle)
- glink_unregister_link_state_cb(wpriv->glink_state.handle);
-
- flush_workqueue(wpriv->work_queue);
- destroy_workqueue(wpriv->work_queue);
-
- /*
- * Clean up glink channel memory in channel state
- * callback only if close channels are called from here.
- */
- if (wpriv->ch) {
- for (i = 0; i < wpriv->no_of_channels; i++) {
- if (wpriv->ch[i]) {
- wpriv->ch[i]->free_mem = true;
- /*
- * Channel handle NULL means channel is already
- * closed. Free the channel memory here itself.
- */
- if (!wpriv->ch[i]->handle) {
- kfree(wpriv->ch[i]);
- wpriv->ch[i] = NULL;
- } else {
- wdsp_glink_close_ch(wpriv->ch[i]);
- }
- }
- }
-
- kfree(wpriv->ch);
- wpriv->ch = NULL;
- }
-
- mutex_destroy(&wpriv->glink_mutex);
- mutex_destroy(&wpriv->rsp_mutex);
- kfree(wpriv);
+ pr_debug("%s: file->private_data = %pK\n", __func__,
+ file->private_data);
file->private_data = NULL;
-done:
+ return 0;
+}
+
+static struct rpmsg_driver wdsp_rpmsg_driver = {
+ .probe = wdsp_rpmsg_probe,
+ .remove = wdsp_rpmsg_remove,
+ .callback = wdsp_rpmsg_callback,
+ /* Update this dynamically before register_rpmsg() */
+ .id_table = NULL,
+ .drv = {
+ .name = "wdsp_rpmsg",
+ },
+};
+
+static int wdsp_register_rpmsg(struct platform_device *pdev,
+ struct wdsp_glink_dev *wdev)
+{
+ int ret = 0;
+ int i, no_of_channels;
+ struct rpmsg_device_id *wdsp_rpmsg_id_table, *id_table;
+ const char *ch_name = NULL;
+
+ wpriv = devm_kzalloc(&pdev->dev,
+ sizeof(struct wdsp_glink_priv), GFP_KERNEL);
+ if (!wpriv)
+ return -ENOMEM;
+
+ no_of_channels = of_property_count_strings(pdev->dev.of_node,
+ "qcom,wdsp-channels");
+ if (no_of_channels < 0) {
+ dev_err(&pdev->dev, "%s: channel name parse error %d\n",
+ __func__, no_of_channels);
+ return -EINVAL;
+ }
+
+ wpriv->ch = devm_kzalloc(&pdev->dev,
+ (sizeof(struct wdsp_glink_priv *) * no_of_channels),
+ GFP_KERNEL);
+ if (!wpriv->ch)
+ return -ENOMEM;
+
+ for (i = 0; i < no_of_channels; i++) {
+ ret = of_property_read_string_index(pdev->dev.of_node,
+ "qcom,wdsp-channels", i,
+ &ch_name);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: channel name parse error %d\n",
+ __func__, ret);
+ return -EINVAL;
+ }
+ wpriv->ch[i] = devm_kzalloc(&pdev->dev,
+ sizeof(struct wdsp_glink_priv),
+ GFP_KERNEL);
+ if (!wpriv->ch[i])
+ return -ENOMEM;
+
+ strlcpy(wpriv->ch[i]->ch_name, ch_name, RPMSG_NAME_SIZE);
+ wpriv->ch[i]->wpriv = wpriv;
+ spin_lock_init(&wpriv->ch[i]->ch_lock);
+ }
+ init_waitqueue_head(&wpriv->ch_state_wait);
+ init_completion(&wpriv->rsp_complete);
+ spin_lock_init(&wpriv->rsp_lock);
+
+ wpriv->wdev = wdev;
+ wpriv->dev = wdev->dev;
+ wpriv->work_queue = create_singlethread_workqueue("wdsp_glink_wq");
+ if (!wpriv->work_queue) {
+ dev_err(&pdev->dev, "%s: Error creating wdsp_glink_wq\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ wdsp_rpmsg_id_table = devm_kzalloc(&pdev->dev,
+ (sizeof(struct rpmsg_device_id) *
+ (no_of_channels + 1)),
+ GFP_KERNEL);
+ if (!wdsp_rpmsg_id_table) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ wpriv->no_of_channels = no_of_channels;
+ id_table = wdsp_rpmsg_id_table;
+ for (i = 0; i < no_of_channels; i++) {
+ strlcpy(id_table->name, wpriv->ch[i]->ch_name,
+ RPMSG_NAME_SIZE);
+ id_table++;
+ }
+ wdsp_rpmsg_driver.id_table = wdsp_rpmsg_id_table;
+ ret = register_rpmsg_driver(&wdsp_rpmsg_driver);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "%s: Rpmsg driver register failed, err = %d\n",
+ __func__, ret);
+ goto err;
+ }
+
+ return 0;
+
+err:
+ destroy_workqueue(wpriv->work_queue);
return ret;
}
@@ -1109,10 +654,6 @@
.release = wdsp_glink_release,
};
-/*
- * wdsp_glink_probe - Driver probe to expose char device
- * pdev: Pointer to device tree data.
- */
static int wdsp_glink_probe(struct platform_device *pdev)
{
int ret;
@@ -1156,7 +697,15 @@
__func__, ret);
goto err_cdev_add;
}
- platform_set_drvdata(pdev, wdev);
+
+ ret = wdsp_register_rpmsg(pdev, wdev);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "%s: Failed to register with rpmsg, err = %d\n",
+ __func__, ret);
+ goto err_cdev_add;
+ }
+ platform_set_drvdata(pdev, wpriv);
+
goto done;
err_cdev_add:
@@ -1169,28 +718,25 @@
unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
err_chrdev:
- devm_kfree(&pdev->dev, wdev);
-
done:
return ret;
}
-/*
- * wdsp_glink_remove - Driver remove to handle cleanup
- * pdev: Pointer to device tree data.
- */
static int wdsp_glink_remove(struct platform_device *pdev)
{
- struct wdsp_glink_dev *wdev = platform_get_drvdata(pdev);
+ struct wdsp_glink_priv *wpriv = platform_get_drvdata(pdev);
- if (wdev) {
- cdev_del(&wdev->cdev);
- device_destroy(wdev->cls, wdev->dev_num);
- class_destroy(wdev->cls);
- unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
- devm_kfree(&pdev->dev, wdev);
- } else {
- dev_err(&pdev->dev, "%s: Invalid device data\n", __func__);
+ unregister_rpmsg_driver(&wdsp_rpmsg_driver);
+
+ if (wpriv) {
+ flush_workqueue(wpriv->work_queue);
+ destroy_workqueue(wpriv->work_queue);
+ if (wpriv->wdev) {
+ cdev_del(&wpriv->wdev->cdev);
+ device_destroy(wpriv->wdev->cls, wpriv->wdev->dev_num);
+ class_destroy(wpriv->wdev->cls);
+ unregister_chrdev_region(0, MINOR_NUMBER_COUNT);
+ }
}
return 0;
diff --git a/soc/Android.mk b/soc/Android.mk
index 1c256fe..fa2569a 100644
--- a/soc/Android.mk
+++ b/soc/Android.mk
@@ -11,9 +11,13 @@
AUDIO_SELECT := CONFIG_SND_SOC_SDM670=m
endif
+ifeq ($(call is-board-platform,msmnile),true)
+AUDIO_SELECT := CONFIG_SND_SOC_SDM855=m
+endif
+
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
-ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 sdm845 sdm670 qcs605 msmnile),true)
LOCAL_PATH := $(call my-dir)
diff --git a/soc/Kbuild b/soc/Kbuild
index 29f69d5..36a2c88 100644
--- a/soc/Kbuild
+++ b/soc/Kbuild
@@ -29,6 +29,11 @@
export
INCS += -include $(AUDIO_ROOT)/config/sdm670autoconf.h
endif
+ ifeq ($(CONFIG_ARCH_SDM855), y)
+ include $(AUDIO_ROOT)/config/sdm855auto.conf
+ export
+ INCS += -include $(AUDIO_ROOT)/config/sdm855autoconf.h
+ endif
endif
# As per target team, build is done as follows:
diff --git a/soc/core.h b/soc/core.h
index 451c696..b9f94ca 120000
--- a/soc/core.h
+++ b/soc/core.h
@@ -1 +1 @@
-../../../../../kernel/msm-4.9/drivers/pinctrl/core.h
\ No newline at end of file
+../../../../../kernel/msm-4.14/drivers/pinctrl/core.h
\ No newline at end of file
diff --git a/soc/pinctrl-utils.h b/soc/pinctrl-utils.h
index 2ea9d23..0f74549 120000
--- a/soc/pinctrl-utils.h
+++ b/soc/pinctrl-utils.h
@@ -1 +1 @@
-../../../../../kernel/msm-4.9/drivers/pinctrl/pinctrl-utils.h
\ No newline at end of file
+../../../../../kernel/msm-4.14/drivers/pinctrl/pinctrl-utils.h
\ No newline at end of file
diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c
index dc1f786..38f8a3d 100644
--- a/soc/swr-wcd-ctrl.c
+++ b/soc/swr-wcd-ctrl.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1291,33 +1291,49 @@
u64 id = 0;
int ret = -EINVAL;
struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(mstr);
+ struct swr_device *swr_dev;
+ u32 num_dev = 0;
if (!swrm) {
pr_err("%s: Invalid handle to swr controller\n",
__func__);
return ret;
}
+ if (swrm->num_dev)
+ num_dev = swrm->num_dev;
+ else
+ num_dev = mstr->num_dev;
pm_runtime_get_sync(&swrm->pdev->dev);
- for (i = 1; i < (mstr->num_dev + 1); i++) {
+ for (i = 1; i < (num_dev + 1); i++) {
id = ((u64)(swrm->read(swrm->handle,
SWRM_ENUMERATOR_SLAVE_DEV_ID_2(i))) << 32);
id |= swrm->read(swrm->handle,
SWRM_ENUMERATOR_SLAVE_DEV_ID_1(i));
- if ((id & SWR_DEV_ID_MASK) == dev_id) {
- if (swrm_get_device_status(swrm, i) == 0x01) {
- *dev_num = i;
- ret = 0;
- } else {
- dev_err(swrm->dev, "%s: device is not ready\n",
- __func__);
+ /*
+ * As pm_runtime_get_sync() brings all slaves out of reset
+ * update logical device number for all slaves.
+ */
+ list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
+ if (swr_dev->addr == (id & SWR_DEV_ID_MASK)) {
+ u32 status = swrm_get_device_status(swrm, i);
+
+ if ((status == 0x01) || (status == 0x02)) {
+ swr_dev->dev_num = i;
+ if ((id & SWR_DEV_ID_MASK) == dev_id) {
+ *dev_num = i;
+ ret = 0;
+ }
+ dev_dbg(swrm->dev, "%s: devnum %d is assigned for dev addr %lx\n",
+ __func__, i, swr_dev->addr);
+ }
}
- goto found;
}
}
- dev_err(swrm->dev, "%s: device id 0x%llx does not match with 0x%llx\n",
- __func__, id, dev_id);
-found:
+ if (ret)
+ dev_err(swrm->dev, "%s: device 0x%llx is not ready\n",
+ __func__, dev_id);
+
pm_runtime_mark_last_busy(&swrm->pdev->dev);
pm_runtime_put_autosuspend(&swrm->pdev->dev);
return ret;
@@ -1465,7 +1481,21 @@
mutex_init(&swrm->mlock);
INIT_LIST_HEAD(&swrm->mport_list);
mutex_init(&swrm->reslock);
+ mutex_init(&swrm->force_down_lock);
+ ret = of_property_read_u32(swrm->dev->of_node, "qcom,swr-num-dev",
+ &swrm->num_dev);
+ if (ret)
+ dev_dbg(&pdev->dev, "%s: Looking up %s property failed\n",
+ __func__, "qcom,swr-num-dev");
+ else {
+ if (swrm->num_dev > SWR_MAX_SLAVE_DEVICES) {
+ dev_err(&pdev->dev, "%s: num_dev %d > max limit %d\n",
+ __func__, swrm->num_dev, SWR_MAX_SLAVE_DEVICES);
+ ret = -EINVAL;
+ goto err_pdata_fail;
+ }
+ }
ret = swrm->reg_irq(swrm->handle, swr_mstr_interrupt, swrm,
SWR_IRQ_REGISTER);
if (ret) {
@@ -1528,6 +1558,9 @@
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
swrm, SWR_IRQ_FREE);
err_irq_fail:
+ mutex_destroy(&swrm->mlock);
+ mutex_destroy(&swrm->reslock);
+ mutex_destroy(&swrm->force_down_lock);
err_pdata_fail:
kfree(swrm);
err_memory_fail:
@@ -1538,8 +1571,9 @@
{
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
- swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
- swrm, SWR_IRQ_FREE);
+ if (swrm->reg_irq)
+ swrm->reg_irq(swrm->handle, swr_mstr_interrupt,
+ swrm, SWR_IRQ_FREE);
if (swrm->mstr_port) {
kfree(swrm->mstr_port->port);
swrm->mstr_port->port = NULL;
@@ -1551,6 +1585,7 @@
swr_unregister_master(&swrm->master);
mutex_destroy(&swrm->mlock);
mutex_destroy(&swrm->reslock);
+ mutex_destroy(&swrm->force_down_lock);
kfree(swrm);
return 0;
}
@@ -1614,13 +1649,20 @@
int ret = 0;
struct swr_master *mstr = &swrm->master;
struct swr_device *swr_dev;
+ int current_state = 0;
dev_dbg(dev, "%s: pm_runtime: suspend state: %d\n",
__func__, swrm->state);
mutex_lock(&swrm->reslock);
- if ((swrm->state == SWR_MSTR_RESUME) ||
- (swrm->state == SWR_MSTR_UP)) {
- if (swrm_is_port_en(&swrm->master)) {
+ mutex_lock(&swrm->force_down_lock);
+ current_state = swrm->state;
+ mutex_unlock(&swrm->force_down_lock);
+ if ((current_state == SWR_MSTR_RESUME) ||
+ (current_state == SWR_MSTR_UP) ||
+ (current_state == SWR_MSTR_SSR)) {
+
+ if ((current_state != SWR_MSTR_SSR) &&
+ swrm_is_port_en(&swrm->master)) {
dev_dbg(dev, "%s ports are enabled\n", __func__);
ret = -EBUSY;
goto exit;
@@ -1649,27 +1691,16 @@
struct platform_device *pdev = to_platform_device(dev);
struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
int ret = 0;
- struct swr_master *mstr = &swrm->master;
- struct swr_device *swr_dev;
dev_dbg(dev, "%s: swrm state: %d\n", __func__, swrm->state);
- mutex_lock(&swrm->reslock);
- if ((swrm->state == SWR_MSTR_RESUME) ||
- (swrm->state == SWR_MSTR_UP)) {
- list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
- ret = swr_device_down(swr_dev);
- if (ret)
- dev_err(dev,
- "%s: failed to shutdown swr dev %d\n",
- __func__, swr_dev->dev_num);
- }
- dev_dbg(dev, "%s: Shutting down SWRM\n", __func__);
- pm_runtime_disable(dev);
- pm_runtime_set_suspended(dev);
- pm_runtime_enable(dev);
- swrm_clk_request(swrm, false);
- }
- mutex_unlock(&swrm->reslock);
+
+ mutex_lock(&swrm->force_down_lock);
+ swrm->state = SWR_MSTR_SSR;
+ mutex_unlock(&swrm->force_down_lock);
+ /* Use pm runtime function to tear down */
+ ret = pm_runtime_put_sync_suspend(dev);
+ pm_runtime_get_noresume(dev);
+
return ret;
}
diff --git a/soc/swr-wcd-ctrl.h b/soc/swr-wcd-ctrl.h
index 52a60a3..dc8d7f5 100644
--- a/soc/swr-wcd-ctrl.h
+++ b/soc/swr-wcd-ctrl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,8 @@
#define SWR_MSTR_PORT_LEN 8 /* Number of master ports */
+#define SWR_MAX_SLAVE_DEVICES 11
+
#define SWRM_VERSION_1_0 0x01010000
#define SWRM_VERSION_1_2 0x01030000
#define SWRM_VERSION_1_3 0x01040000
@@ -32,6 +34,7 @@
SWR_MSTR_RESUME,
SWR_MSTR_UP,
SWR_MSTR_DOWN,
+ SWR_MSTR_SSR,
};
enum {
@@ -94,6 +97,7 @@
void *data), void *swr_handle, int type);
int irq;
int version;
+ u32 num_dev;
int num_enum_slaves;
int slave_status;
struct swr_mstr_port *mstr_port;
@@ -102,6 +106,8 @@
struct platform_device *pdev;
int num_rx_chs;
u8 num_cfg_devs;
+ struct mutex force_down_lock;
+ int force_down_state;
};
#endif /* _SWR_WCD_CTRL_H */