Add 'techpack/audio/' from commit '92774107c11521a51b8a2815f83cd5fa7ebefdbd'

git-subtree-dir: techpack/audio
git-subtree-mainline: cda692f3f2
git-subtree-split: 92774107c1
This commit is contained in:
UtsavBalar1231
2020-05-25 20:15:47 +05:30
833 changed files with 714860 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
# 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)
TARGET := msmnile
ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq))
AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m
else
AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m
endif
endif
ifeq ($(call is-board-platform,$(MSMSTEPPE)),true)
TARGET := talos
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
ifeq ($(call is-board-platform,$(TRINKET)),true)
TARGET := trinket
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
ifeq ($(call is-board-platform,kona),true)
TARGET := kona
AUDIO_SELECT := CONFIG_SND_SOC_KONA=m
endif
ifeq ($(call is-board-platform,lito),true)
TARGET := lito
AUDIO_SELECT := CONFIG_SND_SOC_LITO=m
endif
ifeq ($(call is-board-platform,atoll),true)
TARGET := atoll
AUDIO_SELECT := CONFIG_SND_SOC_ATOLL=m
endif
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito atoll),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 := $(shell pwd)/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=platform_dlkm
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
KBUILD_OPTIONS += $(AUDIO_SELECT)
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_platform.ko
LOCAL_MODULE_KBUILD_NAME := platform_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
ifeq ($(call is-board-platform-in-list, ),true)
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_cpe_lsm.ko
LOCAL_MODULE_KBUILD_NAME := cpe_lsm_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
endif
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_machine_$(TARGET).ko
LOCAL_MODULE_KBUILD_NAME := machine_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

View File

@@ -0,0 +1,250 @@
# 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 := $(shell pwd)/kernel/msm-4.14
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM8150), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
else
include $(AUDIO_ROOT)/config/sm8150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h
endif
endif
ifeq ($(CONFIG_ARCH_ATOLL), y)
include $(AUDIO_ROOT)/4.0/config/atollauto.conf
export
INCS += -include $(AUDIO_ROOT)/4.0/config/atollautoconf.h
endif
ifeq ($(CONFIG_ARCH_TRINKET), y)
include $(AUDIO_ROOT)/config/sm6150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
include $(AUDIO_ROOT)/config/litoauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h
endif
ifeq ($(CONFIG_ARCH_SDMSHRIKE), y)
include $(AUDIO_ROOT)/config/sm8150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h
endif
ifeq ($(CONFIG_ARCH_QCS405), y)
include $(AUDIO_ROOT)/config/qcs405auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h
endif
ifeq ($(CONFIG_QTI_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
UAPI_DIR := uapi
UAPI_INC := -I$(AUDIO_ROOT)/4.0/include/$(UAPI_DIR)
COMMON_DIR := include
COMMON_INC := -I$(AUDIO_ROOT)/4.0/$(COMMON_DIR)
endif
############ ASoC Drivers ############
# for SM8150 sound card driver
ifdef CONFIG_SND_SOC_SM8150
MACHINE_OBJS += sm8150.o
MACHINE_OBJS += machine_815x_init.o
endif
# for SM6150 sound card driver
ifdef CONFIG_SND_SOC_SM6150
MACHINE_OBJS += sm6150.o
endif
# for qcs405 sound card driver
ifdef CONFIG_SND_SOC_QCS405
MACHINE_OBJS += qcs405.o
endif
# for KONA sound card driver
ifdef CONFIG_SND_SOC_KONA
MACHINE_OBJS += kona.o
endif
ifdef CONFIG_SND_SOC_LITO
MACHINE_OBJS += kona.o
endif
# for ATOLL soound card driver
ifdef CONFIG_SND_SOC_ATOLL
MACHINE_OBJS += kona.o
endif
# for sa8155 sound card driver
ifdef CONFIG_SND_SOC_SA8155
MACHINE_OBJS += sa8155.o
endif
ifdef CONFIG_SND_SOC_CPE
CPE_LSM_OBJS += msm-cpe-lsm.o
endif
ifdef CONFIG_SND_SOC_QDSP6V2
PLATFORM_OBJS += msm-audio-effects-q6-v2.o
PLATFORM_OBJS += msm-compress-q6-v2.o
PLATFORM_OBJS += msm-dai-fe.o
PLATFORM_OBJS += msm-dai-q6-hdmi-v2.o
PLATFORM_OBJS += msm-dai-q6-v2.o
PLATFORM_OBJS += msm-dai-stub-v2.o
PLATFORM_OBJS += msm-lsm-client.o
PLATFORM_OBJS += msm-pcm-afe-v2.o
PLATFORM_OBJS += msm-pcm-dtmf-v2.o
PLATFORM_OBJS += msm-pcm-hostless.o
PLATFORM_OBJS += msm-pcm-host-voice-v2.o
PLATFORM_OBJS += msm-pcm-loopback-v2.o
PLATFORM_OBJS += msm-pcm-q6-noirq.o
PLATFORM_OBJS += msm-pcm-q6-v2.o
PLATFORM_OBJS += msm-pcm-routing-v2.o
PLATFORM_OBJS += msm-pcm-voice-v2.o
PLATFORM_OBJS += msm-pcm-voip-v2.o
PLATFORM_OBJS += msm-transcode-loopback-q6-v2.o
PLATFORM_OBJS += platform_init.o
endif
ifdef CONFIG_WCD9XXX_CODEC_CORE
PLATFORM_OBJS += msm-dai-slim.o
endif
ifdef CONFIG_DOLBY_DS2
PLATFORM_OBJS += msm-ds2-dap-config.o
endif
ifdef CONFIG_DOLBY_LICENSE
PLATFORM_OBJS += msm-ds2-dap-config.o
endif
ifdef CONFIG_SND_HWDEP_ROUTING
PLATFORM_OBJS += msm-pcm-routing-devdep.o
endif
ifdef CONFIG_QTI_PP
PLATFORM_OBJS += msm-qti-pp-config.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/wcd934x/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/wcd937x/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/wcd938x/Module.symvers
else
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/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/asoc/codecs/wcd934x/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd937x/Module.symvers
endif
endif
ifeq ($(KERNEL_BUILD), 1)
obj-y += codecs/
endif
# Module information used by KBuild framework
obj-$(CONFIG_SND_SOC_QDSP6V2) += platform_dlkm.o
platform_dlkm-y := $(PLATFORM_OBJS)
obj-$(CONFIG_SND_SOC_SM8150) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_SM6150) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_ATOLL) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_QCS405) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_KONA) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_LITO) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_SA8155) += machine_dlkm.o
machine_dlkm-y := $(MACHINE_OBJS)
obj-$(CONFIG_SND_SOC_CPE) += cpe_lsm_dlkm.o
cpe_lsm_dlkm-y := $(CPE_LSM_OBJS)
# inject some build related information

View File

@@ -0,0 +1,145 @@
# 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)
ifeq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au))
AUDIO_SELECT := CONFIG_SND_SOC_SA8155=m
else
AUDIO_SELECT := CONFIG_SND_SOC_SM8150=m
endif
endif
ifeq ($(call is-board-platform,$(MSMSTEPPE)),true)
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
ifeq ($(call is-board-platform,$(TRINKET)),true)
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
ifeq ($(call is-board-platform,kona),true)
AUDIO_SELECT := CONFIG_SND_SOC_KONA=m
endif
ifeq ($(call is-board-platform,lito),true)
AUDIO_SELECT := CONFIG_SND_SOC_LITO=m
endif
ifeq ($(call is-board-platform,atoll),true)
AUDIO_SELECT := CONFIG_SND_SOC_ATOLL=m
endif
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET) kona lito atoll),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 := $(shell pwd)/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=wcd_core_dlkm
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
KBUILD_OPTIONS += $(AUDIO_SELECT)
###########################################################
ifneq ($(TARGET_PRODUCT), $(filter $(TARGET_PRODUCT), msmnile_au msmnile_gvmq))
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_core.ko
LOCAL_MODULE_KBUILD_NAME := wcd_core_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9xxx.ko
LOCAL_MODULE_KBUILD_NAME := wcd9xxx_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
ifeq ($(call is-board-platform-in-list, ),true)
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_cpe.ko
LOCAL_MODULE_KBUILD_NAME := wcd_cpe_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
endif
###########################################################
ifeq ($(call is-board-platform-in-list,msmnile $(MSMSTEPPE) $(TRINKET)),true)
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd_spi.ko
LOCAL_MODULE_KBUILD_NAME := wcd_spi_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
endif
###########################################################
ifeq ($(call is-board-platform-in-list, ),true)
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd9335.ko
LOCAL_MODULE_KBUILD_NAME := wcd9335_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
endif
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa881x.ko
LOCAL_MODULE_KBUILD_NAME := wsa881x_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_mbhc.ko
LOCAL_MODULE_KBUILD_NAME := mbhc_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
endif
############################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_stub.ko
LOCAL_MODULE_KBUILD_NAME := stub_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
##########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_hdmi.ko
LOCAL_MODULE_KBUILD_NAME := hdmi_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

View File

@@ -0,0 +1,254 @@
# 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 := $(shell pwd)/kernel/msm-4.19
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_SM8150), y)
ifdef CONFIG_SND_SOC_SA8155
include $(AUDIO_ROOT)/config/sa8155auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sa8155autoconf.h
else
include $(AUDIO_ROOT)/config/sm8150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h
endif
endif
ifeq ($(CONFIG_ARCH_ATOLL), y)
include $(AUDIO_ROOT)/4.0/config/atollauto.conf
export
INCS += -include $(AUDIO_ROOT)/4.0/config/atollautoconf.h
endif
ifeq ($(CONFIG_ARCH_TRINKET), y)
include $(AUDIO_ROOT)/config/sm6150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
include $(AUDIO_ROOT)/config/litoauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h
endif
ifeq ($(CONFIG_ARCH_SDMSHRIKE), y)
include $(AUDIO_ROOT)/config/sm8150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm8150autoconf.h
endif
ifeq ($(CONFIG_ARCH_QCS405), y)
include $(AUDIO_ROOT)/config/qcs405auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.h
endif
ifeq ($(CONFIG_QTI_GVM), y)
include $(AUDIO_ROOT)/config/gvmauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/gvmautoconf.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
UAPI_DIR := uapi
UAPI_INC := -I$(AUDIO_ROOT)/4.0/include/$(UAPI_DIR)
COMMON_DIR := include
COMMON_INC := -I$(AUDIO_ROOT)/4.0/$(COMMON_DIR)
endif
############ ASoC Codecs ############
ifdef CONFIG_WCD9XXX_CODEC_CORE
CORE_OBJS += wcd9xxx-rst.o
CORE_OBJS += wcd9xxx-core-init.o
CORE_OBJS += wcd9xxx-core.o
CORE_OBJS += wcd9xxx-irq.o
CORE_OBJS += wcd9xxx-slimslave.o
CORE_OBJS += wcd9xxx-utils.o
CORE_OBJS += wcd9335-regmap.o
CORE_OBJS += wcd9335-tables.o
CORE_OBJS += msm-cdc-pinctrl.o
CORE_OBJS += msm-cdc-supply.o
CORE_OBJS += wcd934x/wcd934x-regmap.o
CORE_OBJS += wcd934x/wcd934x-tables.o
endif
ifdef CONFIG_WCD9XXX_CODEC_CORE_V2
CORE_OBJS += wcd9xxx-core-init.o
CORE_OBJS += msm-cdc-pinctrl.o
CORE_OBJS += msm-cdc-supply.o
endif
ifdef CONFIG_SND_SOC_WCD9XXX_V2
ifdef CONFIG_WCD9XXX_CODEC_CORE
WCD9XXX_OBJS += wcd9xxx-common-v2.o
WCD9XXX_OBJS += wcd9xxx-resmgr-v2.o
else
WCD9XXX_OBJS += wcd-clsh.o
endif
WCD9XXX_OBJS += wcdcal-hwdep.o
WCD9XXX_OBJS += wcd9xxx-soc-init.o
WCD9XXX_OBJS += wcd-dsp-utils.o
WCD9XXX_OBJS += wcd-dsp-mgr.o
WCD9XXX_OBJS += audio-ext-clk-up.o
endif
ifdef CONFIG_SND_SOC_WCD9335
WCD9335_OBJS += wcd9335.o
endif
ifdef CONFIG_SND_SOC_WSA881X
WSA881X_OBJS += wsa881x.o
WSA881X_OBJS += wsa881x-tables.o
WSA881X_OBJS += wsa881x-regmap.o
WSA881X_OBJS += wsa881x-temp-sensor.o
endif
ifdef CONFIG_SND_SOC_MSM_STUB
STUB_OBJS += msm_stub.o
endif
ifdef CONFIG_SND_SOC_WCD_SPI
SPI_OBJS += wcd-spi.o
endif
ifdef CONFIG_SND_SOC_WCD_CPE
WCD_CPE_OBJS += wcd_cpe_core.o
WCD_CPE_OBJS += wcd_cpe_services.o
endif
ifdef CONFIG_SND_SOC_WCD_MBHC
MBHC_OBJS += wcd-mbhc-v2.o
endif
ifdef CONFIG_SND_SOC_WCD_MBHC_ADC
MBHC_OBJS += wcd-mbhc-adc.o
endif
ifdef CONFIG_SND_SOC_WCD_MBHC_LEGACY
MBHC_OBJS += wcd-mbhc-legacy.o
endif
ifdef CONFIG_SND_SOC_MSM_HDMI_CODEC_RX
HDMICODEC_OBJS += msm_hdmi_codec_rx.o
endif
ifdef CONFIG_SND_SOC_WCD_IRQ
CORE_OBJS += wcd-irq.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/soc/Module.symvers
else
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
endif
endif
ifeq ($(KERNEL_BUILD), 1)
obj-y += wcd934x/
obj-y += wcd937x/
obj-y += wcd938x/
obj-y += bolero/
endif
# Module information used by KBuild framework
obj-$(CONFIG_WCD9XXX_CODEC_CORE) += wcd_core_dlkm.o
obj-$(CONFIG_WCD9XXX_CODEC_CORE_V2) += wcd_core_dlkm.o
wcd_core_dlkm-y := $(CORE_OBJS)
obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += wcd9xxx_dlkm.o
wcd9xxx_dlkm-y := $(WCD9XXX_OBJS)
obj-$(CONFIG_SND_SOC_WCD9335) += wcd9335_dlkm.o
wcd9335_dlkm-y := $(WCD9335_OBJS)
obj-$(CONFIG_SND_SOC_WSA881X) += wsa881x_dlkm.o
wsa881x_dlkm-y := $(WSA881X_OBJS)
obj-$(CONFIG_SND_SOC_MSM_STUB) += stub_dlkm.o
stub_dlkm-y := $(STUB_OBJS)
obj-$(CONFIG_SND_SOC_WCD_CPE) += wcd_cpe_dlkm.o
wcd_cpe_dlkm-y := $(WCD_CPE_OBJS)
obj-$(CONFIG_SND_SOC_WCD_SPI) += wcd_spi_dlkm.o
wcd_spi_dlkm-y := $(SPI_OBJS)
obj-$(CONFIG_SND_SOC_WCD_MBHC) += mbhc_dlkm.o
mbhc_dlkm-y := $(MBHC_OBJS)
obj-$(CONFIG_SND_SOC_MSM_HDMI_CODEC_RX) += hdmi_dlkm.o
hdmi_dlkm-y := $(HDMICODEC_OBJS)
# inject some build related information

View File

@@ -0,0 +1,629 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include "../../../drivers/clk/qcom/common.h"
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <dt-bindings/clock/qcom,audio-ext-clk-v2.h>
#include <dsp/q6afe-v2.h>
#include "audio-ext-clk-up.h"
enum {
AUDIO_EXT_CLK_PMI,
AUDIO_EXT_CLK_LNBB2,
AUDIO_EXT_CLK_LPASS,
AUDIO_EXT_CLK_LPASS2,
AUDIO_EXT_CLK_LPASS3,
AUDIO_EXT_CLK_LPASS4,
AUDIO_EXT_CLK_LPASS5,
AUDIO_EXT_CLK_LPASS6,
AUDIO_EXT_CLK_LPASS7,
AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE,
AUDIO_EXT_CLK_LPASS8,
AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE,
AUDIO_EXT_CLK_LPASS_MAX,
AUDIO_EXT_CLK_EXTERNAL_PLL = AUDIO_EXT_CLK_LPASS_MAX,
AUDIO_EXT_CLK_MAX,
};
struct pinctrl_info {
struct pinctrl *pinctrl;
struct pinctrl_state *sleep;
struct pinctrl_state *active;
char __iomem *base;
};
struct audio_ext_clk {
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;
const char *clk_name;
uint32_t lpass_core_hwvote_client_handle;
uint32_t lpass_audio_hwvote_client_handle;
};
static inline struct audio_ext_clk_priv *to_audio_clk(struct clk_hw *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_clk_priv *clk_priv = to_audio_clk(hw);
struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
int ret;
if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) &&
(clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) {
clk_priv->clk_cfg.enable = 1;
trace_printk("%s: vote for %d clock\n",
__func__, clk_priv->clk_src);
ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
if (ret < 0) {
pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n",
__func__);
return 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;
}
}
if (pnctrl_info->base)
iowrite32(1, pnctrl_info->base);
return 0;
}
static void audio_ext_clk_unprepare(struct clk_hw *hw)
{
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) {
ret = pinctrl_select_state(pnctrl_info->pinctrl,
pnctrl_info->sleep);
if (ret) {
pr_err("%s: active state select failed with %d\n",
__func__, ret);
return;
}
}
if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) &&
(clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX)) {
clk_priv->clk_cfg.enable = 0;
trace_printk("%s: unvote for %d clock\n",
__func__, clk_priv->clk_src);
ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
if (ret < 0)
pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
__func__, ret);
}
if (pnctrl_info->base)
iowrite32(0, pnctrl_info->base);
}
static u8 audio_ext_clk_get_parent(struct clk_hw *hw)
{
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
int num_parents = clk_hw_get_num_parents(hw);
const char * const *parent_names = hw->init->parent_names;
u8 i = 0, ret = hw->init->num_parents + 1;
if ((clk_priv->clk_src == AUDIO_EXT_CLK_PMI) && clk_priv->clk_name) {
for (i = 0; i < num_parents; i++) {
if (!strcmp(parent_names[i], clk_priv->clk_name))
ret = i;
}
pr_debug("%s: parent index = %u\n", __func__, ret);
return ret;
} else
return 0;
}
static int lpass_hw_vote_prepare(struct clk_hw *hw)
{
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
int ret;
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
trace_printk("%s: vote for %d clock\n",
__func__, clk_priv->clk_src);
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_MACRO_BLOCK,
"LPASS_HW_MACRO",
&clk_priv->lpass_core_hwvote_client_handle);
if (ret < 0) {
pr_err("%s lpass core hw vote failed %d\n",
__func__, ret);
return ret;
}
}
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) {
trace_printk("%s: vote for %d clock\n",
__func__, clk_priv->clk_src);
ret = afe_vote_lpass_core_hw(AFE_LPASS_CORE_HW_DCODEC_BLOCK,
"LPASS_HW_DCODEC",
&clk_priv->lpass_audio_hwvote_client_handle);
if (ret < 0) {
pr_err("%s lpass audio hw vote failed %d\n",
__func__, ret);
return ret;
}
}
return 0;
}
static void lpass_hw_vote_unprepare(struct clk_hw *hw)
{
struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
int ret = 0;
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE) {
trace_printk("%s: unvote for %d clock\n",
__func__, clk_priv->clk_src);
ret = afe_unvote_lpass_core_hw(
AFE_LPASS_CORE_HW_MACRO_BLOCK,
clk_priv->lpass_core_hwvote_client_handle);
if (ret < 0) {
pr_err("%s lpass core hw vote failed %d\n",
__func__, ret);
}
}
if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_AUDIO_HW_VOTE) {
trace_printk("%s: unvote for %d clock\n",
__func__, clk_priv->clk_src);
ret = afe_unvote_lpass_core_hw(
AFE_LPASS_CORE_HW_DCODEC_BLOCK,
clk_priv->lpass_audio_hwvote_client_handle);
if (ret < 0) {
pr_err("%s lpass audio hw unvote failed %d\n",
__func__, ret);
}
}
}
static const struct clk_ops audio_ext_clk_ops = {
.prepare = audio_ext_clk_prepare,
.unprepare = audio_ext_clk_unprepare,
.get_parent = audio_ext_clk_get_parent,
};
static const struct clk_ops lpass_hw_vote_ops = {
.prepare = lpass_hw_vote_prepare,
.unprepare = lpass_hw_vote_unprepare,
};
static const char * const audio_ext_pmi_div_clk[] = {
"qpnp_clkdiv_1",
"pms405_div_clk1",
"pm6150_div_clk1",
"pm6125_div_clk1",
};
static int audio_ext_clk_dummy_prepare(struct clk_hw *hw)
{
return 0;
}
static void audio_ext_clk_dummy_unprepare(struct clk_hw *hw)
{
}
static const struct clk_ops audio_ext_clk_dummy_ops = {
.prepare = audio_ext_clk_dummy_prepare,
.unprepare = audio_ext_clk_dummy_unprepare,
};
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 = audio_ext_pmi_div_clk,
.num_parents =
ARRAY_SIZE(audio_ext_pmi_div_clk),
.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 = &audio_ext_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,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk2",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk3",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk4",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk5",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk6",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk7",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.hw.init = &(struct clk_init_data){
.name = "lpass_hw_vote_clk",
.ops = &lpass_hw_vote_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_lpass_mclk8",
.ops = &audio_ext_clk_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.hw.init = &(struct clk_init_data){
.name = "lpass_audio_hw_vote_clk",
.ops = &lpass_hw_vote_ops,
},
},
},
{
.pnctrl_info = {NULL},
.fact = {
.mult = 1,
.div = 1,
.hw.init = &(struct clk_init_data){
.name = "audio_external_pll_clk",
.ops = &audio_ext_clk_ops,
},
},
},
};
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;
pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
if (pnctrl_info->pinctrl) {
dev_err(dev, "%s: already requested before\n",
__func__);
return -EINVAL;
}
pinctrl = devm_pinctrl_get(dev);
if (IS_ERR_OR_NULL(pinctrl)) {
dev_err(dev, "%s: Unable to get pinctrl handle\n",
__func__);
return -EINVAL;
}
pnctrl_info->pinctrl = pinctrl;
/* get all state handles from Device Tree */
pnctrl_info->sleep = pinctrl_lookup_state(pinctrl, "sleep");
if (IS_ERR(pnctrl_info->sleep)) {
dev_err(dev, "%s: could not get sleep pinstate\n",
__func__);
goto err;
}
pnctrl_info->active = pinctrl_lookup_state(pinctrl, "active");
if (IS_ERR(pnctrl_info->active)) {
dev_err(dev, "%s: could not get active pinstate\n",
__func__);
goto err;
}
/* Reset the TLMM pins to a default state */
ret = pinctrl_select_state(pnctrl_info->pinctrl,
pnctrl_info->sleep);
if (ret) {
dev_err(dev, "%s: Disable TLMM pins failed with %d\n",
__func__, ret);
goto err;
}
ret = of_property_read_u32(dev->of_node, "qcom,mclk-clk-reg", &reg);
if (ret < 0) {
dev_dbg(dev, "%s: miss mclk reg\n", __func__);
} else {
pnctrl_info->base = ioremap(reg, sizeof(u32));
if (pnctrl_info->base == NULL) {
dev_err(dev, "%s ioremap failed\n", __func__);
goto err;
}
}
return 0;
err:
devm_pinctrl_put(pnctrl_info->pinctrl);
return -EINVAL;
}
static int audio_put_pinctrl(struct platform_device *pdev)
{
struct audio_ext_clk_priv *clk_priv = platform_get_drvdata(pdev);
struct pinctrl_info *pnctrl_info = NULL;
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;
}
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);
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, use_pinctrl = 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_name = NULL;
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 = of_property_read_string(pdev->dev.of_node, "pmic-clock-names",
&clk_priv->clk_name);
if (ret)
dev_dbg(&pdev->dev, "%s: could not find pmic clock names\n",
__func__);
/*
* property qcom,use-pinctrl to be defined in DTSI to val 1
* for clock nodes using pinctrl
*/
of_property_read_u32(pdev->dev.of_node, "qcom,use-pinctrl",
&use_pinctrl);
dev_dbg(&pdev->dev, "%s: use-pinctrl : %d\n",
__func__, use_pinctrl);
if (use_pinctrl) {
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)
{
audio_put_pinctrl(pdev);
return 0;
}
static const struct of_device_id audio_ref_clk_match[] = {
{.compatible = "qcom,audio-ref-clk"},
{}
};
MODULE_DEVICE_TABLE(of, audio_ref_clk_match);
static struct platform_driver audio_ref_clk_driver = {
.driver = {
.name = "audio-ref-clk",
.owner = THIS_MODULE,
.of_match_table = audio_ref_clk_match,
.suppress_bind_attrs = true,
},
.probe = audio_ref_clk_probe,
.remove = audio_ref_clk_remove,
};
int audio_ref_clk_platform_init(void)
{
return platform_driver_register(&audio_ref_clk_driver);
}
void audio_ref_clk_platform_exit(void)
{
platform_driver_unregister(&audio_ref_clk_driver);
}
MODULE_DESCRIPTION("Audio Ref Up Clock module platform driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*/
#ifndef __AUDIO_EXT_CLK_UP_H_
#define __AUDIO_EXT_CLK_UP_H_
int audio_ref_clk_platform_init(void);
void audio_ref_clk_platform_exit(void);
#endif

View File

@@ -0,0 +1,341 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2017, 2019 The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/clk/msm-clk-provider.h>
#include <linux/clk/msm-clk.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <dt-bindings/clock/audio-ext-clk.h>
#include <sound/q6afe-v2.h>
#include "audio-ext-clk-up.h"
struct pinctrl_info {
struct pinctrl *pinctrl;
struct pinctrl_state *sleep;
struct pinctrl_state *active;
};
struct audio_ext_ap_clk {
bool enabled;
int gpio;
struct clk c;
};
struct audio_ext_pmi_clk {
int gpio;
struct clk c;
};
struct audio_ext_ap_clk2 {
bool enabled;
struct pinctrl_info pnctrl_info;
struct clk c;
};
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 inline struct audio_ext_ap_clk *to_audio_ap_clk(struct clk *clk)
{
return container_of(clk, struct audio_ext_ap_clk, c);
}
static int audio_ext_clk_prepare(struct clk *clk)
{
struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(clk);
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 *clk)
{
struct audio_ext_ap_clk *audio_clk = to_audio_ap_clk(clk);
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 *clk)
{
return container_of(clk, struct audio_ext_ap_clk2, c);
}
static int audio_ext_clk2_prepare(struct clk *clk)
{
struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(clk);
struct pinctrl_info *pnctrl_info = &audio_clk2->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 *clk)
{
struct audio_ext_ap_clk2 *audio_clk2 = to_audio_ap_clk2(clk);
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 const struct clk_ops audio_ext_ap_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 struct audio_ext_pmi_clk audio_pmi_clk = {
.gpio = -EINVAL,
.c = {
.dbg_name = "audio_ext_pmi_clk",
.ops = &clk_ops_dummy,
CLK_INIT(audio_pmi_clk.c),
},
};
static struct audio_ext_pmi_clk audio_pmi_lnbb_clk = {
.gpio = -EINVAL,
.c = {
.dbg_name = "audio_ext_pmi_lnbb_clk",
.ops = &clk_ops_dummy,
CLK_INIT(audio_pmi_lnbb_clk.c),
},
};
static struct audio_ext_ap_clk audio_ap_clk = {
.gpio = -EINVAL,
.c = {
.dbg_name = "audio_ext_ap_clk",
.ops = &audio_ext_ap_clk_ops,
CLK_INIT(audio_ap_clk.c),
},
};
static struct audio_ext_ap_clk2 audio_ap_clk2 = {
.c = {
.dbg_name = "audio_ext_ap_clk2",
.ops = &audio_ext_ap_clk2_ops,
CLK_INIT(audio_ap_clk2.c),
},
};
static struct clk_lookup audio_ref_clock[] = {
CLK_LIST(audio_ap_clk),
CLK_LIST(audio_pmi_clk),
CLK_LIST(audio_pmi_lnbb_clk),
CLK_LIST(audio_ap_clk2),
};
static int audio_get_pinctrl(struct platform_device *pdev)
{
struct pinctrl_info *pnctrl_info;
struct pinctrl *pinctrl;
int ret;
pnctrl_info = &audio_ap_clk2.pnctrl_info;
if (pnctrl_info->pinctrl) {
dev_dbg(&pdev->dev, "%s: already requested before\n",
__func__);
return -EINVAL;
}
pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR_OR_NULL(pinctrl)) {
dev_dbg(&pdev->dev, "%s: Unable to get pinctrl handle\n",
__func__);
return -EINVAL;
}
pnctrl_info->pinctrl = pinctrl;
/* get all state handles from Device Tree */
pnctrl_info->sleep = pinctrl_lookup_state(pinctrl, "sleep");
if (IS_ERR(pnctrl_info->sleep)) {
dev_err(&pdev->dev, "%s: could not get sleep pinstate\n",
__func__);
goto err;
}
pnctrl_info->active = pinctrl_lookup_state(pinctrl, "active");
if (IS_ERR(pnctrl_info->active)) {
dev_err(&pdev->dev, "%s: could not get active pinstate\n",
__func__);
goto err;
}
/* Reset the TLMM pins to a default state */
ret = pinctrl_select_state(pnctrl_info->pinctrl,
pnctrl_info->sleep);
if (ret) {
dev_err(&pdev->dev, "%s: Disable TLMM pins failed with %d\n",
__func__, ret);
goto err;
}
return 0;
err:
devm_pinctrl_put(pnctrl_info->pinctrl);
return -EINVAL;
}
static int audio_ref_clk_probe(struct platform_device *pdev)
{
int clk_gpio;
int ret;
struct clk *audio_clk;
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_clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(audio_clk)) {
dev_err(&pdev->dev, "Failed to get RPM div clk\n");
ret = PTR_ERR(audio_clk);
goto err_gpio;
}
audio_pmi_clk.c.parent = audio_clk;
audio_pmi_clk.gpio = clk_gpio;
} else
audio_ap_clk.gpio = clk_gpio;
} else {
if (of_property_read_bool(pdev->dev.of_node,
"qcom,node_has_rpm_clock")) {
audio_clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(audio_clk)) {
dev_err(&pdev->dev, "Failed to get lnbbclk2\n");
ret = PTR_ERR(audio_clk);
goto err;
}
audio_pmi_lnbb_clk.c.parent = audio_clk;
audio_pmi_lnbb_clk.gpio = -EINVAL;
}
}
ret = audio_get_pinctrl(pdev);
if (ret)
dev_dbg(&pdev->dev, "%s: Parsing pinctrl failed\n",
__func__);
ret = of_msm_clock_register(pdev->dev.of_node, audio_ref_clock,
ARRAY_SIZE(audio_ref_clock));
if (ret) {
dev_err(&pdev->dev, "%s: audio ref clock register failed\n",
__func__);
goto err_gpio;
}
return 0;
err_gpio:
gpio_free(clk_gpio);
err:
return ret;
}
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;
}
return 0;
}
static const struct of_device_id audio_ref_clk_match[] = {
{.compatible = "qcom,audio-ref-clk"},
{}
};
MODULE_DEVICE_TABLE(of, audio_ref_clk_match);
static struct platform_driver audio_ref_clk_driver = {
.driver = {
.name = "audio-ref-clk",
.owner = THIS_MODULE,
.of_match_table = audio_ref_clk_match,
.suppress_bind_attrs = true,
},
.probe = audio_ref_clk_probe,
.remove = audio_ref_clk_remove,
};
int audio_ref_clk_platform_init(void)
{
return platform_driver_register(&audio_ref_clk_driver);
}
void audio_ref_clk_platform_exit(void)
{
platform_driver_unregister(&audio_ref_clk_driver);
}
MODULE_DESCRIPTION("Audio Ref Clock module platform driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,94 @@
# 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,$(MSMSTEPPE) $(TRINKET)),true)
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
ifeq ($(call is-board-platform,kona),true)
AUDIO_SELECT := CONFIG_SND_SOC_KONA=m
endif
ifeq ($(call is-board-platform,lito),true)
AUDIO_SELECT := CONFIG_SND_SOC_LITO=m
endif
ifeq ($(call is-board-platform,atoll),true)
AUDIO_SELECT := CONFIG_SND_SOC_ATOLL=m
endif
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona lito atoll),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 := $(shell pwd)/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=bolero_cdc_dlkm
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
KBUILD_OPTIONS += $(AUDIO_SELECT)
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_bolero_cdc.ko
LOCAL_MODULE_KBUILD_NAME := bolero_cdc_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wsa_macro.ko
LOCAL_MODULE_KBUILD_NAME := wsa_macro_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_va_macro.ko
LOCAL_MODULE_KBUILD_NAME := va_macro_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_tx_macro.ko
LOCAL_MODULE_KBUILD_NAME := tx_macro_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_rx_macro.ko
LOCAL_MODULE_KBUILD_NAME := rx_macro_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

View File

@@ -0,0 +1,168 @@
# 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 := $(shell pwd)/kernel/msm-4.19
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_ATOLL), y)
include $(AUDIO_ROOT)/4.0/config/atollauto.conf
export
INCS += -include $(AUDIO_ROOT)/4.0/config/atollautoconf.h
endif
ifeq ($(CONFIG_ARCH_TRINKET), y)
include $(AUDIO_ROOT)/config/sm6150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.h
endif
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
include $(AUDIO_ROOT)/config/litoauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h
endif
ifeq ($(CONFIG_ARCH_QCS405), y)
include $(AUDIO_ROOT)/config/qcs405auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/qcs405autoconf.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
UAPI_DIR := uapi
UAPI_INC := -I$(AUDIO_ROOT)/4.0/include/$(UAPI_DIR)
COMMON_DIR := include
COMMON_INC := -I$(AUDIO_ROOT)/4.0/$(COMMON_DIR)
endif
############ BOLERO ############
# for BOLERO Codec
ifdef CONFIG_SND_SOC_BOLERO
BOLERO_OBJS += bolero-cdc.o
BOLERO_OBJS += bolero-cdc-utils.o
BOLERO_OBJS += bolero-cdc-regmap.o
BOLERO_OBJS += bolero-cdc-tables.o
BOLERO_OBJS += bolero-clk-rsc.o
endif
ifdef CONFIG_WSA_MACRO
WSA_OBJS += wsa-macro.o
endif
ifdef CONFIG_VA_MACRO
VA_OBJS += va-macro.o
endif
ifdef CONFIG_TX_MACRO
TX_OBJS += tx-macro.o
endif
ifdef CONFIG_RX_MACRO
RX_OBJS += rx-macro.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/ipc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/soc/Module.symvers
else
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
endif
# Module information used by KBuild framework
obj-$(CONFIG_SND_SOC_BOLERO) += bolero_cdc_dlkm.o
bolero_cdc_dlkm-y := $(BOLERO_OBJS)
obj-$(CONFIG_WSA_MACRO) += wsa_macro_dlkm.o
wsa_macro_dlkm-y := $(WSA_OBJS)
obj-$(CONFIG_VA_MACRO) += va_macro_dlkm.o
va_macro_dlkm-y := $(VA_OBJS)
obj-$(CONFIG_TX_MACRO) += tx_macro_dlkm.o
tx_macro_dlkm-y := $(TX_OBJS)
obj-$(CONFIG_RX_MACRO) += rx_macro_dlkm.o
rx_macro_dlkm-y := $(RX_OBJS)
# inject some build related information

View File

@@ -0,0 +1,838 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#ifndef _BOLERO_CDC_REGISTERS_H
#define _BOLERO_CDC_REGISTERS_H
#define TX_START_OFFSET 0x0000
#define BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (TX_START_OFFSET + 0x0000)
#define BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL (TX_START_OFFSET + 0x0004)
#define BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL (TX_START_OFFSET + 0x0008)
#define BOLERO_CDC_TX_TOP_CSR_TOP_CFG0 (TX_START_OFFSET + 0x0080)
#define BOLERO_CDC_TX_TOP_CSR_ANC_CFG (TX_START_OFFSET + 0x0084)
#define BOLERO_CDC_TX_TOP_CSR_SWR_CTRL (TX_START_OFFSET + 0x0088)
#define BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK (TX_START_OFFSET + 0x0090)
#define BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS (TX_START_OFFSET + 0x0094)
#define BOLERO_CDC_TX_TOP_CSR_DEBUG_EN (TX_START_OFFSET + 0x0098)
#define BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL (TX_START_OFFSET + 0x00A4)
#define BOLERO_CDC_TX_TOP_CSR_I2S_CLK (TX_START_OFFSET + 0x00A8)
#define BOLERO_CDC_TX_TOP_CSR_I2S_RESET (TX_START_OFFSET + 0x00AC)
#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL (TX_START_OFFSET + 0x00C0)
#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL (TX_START_OFFSET + 0x00C4)
#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL (TX_START_OFFSET + 0x00C8)
#define BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL (TX_START_OFFSET + 0x00CC)
#define BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL (TX_START_OFFSET + 0x00D0)
#define BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL (TX_START_OFFSET + 0x00D4)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 (TX_START_OFFSET + 0x0100)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 (TX_START_OFFSET + 0x0104)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0 (TX_START_OFFSET + 0x0108)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1 (TX_START_OFFSET + 0x010C)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0 (TX_START_OFFSET + 0x0110)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1 (TX_START_OFFSET + 0x0114)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0 (TX_START_OFFSET + 0x0118)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1 (TX_START_OFFSET + 0x011C)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0 (TX_START_OFFSET + 0x0120)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1 (TX_START_OFFSET + 0x0124)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0 (TX_START_OFFSET + 0x0128)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1 (TX_START_OFFSET + 0x012C)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0 (TX_START_OFFSET + 0x0130)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1 (TX_START_OFFSET + 0x0134)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0 (TX_START_OFFSET + 0x0138)
#define BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1 (TX_START_OFFSET + 0x013C)
#define BOLERO_CDC_TX_ANC0_CLK_RESET_CTL (TX_START_OFFSET + 0x0200)
#define BOLERO_CDC_TX_ANC0_MODE_1_CTL (TX_START_OFFSET + 0x0204)
#define BOLERO_CDC_TX_ANC0_MODE_2_CTL (TX_START_OFFSET + 0x0208)
#define BOLERO_CDC_TX_ANC0_FF_SHIFT (TX_START_OFFSET + 0x020C)
#define BOLERO_CDC_TX_ANC0_FB_SHIFT (TX_START_OFFSET + 0x0210)
#define BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL (TX_START_OFFSET + 0x0214)
#define BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL (TX_START_OFFSET + 0x0218)
#define BOLERO_CDC_TX_ANC0_LPF_FB_CTL (TX_START_OFFSET + 0x021C)
#define BOLERO_CDC_TX_ANC0_SMLPF_CTL (TX_START_OFFSET + 0x0220)
#define BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL (TX_START_OFFSET + 0x0224)
#define BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL (TX_START_OFFSET + 0x0228)
#define BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL (TX_START_OFFSET + 0x022C)
#define BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL (TX_START_OFFSET + 0x0230)
#define BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL (TX_START_OFFSET + 0x0234)
#define BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL (TX_START_OFFSET + 0x0238)
#define BOLERO_CDC_TX_ANC0_FB_GAIN_CTL (TX_START_OFFSET + 0x023C)
#define BOLERO_CDC_TX0_TX_PATH_CTL (TX_START_OFFSET + 0x0400)
#define BOLERO_CDC_TX0_TX_PATH_CFG0 (TX_START_OFFSET + 0x0404)
#define BOLERO_CDC_TX0_TX_PATH_CFG1 (TX_START_OFFSET + 0x0408)
#define BOLERO_CDC_TX0_TX_VOL_CTL (TX_START_OFFSET + 0x040C)
#define BOLERO_CDC_TX0_TX_PATH_SEC0 (TX_START_OFFSET + 0x0410)
#define BOLERO_CDC_TX0_TX_PATH_SEC1 (TX_START_OFFSET + 0x0414)
#define BOLERO_CDC_TX0_TX_PATH_SEC2 (TX_START_OFFSET + 0x0418)
#define BOLERO_CDC_TX0_TX_PATH_SEC3 (TX_START_OFFSET + 0x041C)
#define BOLERO_CDC_TX0_TX_PATH_SEC4 (TX_START_OFFSET + 0x0420)
#define BOLERO_CDC_TX0_TX_PATH_SEC5 (TX_START_OFFSET + 0x0424)
#define BOLERO_CDC_TX0_TX_PATH_SEC6 (TX_START_OFFSET + 0x0428)
#define BOLERO_CDC_TX0_TX_PATH_SEC7 (TX_START_OFFSET + 0x042C)
#define BOLERO_CDC_TX1_TX_PATH_CTL (TX_START_OFFSET + 0x0480)
#define BOLERO_CDC_TX1_TX_PATH_CFG0 (TX_START_OFFSET + 0x0484)
#define BOLERO_CDC_TX1_TX_PATH_CFG1 (TX_START_OFFSET + 0x0488)
#define BOLERO_CDC_TX1_TX_VOL_CTL (TX_START_OFFSET + 0x048C)
#define BOLERO_CDC_TX1_TX_PATH_SEC0 (TX_START_OFFSET + 0x0490)
#define BOLERO_CDC_TX1_TX_PATH_SEC1 (TX_START_OFFSET + 0x0494)
#define BOLERO_CDC_TX1_TX_PATH_SEC2 (TX_START_OFFSET + 0x0498)
#define BOLERO_CDC_TX1_TX_PATH_SEC3 (TX_START_OFFSET + 0x049C)
#define BOLERO_CDC_TX1_TX_PATH_SEC4 (TX_START_OFFSET + 0x04A0)
#define BOLERO_CDC_TX1_TX_PATH_SEC5 (TX_START_OFFSET + 0x04A4)
#define BOLERO_CDC_TX1_TX_PATH_SEC6 (TX_START_OFFSET + 0x04A8)
#define BOLERO_CDC_TX2_TX_PATH_CTL (TX_START_OFFSET + 0x0500)
#define BOLERO_CDC_TX2_TX_PATH_CFG0 (TX_START_OFFSET + 0x0504)
#define BOLERO_CDC_TX2_TX_PATH_CFG1 (TX_START_OFFSET + 0x0508)
#define BOLERO_CDC_TX2_TX_VOL_CTL (TX_START_OFFSET + 0x050C)
#define BOLERO_CDC_TX2_TX_PATH_SEC0 (TX_START_OFFSET + 0x0510)
#define BOLERO_CDC_TX2_TX_PATH_SEC1 (TX_START_OFFSET + 0x0514)
#define BOLERO_CDC_TX2_TX_PATH_SEC2 (TX_START_OFFSET + 0x0518)
#define BOLERO_CDC_TX2_TX_PATH_SEC3 (TX_START_OFFSET + 0x051C)
#define BOLERO_CDC_TX2_TX_PATH_SEC4 (TX_START_OFFSET + 0x0520)
#define BOLERO_CDC_TX2_TX_PATH_SEC5 (TX_START_OFFSET + 0x0524)
#define BOLERO_CDC_TX2_TX_PATH_SEC6 (TX_START_OFFSET + 0x0528)
#define BOLERO_CDC_TX3_TX_PATH_CTL (TX_START_OFFSET + 0x0580)
#define BOLERO_CDC_TX3_TX_PATH_CFG0 (TX_START_OFFSET + 0x0584)
#define BOLERO_CDC_TX3_TX_PATH_CFG1 (TX_START_OFFSET + 0x0588)
#define BOLERO_CDC_TX3_TX_VOL_CTL (TX_START_OFFSET + 0x058C)
#define BOLERO_CDC_TX3_TX_PATH_SEC0 (TX_START_OFFSET + 0x0590)
#define BOLERO_CDC_TX3_TX_PATH_SEC1 (TX_START_OFFSET + 0x0594)
#define BOLERO_CDC_TX3_TX_PATH_SEC2 (TX_START_OFFSET + 0x0598)
#define BOLERO_CDC_TX3_TX_PATH_SEC3 (TX_START_OFFSET + 0x059C)
#define BOLERO_CDC_TX3_TX_PATH_SEC4 (TX_START_OFFSET + 0x05A0)
#define BOLERO_CDC_TX3_TX_PATH_SEC5 (TX_START_OFFSET + 0x05A4)
#define BOLERO_CDC_TX3_TX_PATH_SEC6 (TX_START_OFFSET + 0x05A8)
#define BOLERO_CDC_TX4_TX_PATH_CTL (TX_START_OFFSET + 0x0600)
#define BOLERO_CDC_TX4_TX_PATH_CFG0 (TX_START_OFFSET + 0x0604)
#define BOLERO_CDC_TX4_TX_PATH_CFG1 (TX_START_OFFSET + 0x0608)
#define BOLERO_CDC_TX4_TX_VOL_CTL (TX_START_OFFSET + 0x060C)
#define BOLERO_CDC_TX4_TX_PATH_SEC0 (TX_START_OFFSET + 0x0610)
#define BOLERO_CDC_TX4_TX_PATH_SEC1 (TX_START_OFFSET + 0x0614)
#define BOLERO_CDC_TX4_TX_PATH_SEC2 (TX_START_OFFSET + 0x0618)
#define BOLERO_CDC_TX4_TX_PATH_SEC3 (TX_START_OFFSET + 0x061C)
#define BOLERO_CDC_TX4_TX_PATH_SEC4 (TX_START_OFFSET + 0x0620)
#define BOLERO_CDC_TX4_TX_PATH_SEC5 (TX_START_OFFSET + 0x0624)
#define BOLERO_CDC_TX4_TX_PATH_SEC6 (TX_START_OFFSET + 0x0628)
#define BOLERO_CDC_TX5_TX_PATH_CTL (TX_START_OFFSET + 0x0680)
#define BOLERO_CDC_TX5_TX_PATH_CFG0 (TX_START_OFFSET + 0x0684)
#define BOLERO_CDC_TX5_TX_PATH_CFG1 (TX_START_OFFSET + 0x0688)
#define BOLERO_CDC_TX5_TX_VOL_CTL (TX_START_OFFSET + 0x068C)
#define BOLERO_CDC_TX5_TX_PATH_SEC0 (TX_START_OFFSET + 0x0690)
#define BOLERO_CDC_TX5_TX_PATH_SEC1 (TX_START_OFFSET + 0x0694)
#define BOLERO_CDC_TX5_TX_PATH_SEC2 (TX_START_OFFSET + 0x0698)
#define BOLERO_CDC_TX5_TX_PATH_SEC3 (TX_START_OFFSET + 0x069C)
#define BOLERO_CDC_TX5_TX_PATH_SEC4 (TX_START_OFFSET + 0x06A0)
#define BOLERO_CDC_TX5_TX_PATH_SEC5 (TX_START_OFFSET + 0x06A4)
#define BOLERO_CDC_TX5_TX_PATH_SEC6 (TX_START_OFFSET + 0x06A8)
#define BOLERO_CDC_TX6_TX_PATH_CTL (TX_START_OFFSET + 0x0700)
#define BOLERO_CDC_TX6_TX_PATH_CFG0 (TX_START_OFFSET + 0x0704)
#define BOLERO_CDC_TX6_TX_PATH_CFG1 (TX_START_OFFSET + 0x0708)
#define BOLERO_CDC_TX6_TX_VOL_CTL (TX_START_OFFSET + 0x070C)
#define BOLERO_CDC_TX6_TX_PATH_SEC0 (TX_START_OFFSET + 0x0710)
#define BOLERO_CDC_TX6_TX_PATH_SEC1 (TX_START_OFFSET + 0x0714)
#define BOLERO_CDC_TX6_TX_PATH_SEC2 (TX_START_OFFSET + 0x0718)
#define BOLERO_CDC_TX6_TX_PATH_SEC3 (TX_START_OFFSET + 0x071C)
#define BOLERO_CDC_TX6_TX_PATH_SEC4 (TX_START_OFFSET + 0x0720)
#define BOLERO_CDC_TX6_TX_PATH_SEC5 (TX_START_OFFSET + 0x0724)
#define BOLERO_CDC_TX6_TX_PATH_SEC6 (TX_START_OFFSET + 0x0728)
#define BOLERO_CDC_TX7_TX_PATH_CTL (TX_START_OFFSET + 0x0780)
#define BOLERO_CDC_TX7_TX_PATH_CFG0 (TX_START_OFFSET + 0x0784)
#define BOLERO_CDC_TX7_TX_PATH_CFG1 (TX_START_OFFSET + 0x0788)
#define BOLERO_CDC_TX7_TX_VOL_CTL (TX_START_OFFSET + 0x078C)
#define BOLERO_CDC_TX7_TX_PATH_SEC0 (TX_START_OFFSET + 0x0790)
#define BOLERO_CDC_TX7_TX_PATH_SEC1 (TX_START_OFFSET + 0x0794)
#define BOLERO_CDC_TX7_TX_PATH_SEC2 (TX_START_OFFSET + 0x0798)
#define BOLERO_CDC_TX7_TX_PATH_SEC3 (TX_START_OFFSET + 0x079C)
#define BOLERO_CDC_TX7_TX_PATH_SEC4 (TX_START_OFFSET + 0x07A0)
#define BOLERO_CDC_TX7_TX_PATH_SEC5 (TX_START_OFFSET + 0x07A4)
#define BOLERO_CDC_TX7_TX_PATH_SEC6 (TX_START_OFFSET + 0x07A8)
#define TX_MAX_OFFSET (TX_START_OFFSET + 0x07A8)
#define BOLERO_CDC_TX_MACRO_MAX 0x1EB /* 7A8/4 = 1EA + 1 */
#define RX_START_OFFSET 0x1000
#define BOLERO_CDC_RX_TOP_TOP_CFG0 (RX_START_OFFSET + 0x0000)
#define BOLERO_CDC_RX_TOP_SWR_CTRL (RX_START_OFFSET + 0x0008)
#define BOLERO_CDC_RX_TOP_DEBUG (RX_START_OFFSET + 0x000C)
#define BOLERO_CDC_RX_TOP_DEBUG_BUS (RX_START_OFFSET + 0x0010)
#define BOLERO_CDC_RX_TOP_DEBUG_EN0 (RX_START_OFFSET + 0x0014)
#define BOLERO_CDC_RX_TOP_DEBUG_EN1 (RX_START_OFFSET + 0x0018)
#define BOLERO_CDC_RX_TOP_DEBUG_EN2 (RX_START_OFFSET + 0x001C)
#define BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB (RX_START_OFFSET + 0x0020)
#define BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB (RX_START_OFFSET + 0x0024)
#define BOLERO_CDC_RX_TOP_HPHL_COMP_LUT (RX_START_OFFSET + 0x0028)
#define BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB (RX_START_OFFSET + 0x002C)
#define BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB (RX_START_OFFSET + 0x0030)
#define BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB (RX_START_OFFSET + 0x0034)
#define BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB (RX_START_OFFSET + 0x0038)
#define BOLERO_CDC_RX_TOP_HPHR_COMP_LUT (RX_START_OFFSET + 0x003C)
#define BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB (RX_START_OFFSET + 0x0040)
#define BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB (RX_START_OFFSET + 0x0044)
#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG0 (RX_START_OFFSET + 0x0070)
#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG1 (RX_START_OFFSET + 0x0074)
#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2 (RX_START_OFFSET + 0x0078)
#define BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG3 (RX_START_OFFSET + 0x007C)
#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG0 (RX_START_OFFSET + 0x0080)
#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG1 (RX_START_OFFSET + 0x0084)
#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2 (RX_START_OFFSET + 0x0088)
#define BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG3 (RX_START_OFFSET + 0x008C)
#define BOLERO_CDC_RX_TOP_RX_I2S_CTL (RX_START_OFFSET + 0x0090)
#define BOLERO_CDC_RX_TOP_TX_I2S2_CTL (RX_START_OFFSET + 0x0094)
#define BOLERO_CDC_RX_TOP_I2S_CLK (RX_START_OFFSET + 0x0098)
#define BOLERO_CDC_RX_TOP_I2S_RESET (RX_START_OFFSET + 0x009C)
#define BOLERO_CDC_RX_TOP_I2S_MUX (RX_START_OFFSET + 0x00A0)
#define BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL (RX_START_OFFSET + 0x0100)
#define BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL \
(RX_START_OFFSET + 0x0104)
#define BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL (RX_START_OFFSET + 0x0108)
#define BOLERO_CDC_RX_CLK_RST_CTRL_DSD_CONTROL (RX_START_OFFSET + 0x010C)
#define BOLERO_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL \
(RX_START_OFFSET + 0x0110)
#define BOLERO_CDC_RX_SOFTCLIP_CRC (RX_START_OFFSET + 0x0140)
#define BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL (RX_START_OFFSET + 0x0144)
#define BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0 (RX_START_OFFSET + 0x0180)
#define BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1 (RX_START_OFFSET + 0x0184)
#define BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0 (RX_START_OFFSET + 0x0188)
#define BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1 (RX_START_OFFSET + 0x018C)
#define BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0 (RX_START_OFFSET + 0x0190)
#define BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1 (RX_START_OFFSET + 0x0194)
#define BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4 (RX_START_OFFSET + 0x0198)
#define BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5 (RX_START_OFFSET + 0x019C)
#define BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0 (RX_START_OFFSET + 0x01A0)
#define BOLERO_CDC_RX_CLSH_CRC (RX_START_OFFSET + 0x0200)
#define BOLERO_CDC_RX_CLSH_DLY_CTRL (RX_START_OFFSET + 0x0204)
#define BOLERO_CDC_RX_CLSH_DECAY_CTRL (RX_START_OFFSET + 0x0208)
#define BOLERO_CDC_RX_CLSH_HPH_V_PA (RX_START_OFFSET + 0x020C)
#define BOLERO_CDC_RX_CLSH_EAR_V_PA (RX_START_OFFSET + 0x0210)
#define BOLERO_CDC_RX_CLSH_HPH_V_HD (RX_START_OFFSET + 0x0214)
#define BOLERO_CDC_RX_CLSH_EAR_V_HD (RX_START_OFFSET + 0x0218)
#define BOLERO_CDC_RX_CLSH_K1_MSB (RX_START_OFFSET + 0x021C)
#define BOLERO_CDC_RX_CLSH_K1_LSB (RX_START_OFFSET + 0x0220)
#define BOLERO_CDC_RX_CLSH_K2_MSB (RX_START_OFFSET + 0x0224)
#define BOLERO_CDC_RX_CLSH_K2_LSB (RX_START_OFFSET + 0x0228)
#define BOLERO_CDC_RX_CLSH_IDLE_CTRL (RX_START_OFFSET + 0x022C)
#define BOLERO_CDC_RX_CLSH_IDLE_HPH (RX_START_OFFSET + 0x0230)
#define BOLERO_CDC_RX_CLSH_IDLE_EAR (RX_START_OFFSET + 0x0234)
#define BOLERO_CDC_RX_CLSH_TEST0 (RX_START_OFFSET + 0x0238)
#define BOLERO_CDC_RX_CLSH_TEST1 (RX_START_OFFSET + 0x023C)
#define BOLERO_CDC_RX_CLSH_OVR_VREF (RX_START_OFFSET + 0x0240)
#define BOLERO_CDC_RX_CLSH_CLSG_CTL (RX_START_OFFSET + 0x0244)
#define BOLERO_CDC_RX_CLSH_CLSG_CFG1 (RX_START_OFFSET + 0x0248)
#define BOLERO_CDC_RX_CLSH_CLSG_CFG2 (RX_START_OFFSET + 0x024C)
#define BOLERO_CDC_RX_BCL_VBAT_PATH_CTL (RX_START_OFFSET + 0x0280)
#define BOLERO_CDC_RX_BCL_VBAT_CFG (RX_START_OFFSET + 0x0284)
#define BOLERO_CDC_RX_BCL_VBAT_ADC_CAL1 (RX_START_OFFSET + 0x0288)
#define BOLERO_CDC_RX_BCL_VBAT_ADC_CAL2 (RX_START_OFFSET + 0x028C)
#define BOLERO_CDC_RX_BCL_VBAT_ADC_CAL3 (RX_START_OFFSET + 0x0290)
#define BOLERO_CDC_RX_BCL_VBAT_PK_EST1 (RX_START_OFFSET + 0x0294)
#define BOLERO_CDC_RX_BCL_VBAT_PK_EST2 (RX_START_OFFSET + 0x0298)
#define BOLERO_CDC_RX_BCL_VBAT_PK_EST3 (RX_START_OFFSET + 0x029C)
#define BOLERO_CDC_RX_BCL_VBAT_RF_PROC1 (RX_START_OFFSET + 0x02A0)
#define BOLERO_CDC_RX_BCL_VBAT_RF_PROC2 (RX_START_OFFSET + 0x02A4)
#define BOLERO_CDC_RX_BCL_VBAT_TAC1 (RX_START_OFFSET + 0x02A8)
#define BOLERO_CDC_RX_BCL_VBAT_TAC2 (RX_START_OFFSET + 0x02AC)
#define BOLERO_CDC_RX_BCL_VBAT_TAC3 (RX_START_OFFSET + 0x02B0)
#define BOLERO_CDC_RX_BCL_VBAT_TAC4 (RX_START_OFFSET + 0x02B4)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD1 (RX_START_OFFSET + 0x02B8)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD2 (RX_START_OFFSET + 0x02BC)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD3 (RX_START_OFFSET + 0x02C0)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD4 (RX_START_OFFSET + 0x02C4)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD5 (RX_START_OFFSET + 0x02C8)
#define BOLERO_CDC_RX_BCL_VBAT_DEBUG1 (RX_START_OFFSET + 0x02CC)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD_MON (RX_START_OFFSET + 0x02D0)
#define BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL (RX_START_OFFSET + 0x02D4)
#define BOLERO_CDC_RX_BCL_VBAT_BAN (RX_START_OFFSET + 0x02D8)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1 (RX_START_OFFSET + 0x02DC)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2 (RX_START_OFFSET + 0x02E0)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3 (RX_START_OFFSET + 0x02E4)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4 (RX_START_OFFSET + 0x02E8)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5 (RX_START_OFFSET + 0x02EC)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6 (RX_START_OFFSET + 0x02F0)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7 (RX_START_OFFSET + 0x02F4)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8 (RX_START_OFFSET + 0x02F8)
#define BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9 (RX_START_OFFSET + 0x02FC)
#define BOLERO_CDC_RX_BCL_VBAT_ATTN1 (RX_START_OFFSET + 0x0300)
#define BOLERO_CDC_RX_BCL_VBAT_ATTN2 (RX_START_OFFSET + 0x0304)
#define BOLERO_CDC_RX_BCL_VBAT_ATTN3 (RX_START_OFFSET + 0x0308)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1 (RX_START_OFFSET + 0x030C)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL2 (RX_START_OFFSET + 0x0310)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1 (RX_START_OFFSET + 0x0314)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2 (RX_START_OFFSET + 0x0318)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3 (RX_START_OFFSET + 0x031C)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG4 (RX_START_OFFSET + 0x0320)
#define BOLERO_CDC_RX_BCL_VBAT_DECODE_ST (RX_START_OFFSET + 0x0324)
#define BOLERO_CDC_RX_INTR_CTRL_CFG (RX_START_OFFSET + 0x0340)
#define BOLERO_CDC_RX_INTR_CTRL_CLR_COMMIT (RX_START_OFFSET + 0x0344)
#define BOLERO_CDC_RX_INTR_CTRL_PIN1_MASK0 (RX_START_OFFSET + 0x0360)
#define BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0 (RX_START_OFFSET + 0x0368)
#define BOLERO_CDC_RX_INTR_CTRL_PIN1_CLEAR0 (RX_START_OFFSET + 0x0370)
#define BOLERO_CDC_RX_INTR_CTRL_PIN2_MASK0 (RX_START_OFFSET + 0x0380)
#define BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0 (RX_START_OFFSET + 0x0388)
#define BOLERO_CDC_RX_INTR_CTRL_PIN2_CLEAR0 (RX_START_OFFSET + 0x0390)
#define BOLERO_CDC_RX_INTR_CTRL_LEVEL0 (RX_START_OFFSET + 0x03C0)
#define BOLERO_CDC_RX_INTR_CTRL_BYPASS0 (RX_START_OFFSET + 0x03C8)
#define BOLERO_CDC_RX_INTR_CTRL_SET0 (RX_START_OFFSET + 0x03D0)
#define BOLERO_CDC_RX_RX0_RX_PATH_CTL (RX_START_OFFSET + 0x0400)
#define BOLERO_CDC_RX_RX0_RX_PATH_CFG0 (RX_START_OFFSET + 0x0404)
#define BOLERO_CDC_RX_RX0_RX_PATH_CFG1 (RX_START_OFFSET + 0x0408)
#define BOLERO_CDC_RX_RX0_RX_PATH_CFG2 (RX_START_OFFSET + 0x040C)
#define BOLERO_CDC_RX_RX0_RX_PATH_CFG3 (RX_START_OFFSET + 0x0410)
#define BOLERO_CDC_RX_RX0_RX_VOL_CTL (RX_START_OFFSET + 0x0414)
#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL (RX_START_OFFSET + 0x0418)
#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_CFG (RX_START_OFFSET + 0x041C)
#define BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL (RX_START_OFFSET + 0x0420)
#define BOLERO_CDC_RX_RX0_RX_PATH_SEC1 (RX_START_OFFSET + 0x0424)
#define BOLERO_CDC_RX_RX0_RX_PATH_SEC2 (RX_START_OFFSET + 0x0428)
#define BOLERO_CDC_RX_RX0_RX_PATH_SEC3 (RX_START_OFFSET + 0x042C)
#define BOLERO_CDC_RX_RX0_RX_PATH_SEC4 (RX_START_OFFSET + 0x0430)
#define BOLERO_CDC_RX_RX0_RX_PATH_SEC7 (RX_START_OFFSET + 0x0434)
#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC0 (RX_START_OFFSET + 0x0438)
#define BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC1 (RX_START_OFFSET + 0x043C)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL (RX_START_OFFSET + 0x0440)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA1 (RX_START_OFFSET + 0x0444)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA2 (RX_START_OFFSET + 0x0448)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA3 (RX_START_OFFSET + 0x044C)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA4 (RX_START_OFFSET + 0x0450)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA5 (RX_START_OFFSET + 0x0454)
#define BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA6 (RX_START_OFFSET + 0x0458)
#define BOLERO_CDC_RX_RX1_RX_PATH_CTL (RX_START_OFFSET + 0x0480)
#define BOLERO_CDC_RX_RX1_RX_PATH_CFG0 (RX_START_OFFSET + 0x0484)
#define BOLERO_CDC_RX_RX1_RX_PATH_CFG1 (RX_START_OFFSET + 0x0488)
#define BOLERO_CDC_RX_RX1_RX_PATH_CFG2 (RX_START_OFFSET + 0x048C)
#define BOLERO_CDC_RX_RX1_RX_PATH_CFG3 (RX_START_OFFSET + 0x0490)
#define BOLERO_CDC_RX_RX1_RX_VOL_CTL (RX_START_OFFSET + 0x0494)
#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_CTL (RX_START_OFFSET + 0x0498)
#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_CFG (RX_START_OFFSET + 0x049C)
#define BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL (RX_START_OFFSET + 0x04A0)
#define BOLERO_CDC_RX_RX1_RX_PATH_SEC1 (RX_START_OFFSET + 0x04A4)
#define BOLERO_CDC_RX_RX1_RX_PATH_SEC2 (RX_START_OFFSET + 0x04A8)
#define BOLERO_CDC_RX_RX1_RX_PATH_SEC3 (RX_START_OFFSET + 0x04AC)
#define BOLERO_CDC_RX_RX1_RX_PATH_SEC4 (RX_START_OFFSET + 0x04B0)
#define BOLERO_CDC_RX_RX1_RX_PATH_SEC7 (RX_START_OFFSET + 0x04B4)
#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC0 (RX_START_OFFSET + 0x04B8)
#define BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC1 (RX_START_OFFSET + 0x04BC)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL (RX_START_OFFSET + 0x04C0)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA1 (RX_START_OFFSET + 0x04C4)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA2 (RX_START_OFFSET + 0x04C8)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA3 (RX_START_OFFSET + 0x04CC)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA4 (RX_START_OFFSET + 0x04D0)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA5 (RX_START_OFFSET + 0x04D4)
#define BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA6 (RX_START_OFFSET + 0x04D8)
#define BOLERO_CDC_RX_RX2_RX_PATH_CTL (RX_START_OFFSET + 0x0500)
#define BOLERO_CDC_RX_RX2_RX_PATH_CFG0 (RX_START_OFFSET + 0x0504)
#define BOLERO_CDC_RX_RX2_RX_PATH_CFG1 (RX_START_OFFSET + 0x0508)
#define BOLERO_CDC_RX_RX2_RX_PATH_CFG2 (RX_START_OFFSET + 0x050C)
#define BOLERO_CDC_RX_RX2_RX_PATH_CFG3 (RX_START_OFFSET + 0x0510)
#define BOLERO_CDC_RX_RX2_RX_VOL_CTL (RX_START_OFFSET + 0x0514)
#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_CTL (RX_START_OFFSET + 0x0518)
#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_CFG (RX_START_OFFSET + 0x051C)
#define BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL (RX_START_OFFSET + 0x0520)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC0 (RX_START_OFFSET + 0x0524)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC1 (RX_START_OFFSET + 0x0528)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC2 (RX_START_OFFSET + 0x052C)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC3 (RX_START_OFFSET + 0x0530)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC4 (RX_START_OFFSET + 0x0534)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC5 (RX_START_OFFSET + 0x0538)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC6 (RX_START_OFFSET + 0x053C)
#define BOLERO_CDC_RX_RX2_RX_PATH_SEC7 (RX_START_OFFSET + 0x0540)
#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC0 (RX_START_OFFSET + 0x0544)
#define BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC1 (RX_START_OFFSET + 0x0548)
#define BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL (RX_START_OFFSET + 0x054C)
#define BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL (RX_START_OFFSET + 0x0780)
#define BOLERO_CDC_RX_IDLE_DETECT_CFG0 (RX_START_OFFSET + 0x0784)
#define BOLERO_CDC_RX_IDLE_DETECT_CFG1 (RX_START_OFFSET + 0x0788)
#define BOLERO_CDC_RX_IDLE_DETECT_CFG2 (RX_START_OFFSET + 0x078C)
#define BOLERO_CDC_RX_IDLE_DETECT_CFG3 (RX_START_OFFSET + 0x0790)
#define BOLERO_CDC_RX_COMPANDER0_CTL0 (RX_START_OFFSET + 0x0800)
#define BOLERO_CDC_RX_COMPANDER0_CTL1 (RX_START_OFFSET + 0x0804)
#define BOLERO_CDC_RX_COMPANDER0_CTL2 (RX_START_OFFSET + 0x0808)
#define BOLERO_CDC_RX_COMPANDER0_CTL3 (RX_START_OFFSET + 0x080C)
#define BOLERO_CDC_RX_COMPANDER0_CTL4 (RX_START_OFFSET + 0x0810)
#define BOLERO_CDC_RX_COMPANDER0_CTL5 (RX_START_OFFSET + 0x0814)
#define BOLERO_CDC_RX_COMPANDER0_CTL6 (RX_START_OFFSET + 0x0818)
#define BOLERO_CDC_RX_COMPANDER0_CTL7 (RX_START_OFFSET + 0x081C)
#define BOLERO_CDC_RX_COMPANDER1_CTL0 (RX_START_OFFSET + 0x0840)
#define BOLERO_CDC_RX_COMPANDER1_CTL1 (RX_START_OFFSET + 0x0844)
#define BOLERO_CDC_RX_COMPANDER1_CTL2 (RX_START_OFFSET + 0x0848)
#define BOLERO_CDC_RX_COMPANDER1_CTL3 (RX_START_OFFSET + 0x084C)
#define BOLERO_CDC_RX_COMPANDER1_CTL4 (RX_START_OFFSET + 0x0850)
#define BOLERO_CDC_RX_COMPANDER1_CTL5 (RX_START_OFFSET + 0x0854)
#define BOLERO_CDC_RX_COMPANDER1_CTL6 (RX_START_OFFSET + 0x0858)
#define BOLERO_CDC_RX_COMPANDER1_CTL7 (RX_START_OFFSET + 0x085C)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL \
(RX_START_OFFSET + 0x0A00)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL \
(RX_START_OFFSET + 0x0A04)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL \
(RX_START_OFFSET + 0x0A08)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL \
(RX_START_OFFSET + 0x0A0C)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL \
(RX_START_OFFSET + 0x0A10)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL \
(RX_START_OFFSET + 0x0A14)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL \
(RX_START_OFFSET + 0x0A18)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL \
(RX_START_OFFSET + 0x0A1C)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL \
(RX_START_OFFSET + 0x0A20)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL (RX_START_OFFSET + 0x0A24)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL \
(RX_START_OFFSET + 0x0A28)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL \
(RX_START_OFFSET + 0x0A2C)
#define BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL \
(RX_START_OFFSET + 0x0A30)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL \
(RX_START_OFFSET + 0x0A80)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL \
(RX_START_OFFSET + 0x0A84)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL \
(RX_START_OFFSET + 0x0A88)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL \
(RX_START_OFFSET + 0x0A8C)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL \
(RX_START_OFFSET + 0x0A90)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL \
(RX_START_OFFSET + 0x0A94)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL \
(RX_START_OFFSET + 0x0A98)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL \
(RX_START_OFFSET + 0x0A9C)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL \
(RX_START_OFFSET + 0x0AA0)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_CTL (RX_START_OFFSET + 0x0AA4)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL \
(RX_START_OFFSET + 0x0AA8)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL \
(RX_START_OFFSET + 0x0AAC)
#define BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL \
(RX_START_OFFSET + 0x0AB0)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0 (RX_START_OFFSET + 0x0B00)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1 (RX_START_OFFSET + 0x0B04)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2 (RX_START_OFFSET + 0x0B08)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3 (RX_START_OFFSET + 0x0B0C)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0 (RX_START_OFFSET + 0x0B10)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1 (RX_START_OFFSET + 0x0B14)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2 (RX_START_OFFSET + 0x0B18)
#define BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3 (RX_START_OFFSET + 0x0B1C)
#define BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL \
(RX_START_OFFSET + 0x0B40)
#define BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1 \
(RX_START_OFFSET + 0x0B44)
#define BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL \
(RX_START_OFFSET + 0x0B50)
#define BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1 \
(RX_START_OFFSET + 0x0B54)
#define BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL \
(RX_START_OFFSET + 0x0C00)
#define BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0 (RX_START_OFFSET + 0x0C04)
#define BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL \
(RX_START_OFFSET + 0x0C40)
#define BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0 (RX_START_OFFSET + 0x0C44)
#define BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL \
(RX_START_OFFSET + 0x0C80)
#define BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0 (RX_START_OFFSET + 0x0C84)
#define BOLERO_CDC_RX_EC_ASRC0_CLK_RST_CTL (RX_START_OFFSET + 0x0D00)
#define BOLERO_CDC_RX_EC_ASRC0_CTL0 (RX_START_OFFSET + 0x0D04)
#define BOLERO_CDC_RX_EC_ASRC0_CTL1 (RX_START_OFFSET + 0x0D08)
#define BOLERO_CDC_RX_EC_ASRC0_FIFO_CTL (RX_START_OFFSET + 0x0D0C)
#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB \
(RX_START_OFFSET + 0x0D10)
#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB \
(RX_START_OFFSET + 0x0D14)
#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB \
(RX_START_OFFSET + 0x0D18)
#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB \
(RX_START_OFFSET + 0x0D1C)
#define BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO (RX_START_OFFSET + 0x0D20)
#define BOLERO_CDC_RX_EC_ASRC1_CLK_RST_CTL (RX_START_OFFSET + 0x0D40)
#define BOLERO_CDC_RX_EC_ASRC1_CTL0 (RX_START_OFFSET + 0x0D44)
#define BOLERO_CDC_RX_EC_ASRC1_CTL1 (RX_START_OFFSET + 0x0D48)
#define BOLERO_CDC_RX_EC_ASRC1_FIFO_CTL (RX_START_OFFSET + 0x0D4C)
#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB \
(RX_START_OFFSET + 0x0D50)
#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB \
(RX_START_OFFSET + 0x0D54)
#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB \
(RX_START_OFFSET + 0x0D58)
#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB \
(RX_START_OFFSET + 0x0D5C)
#define BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO (RX_START_OFFSET + 0x0D60)
#define BOLERO_CDC_RX_EC_ASRC2_CLK_RST_CTL (RX_START_OFFSET + 0x0D80)
#define BOLERO_CDC_RX_EC_ASRC2_CTL0 (RX_START_OFFSET + 0x0D84)
#define BOLERO_CDC_RX_EC_ASRC2_CTL1 (RX_START_OFFSET + 0x0D88)
#define BOLERO_CDC_RX_EC_ASRC2_FIFO_CTL (RX_START_OFFSET + 0x0D8C)
#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB \
(RX_START_OFFSET + 0x0D90)
#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB \
(RX_START_OFFSET + 0x0D94)
#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB \
(RX_START_OFFSET + 0x0D98)
#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB \
(RX_START_OFFSET + 0x0D9C)
#define BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO (RX_START_OFFSET + 0x0DA0)
#define BOLERO_CDC_RX_DSD0_PATH_CTL (RX_START_OFFSET + 0x0F00)
#define BOLERO_CDC_RX_DSD0_CFG0 (RX_START_OFFSET + 0x0F04)
#define BOLERO_CDC_RX_DSD0_CFG1 (RX_START_OFFSET + 0x0F08)
#define BOLERO_CDC_RX_DSD0_CFG2 (RX_START_OFFSET + 0x0F0C)
#define BOLERO_CDC_RX_DSD1_PATH_CTL (RX_START_OFFSET + 0x0F80)
#define BOLERO_CDC_RX_DSD1_CFG0 (RX_START_OFFSET + 0x0F84)
#define BOLERO_CDC_RX_DSD1_CFG1 (RX_START_OFFSET + 0x0F88)
#define BOLERO_CDC_RX_DSD1_CFG2 (RX_START_OFFSET + 0x0F8C)
#define RX_MAX_OFFSET (RX_START_OFFSET + 0x0F8C)
#define BOLERO_CDC_RX_MACRO_MAX 0x3E4 /* F8C/4 = 3E3 + 1 */
/* WSA - macro#2 */
#define WSA_START_OFFSET 0x2000
#define BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL \
(WSA_START_OFFSET + 0x0000)
#define BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL \
(WSA_START_OFFSET + 0x0004)
#define BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL (WSA_START_OFFSET + 0x0008)
#define BOLERO_CDC_WSA_TOP_TOP_CFG0 (WSA_START_OFFSET + 0x0080)
#define BOLERO_CDC_WSA_TOP_TOP_CFG1 (WSA_START_OFFSET + 0x0084)
#define BOLERO_CDC_WSA_TOP_FREQ_MCLK (WSA_START_OFFSET + 0x0088)
#define BOLERO_CDC_WSA_TOP_DEBUG_BUS_SEL (WSA_START_OFFSET + 0x008C)
#define BOLERO_CDC_WSA_TOP_DEBUG_EN0 (WSA_START_OFFSET + 0x0090)
#define BOLERO_CDC_WSA_TOP_DEBUG_EN1 (WSA_START_OFFSET + 0x0094)
#define BOLERO_CDC_WSA_TOP_DEBUG_DSM_LB (WSA_START_OFFSET + 0x0098)
#define BOLERO_CDC_WSA_TOP_RX_I2S_CTL (WSA_START_OFFSET + 0x009C)
#define BOLERO_CDC_WSA_TOP_TX_I2S_CTL (WSA_START_OFFSET + 0x00A0)
#define BOLERO_CDC_WSA_TOP_I2S_CLK (WSA_START_OFFSET + 0x00A4)
#define BOLERO_CDC_WSA_TOP_I2S_RESET (WSA_START_OFFSET + 0x00A8)
#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0 (WSA_START_OFFSET + 0x0100)
#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1 (WSA_START_OFFSET + 0x0104)
#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0 (WSA_START_OFFSET + 0x0108)
#define BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1 (WSA_START_OFFSET + 0x010C)
#define BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0 (WSA_START_OFFSET + 0x0110)
#define BOLERO_CDC_WSA_RX_INP_MUX_RX_EC_CFG0 (WSA_START_OFFSET + 0x0114)
#define BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0 (WSA_START_OFFSET + 0x0118)
/* VBAT registers */
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL (WSA_START_OFFSET + 0x0180)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG (WSA_START_OFFSET + 0x0184)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1 (WSA_START_OFFSET + 0x0188)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2 (WSA_START_OFFSET + 0x018C)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3 (WSA_START_OFFSET + 0x0190)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST1 (WSA_START_OFFSET + 0x0194)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST2 (WSA_START_OFFSET + 0x0198)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST3 (WSA_START_OFFSET + 0x019C)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1 (WSA_START_OFFSET + 0x01A0)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2 (WSA_START_OFFSET + 0x01A4)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC1 (WSA_START_OFFSET + 0x01A8)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC2 (WSA_START_OFFSET + 0x01AC)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC3 (WSA_START_OFFSET + 0x01B0)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC4 (WSA_START_OFFSET + 0x01B4)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1 (WSA_START_OFFSET + 0x01B8)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2 (WSA_START_OFFSET + 0x01BC)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3 (WSA_START_OFFSET + 0x01C0)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4 (WSA_START_OFFSET + 0x01C4)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5 (WSA_START_OFFSET + 0x01C8)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DEBUG1 (WSA_START_OFFSET + 0x01CC)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON \
(WSA_START_OFFSET + 0x01D0)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL \
(WSA_START_OFFSET + 0x01D4)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BAN (WSA_START_OFFSET + 0x01D8)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1 \
(WSA_START_OFFSET + 0x01DC)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2 \
(WSA_START_OFFSET + 0x01E0)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3 \
(WSA_START_OFFSET + 0x01E4)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4 \
(WSA_START_OFFSET + 0x01E8)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5 \
(WSA_START_OFFSET + 0x01EC)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6 \
(WSA_START_OFFSET + 0x01F0)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7 \
(WSA_START_OFFSET + 0x01F4)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8 \
(WSA_START_OFFSET + 0x01F8)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9 \
(WSA_START_OFFSET + 0x01FC)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1 (WSA_START_OFFSET + 0x0200)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2 (WSA_START_OFFSET + 0x0204)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3 (WSA_START_OFFSET + 0x0208)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1 \
(WSA_START_OFFSET + 0x020C)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2 \
(WSA_START_OFFSET + 0x0210)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1 \
(WSA_START_OFFSET + 0x0214)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2 \
(WSA_START_OFFSET + 0x0218)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3 \
(WSA_START_OFFSET + 0x021C)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4 \
(WSA_START_OFFSET + 0x0220)
#define BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST (WSA_START_OFFSET + 0x0224)
#define BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x0244)
#define BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x0248)
#define BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x0264)
#define BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x0268)
#define BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x0284)
#define BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x0288)
#define BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL (WSA_START_OFFSET + 0x02A4)
#define BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0 (WSA_START_OFFSET + 0x02A8)
#define BOLERO_CDC_WSA_INTR_CTRL_CFG (WSA_START_OFFSET + 0x0340)
#define BOLERO_CDC_WSA_INTR_CTRL_CLR_COMMIT (WSA_START_OFFSET + 0x0344)
#define BOLERO_CDC_WSA_INTR_CTRL_PIN1_MASK0 (WSA_START_OFFSET + 0x0360)
#define BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0 (WSA_START_OFFSET + 0x0368)
#define BOLERO_CDC_WSA_INTR_CTRL_PIN1_CLEAR0 (WSA_START_OFFSET + 0x0370)
#define BOLERO_CDC_WSA_INTR_CTRL_PIN2_MASK0 (WSA_START_OFFSET + 0x0380)
#define BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0 (WSA_START_OFFSET + 0x0388)
#define BOLERO_CDC_WSA_INTR_CTRL_PIN2_CLEAR0 (WSA_START_OFFSET + 0x0390)
#define BOLERO_CDC_WSA_INTR_CTRL_LEVEL0 (WSA_START_OFFSET + 0x03C0)
#define BOLERO_CDC_WSA_INTR_CTRL_BYPASS0 (WSA_START_OFFSET + 0x03C8)
#define BOLERO_CDC_WSA_INTR_CTRL_SET0 (WSA_START_OFFSET + 0x03D0)
#define BOLERO_CDC_WSA_RX0_RX_PATH_CTL (WSA_START_OFFSET + 0x0400)
#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG0 (WSA_START_OFFSET + 0x0404)
#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG1 (WSA_START_OFFSET + 0x0408)
#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG2 (WSA_START_OFFSET + 0x040C)
#define BOLERO_CDC_WSA_RX0_RX_PATH_CFG3 (WSA_START_OFFSET + 0x0410)
#define BOLERO_CDC_WSA_RX0_RX_VOL_CTL (WSA_START_OFFSET + 0x0414)
#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL (WSA_START_OFFSET + 0x0418)
#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG (WSA_START_OFFSET + 0x041C)
#define BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL (WSA_START_OFFSET + 0x0420)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC0 (WSA_START_OFFSET + 0x0424)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC1 (WSA_START_OFFSET + 0x0428)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC2 (WSA_START_OFFSET + 0x042C)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC3 (WSA_START_OFFSET + 0x0430)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC5 (WSA_START_OFFSET + 0x0438)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC6 (WSA_START_OFFSET + 0x043C)
#define BOLERO_CDC_WSA_RX0_RX_PATH_SEC7 (WSA_START_OFFSET + 0x0440)
#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0 (WSA_START_OFFSET + 0x0444)
#define BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC1 (WSA_START_OFFSET + 0x0448)
#define BOLERO_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL (WSA_START_OFFSET + 0x044C)
#define BOLERO_CDC_WSA_RX1_RX_PATH_CTL (WSA_START_OFFSET + 0x0480)
#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG0 (WSA_START_OFFSET + 0x0484)
#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG1 (WSA_START_OFFSET + 0x0488)
#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG2 (WSA_START_OFFSET + 0x048C)
#define BOLERO_CDC_WSA_RX1_RX_PATH_CFG3 (WSA_START_OFFSET + 0x0490)
#define BOLERO_CDC_WSA_RX1_RX_VOL_CTL (WSA_START_OFFSET + 0x0494)
#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL (WSA_START_OFFSET + 0x0498)
#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG (WSA_START_OFFSET + 0x049C)
#define BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL (WSA_START_OFFSET + 0x04A0)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC0 (WSA_START_OFFSET + 0x04A4)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC1 (WSA_START_OFFSET + 0x04A8)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC2 (WSA_START_OFFSET + 0x04AC)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC3 (WSA_START_OFFSET + 0x04B0)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC5 (WSA_START_OFFSET + 0x04B8)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC6 (WSA_START_OFFSET + 0x04BC)
#define BOLERO_CDC_WSA_RX1_RX_PATH_SEC7 (WSA_START_OFFSET + 0x04C0)
#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0 (WSA_START_OFFSET + 0x04C4)
#define BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC1 (WSA_START_OFFSET + 0x04C8)
#define BOLERO_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL (WSA_START_OFFSET + 0x04CC)
#define BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL (WSA_START_OFFSET + 0x0500)
#define BOLERO_CDC_WSA_BOOST0_BOOST_CTL (WSA_START_OFFSET + 0x0504)
#define BOLERO_CDC_WSA_BOOST0_BOOST_CFG1 (WSA_START_OFFSET + 0x0508)
#define BOLERO_CDC_WSA_BOOST0_BOOST_CFG2 (WSA_START_OFFSET + 0x050C)
#define BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL (WSA_START_OFFSET + 0x0540)
#define BOLERO_CDC_WSA_BOOST1_BOOST_CTL (WSA_START_OFFSET + 0x0544)
#define BOLERO_CDC_WSA_BOOST1_BOOST_CFG1 (WSA_START_OFFSET + 0x0548)
#define BOLERO_CDC_WSA_BOOST1_BOOST_CFG2 (WSA_START_OFFSET + 0x054C)
#define BOLERO_CDC_WSA_COMPANDER0_CTL0 (WSA_START_OFFSET + 0x0580)
#define BOLERO_CDC_WSA_COMPANDER0_CTL1 (WSA_START_OFFSET + 0x0584)
#define BOLERO_CDC_WSA_COMPANDER0_CTL2 (WSA_START_OFFSET + 0x0588)
#define BOLERO_CDC_WSA_COMPANDER0_CTL3 (WSA_START_OFFSET + 0x058C)
#define BOLERO_CDC_WSA_COMPANDER0_CTL4 (WSA_START_OFFSET + 0x0590)
#define BOLERO_CDC_WSA_COMPANDER0_CTL5 (WSA_START_OFFSET + 0x0594)
#define BOLERO_CDC_WSA_COMPANDER0_CTL6 (WSA_START_OFFSET + 0x0598)
#define BOLERO_CDC_WSA_COMPANDER0_CTL7 (WSA_START_OFFSET + 0x059C)
#define BOLERO_CDC_WSA_COMPANDER1_CTL0 (WSA_START_OFFSET + 0x05C0)
#define BOLERO_CDC_WSA_COMPANDER1_CTL1 (WSA_START_OFFSET + 0x05C4)
#define BOLERO_CDC_WSA_COMPANDER1_CTL2 (WSA_START_OFFSET + 0x05C8)
#define BOLERO_CDC_WSA_COMPANDER1_CTL3 (WSA_START_OFFSET + 0x05CC)
#define BOLERO_CDC_WSA_COMPANDER1_CTL4 (WSA_START_OFFSET + 0x05D0)
#define BOLERO_CDC_WSA_COMPANDER1_CTL5 (WSA_START_OFFSET + 0x05D4)
#define BOLERO_CDC_WSA_COMPANDER1_CTL6 (WSA_START_OFFSET + 0x05D8)
#define BOLERO_CDC_WSA_COMPANDER1_CTL7 (WSA_START_OFFSET + 0x05DC)
#define BOLERO_CDC_WSA_SOFTCLIP0_CRC (WSA_START_OFFSET + 0x0600)
#define BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL (WSA_START_OFFSET + 0x0604)
#define BOLERO_CDC_WSA_SOFTCLIP1_CRC (WSA_START_OFFSET + 0x0640)
#define BOLERO_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL (WSA_START_OFFSET + 0x0644)
#define BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL \
(WSA_START_OFFSET + 0x0680)
#define BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0 (WSA_START_OFFSET + 0x0684)
#define BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL \
(WSA_START_OFFSET + 0x06C0)
#define BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0 (WSA_START_OFFSET + 0x06C4)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL (WSA_START_OFFSET + 0x0700)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_CTL0 (WSA_START_OFFSET + 0x0704)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_CTL1 (WSA_START_OFFSET + 0x0708)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_FIFO_CTL (WSA_START_OFFSET + 0x070C)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB \
(WSA_START_OFFSET + 0x0710)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB \
(WSA_START_OFFSET + 0x0714)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB \
(WSA_START_OFFSET + 0x0718)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB \
(WSA_START_OFFSET + 0x071C)
#define BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO (WSA_START_OFFSET + 0x0720)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL (WSA_START_OFFSET + 0x0740)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_CTL0 (WSA_START_OFFSET + 0x0744)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_CTL1 (WSA_START_OFFSET + 0x0748)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_FIFO_CTL (WSA_START_OFFSET + 0x074C)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB \
(WSA_START_OFFSET + 0x0750)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB \
(WSA_START_OFFSET + 0x0754)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB \
(WSA_START_OFFSET + 0x0758)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB \
(WSA_START_OFFSET + 0x075C)
#define BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO (WSA_START_OFFSET + 0x0760)
#define WSA_MAX_OFFSET (WSA_START_OFFSET + 0x0760)
#define BOLERO_CDC_WSA_MACRO_MAX 0x1D9 /* 0x760/4 = 0x1D8 + 1 registers */
/* VA macro registers */
#define VA_START_OFFSET 0x3000
#define BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL (VA_START_OFFSET + 0x0000)
#define BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL \
(VA_START_OFFSET + 0x0004)
#define BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL (VA_START_OFFSET + 0x0008)
#define BOLERO_CDC_VA_TOP_CSR_TOP_CFG0 (VA_START_OFFSET + 0x0080)
#define BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL (VA_START_OFFSET + 0x0084)
#define BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL (VA_START_OFFSET + 0x0088)
#define BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL (VA_START_OFFSET + 0x008C)
#define BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL (VA_START_OFFSET + 0x0090)
#define BOLERO_CDC_VA_TOP_CSR_DMIC_CFG (VA_START_OFFSET + 0x0094)
#define BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS (VA_START_OFFSET + 0x009C)
#define BOLERO_CDC_VA_TOP_CSR_DEBUG_EN (VA_START_OFFSET + 0x00A0)
#define BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL (VA_START_OFFSET + 0x00A4)
#define BOLERO_CDC_VA_TOP_CSR_I2S_CLK (VA_START_OFFSET + 0x00A8)
#define BOLERO_CDC_VA_TOP_CSR_I2S_RESET (VA_START_OFFSET + 0x00AC)
#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_0 (VA_START_OFFSET + 0x00C0)
#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_1 (VA_START_OFFSET + 0x00C4)
#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_2 (VA_START_OFFSET + 0x00C8)
#define BOLERO_CDC_VA_TOP_CSR_CORE_ID_3 (VA_START_OFFSET + 0x00CC)
#define VA_TOP_MAX_OFFSET (VA_START_OFFSET + 0x00CC)
#define BOLERO_CDC_VA_MACRO_TOP_MAX 0x34 /* 0x0CC/4 = 0x33 + 1 = 0x34 */
#define BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0 (VA_START_OFFSET + 0x00D0)
#define BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1 (VA_START_OFFSET + 0x00D4)
#define BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2 (VA_START_OFFSET + 0x00D8)
#define BOLERO_CDC_VA_TOP_CSR_SWR_CTRL (VA_START_OFFSET + 0x00DC)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 (VA_START_OFFSET + 0x0100)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 (VA_START_OFFSET + 0x0104)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0 (VA_START_OFFSET + 0x0108)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1 (VA_START_OFFSET + 0x010C)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0 (VA_START_OFFSET + 0x0110)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1 (VA_START_OFFSET + 0x0114)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0 (VA_START_OFFSET + 0x0118)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1 (VA_START_OFFSET + 0x011C)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0 (VA_START_OFFSET + 0x0120)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1 (VA_START_OFFSET + 0x0124)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0 (VA_START_OFFSET + 0x0128)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1 (VA_START_OFFSET + 0x012C)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0 (VA_START_OFFSET + 0x0130)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1 (VA_START_OFFSET + 0x0134)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0 (VA_START_OFFSET + 0x0138)
#define BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1 (VA_START_OFFSET + 0x013C)
#define BOLERO_CDC_VA_TX0_TX_PATH_CTL (VA_START_OFFSET + 0x0400)
#define BOLERO_CDC_VA_TX0_TX_PATH_CFG0 (VA_START_OFFSET + 0x0404)
#define BOLERO_CDC_VA_TX0_TX_PATH_CFG1 (VA_START_OFFSET + 0x0408)
#define BOLERO_CDC_VA_TX0_TX_VOL_CTL (VA_START_OFFSET + 0x040C)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC0 (VA_START_OFFSET + 0x0410)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC1 (VA_START_OFFSET + 0x0414)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC2 (VA_START_OFFSET + 0x0418)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC3 (VA_START_OFFSET + 0x041C)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC4 (VA_START_OFFSET + 0x0420)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC5 (VA_START_OFFSET + 0x0424)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC6 (VA_START_OFFSET + 0x0428)
#define BOLERO_CDC_VA_TX0_TX_PATH_SEC7 (VA_START_OFFSET + 0x042C)
#define BOLERO_CDC_VA_TX1_TX_PATH_CTL (VA_START_OFFSET + 0x0480)
#define BOLERO_CDC_VA_TX1_TX_PATH_CFG0 (VA_START_OFFSET + 0x0484)
#define BOLERO_CDC_VA_TX1_TX_PATH_CFG1 (VA_START_OFFSET + 0x0488)
#define BOLERO_CDC_VA_TX1_TX_VOL_CTL (VA_START_OFFSET + 0x048C)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC0 (VA_START_OFFSET + 0x0490)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC1 (VA_START_OFFSET + 0x0494)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC2 (VA_START_OFFSET + 0x0498)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC3 (VA_START_OFFSET + 0x049C)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC4 (VA_START_OFFSET + 0x04A0)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC5 (VA_START_OFFSET + 0x04A4)
#define BOLERO_CDC_VA_TX1_TX_PATH_SEC6 (VA_START_OFFSET + 0x04A8)
#define BOLERO_CDC_VA_TX2_TX_PATH_CTL (VA_START_OFFSET + 0x0500)
#define BOLERO_CDC_VA_TX2_TX_PATH_CFG0 (VA_START_OFFSET + 0x0504)
#define BOLERO_CDC_VA_TX2_TX_PATH_CFG1 (VA_START_OFFSET + 0x0508)
#define BOLERO_CDC_VA_TX2_TX_VOL_CTL (VA_START_OFFSET + 0x050C)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC0 (VA_START_OFFSET + 0x0510)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC1 (VA_START_OFFSET + 0x0514)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC2 (VA_START_OFFSET + 0x0518)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC3 (VA_START_OFFSET + 0x051C)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC4 (VA_START_OFFSET + 0x0520)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC5 (VA_START_OFFSET + 0x0524)
#define BOLERO_CDC_VA_TX2_TX_PATH_SEC6 (VA_START_OFFSET + 0x0528)
#define BOLERO_CDC_VA_TX3_TX_PATH_CTL (VA_START_OFFSET + 0x0580)
#define BOLERO_CDC_VA_TX3_TX_PATH_CFG0 (VA_START_OFFSET + 0x0584)
#define BOLERO_CDC_VA_TX3_TX_PATH_CFG1 (VA_START_OFFSET + 0x0588)
#define BOLERO_CDC_VA_TX3_TX_VOL_CTL (VA_START_OFFSET + 0x058C)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC0 (VA_START_OFFSET + 0x0590)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC1 (VA_START_OFFSET + 0x0594)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC2 (VA_START_OFFSET + 0x0598)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC3 (VA_START_OFFSET + 0x059C)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC4 (VA_START_OFFSET + 0x05A0)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC5 (VA_START_OFFSET + 0x05A4)
#define BOLERO_CDC_VA_TX3_TX_PATH_SEC6 (VA_START_OFFSET + 0x05A8)
#define BOLERO_CDC_VA_TX4_TX_PATH_CTL (VA_START_OFFSET + 0x0600)
#define BOLERO_CDC_VA_TX4_TX_PATH_CFG0 (VA_START_OFFSET + 0x0604)
#define BOLERO_CDC_VA_TX4_TX_PATH_CFG1 (VA_START_OFFSET + 0x0608)
#define BOLERO_CDC_VA_TX4_TX_VOL_CTL (VA_START_OFFSET + 0x060C)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC0 (VA_START_OFFSET + 0x0610)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC1 (VA_START_OFFSET + 0x0614)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC2 (VA_START_OFFSET + 0x0618)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC3 (VA_START_OFFSET + 0x061C)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC4 (VA_START_OFFSET + 0x0620)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC5 (VA_START_OFFSET + 0x0624)
#define BOLERO_CDC_VA_TX4_TX_PATH_SEC6 (VA_START_OFFSET + 0x0628)
#define BOLERO_CDC_VA_TX5_TX_PATH_CTL (VA_START_OFFSET + 0x0680)
#define BOLERO_CDC_VA_TX5_TX_PATH_CFG0 (VA_START_OFFSET + 0x0684)
#define BOLERO_CDC_VA_TX5_TX_PATH_CFG1 (VA_START_OFFSET + 0x0688)
#define BOLERO_CDC_VA_TX5_TX_VOL_CTL (VA_START_OFFSET + 0x068C)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC0 (VA_START_OFFSET + 0x0690)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC1 (VA_START_OFFSET + 0x0694)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC2 (VA_START_OFFSET + 0x0698)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC3 (VA_START_OFFSET + 0x069C)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC4 (VA_START_OFFSET + 0x06A0)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC5 (VA_START_OFFSET + 0x06A4)
#define BOLERO_CDC_VA_TX5_TX_PATH_SEC6 (VA_START_OFFSET + 0x06A8)
#define BOLERO_CDC_VA_TX6_TX_PATH_CTL (VA_START_OFFSET + 0x0700)
#define BOLERO_CDC_VA_TX6_TX_PATH_CFG0 (VA_START_OFFSET + 0x0704)
#define BOLERO_CDC_VA_TX6_TX_PATH_CFG1 (VA_START_OFFSET + 0x0708)
#define BOLERO_CDC_VA_TX6_TX_VOL_CTL (VA_START_OFFSET + 0x070C)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC0 (VA_START_OFFSET + 0x0710)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC1 (VA_START_OFFSET + 0x0714)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC2 (VA_START_OFFSET + 0x0718)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC3 (VA_START_OFFSET + 0x071C)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC4 (VA_START_OFFSET + 0x0720)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC5 (VA_START_OFFSET + 0x0724)
#define BOLERO_CDC_VA_TX6_TX_PATH_SEC6 (VA_START_OFFSET + 0x0728)
#define BOLERO_CDC_VA_TX7_TX_PATH_CTL (VA_START_OFFSET + 0x0780)
#define BOLERO_CDC_VA_TX7_TX_PATH_CFG0 (VA_START_OFFSET + 0x0784)
#define BOLERO_CDC_VA_TX7_TX_PATH_CFG1 (VA_START_OFFSET + 0x0788)
#define BOLERO_CDC_VA_TX7_TX_VOL_CTL (VA_START_OFFSET + 0x078C)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC0 (VA_START_OFFSET + 0x0790)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC1 (VA_START_OFFSET + 0x0794)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC2 (VA_START_OFFSET + 0x0798)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC3 (VA_START_OFFSET + 0x079C)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC4 (VA_START_OFFSET + 0x07A0)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC5 (VA_START_OFFSET + 0x07A4)
#define BOLERO_CDC_VA_TX7_TX_PATH_SEC6 (VA_START_OFFSET + 0x07A8)
#define VA_MAX_OFFSET (VA_START_OFFSET + 0x07A8)
#define BOLERO_CDC_VA_MACRO_MAX 0x1EB /* 7A8/4 = 1EA + 1 = 1EB */
#define BOLERO_CDC_MAX_REGISTER VA_MAX_OFFSET
#define BOLERO_REG(reg) (((reg) & 0x0FFF)/4)
#endif

View File

@@ -0,0 +1,871 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
#include "bolero-cdc.h"
#include "internal.h"
static const struct reg_default bolero_defaults[] = {
/* TX Macro */
{ BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL, 0x00 },
{ BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00 },
{ BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_TOP_CFG0, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_ANC_CFG, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_CTRL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_DEBUG_EN, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL, 0x0C},
{ BOLERO_CDC_TX_TOP_CSR_I2S_CLK, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_I2S_RESET, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL, 0x00},
{ BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0, 0x00},
{ BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1, 0x00},
{ BOLERO_CDC_TX_ANC0_CLK_RESET_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_MODE_1_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_MODE_2_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_FF_SHIFT, 0x00},
{ BOLERO_CDC_TX_ANC0_FB_SHIFT, 0x00},
{ BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_LPF_FB_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_SMLPF_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL, 0x00},
{ BOLERO_CDC_TX_ANC0_FB_GAIN_CTL, 0x00},
{ BOLERO_CDC_TX0_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX0_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX0_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX0_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX0_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX0_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX0_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX0_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX0_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX0_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX0_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX0_TX_PATH_SEC7, 0x25},
{ BOLERO_CDC_TX1_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX1_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX1_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX1_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX1_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX1_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX1_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX1_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX1_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX1_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX1_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX2_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX2_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX2_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX2_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX2_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX2_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX2_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX2_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX2_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX2_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX2_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX3_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX3_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX3_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX3_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX3_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX3_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX3_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX3_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX3_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX3_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX3_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX4_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX4_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX4_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX4_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX4_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX4_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX4_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX4_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX4_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX4_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX4_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX5_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX5_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX5_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX5_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX5_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX5_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX5_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX5_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX5_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX5_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX5_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX6_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX6_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX6_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX6_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX6_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX6_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX6_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX6_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX6_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX6_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX6_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_TX7_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_TX7_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_TX7_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_TX7_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_TX7_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_TX7_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_TX7_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_TX7_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_TX7_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_TX7_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_TX7_TX_PATH_SEC6, 0x00},
/* RX Macro */
{ BOLERO_CDC_RX_TOP_TOP_CFG0, 0x00},
{ BOLERO_CDC_RX_TOP_SWR_CTRL, 0x00},
{ BOLERO_CDC_RX_TOP_DEBUG, 0x00},
{ BOLERO_CDC_RX_TOP_DEBUG_BUS, 0x00},
{ BOLERO_CDC_RX_TOP_DEBUG_EN0, 0x00},
{ BOLERO_CDC_RX_TOP_DEBUG_EN1, 0x00},
{ BOLERO_CDC_RX_TOP_DEBUG_EN2, 0x00},
{ BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHL_COMP_LUT, 0x00},
{ BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHR_COMP_LUT, 0x00},
{ BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB, 0x00},
{ BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB, 0x00},
{ BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG0, 0x11},
{ BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG1, 0x20},
{ BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2, 0x00},
{ BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG3, 0x00},
{ BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG0, 0x11},
{ BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG1, 0x20},
{ BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2, 0x00},
{ BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG3, 0x00},
{ BOLERO_CDC_RX_TOP_RX_I2S_CTL, 0x0C},
{ BOLERO_CDC_RX_TOP_TX_I2S2_CTL, 0x0C},
{ BOLERO_CDC_RX_TOP_I2S_CLK, 0x0C},
{ BOLERO_CDC_RX_TOP_I2S_RESET, 0x00},
{ BOLERO_CDC_RX_TOP_I2S_MUX, 0x00},
{ BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
{ BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
{ BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL, 0x00},
{ BOLERO_CDC_RX_CLK_RST_CTRL_DSD_CONTROL, 0x00},
{ BOLERO_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL, 0x08},
{ BOLERO_CDC_RX_SOFTCLIP_CRC, 0x00},
{ BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL, 0x38},
{ BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4, 0x00},
{ BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5, 0x00},
{ BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0, 0x00},
{ BOLERO_CDC_RX_CLSH_CRC, 0x00},
{ BOLERO_CDC_RX_CLSH_DLY_CTRL, 0x03},
{ BOLERO_CDC_RX_CLSH_DECAY_CTRL, 0x02},
{ BOLERO_CDC_RX_CLSH_HPH_V_PA, 0x1C},
{ BOLERO_CDC_RX_CLSH_EAR_V_PA, 0x39},
{ BOLERO_CDC_RX_CLSH_HPH_V_HD, 0x0C},
{ BOLERO_CDC_RX_CLSH_EAR_V_HD, 0x0C},
{ BOLERO_CDC_RX_CLSH_K1_MSB, 0x01},
{ BOLERO_CDC_RX_CLSH_K1_LSB, 0x00},
{ BOLERO_CDC_RX_CLSH_K2_MSB, 0x00},
{ BOLERO_CDC_RX_CLSH_K2_LSB, 0x80},
{ BOLERO_CDC_RX_CLSH_IDLE_CTRL, 0x00},
{ BOLERO_CDC_RX_CLSH_IDLE_HPH, 0x00},
{ BOLERO_CDC_RX_CLSH_IDLE_EAR, 0x00},
{ BOLERO_CDC_RX_CLSH_TEST0, 0x07},
{ BOLERO_CDC_RX_CLSH_TEST1, 0x00},
{ BOLERO_CDC_RX_CLSH_OVR_VREF, 0x00},
{ BOLERO_CDC_RX_CLSH_CLSG_CTL, 0x02},
{ BOLERO_CDC_RX_CLSH_CLSG_CFG1, 0x9A},
{ BOLERO_CDC_RX_CLSH_CLSG_CFG2, 0x10},
{ BOLERO_CDC_RX_BCL_VBAT_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_CFG, 0x10},
{ BOLERO_CDC_RX_BCL_VBAT_ADC_CAL1, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_ADC_CAL2, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_ADC_CAL3, 0x04},
{ BOLERO_CDC_RX_BCL_VBAT_PK_EST1, 0xE0},
{ BOLERO_CDC_RX_BCL_VBAT_PK_EST2, 0x01},
{ BOLERO_CDC_RX_BCL_VBAT_PK_EST3, 0x40},
{ BOLERO_CDC_RX_BCL_VBAT_RF_PROC1, 0x2A},
{ BOLERO_CDC_RX_BCL_VBAT_RF_PROC1, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_TAC1, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_TAC2, 0x18},
{ BOLERO_CDC_RX_BCL_VBAT_TAC3, 0x18},
{ BOLERO_CDC_RX_BCL_VBAT_TAC4, 0x03},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD1, 0x01},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD2, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD3, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD4, 0x64},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD5, 0x01},
{ BOLERO_CDC_RX_BCL_VBAT_DEBUG1, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD_MON, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_BAN, 0x0C},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2, 0x77},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3, 0x01},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5, 0x4B},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7, 0x01},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_ATTN1, 0x04},
{ BOLERO_CDC_RX_BCL_VBAT_ATTN2, 0x08},
{ BOLERO_CDC_RX_BCL_VBAT_ATTN3, 0x0C},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1, 0xE0},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL2, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG4, 0x00},
{ BOLERO_CDC_RX_BCL_VBAT_DECODE_ST, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_CFG, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_CLR_COMMIT, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_PIN1_MASK0, 0xFF},
{ BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_PIN1_CLEAR0, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_PIN2_MASK0, 0xFF},
{ BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_PIN2_CLEAR0, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_LEVEL0, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_BYPASS0, 0x00},
{ BOLERO_CDC_RX_INTR_CTRL_SET0, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_CTL, 0x04},
{ BOLERO_CDC_RX_RX0_RX_PATH_CFG0, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_CFG1, 0x64},
{ BOLERO_CDC_RX_RX0_RX_PATH_CFG2, 0x8F},
{ BOLERO_CDC_RX_RX0_RX_PATH_CFG3, 0x00},
{ BOLERO_CDC_RX_RX0_RX_VOL_CTL, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL, 0x04},
{ BOLERO_CDC_RX_RX0_RX_PATH_MIX_CFG, 0x7E},
{ BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_SEC1, 0x08},
{ BOLERO_CDC_RX_RX0_RX_PATH_SEC2, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_SEC3, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_SEC4, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_SEC7, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC0, 0x08},
{ BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC1, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL, 0x08},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA1, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA2, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA3, 0x00},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA4, 0x55},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA5, 0x55},
{ BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA6, 0x55},
{ BOLERO_CDC_RX_RX1_RX_PATH_CTL, 0x04},
{ BOLERO_CDC_RX_RX1_RX_PATH_CFG0, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_CFG1, 0x64},
{ BOLERO_CDC_RX_RX1_RX_PATH_CFG2, 0x8F},
{ BOLERO_CDC_RX_RX1_RX_PATH_CFG3, 0x00},
{ BOLERO_CDC_RX_RX1_RX_VOL_CTL, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_MIX_CTL, 0x04},
{ BOLERO_CDC_RX_RX1_RX_PATH_MIX_CFG, 0x7E},
{ BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_SEC1, 0x08},
{ BOLERO_CDC_RX_RX1_RX_PATH_SEC2, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_SEC3, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_SEC4, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_SEC7, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC0, 0x08},
{ BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC1, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL, 0x08},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA1, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA2, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA3, 0x00},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA4, 0x55},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA5, 0x55},
{ BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA6, 0x55},
{ BOLERO_CDC_RX_RX2_RX_PATH_CTL, 0x04},
{ BOLERO_CDC_RX_RX2_RX_PATH_CFG0, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_CFG1, 0x64},
{ BOLERO_CDC_RX_RX2_RX_PATH_CFG2, 0x8F},
{ BOLERO_CDC_RX_RX2_RX_PATH_CFG3, 0x00},
{ BOLERO_CDC_RX_RX2_RX_VOL_CTL, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_MIX_CTL, 0x04},
{ BOLERO_CDC_RX_RX2_RX_PATH_MIX_CFG, 0x7E},
{ BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC0, 0x04},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC1, 0x08},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC2, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC3, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC4, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC5, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC6, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_SEC7, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC0, 0x08},
{ BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC1, 0x00},
{ BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL, 0x00},
{ BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_IDLE_DETECT_CFG0, 0x07},
{ BOLERO_CDC_RX_IDLE_DETECT_CFG1, 0x3C},
{ BOLERO_CDC_RX_IDLE_DETECT_CFG2, 0x00},
{ BOLERO_CDC_RX_IDLE_DETECT_CFG3, 0x00},
{ BOLERO_CDC_RX_COMPANDER0_CTL0, 0x60},
{ BOLERO_CDC_RX_COMPANDER0_CTL1, 0xDB},
{ BOLERO_CDC_RX_COMPANDER0_CTL2, 0xFF},
{ BOLERO_CDC_RX_COMPANDER0_CTL3, 0x35},
{ BOLERO_CDC_RX_COMPANDER0_CTL4, 0xFF},
{ BOLERO_CDC_RX_COMPANDER0_CTL5, 0x00},
{ BOLERO_CDC_RX_COMPANDER0_CTL6, 0x01},
{ BOLERO_CDC_RX_COMPANDER0_CTL7, 0x28},
{ BOLERO_CDC_RX_COMPANDER1_CTL0, 0x60},
{ BOLERO_CDC_RX_COMPANDER1_CTL1, 0xDB},
{ BOLERO_CDC_RX_COMPANDER1_CTL2, 0xFF},
{ BOLERO_CDC_RX_COMPANDER1_CTL3, 0x35},
{ BOLERO_CDC_RX_COMPANDER1_CTL4, 0xFF},
{ BOLERO_CDC_RX_COMPANDER1_CTL5, 0x00},
{ BOLERO_CDC_RX_COMPANDER1_CTL6, 0x01},
{ BOLERO_CDC_RX_COMPANDER1_CTL7, 0x28},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL, 0x40},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_CTL, 0x40},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL, 0x00},
{ BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2, 0x00},
{ BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3, 0x00},
{ BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL, 0x04},
{ BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1, 0x00},
{ BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL, 0x04},
{ BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1, 0x00},
{ BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0, 0x01},
{ BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0, 0x01},
{ BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0, 0x01},
{ BOLERO_CDC_RX_EC_ASRC0_CLK_RST_CTL, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_CTL0, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_CTL1, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_FIFO_CTL, 0xA8},
{ BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_CLK_RST_CTL, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_CTL0, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_CTL1, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_FIFO_CTL, 0xA8},
{ BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_CLK_RST_CTL, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_CTL0, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_CTL1, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_FIFO_CTL, 0xA8},
{ BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB, 0x00},
{ BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO, 0x00},
{ BOLERO_CDC_RX_DSD0_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_DSD0_CFG0, 0x00},
{ BOLERO_CDC_RX_DSD0_CFG1, 0x62},
{ BOLERO_CDC_RX_DSD0_CFG2, 0x96},
{ BOLERO_CDC_RX_DSD1_PATH_CTL, 0x00},
{ BOLERO_CDC_RX_DSD1_CFG0, 0x00},
{ BOLERO_CDC_RX_DSD1_CFG1, 0x62},
{ BOLERO_CDC_RX_DSD1_CFG2, 0x96},
/* WSA Macro */
{ BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
{ BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
{ BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
{ BOLERO_CDC_WSA_TOP_TOP_CFG0, 0x00},
{ BOLERO_CDC_WSA_TOP_TOP_CFG1, 0x00},
{ BOLERO_CDC_WSA_TOP_FREQ_MCLK, 0x00},
{ BOLERO_CDC_WSA_TOP_DEBUG_BUS_SEL, 0x00},
{ BOLERO_CDC_WSA_TOP_DEBUG_EN0, 0x00},
{ BOLERO_CDC_WSA_TOP_DEBUG_EN1, 0x00},
{ BOLERO_CDC_WSA_TOP_DEBUG_DSM_LB, 0x88},
{ BOLERO_CDC_WSA_TOP_RX_I2S_CTL, 0x0C},
{ BOLERO_CDC_WSA_TOP_TX_I2S_CTL, 0x0C},
{ BOLERO_CDC_WSA_TOP_I2S_CLK, 0x02},
{ BOLERO_CDC_WSA_TOP_I2S_RESET, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_RX_EC_CFG0, 0x00},
{ BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG, 0x10},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3, 0x04},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST1, 0xE0},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST2, 0x01},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST3, 0x40},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1, 0x2A},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC1, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC2, 0x18},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC3, 0x18},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC4, 0x03},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1, 0x01},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4, 0x64},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5, 0x01},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DEBUG1, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BAN, 0x0C},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2, 0x77},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3, 0x01},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5, 0x4B},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7, 0x01},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1, 0x04},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2, 0x08},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3, 0x0C},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1, 0xE0},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4, 0x00},
{ BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST, 0x00},
{ BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL, 0x02},
{ BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0, 0x00},
{ BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL, 0x02},
{ BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0, 0x00},
{ BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL, 0x02},
{ BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0, 0x00},
{ BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL, 0x02},
{ BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_CFG, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_CLR_COMMIT, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_PIN1_MASK0, 0xFF},
{ BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_PIN1_CLEAR0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_PIN2_MASK0, 0xFF},
{ BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_PIN2_CLEAR0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_LEVEL0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_BYPASS0, 0x00},
{ BOLERO_CDC_WSA_INTR_CTRL_SET0, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_CTL, 0x04},
{ BOLERO_CDC_WSA_RX0_RX_PATH_CFG0, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_CFG1, 0x64},
{ BOLERO_CDC_WSA_RX0_RX_PATH_CFG2, 0x8F},
{ BOLERO_CDC_WSA_RX0_RX_PATH_CFG3, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_VOL_CTL, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL, 0x04},
{ BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG, 0x7E},
{ BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC0, 0x04},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC1, 0x08},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC2, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC3, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC5, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC6, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_SEC7, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0, 0x08},
{ BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC1, 0x00},
{ BOLERO_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_CFG0, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_CFG1, 0x64},
{ BOLERO_CDC_WSA_RX1_RX_PATH_CFG2, 0x8F},
{ BOLERO_CDC_WSA_RX1_RX_PATH_CFG3, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_VOL_CTL, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL, 0x04},
{ BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG, 0x7E},
{ BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC0, 0x04},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC1, 0x08},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC2, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC3, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC5, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC6, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_SEC7, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0, 0x08},
{ BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC1, 0x00},
{ BOLERO_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL, 0x00},
{ BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL, 0x00},
{ BOLERO_CDC_WSA_BOOST0_BOOST_CTL, 0xD0},
{ BOLERO_CDC_WSA_BOOST0_BOOST_CFG1, 0x89},
{ BOLERO_CDC_WSA_BOOST0_BOOST_CFG2, 0x04},
{ BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL, 0x00},
{ BOLERO_CDC_WSA_BOOST1_BOOST_CTL, 0xD0},
{ BOLERO_CDC_WSA_BOOST1_BOOST_CFG1, 0x89},
{ BOLERO_CDC_WSA_BOOST1_BOOST_CFG2, 0x04},
{ BOLERO_CDC_WSA_COMPANDER0_CTL0, 0x60},
{ BOLERO_CDC_WSA_COMPANDER0_CTL1, 0xDB},
{ BOLERO_CDC_WSA_COMPANDER0_CTL2, 0xFF},
{ BOLERO_CDC_WSA_COMPANDER0_CTL3, 0x35},
{ BOLERO_CDC_WSA_COMPANDER0_CTL4, 0xFF},
{ BOLERO_CDC_WSA_COMPANDER0_CTL5, 0x00},
{ BOLERO_CDC_WSA_COMPANDER0_CTL6, 0x01},
{ BOLERO_CDC_WSA_COMPANDER0_CTL7, 0x28},
{ BOLERO_CDC_WSA_COMPANDER1_CTL0, 0x60},
{ BOLERO_CDC_WSA_COMPANDER1_CTL1, 0xDB},
{ BOLERO_CDC_WSA_COMPANDER1_CTL2, 0xFF},
{ BOLERO_CDC_WSA_COMPANDER1_CTL3, 0x35},
{ BOLERO_CDC_WSA_COMPANDER1_CTL4, 0xFF},
{ BOLERO_CDC_WSA_COMPANDER1_CTL5, 0x00},
{ BOLERO_CDC_WSA_COMPANDER1_CTL6, 0x01},
{ BOLERO_CDC_WSA_COMPANDER1_CTL7, 0x28},
{ BOLERO_CDC_WSA_SOFTCLIP0_CRC, 0x00},
{ BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL, 0x38},
{ BOLERO_CDC_WSA_SOFTCLIP1_CRC, 0x00},
{ BOLERO_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL, 0x38},
{ BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL, 0x00},
{ BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0, 0x01},
{ BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL, 0x00},
{ BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0, 0x01},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_CTL0, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_CTL1, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_FIFO_CTL, 0xA8},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_CTL0, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_CTL1, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_FIFO_CTL, 0xA8},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB, 0x00},
{ BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO, 0x00},
/* VA macro */
{ BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
{ BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
{ BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC_CFG, 0x80},
{ BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DEBUG_EN, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL, 0x0C},
{ BOLERO_CDC_VA_TOP_CSR_I2S_CLK, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_I2S_RESET, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_CORE_ID_0, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_CORE_ID_1, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_CORE_ID_2, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_CORE_ID_3, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0, 0xEE},
{ BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1, 0xEE},
{ BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2, 0xEE},
{ BOLERO_CDC_VA_TOP_CSR_SWR_CTRL, 0x06},
/* VA core */
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0, 0x00},
{ BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1, 0x00},
{ BOLERO_CDC_VA_TX0_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX0_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX0_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX0_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX0_TX_PATH_SEC7, 0x25},
{ BOLERO_CDC_VA_TX1_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX1_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX1_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX1_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX1_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX2_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX2_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX2_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX2_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX2_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX3_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX3_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX3_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX3_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX3_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX4_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX4_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX4_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX4_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX4_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX5_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX5_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX5_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX5_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX5_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX6_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX6_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX6_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX6_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX6_TX_PATH_SEC6, 0x00},
{ BOLERO_CDC_VA_TX7_TX_PATH_CTL, 0x04},
{ BOLERO_CDC_VA_TX7_TX_PATH_CFG0, 0x10},
{ BOLERO_CDC_VA_TX7_TX_PATH_CFG1, 0x0B},
{ BOLERO_CDC_VA_TX7_TX_VOL_CTL, 0x00},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC0, 0x00},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC1, 0x00},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC2, 0x01},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC3, 0x3C},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC4, 0x20},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC5, 0x00},
{ BOLERO_CDC_VA_TX7_TX_PATH_SEC6, 0x00},
};
static bool bolero_is_readable_register(struct device *dev,
unsigned int reg)
{
struct bolero_priv *priv = dev_get_drvdata(dev);
u16 reg_offset;
int macro_id;
u8 *reg_tbl = NULL;
if (!priv)
return false;
macro_id = bolero_get_macro_id(priv->va_without_decimation,
reg);
if (macro_id < 0 || !priv->macros_supported[macro_id])
return false;
reg_tbl = bolero_reg_access[macro_id];
reg_offset = (reg - macro_id_base_offset[macro_id])/4;
if (reg_tbl)
return (reg_tbl[reg_offset] & RD_REG);
return false;
}
static bool bolero_is_writeable_register(struct device *dev,
unsigned int reg)
{
struct bolero_priv *priv = dev_get_drvdata(dev);
u16 reg_offset;
int macro_id;
const u8 *reg_tbl = NULL;
if (!priv)
return false;
macro_id = bolero_get_macro_id(priv->va_without_decimation,
reg);
if (macro_id < 0 || !priv->macros_supported[macro_id])
return false;
reg_tbl = bolero_reg_access[macro_id];
reg_offset = (reg - macro_id_base_offset[macro_id])/4;
if (reg_tbl)
return (reg_tbl[reg_offset] & WR_REG);
return false;
}
static bool bolero_is_volatile_register(struct device *dev,
unsigned int reg)
{
/* Update volatile list for rx/tx macros */
switch (reg) {
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_0:
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_1:
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_2:
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_3:
case BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL:
case BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL:
case BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL:
case BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL:
case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL:
case BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL:
case BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST:
case BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0:
case BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0:
case BOLERO_CDC_WSA_COMPANDER0_CTL6:
case BOLERO_CDC_WSA_COMPANDER1_CTL6:
case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB:
case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB:
case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB:
case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB:
case BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO:
case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB:
case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB:
case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB:
case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB:
case BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO:
case BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB:
case BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB:
case BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB:
case BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB:
case BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB:
case BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB:
case BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB:
case BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB:
case BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2:
case BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2:
case BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL:
case BOLERO_CDC_RX_BCL_VBAT_DECODE_ST:
case BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0:
case BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0:
case BOLERO_CDC_RX_COMPANDER0_CTL6:
case BOLERO_CDC_RX_COMPANDER1_CTL6:
case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB:
case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB:
case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB:
case BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB:
case BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO:
case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB:
case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB:
case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB:
case BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB:
case BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO:
case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB:
case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB:
case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB:
case BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB:
case BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO:
return true;
}
return false;
}
const struct regmap_config bolero_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.reg_stride = 4,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = bolero_defaults,
.num_reg_defaults = ARRAY_SIZE(bolero_defaults),
.max_register = BOLERO_CDC_MAX_REGISTER,
.writeable_reg = bolero_is_writeable_register,
.volatile_reg = bolero_is_volatile_register,
.readable_reg = bolero_is_readable_register,
};

View File

@@ -0,0 +1,978 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*/
#include <linux/types.h>
#include "bolero-cdc.h"
#include "internal.h"
u8 bolero_tx_reg_access[BOLERO_CDC_TX_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_ANC_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_CLK_RESET_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_SHIFT)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_SHIFT)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FB_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_SMLPF_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_GAIN_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX4_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX5_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX6_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX7_TX_PATH_SEC6)] = RD_WR_REG,
};
u8 bolero_tx_reg_access_v2[BOLERO_CDC_TX_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_ANC_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_TOP_CSR_SWR_AMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_CLK_RESET_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_MODE_2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_SHIFT)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_SHIFT)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_A_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FF_B_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_LPF_FB_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_SMLPF_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_DCFLT_SHIFT_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_ADAPT_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_IIR_COEFF_2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_A_GAIN_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FF_B_GAIN_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_ANC0_FB_GAIN_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX0_TX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX1_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX2_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_TX3_TX_PATH_SEC6)] = RD_WR_REG,
};
u8 bolero_rx_reg_access[BOLERO_CDC_RX_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_RX_TOP_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_SWR_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_EN0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_EN1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DEBUG_EN2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_WR_LSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_WR_MSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_LUT)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_RD_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHL_COMP_RD_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_WR_LSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_WR_MSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_LUT)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_RD_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_HPHR_COMP_RD_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG2)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD0_DEBUG_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG2)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_DSD1_DEBUG_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_RX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_TX_I2S2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_TOP_I2S_MUX)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_DSD_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLK_RST_CTRL_ASRC_SHARE_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SOFTCLIP_CRC)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SOFTCLIP_SOFTCLIP_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_INT2_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_RX_MIX_CFG5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_CRC)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_DLY_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_DECAY_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_HPH_V_PA)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_EAR_V_PA)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_HPH_V_HD)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_EAR_V_HD)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_K1_MSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_K1_LSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_K2_MSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_K2_LSB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_IDLE_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_IDLE_HPH)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_IDLE_EAR)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_TEST0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_TEST1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_OVR_VREF)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_CLSG_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_CLSG_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_CLSH_CLSG_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ADC_CAL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ADC_CAL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ADC_CAL3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PK_EST1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PK_EST2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_PK_EST3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_RF_PROC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_RF_PROC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_TAC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DEBUG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_UPD_MON)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_GAIN_MON_VAL)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BAN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD8)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_BCL_GAIN_UPD9)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ATTN1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ATTN2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_ATTN3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_CFG4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_BCL_VBAT_DECODE_ST)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_CLR_COMMIT)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN1_MASK0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN1_STATUS0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN1_CLEAR0)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN2_MASK0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN2_STATUS0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_PIN2_CLEAR0)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_LEVEL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_BYPASS0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_INTR_CTRL_SET0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_VOL_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_MIX_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX0_RX_PATH_DSM_DATA6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_VOL_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_MIX_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX1_RX_PATH_DSM_DATA6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_VOL_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_MIX_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_RX2_RX_PATH_DSM_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IDLE_DETECT_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL6)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER0_CTL7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL6)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_COMPANDER1_CTL7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B4_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B5_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B6_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B7_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_B8_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL)] =
RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR0_IIR_COEF_B2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B4_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B5_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B6_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B7_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_B8_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL)] =
RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_IIR1_IIR_COEF_B2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR0_MIX_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_IIR_INP_MUX_IIR1_MIX_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC0_ST_SRC_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_SIDETONE_SRC1_ST_SRC_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ0_EC_REF_HQ_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ1_EC_REF_HQ_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_REF_HQ2_EC_REF_HQ_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_CLK_RST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_FIFO_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMIN_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FMAX_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC0_STATUS_FIFO)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_CLK_RST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_FIFO_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMIN_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FMAX_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC1_STATUS_FIFO)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_CLK_RST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_FIFO_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMIN_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FMAX_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_EC_ASRC2_STATUS_FIFO)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD0_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD0_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD1_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_RX_DSD1_CFG2)] = RD_WR_REG,
};
u8 bolero_va_reg_access[BOLERO_CDC_VA_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX4_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX5_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX6_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX7_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX4_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX5_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX6_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX7_TX_PATH_SEC6)] = RD_WR_REG,
};
u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX] = {
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
};
u8 bolero_va_reg_access_v2[BOLERO_CDC_VA_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG,
};
u8 bolero_va_reg_access_v3[BOLERO_CDC_VA_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_BUS)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DEBUG_EN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_1)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_2)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_CORE_ID_3)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_MIC_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_SWR_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX0_TX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX1_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX2_TX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TX3_TX_PATH_SEC6)] = RD_WR_REG,
};
u8 bolero_wsa_reg_access[BOLERO_CDC_WSA_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_TOP_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_FREQ_MCLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_BUS_SEL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_EN0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_EN1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_DEBUG_DSM_LB)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_RX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_TX_I2S_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_I2S_CLK)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TOP_I2S_RESET)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT0_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_INT1_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_MIX_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_RX_EC_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX_INP_MUX_SOFTCLIP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_ADC_CAL3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_PK_EST3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_RF_PROC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_TAC4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DEBUG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_UPD_MON)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BAN)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD8)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_GAIN_UPD9)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_BCL_ATTN3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_CFG4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX0_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX1_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX2_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_TX3_SPKR_PROT_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_CLR_COMMIT)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN1_MASK0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN1_CLEAR0)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN2_MASK0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN2_STATUS0)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_PIN2_CLEAR0)] = WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_LEVEL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_BYPASS0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_INTR_CTRL_SET0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_VOL_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_MIX_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX0_RX_PATH_DSMDEM_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_CFG3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_VOL_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CFG)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_VOL_MIX_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC6)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_SEC7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_MIX_SEC1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_RX1_RX_PATH_DSMDEM_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST0_BOOST_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_CFG1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_BOOST1_BOOST_CFG2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL6)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER0_CTL7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL2)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL3)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL4)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL5)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL6)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_COMPANDER1_CTL7)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP0_CRC)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP0_SOFTCLIP_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP1_CRC)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SOFTCLIP1_SOFTCLIP_CTRL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_EC_HQ0_EC_REF_HQ_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_PATH_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_EC_HQ1_EC_REF_HQ_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_CLK_RST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_FIFO_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMIN_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FMAX_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC0_STATUS_FIFO)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_CLK_RST_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_CTL0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_CTL1)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_FIFO_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMIN_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_LSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FMAX_CNTR_MSB)] = RD_REG,
[BOLERO_REG(BOLERO_CDC_WSA_SPLINE_ASRC1_STATUS_FIFO)] = RD_REG,
};
u8 *bolero_reg_access[MAX_MACRO] = {
[TX_MACRO] = bolero_tx_reg_access,
[RX_MACRO] = bolero_rx_reg_access,
[WSA_MACRO] = bolero_wsa_reg_access,
[VA_MACRO] = bolero_va_reg_access,
};

View File

@@ -0,0 +1,172 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/regmap.h>
#include "bolero-cdc.h"
#include "internal.h"
#define REG_BYTES 2
#define VAL_BYTES 1
const u16 macro_id_base_offset[MAX_MACRO] = {
TX_START_OFFSET,
RX_START_OFFSET,
WSA_START_OFFSET,
VA_START_OFFSET,
};
int bolero_get_macro_id(bool va_no_dec_flag, u16 reg)
{
if (reg >= TX_START_OFFSET
&& reg <= TX_MAX_OFFSET)
return TX_MACRO;
if (reg >= RX_START_OFFSET
&& reg <= RX_MAX_OFFSET)
return RX_MACRO;
if (reg >= WSA_START_OFFSET
&& reg <= WSA_MAX_OFFSET)
return WSA_MACRO;
if (!va_no_dec_flag &&
(reg >= VA_START_OFFSET &&
reg <= VA_MAX_OFFSET))
return VA_MACRO;
if (va_no_dec_flag &&
(reg >= VA_START_OFFSET &&
reg <= VA_TOP_MAX_OFFSET))
return VA_MACRO;
return -EINVAL;
}
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 bolero_priv *priv = dev_get_drvdata(dev);
u16 *reg_p;
u16 __reg;
int macro_id, i;
u8 temp = 0;
int ret = -EINVAL;
if (!priv) {
dev_err(dev, "%s: priv is NULL\n", __func__);
return ret;
}
if (!reg || !val) {
dev_err(dev, "%s: reg or val is NULL\n", __func__);
return ret;
}
if (reg_size != REG_BYTES) {
dev_err(dev, "%s: register size %zd bytes, not supported\n",
__func__, reg_size);
return ret;
}
reg_p = (u16 *)reg;
macro_id = bolero_get_macro_id(priv->va_without_decimation,
reg_p[0]);
if (macro_id < 0 || !priv->macros_supported[macro_id])
return 0;
mutex_lock(&priv->io_lock);
for (i = 0; i < val_size; i++) {
__reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id];
ret = priv->read_dev(priv, macro_id, __reg, &temp);
if (ret < 0) {
dev_err_ratelimited(dev,
"%s: Codec read failed (%d), reg: 0x%x, size:%zd\n",
__func__, ret, reg_p[0] + i * 4, val_size);
break;
}
((u8 *)val)[i] = temp;
dev_dbg(dev, "%s: Read 0x%02x from reg 0x%x\n",
__func__, temp, reg_p[0] + i * 4);
}
mutex_unlock(&priv->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 bolero_priv *priv = dev_get_drvdata(dev);
u16 *reg_p;
u16 __reg;
int macro_id, i;
int ret = -EINVAL;
if (!priv) {
dev_err(dev, "%s: priv is NULL\n", __func__);
return ret;
}
if (!reg || !val) {
dev_err(dev, "%s: reg or val is NULL\n", __func__);
return ret;
}
if (reg_size != REG_BYTES) {
dev_err(dev, "%s: register size %zd bytes, not supported\n",
__func__, reg_size);
return ret;
}
reg_p = (u16 *)reg;
macro_id = bolero_get_macro_id(priv->va_without_decimation,
reg_p[0]);
if (macro_id < 0 || !priv->macros_supported[macro_id])
return 0;
mutex_lock(&priv->io_lock);
for (i = 0; i < val_size; i++) {
__reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id];
ret = priv->write_dev(priv, macro_id, __reg, ((u8 *)val)[i]);
if (ret < 0) {
dev_err_ratelimited(dev,
"%s: Codec write failed (%d), reg:0x%x, size:%zd\n",
__func__, ret, reg_p[0] + i * 4, val_size);
break;
}
dev_dbg(dev, "Write %02x to reg 0x%x\n", ((u8 *)val)[i],
reg_p[0] + i * 4);
}
mutex_unlock(&priv->io_lock);
return ret;
}
static int regmap_bus_write(void *context, const void *data, size_t count)
{
struct device *dev = context;
struct bolero_priv *priv = dev_get_drvdata(dev);
if (!priv)
return -EINVAL;
if (count < REG_BYTES) {
dev_err(dev, "%s: count %zd bytes < %d, not supported\n",
__func__, count, REG_BYTES);
return -EINVAL;
}
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,
};
struct regmap *bolero_regmap_init(struct device *dev,
const struct regmap_config *config)
{
return devm_regmap_init(dev, &regmap_bus_config, dev, config);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,221 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef BOLERO_CDC_H
#define BOLERO_CDC_H
#include <sound/soc.h>
#include <linux/regmap.h>
#define BOLERO_VERSION_1_0 0x0001
#define BOLERO_VERSION_1_1 0x0002
#define BOLERO_VERSION_1_2 0x0003
#define BOLERO_VERSION_2_0 0x0004
#define BOLERO_VERSION_2_1 0x0005
enum {
START_MACRO,
TX_MACRO = START_MACRO,
RX_MACRO,
WSA_MACRO,
VA_MACRO,
MAX_MACRO
};
enum mclk_mux {
MCLK_MUX0,
MCLK_MUX1,
MCLK_MUX_MAX
};
enum {
BOLERO_ADC0 = 1,
BOLERO_ADC1,
BOLERO_ADC2,
BOLERO_ADC3,
BOLERO_ADC_MAX
};
enum {
CLK_SRC_TX_RCG = 0,
CLK_SRC_VA_RCG,
};
enum {
BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */
BOLERO_MACRO_EVT_SSR_DOWN,
BOLERO_MACRO_EVT_SSR_UP,
BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET,
BOLERO_MACRO_EVT_CLK_RESET,
BOLERO_MACRO_EVT_REG_WAKE_IRQ,
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST,
BOLERO_MACRO_EVT_BCS_CLK_OFF,
BOLERO_MACRO_EVT_SSR_GFMUX_UP,
};
enum {
DMIC_TX = 0,
DMIC_VA = 1,
};
enum {
DMIC0 = 0,
DMIC1,
DMIC2,
DMIC3,
DMIC4,
DMIC5,
DMIC6,
DMIC7,
DMIC_MAX
};
struct macro_ops {
int (*init)(struct snd_soc_codec *codec);
int (*exit)(struct snd_soc_codec *codec);
u16 num_dais;
struct device *dev;
struct snd_soc_dai_driver *dai_ptr;
int (*mclk_fn)(struct device *dev, bool enable);
int (*event_handler)(struct snd_soc_codec *codec, u16 event,
u32 data);
int (*reg_wake_irq)(struct snd_soc_codec *codec, u32 data);
int (*set_port_map)(struct snd_soc_codec *codec, u32 uc,
u32 size, void *data);
int (*clk_div_get)(struct snd_soc_codec *codec);
int (*clk_switch)(struct snd_soc_codec *codec, int clk_src);
int (*reg_evt_listener)(struct snd_soc_codec *codec, bool en);
int (*clk_enable)(struct snd_soc_codec *c, bool en);
char __iomem *io_base;
u16 clk_id_req;
u16 default_clk_id;
};
typedef int (*rsc_clk_cb_t)(struct device *dev, u16 event);
#if IS_ENABLED(CONFIG_SND_SOC_BOLERO)
int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb);
void bolero_unregister_res_clk(struct device *dev);
int bolero_register_macro(struct device *dev, u16 macro_id,
struct macro_ops *ops);
void bolero_unregister_macro(struct device *dev, u16 macro_id);
struct device *bolero_get_device_ptr(struct device *dev, u16 macro_id);
struct device *bolero_get_rsc_clk_device_ptr(struct device *dev);
int bolero_info_create_codec_entry(
struct snd_info_entry *codec_root,
struct snd_soc_codec *codec);
int bolero_register_wake_irq(struct snd_soc_codec *codec, u32 data);
void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n);
int bolero_runtime_resume(struct device *dev);
int bolero_runtime_suspend(struct device *dev);
int bolero_set_port_map(struct snd_soc_codec *codec, u32 size, void *data);
int bolero_tx_clk_switch(struct snd_soc_codec *codec, int clk_src);
int bolero_register_event_listener(struct snd_soc_codec *codec,
bool enable);
void bolero_wsa_pa_on(struct device *dev);
bool bolero_check_core_votes(struct device *dev);
int bolero_tx_mclk_enable(struct snd_soc_codec *c, bool enable);
int bolero_get_version(struct device *dev);
int bolero_dmic_clk_enable(struct snd_soc_codec *codec,
u32 dmic, u32 tx_mode, bool enable);
#else
static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb)
{
return 0;
}
static inline void bolero_unregister_res_clk(struct device *dev)
{
}
static inline int bolero_register_macro(struct device *dev,
u16 macro_id,
struct macro_ops *ops)
{
return 0;
}
static inline void bolero_unregister_macro(struct device *dev, u16 macro_id)
{
}
static inline struct device *bolero_get_device_ptr(struct device *dev,
u16 macro_id)
{
return NULL;
}
static int bolero_info_create_codec_entry(
struct snd_info_entry *codec_root,
struct snd_soc_codec *codec)
{
return 0;
}
static inline void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n)
{
}
static inline int bolero_register_wake_irq(struct snd_soc_codec *codec,
u32 data)
{
return 0;
}
static inline int bolero_runtime_resume(struct device *dev)
{
return 0;
}
static int bolero_runtime_suspend(struct device *dev)
{
return 0;
}
static inline int bolero_set_port_map(struct snd_soc_codec codec,
u32 size, void *data)
{
return 0;
}
static inline int bolero_tx_clk_switch(struct snd_soc_codec *codec,
int clk_src)
{
return 0;
}
static inline int bolero_register_event_listener(
struct snd_soc_codec *codec,
bool enable)
{
return 0;
}
static void bolero_wsa_pa_on(struct device *dev)
{
}
static inline bool bolero_check_core_votes(struct device *dev)
{
return false;
}
static int bolero_get_version(struct device *dev)
{
return 0;
}
static int bolero_dmic_clk_enable(struct snd_soc_codec *codec,
u32 dmic, u32 tx_mode, bool enable)
{
return 0;
}
static int bolero_tx_mclk_enable(struct snd_soc_codec *c, bool enable)
{
return 0;
}
#endif /* CONFIG_SND_SOC_BOLERO */
#endif /* BOLERO_CDC_H */

View File

@@ -0,0 +1,768 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/of_platform.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include "bolero-cdc.h"
#include "bolero-clk-rsc.h"
#define DRV_NAME "bolero-clk-rsc"
#define BOLERO_CLK_NAME_LENGTH 30
#define NPL_CLK_OFFSET (TX_NPL_CLK - TX_CORE_CLK)
static char clk_src_name[MAX_CLK][BOLERO_CLK_NAME_LENGTH] = {
"tx_core_clk",
"rx_core_clk",
"wsa_core_clk",
"va_core_clk",
"tx_npl_clk",
"rx_npl_clk",
"wsa_npl_clk",
"va_npl_clk",
};
struct bolero_clk_rsc {
struct device *dev;
struct mutex rsc_clk_lock;
struct mutex fs_gen_lock;
struct clk *clk[MAX_CLK];
int clk_cnt[MAX_CLK];
int reg_seq_en_cnt;
int va_tx_clk_cnt;
bool dev_up;
bool dev_up_gfmux;
u32 num_fs_reg;
u32 *fs_gen_seq;
int default_clk_id[MAX_CLK];
struct regmap *regmap;
char __iomem *rx_clk_muxsel;
char __iomem *wsa_clk_muxsel;
char __iomem *va_clk_muxsel;
};
static int bolero_clk_rsc_cb(struct device *dev, u16 event)
{
struct bolero_clk_rsc *priv;
if (!dev) {
pr_err("%s: Invalid device pointer\n",
__func__);
return -EINVAL;
}
priv = dev_get_drvdata(dev);
if (!priv) {
pr_err("%s: Invalid clk rsc priviate data\n",
__func__);
return -EINVAL;
}
mutex_lock(&priv->rsc_clk_lock);
if (event == BOLERO_MACRO_EVT_SSR_UP) {
priv->dev_up = true;
} else if (event == BOLERO_MACRO_EVT_SSR_DOWN) {
priv->dev_up = false;
priv->dev_up_gfmux = false;
} else if (event == BOLERO_MACRO_EVT_SSR_GFMUX_UP) {
priv->dev_up_gfmux = true;
}
mutex_unlock(&priv->rsc_clk_lock);
return 0;
}
static char __iomem *bolero_clk_rsc_get_clk_muxsel(struct bolero_clk_rsc *priv,
int clk_id)
{
switch (clk_id) {
case RX_CORE_CLK:
return priv->rx_clk_muxsel;
case WSA_CORE_CLK:
return priv->wsa_clk_muxsel;
case VA_CORE_CLK:
return priv->va_clk_muxsel;
case TX_CORE_CLK:
default:
dev_err_ratelimited(priv->dev, "%s: Invalid case\n", __func__);
break;
}
return NULL;
}
int bolero_rsc_clk_reset(struct device *dev, int clk_id)
{
struct device *clk_dev = NULL;
struct bolero_clk_rsc *priv = NULL;
int count = 0;
if (!dev) {
pr_err("%s: dev is null %d\n", __func__);
return -EINVAL;
}
if (clk_id < 0 || clk_id >= MAX_CLK - NPL_CLK_OFFSET) {
pr_err("%s: Invalid clk_id: %d\n",
__func__, clk_id);
return -EINVAL;
}
clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent);
if (!clk_dev) {
pr_err("%s: Invalid rsc clk device\n", __func__);
return -EINVAL;
}
priv = dev_get_drvdata(clk_dev);
if (!priv) {
pr_err("%s: Invalid rsc clk priviate data\n", __func__);
return -EINVAL;
}
mutex_lock(&priv->rsc_clk_lock);
while (__clk_is_enabled(priv->clk[clk_id])) {
clk_disable_unprepare(priv->clk[clk_id + NPL_CLK_OFFSET]);
clk_disable_unprepare(priv->clk[clk_id]);
count++;
}
dev_dbg(priv->dev,
"%s: clock reset after ssr, count %d\n", __func__, count);
trace_printk("%s: clock reset after ssr, count %d\n", __func__, count);
while (count--) {
clk_prepare_enable(priv->clk[clk_id]);
clk_prepare_enable(priv->clk[clk_id + NPL_CLK_OFFSET]);
}
mutex_unlock(&priv->rsc_clk_lock);
return 0;
}
EXPORT_SYMBOL(bolero_rsc_clk_reset);
void bolero_clk_rsc_enable_all_clocks(struct device *dev, bool enable)
{
struct device *clk_dev = NULL;
struct bolero_clk_rsc *priv = NULL;
int i = 0;
if (!dev) {
pr_err("%s: dev is null %d\n", __func__);
return;
}
clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent);
if (!clk_dev) {
pr_err("%s: Invalid rsc clk device\n", __func__);
return;
}
priv = dev_get_drvdata(clk_dev);
if (!priv) {
pr_err("%s: Invalid rsc clk private data\n", __func__);
return;
}
mutex_lock(&priv->rsc_clk_lock);
for (i = 0; i < MAX_CLK - NPL_CLK_OFFSET; i++) {
if (enable) {
if (priv->clk[i])
clk_prepare_enable(priv->clk[i]);
if (priv->clk[i + NPL_CLK_OFFSET])
clk_prepare_enable(
priv->clk[i + NPL_CLK_OFFSET]);
} else {
if (priv->clk[i + NPL_CLK_OFFSET])
clk_disable_unprepare(
priv->clk[i + NPL_CLK_OFFSET]);
if (priv->clk[i])
clk_disable_unprepare(priv->clk[i]);
}
}
mutex_unlock(&priv->rsc_clk_lock);
return;
}
EXPORT_SYMBOL(bolero_clk_rsc_enable_all_clocks);
static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv,
int clk_id,
bool enable)
{
int ret = 0;
if (enable) {
/* Enable Requested Core clk */
if (priv->clk_cnt[clk_id] == 0) {
ret = clk_prepare_enable(priv->clk[clk_id]);
if (ret < 0) {
dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
__func__, clk_id);
goto done;
}
if (priv->clk[clk_id + NPL_CLK_OFFSET]) {
ret = clk_prepare_enable(
priv->clk[clk_id + NPL_CLK_OFFSET]);
if (ret < 0) {
dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
__func__,
clk_id + NPL_CLK_OFFSET);
goto err;
}
}
}
priv->clk_cnt[clk_id]++;
} else {
if (priv->clk_cnt[clk_id] <= 0) {
dev_err_ratelimited(priv->dev, "%s: clk_id: %d is already disabled\n",
__func__, clk_id);
priv->clk_cnt[clk_id] = 0;
goto done;
}
priv->clk_cnt[clk_id]--;
if (priv->clk_cnt[clk_id] == 0) {
if (priv->clk[clk_id + NPL_CLK_OFFSET])
clk_disable_unprepare(
priv->clk[clk_id + NPL_CLK_OFFSET]);
clk_disable_unprepare(priv->clk[clk_id]);
}
}
return ret;
err:
clk_disable_unprepare(priv->clk[clk_id]);
done:
return ret;
}
static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv,
int clk_id,
bool enable)
{
char __iomem *clk_muxsel = NULL;
int ret = 0;
int default_clk_id = priv->default_clk_id[clk_id];
u32 muxsel = 0;
clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id);
if (!clk_muxsel) {
ret = -EINVAL;
goto done;
}
if (enable) {
if (priv->clk_cnt[clk_id] == 0) {
if (clk_id != VA_CORE_CLK) {
ret = bolero_clk_rsc_mux0_clk_request(priv,
default_clk_id,
true);
if (ret < 0)
goto done;
}
ret = clk_prepare_enable(priv->clk[clk_id]);
if (ret < 0) {
dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
__func__, clk_id);
goto err_clk;
}
if (priv->clk[clk_id + NPL_CLK_OFFSET]) {
ret = clk_prepare_enable(
priv->clk[clk_id + NPL_CLK_OFFSET]);
if (ret < 0) {
dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
__func__,
clk_id + NPL_CLK_OFFSET);
goto err_npl_clk;
}
}
/*
* Temp SW workaround to address a glitch issue of
* VA GFMux instance responsible for switching from
* TX MCLK to VA MCLK. This configuration would be taken
* care in DSP itself
*/
if (clk_id != VA_CORE_CLK) {
if (priv->dev_up_gfmux) {
iowrite32(0x1, clk_muxsel);
muxsel = ioread32(clk_muxsel);
trace_printk("%s: muxsel value after enable: %d\n",
__func__, muxsel);
}
bolero_clk_rsc_mux0_clk_request(priv,
default_clk_id,
false);
}
}
priv->clk_cnt[clk_id]++;
} else {
if (priv->clk_cnt[clk_id] <= 0) {
dev_err_ratelimited(priv->dev, "%s: clk_id: %d is already disabled\n",
__func__, clk_id);
priv->clk_cnt[clk_id] = 0;
goto done;
}
priv->clk_cnt[clk_id]--;
if (priv->clk_cnt[clk_id] == 0) {
if (clk_id != VA_CORE_CLK) {
ret = bolero_clk_rsc_mux0_clk_request(priv,
default_clk_id, true);
if (!ret) {
/*
* Temp SW workaround to address a glitch issue
* of VA GFMux instance responsible for
* switching from TX MCLK to VA MCLK.
* This configuration would be taken
* care in DSP itself.
*/
if (priv->dev_up_gfmux) {
iowrite32(0x0, clk_muxsel);
muxsel = ioread32(clk_muxsel);
trace_printk("%s: muxsel value after disable: %d\n",
__func__, muxsel);
}
}
}
if (priv->clk[clk_id + NPL_CLK_OFFSET])
clk_disable_unprepare(
priv->clk[clk_id + NPL_CLK_OFFSET]);
clk_disable_unprepare(priv->clk[clk_id]);
if (clk_id != VA_CORE_CLK) {
if (!ret)
bolero_clk_rsc_mux0_clk_request(priv,
default_clk_id, false);
}
}
}
return ret;
err_npl_clk:
clk_disable_unprepare(priv->clk[clk_id]);
err_clk:
if (clk_id != VA_CORE_CLK)
bolero_clk_rsc_mux0_clk_request(priv, default_clk_id, false);
done:
return ret;
}
static int bolero_clk_rsc_check_and_update_va_clk(struct bolero_clk_rsc *priv,
bool mux_switch,
int clk_id,
bool enable)
{
int ret = 0;
if (enable) {
if (clk_id == VA_CORE_CLK && mux_switch) {
/*
* Handle the following usecase scenarios during enable
* 1. VA only, Active clk is VA_CORE_CLK
* 2. record -> record + VA, Active clk is TX_CORE_CLK
*/
if (priv->clk_cnt[TX_CORE_CLK] == 0) {
ret = bolero_clk_rsc_mux1_clk_request(priv,
VA_CORE_CLK, enable);
if (ret < 0)
goto err;
} else {
ret = bolero_clk_rsc_mux0_clk_request(priv,
TX_CORE_CLK, enable);
if (ret < 0)
goto err;
priv->va_tx_clk_cnt++;
}
} else if ((priv->clk_cnt[TX_CORE_CLK] > 0) &&
(priv->clk_cnt[VA_CORE_CLK] > 0)) {
/*
* Handle following concurrency scenario during enable
* 1. VA-> Record+VA, Increment TX CLK and Disable VA
* 2. VA-> Playback+VA, Increment TX CLK and Disable VA
*/
while (priv->clk_cnt[VA_CORE_CLK] > 0) {
ret = bolero_clk_rsc_mux0_clk_request(priv,
TX_CORE_CLK, true);
if (ret < 0)
goto err;
bolero_clk_rsc_mux1_clk_request(priv,
VA_CORE_CLK, false);
priv->va_tx_clk_cnt++;
}
}
} else {
if (clk_id == VA_CORE_CLK && mux_switch) {
/*
* Handle the following usecase scenarios during disable
* 1. VA only, disable VA_CORE_CLK
* 2. Record + VA -> Record, decrement TX CLK count
*/
if (priv->clk_cnt[VA_CORE_CLK]) {
bolero_clk_rsc_mux1_clk_request(priv,
VA_CORE_CLK, enable);
} else if (priv->va_tx_clk_cnt) {
bolero_clk_rsc_mux0_clk_request(priv,
TX_CORE_CLK, enable);
priv->va_tx_clk_cnt--;
}
} else if (priv->va_tx_clk_cnt == priv->clk_cnt[TX_CORE_CLK]) {
/*
* Handle the following usecase scenarios during disable
* Record+VA-> VA: enable VA CLK, decrement TX CLK count
*/
while (priv->va_tx_clk_cnt) {
ret = bolero_clk_rsc_mux1_clk_request(priv,
VA_CORE_CLK, true);
if (ret < 0)
goto err;
bolero_clk_rsc_mux0_clk_request(priv,
TX_CORE_CLK, false);
priv->va_tx_clk_cnt--;
}
}
}
err:
return ret;
}
/**
* bolero_clk_rsc_fs_gen_request - request to enable/disable fs generation
* sequence
*
* @dev: Macro device pointer
* @enable: enable or disable flag
*/
void bolero_clk_rsc_fs_gen_request(struct device *dev, bool enable)
{
int i;
struct regmap *regmap;
struct device *clk_dev = NULL;
struct bolero_clk_rsc *priv = NULL;
if (!dev) {
pr_err("%s: dev is null %d\n", __func__);
return;
}
clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent);
if (!clk_dev) {
pr_err("%s: Invalid rsc clk device\n", __func__);
return;
}
priv = dev_get_drvdata(clk_dev);
if (!priv) {
pr_err("%s: Invalid rsc clk priviate data\n", __func__);
return;
}
regmap = dev_get_regmap(priv->dev->parent, NULL);
if (!regmap) {
pr_err("%s: regmap is null\n", __func__);
return;
}
mutex_lock(&priv->fs_gen_lock);
if (enable) {
if (priv->reg_seq_en_cnt++ == 0) {
for (i = 0; i < (priv->num_fs_reg * 2); i += 2) {
dev_dbg(priv->dev, "%s: Register: %d, value: %d\n",
__func__, priv->fs_gen_seq[i],
priv->fs_gen_seq[i + 1]);
regmap_update_bits(regmap,
priv->fs_gen_seq[i],
priv->fs_gen_seq[i + 1],
priv->fs_gen_seq[i + 1]);
}
}
} else {
if (priv->reg_seq_en_cnt <= 0) {
dev_err_ratelimited(priv->dev, "%s: req_seq_cnt: %d is already disabled\n",
__func__, priv->reg_seq_en_cnt);
priv->reg_seq_en_cnt = 0;
mutex_unlock(&priv->fs_gen_lock);
return;
}
if (--priv->reg_seq_en_cnt == 0) {
for (i = ((priv->num_fs_reg - 1) * 2); i >= 0; i -= 2) {
dev_dbg(priv->dev, "%s: Register: %d, value: %d\n",
__func__, priv->fs_gen_seq[i],
priv->fs_gen_seq[i + 1]);
regmap_update_bits(regmap, priv->fs_gen_seq[i],
priv->fs_gen_seq[i + 1], 0x0);
}
}
}
mutex_unlock(&priv->fs_gen_lock);
}
EXPORT_SYMBOL(bolero_clk_rsc_fs_gen_request);
/**
* bolero_clk_rsc_request_clock - request for clock to
* enable/disable
*
* @dev: Macro device pointer.
* @default_clk_id: mux0 Core clock ID input.
* @clk_id_req: Core clock ID requested to enable/disable
* @enable: enable or disable clock flag
*
* Returns 0 on success or -EINVAL on error.
*/
int bolero_clk_rsc_request_clock(struct device *dev,
int default_clk_id,
int clk_id_req,
bool enable)
{
int ret = 0;
struct device *clk_dev = NULL;
struct bolero_clk_rsc *priv = NULL;
bool mux_switch = false;
if (!dev) {
pr_err("%s: dev is null %d\n", __func__);
return -EINVAL;
}
if ((clk_id_req < 0 || clk_id_req >= MAX_CLK) &&
(default_clk_id < 0 || default_clk_id >= MAX_CLK)) {
pr_err("%s: Invalid clk_id_req: %d or default_clk_id: %d\n",
__func__, clk_id_req, default_clk_id);
return -EINVAL;
}
clk_dev = bolero_get_rsc_clk_device_ptr(dev->parent);
if (!clk_dev) {
pr_err("%s: Invalid rsc clk device\n", __func__);
return -EINVAL;
}
priv = dev_get_drvdata(clk_dev);
if (!priv) {
pr_err("%s: Invalid rsc clk priviate data\n", __func__);
return -EINVAL;
}
mutex_lock(&priv->rsc_clk_lock);
if (!priv->dev_up && enable) {
dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n",
__func__);
trace_printk("%s: SSR is in progress..\n", __func__);
ret = -EINVAL;
goto err;
}
priv->default_clk_id[clk_id_req] = default_clk_id;
if (default_clk_id != clk_id_req)
mux_switch = true;
if (mux_switch) {
if (clk_id_req != VA_CORE_CLK) {
ret = bolero_clk_rsc_mux1_clk_request(priv, clk_id_req,
enable);
if (ret < 0)
goto err;
}
} else {
ret = bolero_clk_rsc_mux0_clk_request(priv, clk_id_req, enable);
if (ret < 0)
goto err;
}
ret = bolero_clk_rsc_check_and_update_va_clk(priv, mux_switch,
clk_id_req,
enable);
if (ret < 0)
goto err;
dev_dbg(priv->dev, "%s: clk_cnt: %d for requested clk: %d, enable: %d\n",
__func__, priv->clk_cnt[clk_id_req], clk_id_req,
enable);
trace_printk("%s: clk_cnt: %d for requested clk: %d, enable: %d\n",
__func__, priv->clk_cnt[clk_id_req], clk_id_req,
enable);
mutex_unlock(&priv->rsc_clk_lock);
return 0;
err:
mutex_unlock(&priv->rsc_clk_lock);
return ret;
}
EXPORT_SYMBOL(bolero_clk_rsc_request_clock);
static int bolero_clk_rsc_probe(struct platform_device *pdev)
{
int ret = 0, fs_gen_size, i, j;
const char **clk_name_array;
int clk_cnt;
struct clk *clk;
struct bolero_clk_rsc *priv = NULL;
u32 muxsel = 0;
priv = devm_kzalloc(&pdev->dev, sizeof(struct bolero_clk_rsc),
GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* Get clk fs gen sequence from device tree */
if (!of_find_property(pdev->dev.of_node, "qcom,fs-gen-sequence",
&fs_gen_size)) {
dev_err(&pdev->dev, "%s: unable to find qcom,fs-gen-sequence property\n",
__func__);
ret = -EINVAL;
goto err;
}
priv->num_fs_reg = fs_gen_size/(2 * sizeof(u32));
priv->fs_gen_seq = devm_kzalloc(&pdev->dev, fs_gen_size, GFP_KERNEL);
if (!priv->fs_gen_seq) {
ret = -ENOMEM;
goto err;
}
dev_dbg(&pdev->dev, "%s: num_fs_reg %d\n", __func__, priv->num_fs_reg);
/* Parse fs-gen-sequence */
ret = of_property_read_u32_array(pdev->dev.of_node,
"qcom,fs-gen-sequence",
priv->fs_gen_seq,
priv->num_fs_reg * 2);
if (ret < 0) {
dev_err(&pdev->dev, "%s: unable to parse fs-gen-sequence, ret = %d\n",
__func__, ret);
goto err;
}
/* Get clk details from device tree */
clk_cnt = of_property_count_strings(pdev->dev.of_node, "clock-names");
if (clk_cnt <= 0 || clk_cnt > MAX_CLK) {
dev_err(&pdev->dev, "%s: Invalid number of clocks %d",
__func__, clk_cnt);
ret = -EINVAL;
goto err;
}
clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *),
GFP_KERNEL);
if (!clk_name_array) {
ret = -ENOMEM;
goto err;
}
ret = of_property_read_string_array(pdev->dev.of_node, "clock-names",
clk_name_array, clk_cnt);
for (i = 0; i < MAX_CLK; i++) {
priv->clk[i] = NULL;
for (j = 0; j < clk_cnt; j++) {
if (!strcmp(clk_src_name[i], clk_name_array[j])) {
clk = devm_clk_get(&pdev->dev, clk_src_name[i]);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
dev_err(&pdev->dev, "%s: clk get failed for %s with ret %d\n",
__func__, clk_src_name[i], ret);
goto err;
}
priv->clk[i] = clk;
dev_dbg(&pdev->dev, "%s: clk get success for clk name %s\n",
__func__, clk_src_name[i]);
}
}
}
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,rx_mclk_mode_muxsel", &muxsel);
if (ret) {
dev_dbg(&pdev->dev, "%s: could not find qcom,rx_mclk_mode_muxsel entry in dt\n",
__func__);
} else {
priv->rx_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4);
if (!priv->rx_clk_muxsel) {
dev_err(&pdev->dev, "%s: ioremap failed for rx muxsel\n",
__func__);
return -ENOMEM;
}
}
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,wsa_mclk_mode_muxsel", &muxsel);
if (ret) {
dev_dbg(&pdev->dev, "%s: could not find qcom,wsa_mclk_mode_muxsel entry in dt\n",
__func__);
} else {
priv->wsa_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4);
if (!priv->wsa_clk_muxsel) {
dev_err(&pdev->dev, "%s: ioremap failed for wsa muxsel\n",
__func__);
return -ENOMEM;
}
}
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,va_mclk_mode_muxsel", &muxsel);
if (ret) {
dev_dbg(&pdev->dev, "%s: could not find qcom,va_mclk_mode_muxsel entry in dt\n",
__func__);
} else {
priv->va_clk_muxsel = devm_ioremap(&pdev->dev, muxsel, 0x4);
if (!priv->va_clk_muxsel) {
dev_err(&pdev->dev, "%s: ioremap failed for va muxsel\n",
__func__);
return -ENOMEM;
}
}
ret = bolero_register_res_clk(&pdev->dev, bolero_clk_rsc_cb);
if (ret < 0) {
dev_err(&pdev->dev, "%s: Failed to register cb %d",
__func__, ret);
goto err;
}
priv->dev = &pdev->dev;
priv->dev_up = true;
priv->dev_up_gfmux = true;
mutex_init(&priv->rsc_clk_lock);
mutex_init(&priv->fs_gen_lock);
dev_set_drvdata(&pdev->dev, priv);
err:
return ret;
}
static int bolero_clk_rsc_remove(struct platform_device *pdev)
{
struct bolero_clk_rsc *priv = dev_get_drvdata(&pdev->dev);
bolero_unregister_res_clk(&pdev->dev);
of_platform_depopulate(&pdev->dev);
if (!priv)
return -EINVAL;
mutex_destroy(&priv->rsc_clk_lock);
mutex_destroy(&priv->fs_gen_lock);
return 0;
}
static const struct of_device_id bolero_clk_rsc_dt_match[] = {
{.compatible = "qcom,bolero-clk-rsc-mngr"},
{}
};
MODULE_DEVICE_TABLE(of, bolero_clk_rsc_dt_match);
static struct platform_driver bolero_clk_rsc_mgr = {
.driver = {
.name = "bolero-clk-rsc-mngr",
.owner = THIS_MODULE,
.of_match_table = bolero_clk_rsc_dt_match,
.suppress_bind_attrs = true,
},
.probe = bolero_clk_rsc_probe,
.remove = bolero_clk_rsc_remove,
};
int bolero_clk_rsc_mgr_init(void)
{
return platform_driver_register(&bolero_clk_rsc_mgr);
}
void bolero_clk_rsc_mgr_exit(void)
{
platform_driver_unregister(&bolero_clk_rsc_mgr);
}
MODULE_DESCRIPTION("Bolero clock resource manager driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef BOLERO_CLK_RSC_H
#define BOLERO_CLK_RSC_H
#include <linux/regmap.h>
#include <dt-bindings/sound/qcom,bolero-clk-rsc.h>
#if IS_ENABLED(CONFIG_SND_SOC_BOLERO)
int bolero_clk_rsc_mgr_init(void);
void bolero_clk_rsc_mgr_exit(void);
void bolero_clk_rsc_fs_gen_request(struct device *dev,
bool enable);
int bolero_clk_rsc_request_clock(struct device *dev,
int default_clk_id,
int clk_id_req,
bool enable);
int bolero_rsc_clk_reset(struct device *dev, int clk_id);
void bolero_clk_rsc_enable_all_clocks(struct device *dev, bool enable);
#else
static inline void bolero_clk_rsc_fs_gen_request(struct device *dev,
bool enable)
{
}
static inline int bolero_clk_rsc_mgr_init(void)
{
return 0;
}
static inline void bolero_clk_rsc_mgr_exit(void)
{
}
static inline int bolero_clk_rsc_request_clock(struct device *dev,
int default_clk_id,
int clk_id_req,
bool enable)
{
return 0;
}
static inline int bolero_rsc_clk_reset(struct device *dev, int clk_id)
{
return 0;
}
static inline void bolero_clk_rsc_enable_all_clocks(struct device *dev,
bool enable)
{
return;
}
#endif /* CONFIG_SND_SOC_BOLERO */
#endif /* BOLERO_CLK_RSC_H */

View File

@@ -0,0 +1,107 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _BOLERO_INTERNAL_H
#define _BOLERO_INTERNAL_H
#include "bolero-cdc-registers.h"
#define BOLERO_CDC_CHILD_DEVICES_MAX 6
/* from bolero to WCD events */
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
BOLERO_WCD_EVT_PA_ON_POST_FSCLK,
};
enum {
REG_NO_ACCESS,
RD_REG,
WR_REG,
RD_WR_REG
};
/* from WCD to bolero events */
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
};
struct wcd_ctrl_platform_data {
void *handle;
int (*update_wcd_event)(void *handle, u16 event, u32 data);
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
};
struct bolero_priv {
struct device *dev;
struct snd_soc_codec *codec;
struct regmap *regmap;
struct mutex io_lock;
struct mutex clk_lock;
struct mutex vote_lock;
bool va_without_decimation;
bool macros_supported[MAX_MACRO];
bool dev_up;
bool initial_boot;
struct macro_ops macro_params[MAX_MACRO];
struct snd_soc_dai_driver *bolero_dais;
u16 num_dais;
u16 num_macros_registered;
u16 num_macros;
u16 current_mclk_mux_macro[MAX_MACRO];
struct work_struct bolero_add_child_devices_work;
u32 version;
struct clk *lpass_core_hw_vote;
struct clk *lpass_audio_hw_vote;
int core_hw_vote_count;
int core_audio_vote_count;
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
int (*read_dev)(struct bolero_priv *priv,
u16 macro_id, u16 reg, u8 *val);
int (*write_dev)(struct bolero_priv *priv,
u16 macro_id, u16 reg, u8 val);
struct platform_device *pdev_child_devices
[BOLERO_CDC_CHILD_DEVICES_MAX];
u16 child_count;
struct wcd_ctrl_platform_data plat_data;
struct device *wcd_dev;
struct blocking_notifier_head notifier;
struct device *clk_dev;
rsc_clk_cb_t rsc_clk_cb;
s32 dmic_0_1_clk_cnt;
s32 dmic_2_3_clk_cnt;
s32 dmic_4_5_clk_cnt;
s32 dmic_6_7_clk_cnt;
u8 dmic_0_1_clk_div;
u8 dmic_2_3_clk_div;
u8 dmic_4_5_clk_div;
u8 dmic_6_7_clk_div;
};
struct regmap *bolero_regmap_init(struct device *dev,
const struct regmap_config *config);
int bolero_get_macro_id(bool va_no_dec_flag, u16 reg);
extern const struct regmap_config bolero_regmap_config;
extern u8 *bolero_reg_access[MAX_MACRO];
extern u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX];
extern u8 bolero_va_reg_access_v2[BOLERO_CDC_VA_MACRO_MAX];
extern u8 bolero_va_reg_access_v3[BOLERO_CDC_VA_MACRO_MAX];
extern u8 bolero_tx_reg_access_v2[BOLERO_CDC_TX_MACRO_MAX];
extern const u16 macro_id_base_offset[MAX_MACRO];
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#ifndef WSA_MACRO_H
#define WSA_MACRO_H
/*
* Selects compander and smart boost settings
* for a given speaker mode
*/
enum {
WSA_MACRO_SPKR_MODE_DEFAULT,
WSA_MACRO_SPKR_MODE_1, /* COMP Gain = 12dB, Smartboost Max = 5.5V */
};
/* Rx path gain offsets */
enum {
WSA_MACRO_GAIN_OFFSET_M1P5_DB,
WSA_MACRO_GAIN_OFFSET_0_DB,
};
#if IS_ENABLED(CONFIG_WSA_MACRO)
extern int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode);
extern int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec,
int offset);
#else /* CONFIG_WSA_MACRO */
static inline int wsa_macro_set_spkr_mode(struct snd_soc_codec *codec, int mode)
{
return 0;
}
static inline int wsa_macro_set_spkr_gain_offset(struct snd_soc_codec *codec,
int offset);
{
return 0;
}
#endif /* CONFIG_WSA_MACRO */
#endif

View File

@@ -0,0 +1,484 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2014-2016, The Linux Foundation. All rights reserved.
*/
#ifndef __CPE_CMI_H__
#define __CPE_CMI_H__
#include <linux/types.h>
#define CPE_AFE_PORT_1_TX 1
#define CPE_AFE_PORT_3_TX 3
#define CPE_AFE_PORT_ID_2_OUT 0x02
#define CMI_INBAND_MESSAGE_SIZE 127
/*
* Multiple mad types can be supported at once.
* these values can be OR'ed to form the set of
* supported mad types
*/
#define MAD_TYPE_AUDIO (1 << 0)
#define MAD_TYPE_BEACON (1 << 1)
#define MAD_TYPE_ULTRASND (1 << 2)
/* Core service command opcodes */
#define CPE_CORE_SVC_CMD_SHARED_MEM_ALLOC (0x3001)
#define CPE_CORE_SVC_CMDRSP_SHARED_MEM_ALLOC (0x3002)
#define CPE_CORE_SVC_CMD_SHARED_MEM_DEALLOC (0x3003)
#define CPE_CORE_SVC_CMD_DRAM_ACCESS_REQ (0x3004)
#define CPE_CORE_SVC_EVENT_SYSTEM_BOOT (0x3005)
/* core service command opcodes for WCD9335 */
#define CPE_CORE_SVC_CMD_CFG_CLK_PLAN (0x3006)
#define CPE_CORE_SVC_CMD_CLK_FREQ_REQUEST (0x3007)
#define CPE_BOOT_SUCCESS 0x00
#define CPE_BOOT_FAILED 0x01
#define CPE_CORE_VERSION_SYSTEM_BOOT_EVENT 0x01
/* LSM Service command opcodes */
#define CPE_LSM_SESSION_CMD_OPEN_TX (0x2000)
#define CPE_LSM_SESSION_CMD_SET_PARAMS (0x2001)
#define CPE_LSM_SESSION_CMD_REGISTER_SOUND_MODEL (0x2002)
#define CPE_LSM_SESSION_CMD_DEREGISTER_SOUND_MODEL (0x2003)
#define CPE_LSM_SESSION_CMD_START (0x2004)
#define CPE_LSM_SESSION_CMD_STOP (0x2005)
#define CPE_LSM_SESSION_EVENT_DETECTION_STATUS_V2 (0x2006)
#define CPE_LSM_SESSION_CMD_CLOSE_TX (0x2007)
#define CPE_LSM_SESSION_CMD_SHARED_MEM_ALLOC (0x2008)
#define CPE_LSM_SESSION_CMDRSP_SHARED_MEM_ALLOC (0x2009)
#define CPE_LSM_SESSION_CMD_SHARED_MEM_DEALLOC (0x200A)
#define CPE_LSM_SESSION_CMD_TX_BUFF_OUTPUT_CONFIG (0x200f)
#define CPE_LSM_SESSION_CMD_OPEN_TX_V2 (0x200D)
#define CPE_LSM_SESSION_CMD_SET_PARAMS_V2 (0x200E)
/* LSM Service module and param IDs */
#define CPE_LSM_MODULE_ID_VOICE_WAKEUP (0x00012C00)
#define CPE_LSM_MODULE_ID_VOICE_WAKEUP_V2 (0x00012C0D)
#define CPE_LSM_MODULE_FRAMEWORK (0x00012C0E)
#define CPE_LSM_PARAM_ID_ENDPOINT_DETECT_THRESHOLD (0x00012C01)
#define CPE_LSM_PARAM_ID_OPERATION_MODE (0x00012C02)
#define CPE_LSM_PARAM_ID_GAIN (0x00012C03)
#define CPE_LSM_PARAM_ID_CONNECT_TO_PORT (0x00012C04)
#define CPE_LSM_PARAM_ID_MIN_CONFIDENCE_LEVELS (0x00012C07)
/* LSM LAB command opcodes */
#define CPE_LSM_SESSION_CMD_EOB 0x0000200B
#define CPE_LSM_MODULE_ID_LAB 0x00012C08
/* used for enable/disable lab*/
#define CPE_LSM_PARAM_ID_LAB_ENABLE 0x00012C09
/* used for T in LAB config DSP internal buffer*/
#define CPE_LSM_PARAM_ID_LAB_CONFIG 0x00012C0A
#define CPE_LSM_PARAM_ID_REGISTER_SOUND_MODEL (0x00012C14)
#define CPE_LSM_PARAM_ID_DEREGISTER_SOUND_MODEL (0x00012C15)
#define CPE_LSM_PARAM_ID_MEDIA_FMT (0x00012C1E)
/* AFE Service command opcodes */
#define CPE_AFE_PORT_CMD_START (0x1001)
#define CPE_AFE_PORT_CMD_STOP (0x1002)
#define CPE_AFE_PORT_CMD_SUSPEND (0x1003)
#define CPE_AFE_PORT_CMD_RESUME (0x1004)
#define CPE_AFE_PORT_CMD_SHARED_MEM_ALLOC (0x1005)
#define CPE_AFE_PORT_CMDRSP_SHARED_MEM_ALLOC (0x1006)
#define CPE_AFE_PORT_CMD_SHARED_MEM_DEALLOC (0x1007)
#define CPE_AFE_PORT_CMD_GENERIC_CONFIG (0x1008)
#define CPE_AFE_SVC_CMD_LAB_MODE (0x1009)
/* AFE Service module and param IDs */
#define CPE_AFE_CMD_SET_PARAM (0x1000)
#define CPE_AFE_MODULE_ID_SW_MAD (0x0001022D)
#define CPE_AFE_PARAM_ID_SW_MAD_CFG (0x0001022E)
#define CPE_AFE_PARAM_ID_SVM_MODEL (0x0001022F)
#define CPE_AFE_MODULE_HW_MAD (0x00010230)
#define CPE_AFE_PARAM_ID_HW_MAD_CTL (0x00010232)
#define CPE_AFE_PARAM_ID_HW_MAD_CFG (0x00010231)
#define CPE_AFE_MODULE_AUDIO_DEV_INTERFACE (0x0001020C)
#define CPE_AFE_PARAM_ID_GENERIC_PORT_CONFIG (0x00010253)
#define CPE_CMI_BASIC_RSP_OPCODE (0x0001)
#define CPE_HDR_MAX_PLD_SIZE (0x7F)
#define CMI_OBM_FLAG_IN_BAND 0
#define CMI_OBM_FLAG_OUT_BAND 1
#define CMI_SHMEM_ALLOC_FAILED 0xff
/*
* Future Service ID's can be added one line
* before the CMI_CPE_SERVICE_ID_MAX
*/
enum {
CMI_CPE_SERVICE_ID_MIN = 0,
CMI_CPE_CORE_SERVICE_ID,
CMI_CPE_AFE_SERVICE_ID,
CMI_CPE_LSM_SERVICE_ID,
CMI_CPE_SERVICE_ID_MAX,
};
#define CPE_LSM_SESSION_ID_MAX 2
#define IS_VALID_SESSION_ID(s_id) \
(s_id <= CPE_LSM_SESSION_ID_MAX)
#define IS_VALID_SERVICE_ID(s_id) \
(s_id > CMI_CPE_SERVICE_ID_MIN && \
s_id < CMI_CPE_SERVICE_ID_MAX)
#define IS_VALID_PLD_SIZE(p_size) \
(p_size <= CPE_HDR_MAX_PLD_SIZE)
#define CMI_HDR_SET_OPCODE(hdr, cmd) (hdr->opcode = cmd)
#define CMI_HDR_SET(hdr_info, mask, shift, value) \
(hdr_info = (((hdr_info) & ~(mask)) | \
((value << shift) & mask)))
#define SVC_ID_SHIFT 4
#define SVC_ID_MASK (0x07 << SVC_ID_SHIFT)
#define SESSION_ID_SHIFT 0
#define SESSION_ID_MASK (0x0F << SESSION_ID_SHIFT)
#define PAYLD_SIZE_SHIFT 0
#define PAYLD_SIZE_MASK (0x7F << PAYLD_SIZE_SHIFT)
#define OBM_FLAG_SHIFT 7
#define OBM_FLAG_MASK (1 << OBM_FLAG_SHIFT)
#define VERSION_SHIFT 7
#define VERSION_MASK (1 << VERSION_SHIFT)
#define CMI_HDR_SET_SERVICE(hdr, s_id) \
CMI_HDR_SET(hdr->hdr_info, SVC_ID_MASK,\
SVC_ID_SHIFT, s_id)
#define CMI_HDR_GET_SERVICE(hdr) \
((hdr->hdr_info >> SVC_ID_SHIFT) & \
(SVC_ID_MASK >> SVC_ID_SHIFT))
#define CMI_HDR_SET_SESSION(hdr, s_id) \
CMI_HDR_SET(hdr->hdr_info, SESSION_ID_MASK,\
SESSION_ID_SHIFT, s_id)
#define CMI_HDR_GET_SESSION_ID(hdr) \
((hdr->hdr_info >> SESSION_ID_SHIFT) & \
(SESSION_ID_MASK >> SESSION_ID_SHIFT))
#define CMI_GET_HEADER(msg) ((struct cmi_hdr *)(msg))
#define CMI_GET_PAYLOAD(msg) ((void *)(CMI_GET_HEADER(msg) + 1))
#define CMI_GET_OPCODE(msg) (CMI_GET_HEADER(msg)->opcode)
#define CMI_HDR_SET_VERSION(hdr, ver) \
CMI_HDR_SET(hdr->hdr_info, VERSION_MASK, \
VERSION_SHIFT, ver)
#define CMI_HDR_SET_PAYLOAD_SIZE(hdr, p_size) \
CMI_HDR_SET(hdr->pld_info, PAYLD_SIZE_MASK, \
PAYLD_SIZE_SHIFT, p_size)
#define CMI_HDR_GET_PAYLOAD_SIZE(hdr) \
((hdr->pld_info >> PAYLD_SIZE_SHIFT) & \
(PAYLD_SIZE_MASK >> PAYLD_SIZE_SHIFT))
#define CMI_HDR_SET_OBM(hdr, obm_flag) \
CMI_HDR_SET(hdr->pld_info, OBM_FLAG_MASK, \
OBM_FLAG_SHIFT, obm_flag)
#define CMI_HDR_GET_OBM_FLAG(hdr) \
((hdr->pld_info >> OBM_FLAG_SHIFT) & \
(OBM_FLAG_MASK >> OBM_FLAG_SHIFT))
struct cmi_hdr {
/*
* bits 0:3 is session id
* bits 4:6 is service id
* bit 7 is the version flag
*/
u8 hdr_info;
/*
* bits 0:6 is payload size in case of in-band message
* bits 0:6 is size (OBM message size)
* bit 7 is the OBM flag
*/
u8 pld_info;
/* 16 bit command opcode */
u16 opcode;
} __packed;
union cpe_addr {
u64 msw_lsw;
void *kvaddr;
} __packed;
struct cmi_obm {
u32 version;
u32 size;
union cpe_addr data_ptr;
u32 mem_handle;
} __packed;
struct cmi_obm_msg {
struct cmi_hdr hdr;
struct cmi_obm pld;
} __packed;
struct cmi_core_svc_event_system_boot {
u8 status;
u8 version;
u16 sfr_buff_size;
u32 sfr_buff_address;
} __packed;
struct cmi_core_svc_cmd_shared_mem_alloc {
u32 size;
} __packed;
struct cmi_core_svc_cmdrsp_shared_mem_alloc {
u32 addr;
} __packed;
struct cmi_core_svc_cmd_clk_freq_request {
u32 clk_freq;
} __packed;
struct cmi_msg_transport {
u32 size;
u32 addr;
} __packed;
struct cmi_basic_rsp_result {
u8 status;
} __packed;
struct cpe_lsm_cmd_open_tx {
struct cmi_hdr hdr;
u16 app_id;
u16 reserved;
u32 sampling_rate;
} __packed;
struct cpe_lsm_cmd_open_tx_v2 {
struct cmi_hdr hdr;
u32 topology_id;
} __packed;
struct cpe_cmd_shmem_alloc {
struct cmi_hdr hdr;
u32 size;
} __packed;
struct cpe_cmdrsp_shmem_alloc {
struct cmi_hdr hdr;
u32 addr;
} __packed;
struct cpe_cmd_shmem_dealloc {
struct cmi_hdr hdr;
u32 addr;
} __packed;
struct cpe_lsm_event_detect_v2 {
struct cmi_hdr hdr;
u8 detection_status;
u8 size;
u8 payload[0];
} __packed;
struct cpe_lsm_psize_res {
u16 param_size;
u16 reserved;
} __packed;
union cpe_lsm_param_size {
u32 param_size;
struct cpe_lsm_psize_res sr;
} __packed;
struct cpe_param_data {
u32 module_id;
u32 param_id;
union cpe_lsm_param_size p_size;
} __packed;
struct cpe_lsm_param_epd_thres {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u32 epd_begin;
u32 epd_end;
} __packed;
struct cpe_lsm_param_gain {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u16 gain;
u16 reserved;
} __packed;
struct cpe_afe_hw_mad_ctrl {
struct cpe_param_data param;
u32 minor_version;
u16 mad_type;
u16 mad_enable;
} __packed;
struct cpe_afe_port_cfg {
struct cpe_param_data param;
u32 minor_version;
u16 bit_width;
u16 num_channels;
u32 sample_rate;
} __packed;
struct cpe_afe_cmd_port_cfg {
struct cmi_hdr hdr;
u8 bit_width;
u8 num_channels;
u16 buffer_size;
u32 sample_rate;
} __packed;
struct cpe_afe_params {
struct cmi_hdr hdr;
struct cpe_afe_hw_mad_ctrl hw_mad_ctrl;
struct cpe_afe_port_cfg port_cfg;
} __packed;
struct cpe_afe_svc_cmd_mode {
struct cmi_hdr hdr;
u8 mode;
} __packed;
struct cpe_lsm_param_opmode {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u16 mode;
u16 reserved;
} __packed;
struct cpe_lsm_param_connectport {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u16 afe_port_id;
u16 reserved;
} __packed;
/*
* This cannot be sent to CPE as is,
* need to append the conf_levels dynamically
*/
struct cpe_lsm_conf_level {
struct cmi_hdr hdr;
struct cpe_param_data param;
u8 num_active_models;
} __packed;
struct cpe_lsm_output_format_cfg {
struct cmi_hdr hdr;
u8 format;
u8 packing;
u8 data_path_events;
} __packed;
struct cpe_lsm_lab_enable {
struct cpe_param_data param;
u16 enable;
u16 reserved;
} __packed;
struct cpe_lsm_control_lab {
struct cmi_hdr hdr;
struct cpe_lsm_lab_enable lab_enable;
} __packed;
struct cpe_lsm_lab_config {
struct cpe_param_data param;
u32 minor_ver;
u32 latency;
} __packed;
struct cpe_lsm_lab_latency_config {
struct cmi_hdr hdr;
struct cpe_lsm_lab_config latency_cfg;
} __packed;
struct cpe_lsm_media_fmt_param {
struct cmi_hdr hdr;
struct cpe_param_data param;
u32 minor_version;
u32 sample_rate;
u16 num_channels;
u16 bit_width;
} __packed;
#define CPE_PARAM_LSM_LAB_LATENCY_SIZE (\
sizeof(struct cpe_lsm_lab_latency_config) - \
sizeof(struct cmi_hdr))
#define PARAM_SIZE_LSM_LATENCY_SIZE (\
sizeof(struct cpe_lsm_lab_config) - \
sizeof(struct cpe_param_data))
#define CPE_PARAM_SIZE_LSM_LAB_CONTROL (\
sizeof(struct cpe_lsm_control_lab) - \
sizeof(struct cmi_hdr))
#define PARAM_SIZE_LSM_CONTROL_SIZE (sizeof(struct cpe_lsm_lab_enable) - \
sizeof(struct cpe_param_data))
#define PARAM_SIZE_AFE_HW_MAD_CTRL (sizeof(struct cpe_afe_hw_mad_ctrl) - \
sizeof(struct cpe_param_data))
#define PARAM_SIZE_AFE_PORT_CFG (sizeof(struct cpe_afe_port_cfg) - \
sizeof(struct cpe_param_data))
#define CPE_AFE_PARAM_PAYLOAD_SIZE (sizeof(struct cpe_afe_params) - \
sizeof(struct cmi_hdr))
#define OPEN_CMD_PAYLOAD_SIZE (sizeof(struct cpe_lsm_cmd_open_tx) - \
sizeof(struct cmi_hdr))
#define OPEN_V2_CMD_PAYLOAD_SIZE (sizeof(struct cpe_lsm_cmd_open_tx_v2) - \
sizeof(struct cmi_hdr))
#define SHMEM_ALLOC_CMD_PLD_SIZE (sizeof(struct cpe_cmd_shmem_alloc) - \
sizeof(struct cmi_hdr))
#define SHMEM_DEALLOC_CMD_PLD_SIZE (sizeof(struct cpe_cmd_shmem_dealloc) - \
sizeof(struct cmi_hdr))
#define OUT_FMT_CFG_CMD_PAYLOAD_SIZE ( \
sizeof(struct cpe_lsm_output_format_cfg) - \
sizeof(struct cmi_hdr))
#define CPE_AFE_CMD_PORT_CFG_PAYLOAD_SIZE \
(sizeof(struct cpe_afe_cmd_port_cfg) - \
sizeof(struct cmi_hdr))
#define CPE_AFE_CMD_MODE_PAYLOAD_SIZE \
(sizeof(struct cpe_afe_svc_cmd_mode) - \
sizeof(struct cmi_hdr))
#define CPE_CMD_EPD_THRES_PLD_SIZE (sizeof(struct cpe_lsm_param_epd_thres) - \
sizeof(struct cmi_hdr))
#define CPE_EPD_THRES_PARAM_SIZE ((CPE_CMD_EPD_THRES_PLD_SIZE) - \
sizeof(struct cpe_param_data))
#define CPE_CMD_OPMODE_PLD_SIZE (sizeof(struct cpe_lsm_param_opmode) - \
sizeof(struct cmi_hdr))
#define CPE_OPMODE_PARAM_SIZE ((CPE_CMD_OPMODE_PLD_SIZE) -\
sizeof(struct cpe_param_data))
#define CPE_CMD_CONNECTPORT_PLD_SIZE \
(sizeof(struct cpe_lsm_param_connectport) - \
sizeof(struct cmi_hdr))
#define CPE_CONNECTPORT_PARAM_SIZE ((CPE_CMD_CONNECTPORT_PLD_SIZE) - \
sizeof(struct cpe_param_data))
#define CPE_CMD_GAIN_PLD_SIZE (sizeof(struct cpe_lsm_param_gain) - \
sizeof(struct cmi_hdr))
#define CPE_GAIN_PARAM_SIZE ((CPE_CMD_GAIN_PLD_SIZE) - \
sizeof(struct cpe_param_data))
#define CPE_MEDIA_FMT_PLD_SIZE (sizeof(struct cpe_lsm_media_fmt_param) - \
sizeof(struct cmi_hdr))
#define CPE_MEDIA_FMT_PARAM_SIZE ((CPE_MEDIA_FMT_PLD_SIZE) - \
sizeof(struct cpe_param_data))
#endif /* __CPE_CMI_H__ */

View File

@@ -0,0 +1,158 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015, 2017, The Linux Foundation. All rights reserved.
*/
#ifndef __CPE_ERR__
#define __CPE_ERR__
#include <linux/errno.h>
/* ERROR CODES */
/* Success. The operation completed with no errors. */
#define CPE_EOK 0x00000000
/* General failure. */
#define CPE_EFAILED 0x00000001
/* Bad operation parameter. */
#define CPE_EBADPARAM 0x00000002
/* Unsupported routine or operation. */
#define CPE_EUNSUPPORTED 0x00000003
/* Unsupported version. */
#define CPE_EVERSION 0x00000004
/* Unexpected problem encountered. */
#define CPE_EUNEXPECTED 0x00000005
/* Unhandled problem occurred. */
#define CPE_EPANIC 0x00000006
/* Unable to allocate resource. */
#define CPE_ENORESOURCE 0x00000007
/* Invalid handle. */
#define CPE_EHANDLE 0x00000008
/* Operation is already processed. */
#define CPE_EALREADY 0x00000009
/* Operation is not ready to be processed. */
#define CPE_ENOTREADY 0x0000000A
/* Operation is pending completion. */
#define CPE_EPENDING 0x0000000B
/* Operation could not be accepted or processed. */
#define CPE_EBUSY 0x0000000C
/* Operation aborted due to an error. */
#define CPE_EABORTED 0x0000000D
/* Operation preempted by a higher priority. */
#define CPE_EPREEMPTED 0x0000000E
/* Operation requests intervention to complete. */
#define CPE_ECONTINUE 0x0000000F
/* Operation requests immediate intervention to complete. */
#define CPE_EIMMEDIATE 0x00000010
/* Operation is not implemented. */
#define CPE_ENOTIMPL 0x00000011
/* Operation needs more data or resources. */
#define CPE_ENEEDMORE 0x00000012
/* Operation does not have memory. */
#define CPE_ENOMEMORY 0x00000014
/* Item does not exist. */
#define CPE_ENOTEXIST 0x00000015
/* Operation is finished. */
#define CPE_ETERMINATED 0x00000016
/* Max count for adsp error code sent to HLOS*/
#define CPE_ERR_MAX (CPE_ETERMINATED + 1)
/* ERROR STRING */
/* Success. The operation completed with no errors. */
#define CPE_EOK_STR "CPE_EOK"
/* General failure. */
#define CPE_EFAILED_STR "CPE_EFAILED"
/* Bad operation parameter. */
#define CPE_EBADPARAM_STR "CPE_EBADPARAM"
/* Unsupported routine or operation. */
#define CPE_EUNSUPPORTED_STR "CPE_EUNSUPPORTED"
/* Unsupported version. */
#define CPE_EVERSION_STR "CPE_EVERSION"
/* Unexpected problem encountered. */
#define CPE_EUNEXPECTED_STR "CPE_EUNEXPECTED"
/* Unhandled problem occurred. */
#define CPE_EPANIC_STR "CPE_EPANIC"
/* Unable to allocate resource. */
#define CPE_ENORESOURCE_STR "CPE_ENORESOURCE"
/* Invalid handle. */
#define CPE_EHANDLE_STR "CPE_EHANDLE"
/* Operation is already processed. */
#define CPE_EALREADY_STR "CPE_EALREADY"
/* Operation is not ready to be processed. */
#define CPE_ENOTREADY_STR "CPE_ENOTREADY"
/* Operation is pending completion. */
#define CPE_EPENDING_STR "CPE_EPENDING"
/* Operation could not be accepted or processed. */
#define CPE_EBUSY_STR "CPE_EBUSY"
/* Operation aborted due to an error. */
#define CPE_EABORTED_STR "CPE_EABORTED"
/* Operation preempted by a higher priority. */
#define CPE_EPREEMPTED_STR "CPE_EPREEMPTED"
/* Operation requests intervention to complete. */
#define CPE_ECONTINUE_STR "CPE_ECONTINUE"
/* Operation requests immediate intervention to complete. */
#define CPE_EIMMEDIATE_STR "CPE_EIMMEDIATE"
/* Operation is not implemented. */
#define CPE_ENOTIMPL_STR "CPE_ENOTIMPL"
/* Operation needs more data or resources. */
#define CPE_ENEEDMORE_STR "CPE_ENEEDMORE"
/* Operation does not have memory. */
#define CPE_ENOMEMORY_STR "CPE_ENOMEMORY"
/* Item does not exist. */
#define CPE_ENOTEXIST_STR "CPE_ENOTEXIST"
/* Operation is finished. */
#define CPE_ETERMINATED_STR "CPE_ETERMINATED"
/* Unexpected error code. */
#define CPE_ERR_MAX_STR "CPE_ERR_MAX"
struct cpe_err_code {
int lnx_err_code;
char *cpe_err_str;
};
static struct cpe_err_code cpe_err_code_info[CPE_ERR_MAX+1] = {
{ 0, CPE_EOK_STR},
{ -ENOTRECOVERABLE, CPE_EFAILED_STR},
{ -EINVAL, CPE_EBADPARAM_STR},
{ -EOPNOTSUPP, CPE_EUNSUPPORTED_STR},
{ -ENOPROTOOPT, CPE_EVERSION_STR},
{ -ENOTRECOVERABLE, CPE_EUNEXPECTED_STR},
{ -ENOTRECOVERABLE, CPE_EPANIC_STR},
{ -ENOSPC, CPE_ENORESOURCE_STR},
{ -EBADR, CPE_EHANDLE_STR},
{ -EALREADY, CPE_EALREADY_STR},
{ -EPERM, CPE_ENOTREADY_STR},
{ -EINPROGRESS, CPE_EPENDING_STR},
{ -EBUSY, CPE_EBUSY_STR},
{ -ECANCELED, CPE_EABORTED_STR},
{ -EAGAIN, CPE_EPREEMPTED_STR},
{ -EAGAIN, CPE_ECONTINUE_STR},
{ -EAGAIN, CPE_EIMMEDIATE_STR},
{ -EAGAIN, CPE_ENOTIMPL_STR},
{ -ENODATA, CPE_ENEEDMORE_STR},
{ -EADV, CPE_ERR_MAX_STR},
{ -ENOMEM, CPE_ENOMEMORY_STR},
{ -ENODEV, CPE_ENOTEXIST_STR},
{ -EADV, CPE_ETERMINATED_STR},
{ -EADV, CPE_ERR_MAX_STR},
};
static inline int cpe_err_get_lnx_err_code(u32 cpe_error)
{
if (cpe_error > CPE_ERR_MAX)
return cpe_err_code_info[CPE_ERR_MAX].lnx_err_code;
else
return cpe_err_code_info[cpe_error].lnx_err_code;
}
static inline char *cpe_err_get_err_str(u32 cpe_error)
{
if (cpe_error > CPE_ERR_MAX)
return cpe_err_code_info[CPE_ERR_MAX].cpe_err_str;
else
return cpe_err_code_info[cpe_error].cpe_err_str;
}
#endif

View File

@@ -0,0 +1,334 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <asoc/msm-cdc-pinctrl.h>
#define MAX_GPIOS 16
struct msm_cdc_pinctrl_info {
struct pinctrl *pinctrl;
struct pinctrl_state *pinctrl_active;
struct pinctrl_state *pinctrl_sleep;
int gpio;
bool state;
char __iomem *chip_wakeup_register[MAX_GPIOS];
u32 chip_wakeup_maskbit[MAX_GPIOS];
u32 count;
u32 wakeup_reg_count;
bool wakeup_capable;
bool chip_wakeup_reg;
};
static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata(
struct device_node *np)
{
struct platform_device *pdev;
struct msm_cdc_pinctrl_info *gpio_data;
if (!np) {
pr_err("%s: device node is null\n", __func__);
return NULL;
}
pdev = of_find_device_by_node(np);
if (!pdev) {
pr_err("%s: platform device not found!\n", __func__);
return NULL;
}
gpio_data = dev_get_drvdata(&pdev->dev);
if (!gpio_data)
dev_err(&pdev->dev, "%s: cannot find cdc gpio info\n",
__func__);
return gpio_data;
}
/*
* msm_cdc_get_gpio_state: select pinctrl sleep state
* @np: pointer to struct device_node
*
* Returns error code for failure and GPIO value on success
*/
int msm_cdc_get_gpio_state(struct device_node *np)
{
struct msm_cdc_pinctrl_info *gpio_data;
int value = -EINVAL;
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
if (!gpio_data)
return value;
if (gpio_is_valid(gpio_data->gpio))
value = gpio_get_value_cansleep(gpio_data->gpio);
return value;
}
EXPORT_SYMBOL(msm_cdc_get_gpio_state);
/*
* msm_cdc_pinctrl_select_sleep_state: select pinctrl sleep state
* @np: pointer to struct device_node
*
* Returns error code for failure
*/
int msm_cdc_pinctrl_select_sleep_state(struct device_node *np)
{
struct msm_cdc_pinctrl_info *gpio_data;
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
if (!gpio_data)
return -EINVAL;
if (!gpio_data->pinctrl_sleep) {
pr_err("%s: pinctrl sleep state is null\n", __func__);
return -EINVAL;
}
gpio_data->state = false;
return pinctrl_select_state(gpio_data->pinctrl,
gpio_data->pinctrl_sleep);
}
EXPORT_SYMBOL(msm_cdc_pinctrl_select_sleep_state);
/*
* msm_cdc_pinctrl_select_active_state: select pinctrl active state
* @np: pointer to struct device_node
*
* Returns error code for failure
*/
int msm_cdc_pinctrl_select_active_state(struct device_node *np)
{
struct msm_cdc_pinctrl_info *gpio_data;
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
if (!gpio_data)
return -EINVAL;
if (!gpio_data->pinctrl_active) {
pr_err("%s: pinctrl active state is null\n", __func__);
return -EINVAL;
}
gpio_data->state = true;
return pinctrl_select_state(gpio_data->pinctrl,
gpio_data->pinctrl_active);
}
EXPORT_SYMBOL(msm_cdc_pinctrl_select_active_state);
/*
* msm_cdc_pinctrl_get_state: get curren pinctrl state
* @np: pointer to struct device_node
*
* Returns 0 for sleep state, 1 for active state,
* error code for failure
*/
int msm_cdc_pinctrl_get_state(struct device_node *np)
{
struct msm_cdc_pinctrl_info *gpio_data;
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
if (!gpio_data)
return -EINVAL;
return gpio_data->state;
}
EXPORT_SYMBOL(msm_cdc_pinctrl_get_state);
/*
* msm_cdc_pinctrl_set_wakeup_capable: Set a pinctrl to wakeup capable
* @np: pointer to struct device_node
* @enable: wakeup capable when set to true
*
* Returns 0 for success and error code for failure
*/
int msm_cdc_pinctrl_set_wakeup_capable(struct device_node *np, bool enable)
{
struct msm_cdc_pinctrl_info *gpio_data;
int ret = 0;
u32 i = 0, temp = 0;
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
if (!gpio_data)
return -EINVAL;
if (gpio_data->chip_wakeup_reg) {
for (i = 0; i < gpio_data->wakeup_reg_count; i++) {
temp = ioread32(gpio_data->chip_wakeup_register[i]);
if (enable)
temp |= (1 <<
gpio_data->chip_wakeup_maskbit[i]);
else
temp &= ~(1 <<
gpio_data->chip_wakeup_maskbit[i]);
iowrite32(temp, gpio_data->chip_wakeup_register[i]);
}
}
return ret;
}
EXPORT_SYMBOL(msm_cdc_pinctrl_set_wakeup_capable);
static int msm_cdc_pinctrl_probe(struct platform_device *pdev)
{
int ret = 0;
struct msm_cdc_pinctrl_info *gpio_data;
u32 chip_wakeup_reg[MAX_GPIOS] = {0};
u32 chip_wakeup_default_val[MAX_GPIOS] = {0};
u32 i = 0, temp = 0;
int count = 0;
gpio_data = devm_kzalloc(&pdev->dev,
sizeof(struct msm_cdc_pinctrl_info),
GFP_KERNEL);
if (!gpio_data)
return -ENOMEM;
gpio_data->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR_OR_NULL(gpio_data->pinctrl)) {
dev_err(&pdev->dev, "%s: Cannot get cdc gpio pinctrl:%ld\n",
__func__, PTR_ERR(gpio_data->pinctrl));
ret = PTR_ERR(gpio_data->pinctrl);
goto err_pctrl_get;
}
gpio_data->pinctrl_active = pinctrl_lookup_state(
gpio_data->pinctrl, "aud_active");
if (IS_ERR_OR_NULL(gpio_data->pinctrl_active)) {
dev_err(&pdev->dev, "%s: Cannot get aud_active pinctrl state:%ld\n",
__func__, PTR_ERR(gpio_data->pinctrl_active));
ret = PTR_ERR(gpio_data->pinctrl_active);
goto err_lookup_state;
}
gpio_data->pinctrl_sleep = pinctrl_lookup_state(
gpio_data->pinctrl, "aud_sleep");
if (IS_ERR_OR_NULL(gpio_data->pinctrl_sleep)) {
dev_err(&pdev->dev, "%s: Cannot get aud_sleep pinctrl state:%ld\n",
__func__, PTR_ERR(gpio_data->pinctrl_sleep));
ret = PTR_ERR(gpio_data->pinctrl_sleep);
goto err_lookup_state;
}
/* skip setting to sleep state for LPI_TLMM GPIOs */
if (!of_property_read_bool(pdev->dev.of_node, "qcom,lpi-gpios")) {
/* Set pinctrl state to aud_sleep by default */
ret = pinctrl_select_state(gpio_data->pinctrl,
gpio_data->pinctrl_sleep);
if (ret)
dev_err(&pdev->dev, "%s: set cdc gpio sleep state fail: %d\n",
__func__, ret);
}
count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,chip-wakeup-reg");
if (count <= 0)
goto cdc_rst;
if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,chip-wakeup-reg",
chip_wakeup_reg, count)) {
if (of_property_read_u32_array(pdev->dev.of_node,
"qcom,chip-wakeup-maskbit",
gpio_data->chip_wakeup_maskbit, count)) {
dev_err(&pdev->dev,
"chip-wakeup-maskbit needed if chip-wakeup-reg is defined!\n");
goto cdc_rst;
}
gpio_data->chip_wakeup_reg = true;
for (i = 0; i < count; i++) {
gpio_data->chip_wakeup_register[i] =
devm_ioremap(&pdev->dev, chip_wakeup_reg[i], 0x4);
}
if (!of_property_read_u32_array(pdev->dev.of_node,
"qcom,chip-wakeup-default-val",
chip_wakeup_default_val, count)) {
for (i = 0; i < count; i++) {
temp = ioread32(gpio_data->chip_wakeup_register[i]);
if (chip_wakeup_default_val[i])
temp |= (1 <<
gpio_data->chip_wakeup_maskbit[i]);
else
temp &= ~(1 <<
gpio_data->chip_wakeup_maskbit[i]);
iowrite32(temp, gpio_data->chip_wakeup_register[i]);
}
}
gpio_data->wakeup_reg_count = count;
}
cdc_rst:
gpio_data->gpio = of_get_named_gpio(pdev->dev.of_node,
"qcom,cdc-rst-n-gpio", 0);
if (gpio_is_valid(gpio_data->gpio)) {
ret = gpio_request(gpio_data->gpio, "MSM_CDC_RESET");
if (ret) {
dev_err(&pdev->dev, "%s: Failed to request gpio %d\n",
__func__, gpio_data->gpio);
goto err_lookup_state;
}
}
dev_set_drvdata(&pdev->dev, gpio_data);
return 0;
err_lookup_state:
devm_pinctrl_put(gpio_data->pinctrl);
err_pctrl_get:
devm_kfree(&pdev->dev, gpio_data);
return ret;
}
static int msm_cdc_pinctrl_remove(struct platform_device *pdev)
{
struct msm_cdc_pinctrl_info *gpio_data;
gpio_data = dev_get_drvdata(&pdev->dev);
/* to free the requested gpio before exiting */
if (gpio_data) {
if (gpio_is_valid(gpio_data->gpio))
gpio_free(gpio_data->gpio);
if (gpio_data->pinctrl)
devm_pinctrl_put(gpio_data->pinctrl);
}
devm_kfree(&pdev->dev, gpio_data);
return 0;
}
static const struct of_device_id msm_cdc_pinctrl_match[] = {
{.compatible = "qcom,msm-cdc-pinctrl"},
{}
};
static struct platform_driver msm_cdc_pinctrl_driver = {
.driver = {
.name = "msm-cdc-pinctrl",
.owner = THIS_MODULE,
.of_match_table = msm_cdc_pinctrl_match,
.suppress_bind_attrs = true,
},
.probe = msm_cdc_pinctrl_probe,
.remove = msm_cdc_pinctrl_remove,
};
int msm_cdc_pinctrl_drv_init(void)
{
return platform_driver_register(&msm_cdc_pinctrl_driver);
}
void msm_cdc_pinctrl_drv_exit(void)
{
platform_driver_unregister(&msm_cdc_pinctrl_driver);
}
MODULE_DESCRIPTION("MSM CODEC pin control platform driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,566 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_irq.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/regulator/consumer.h>
#include <asoc/msm-cdc-supply.h>
#define CODEC_DT_MAX_PROP_SIZE 40
static int msm_cdc_dt_parse_vreg_info(struct device *dev,
struct cdc_regulator *cdc_vreg,
const char *name, bool is_ond)
{
char prop_name[CODEC_DT_MAX_PROP_SIZE];
struct device_node *regulator_node = NULL;
const __be32 *prop;
int len, rc;
u32 prop_val;
/* Parse supply name */
snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply", name);
regulator_node = of_parse_phandle(dev->of_node, prop_name, 0);
if (!regulator_node) {
dev_err(dev, "%s: Looking up %s property in node %s failed",
__func__, prop_name, dev->of_node->full_name);
rc = -EINVAL;
goto done;
}
cdc_vreg->name = name;
cdc_vreg->ondemand = is_ond;
/* Parse supply - voltage */
snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-voltage", name);
prop = of_get_property(dev->of_node, prop_name, &len);
if (!prop || (len != (2 * sizeof(__be32)))) {
dev_err(dev, "%s: %s %s property\n", __func__,
prop ? "invalid format" : "no", prop_name);
rc = -EINVAL;
goto done;
} else {
cdc_vreg->min_uV = be32_to_cpup(&prop[0]);
cdc_vreg->max_uV = be32_to_cpup(&prop[1]);
}
/* Parse supply - current */
snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "qcom,%s-current", name);
rc = of_property_read_u32(dev->of_node, prop_name, &prop_val);
if (rc) {
dev_err(dev, "%s: Looking up %s property in node %s failed",
__func__, prop_name, dev->of_node->full_name);
goto done;
}
cdc_vreg->optimum_uA = prop_val;
dev_info(dev, "%s: %s: vol=[%d %d]uV, curr=[%d]uA, ond %d\n",
__func__, cdc_vreg->name, cdc_vreg->min_uV, cdc_vreg->max_uV,
cdc_vreg->optimum_uA, cdc_vreg->ondemand);
done:
return rc;
}
static int msm_cdc_parse_supplies(struct device *dev,
struct cdc_regulator *cdc_reg,
const char *sup_list, int sup_cnt,
bool is_ond)
{
int idx, rc = 0;
const char *name = NULL;
for (idx = 0; idx < sup_cnt; idx++) {
rc = of_property_read_string_index(dev->of_node, sup_list, idx,
&name);
if (rc) {
dev_err(dev, "%s: read string %s[%d] error (%d)\n",
__func__, sup_list, idx, rc);
goto done;
}
dev_dbg(dev, "%s: Found cdc supply %s as part of %s\n",
__func__, name, sup_list);
rc = msm_cdc_dt_parse_vreg_info(dev, &cdc_reg[idx], name,
is_ond);
if (rc) {
dev_err(dev, "%s: parse %s vreg info failed (%d)\n",
__func__, name, rc);
goto done;
}
}
done:
return rc;
}
static int msm_cdc_check_supply_param(struct device *dev,
struct cdc_regulator *cdc_vreg,
int num_supplies)
{
if (!dev) {
pr_err("%s: device is NULL\n", __func__);
return -ENODEV;
}
if (!cdc_vreg || (num_supplies <= 0)) {
dev_err(dev, "%s: supply check failed: vreg: %pK, num_supplies: %d\n",
__func__, cdc_vreg, num_supplies);
return -EINVAL;
}
return 0;
}
/*
* 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
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
*
* Return error code if supply disable is failed
*/
int msm_cdc_disable_static_supplies(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies)
{
int rc, i;
if ((!dev) || (!supplies) || (!cdc_vreg)) {
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)
continue;
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);
else
dev_dbg(dev, "%s: disabled regulator %s\n",
__func__, supplies[i].supply);
}
return rc;
}
EXPORT_SYMBOL(msm_cdc_disable_static_supplies);
/*
* msm_cdc_release_supplies:
* Release codec power supplies
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
*
* Return error code if supply disable is failed
*/
int msm_cdc_release_supplies(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies)
{
int rc = 0;
int i;
if ((!dev) || (!supplies) || (!cdc_vreg)) {
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;
msm_cdc_disable_static_supplies(dev, supplies, cdc_vreg,
num_supplies);
for (i = 0; i < num_supplies; i++) {
if (regulator_count_voltages(supplies[i].consumer) < 0)
continue;
regulator_set_voltage(supplies[i].consumer, 0,
cdc_vreg[i].max_uV);
regulator_set_load(supplies[i].consumer, 0);
}
return rc;
}
EXPORT_SYMBOL(msm_cdc_release_supplies);
/*
* msm_cdc_enable_static_supplies:
* Enable codec static supplies
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
*
* Return error code if supply enable is failed
*/
int msm_cdc_enable_static_supplies(struct device *dev,
struct regulator_bulk_data *supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies)
{
int rc, i;
if ((!dev) || (!supplies) || (!cdc_vreg)) {
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)
continue;
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;
}
}
while (rc && i--)
if (!cdc_vreg[i].ondemand)
regulator_disable(supplies[i].consumer);
return rc;
}
EXPORT_SYMBOL(msm_cdc_enable_static_supplies);
/*
* msm_cdc_init_supplies:
* Initialize codec static supplies
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
*
* Return error code if supply init is failed
*/
int msm_cdc_init_supplies(struct device *dev,
struct regulator_bulk_data **supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies)
{
return msm_cdc_init_supplies_v2(dev, supplies, cdc_vreg,
num_supplies, false);
}
EXPORT_SYMBOL(msm_cdc_init_supplies);
/*
* msm_cdc_init_supplies_v2:
* Initialize codec static supplies.
* Initialize codec dynamic supplies based on vote_regulator_on_demand
*
* @dev: pointer to codec device
* @supplies: pointer to regulator bulk data
* @cdc_vreg: pointer to platform regulator data
* @num_supplies: number of supplies
* @vote_regulator_on_demand: initialize codec dynamic supplies at runtime
*
* Return error code if supply init is failed
*/
int msm_cdc_init_supplies_v2(struct device *dev,
struct regulator_bulk_data **supplies,
struct cdc_regulator *cdc_vreg,
int num_supplies, u32 vote_regulator_on_demand)
{
struct regulator_bulk_data *vsup;
int rc;
int i;
if (!dev || !cdc_vreg) {
pr_err("%s: device pointer or dce_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;
vsup = devm_kcalloc(dev, num_supplies,
sizeof(struct regulator_bulk_data),
GFP_KERNEL);
if (!vsup)
return -ENOMEM;
for (i = 0; i < num_supplies; i++) {
if (!cdc_vreg[i].name) {
dev_err(dev, "%s: supply name not defined\n",
__func__);
rc = -EINVAL;
goto err_supply;
}
vsup[i].supply = cdc_vreg[i].name;
}
rc = devm_regulator_bulk_get(dev, num_supplies, vsup);
if (rc) {
dev_err(dev, "%s: failed to get supplies (%d)\n",
__func__, rc);
goto err_supply;
}
/* Set voltage and current on regulators */
for (i = 0; i < num_supplies; i++) {
if (regulator_count_voltages(vsup[i].consumer) < 0)
continue;
if (cdc_vreg[i].ondemand && vote_regulator_on_demand)
continue;
rc = regulator_set_voltage(vsup[i].consumer,
cdc_vreg[i].min_uV,
cdc_vreg[i].max_uV);
if (rc) {
dev_err(dev, "%s: set regulator voltage failed for %s, err:%d\n",
__func__, vsup[i].supply, rc);
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_supply;
}
}
*supplies = vsup;
return 0;
err_supply:
return rc;
}
EXPORT_SYMBOL(msm_cdc_init_supplies_v2);
/*
* msm_cdc_get_power_supplies:
* Get codec power supplies from device tree.
* Allocate memory to hold regulator data for
* all power supplies.
*
* @dev: pointer to codec device
* @cdc_vreg: pointer to codec regulator
* @total_num_supplies: total number of supplies read from DT
*
* Return error code if supply disable is failed
*/
int msm_cdc_get_power_supplies(struct device *dev,
struct cdc_regulator **cdc_vreg,
int *total_num_supplies)
{
const char *static_prop_name = "qcom,cdc-static-supplies";
const char *ond_prop_name = "qcom,cdc-on-demand-supplies";
const char *cp_prop_name = "qcom,cdc-cp-supplies";
int static_sup_cnt = 0;
int ond_sup_cnt = 0;
int cp_sup_cnt = 0;
int num_supplies = 0;
struct cdc_regulator *cdc_reg;
int rc;
if (!dev) {
pr_err("%s: device pointer is NULL\n", __func__);
return -EINVAL;
}
static_sup_cnt = of_property_count_strings(dev->of_node,
static_prop_name);
if (static_sup_cnt < 0) {
dev_err(dev, "%s: Failed to get static supplies(%d)\n",
__func__, static_sup_cnt);
rc = static_sup_cnt;
goto err_supply_cnt;
}
ond_sup_cnt = of_property_count_strings(dev->of_node, ond_prop_name);
if (ond_sup_cnt < 0)
ond_sup_cnt = 0;
cp_sup_cnt = of_property_count_strings(dev->of_node,
cp_prop_name);
if (cp_sup_cnt < 0)
cp_sup_cnt = 0;
num_supplies = static_sup_cnt + ond_sup_cnt + cp_sup_cnt;
if (num_supplies <= 0) {
dev_err(dev, "%s: supply count is 0 or negative\n", __func__);
rc = -EINVAL;
goto err_supply_cnt;
}
cdc_reg = devm_kcalloc(dev, num_supplies,
sizeof(struct cdc_regulator),
GFP_KERNEL);
if (!cdc_reg) {
rc = -ENOMEM;
goto err_mem_alloc;
}
rc = msm_cdc_parse_supplies(dev, cdc_reg, static_prop_name,
static_sup_cnt, false);
if (rc) {
dev_err(dev, "%s: failed to parse static supplies(%d)\n",
__func__, rc);
goto err_sup;
}
rc = msm_cdc_parse_supplies(dev, &cdc_reg[static_sup_cnt],
ond_prop_name, ond_sup_cnt,
true);
if (rc) {
dev_err(dev, "%s: failed to parse demand supplies(%d)\n",
__func__, rc);
goto err_sup;
}
rc = msm_cdc_parse_supplies(dev,
&cdc_reg[static_sup_cnt + ond_sup_cnt],
cp_prop_name, cp_sup_cnt, true);
if (rc) {
dev_err(dev, "%s: failed to parse cp supplies(%d)\n",
__func__, rc);
goto err_sup;
}
*cdc_vreg = cdc_reg;
*total_num_supplies = num_supplies;
return 0;
err_sup:
err_supply_cnt:
err_mem_alloc:
return rc;
}
EXPORT_SYMBOL(msm_cdc_get_power_supplies);

View File

@@ -0,0 +1,848 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/err.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <linux/msm_ext_display.h>
#define MSM_EXT_DISP_PCM_RATES SNDRV_PCM_RATE_48000
#define AUD_EXT_DISP_ACK_DISCONNECT (AUDIO_ACK_CONNECT ^ AUDIO_ACK_CONNECT)
#define AUD_EXT_DISP_ACK_CONNECT (AUDIO_ACK_CONNECT)
#define AUD_EXT_DISP_ACK_ENABLE (AUDIO_ACK_SET_ENABLE | AUDIO_ACK_ENABLE)
#define SOC_EXT_DISP_AUDIO_TYPE(index) \
static SOC_ENUM_SINGLE_DECL(ext_disp_audio_type##index, SND_SOC_NOPM, \
index, ext_disp_audio_type_text)
#define SOC_EXT_DISP_AUDIO_ACK_STATE(index) \
static SOC_ENUM_SINGLE_DECL(ext_disp_audio_ack_state##index, \
SND_SOC_NOPM, index, ext_disp_audio_ack_text)
#define SWITCH_DP_CODEC(codec_info, codec_data, dai_id) \
codec_info.type = EXT_DISPLAY_TYPE_DP; \
codec_info.ctrl_id = codec_data->ctl[dai_id]; \
codec_info.stream_id = codec_data->stream[dai_id]; \
msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev, \
&codec_info)
enum {
DP_CONTROLLER0 = 0,
DP_CONTROLLER_MAX,
};
enum {
DP_STREAM0 = 0,
DP_STREAM1,
DP_STREAM_MAX,
};
/*
* Dai id cannot be zero, if component has more than one dai and dai id
* is used to differentiate between them
*/
enum {
DP_DAI1 = 1,
DP_DAI2,
HDMI_DAI,
DP_DAI_MAX,
};
static const char *const ext_disp_audio_type_text[] = {"None", "HDMI", "DP"};
static const char *const ext_disp_audio_ack_text[] = {"Disconnect", "Connect",
"Ack_Enable"};
SOC_EXT_DISP_AUDIO_TYPE(1);
SOC_EXT_DISP_AUDIO_ACK_STATE(1);
SOC_EXT_DISP_AUDIO_TYPE(2);
SOC_EXT_DISP_AUDIO_ACK_STATE(2);
struct msm_ext_disp_audio_codec_rx_data {
struct platform_device *ext_disp_core_pdev;
struct msm_ext_disp_audio_codec_ops ext_disp_ops;
struct mutex dp_ops_lock;
int cable_status[DP_DAI_MAX];
int stream[DP_DAI_MAX];
int ctl[DP_DAI_MAX];
};
static int msm_ext_disp_edid_ctl_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct msm_ext_disp_audio_codec_rx_data *codec_data;
struct msm_ext_disp_audio_edid_blk edid_blk;
int rc = 0;
struct msm_ext_disp_codec_id codec_info;
int dai_id = kcontrol->private_value;
codec_data = snd_soc_codec_get_drvdata(codec);
if (!codec_data) {
dev_err(codec->dev, "%s: codec_data is NULL\n", __func__);
return -EINVAL;
}
dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) {
dev_dbg(codec->dev, "%s: get_audio_edid_blk() is NULL\n",
__func__);
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
uinfo->count = 0;
mutex_unlock(&codec_data->dp_ops_lock);
return 0;
}
rc = codec_data->ext_disp_ops.get_audio_edid_blk(
codec_data->ext_disp_core_pdev, &edid_blk);
mutex_unlock(&codec_data->dp_ops_lock);
if (rc >= 0) {
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
uinfo->count = edid_blk.audio_data_blk_size +
edid_blk.spk_alloc_data_blk_size;
}
dev_dbg(codec->dev, "%s: count: %d\n", __func__, uinfo->count);
return rc;
}
static int msm_ext_disp_edid_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) {
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct msm_ext_disp_audio_codec_rx_data *codec_data;
struct msm_ext_disp_audio_edid_blk edid_blk;
struct msm_ext_disp_codec_id codec_info;
int rc = 0;
int dai_id = kcontrol->private_value;
codec_data = snd_soc_codec_get_drvdata(codec);
if (!codec_data || !codec_data->ext_disp_ops.get_audio_edid_blk) {
dev_err(codec->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n",
__func__);
return -EINVAL;
}
dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.get_audio_edid_blk || rc) {
dev_err(codec->dev, "%s: codec_data or get_audio_edid_blk() is NULL\n",
__func__);
mutex_unlock(&codec_data->dp_ops_lock);
return -EINVAL;
}
rc = codec_data->ext_disp_ops.get_audio_edid_blk(
codec_data->ext_disp_core_pdev, &edid_blk);
mutex_unlock(&codec_data->dp_ops_lock);
if (rc >= 0) {
if (sizeof(ucontrol->value.bytes.data) <
(edid_blk.audio_data_blk_size +
edid_blk.spk_alloc_data_blk_size)) {
dev_err(codec->dev,
"%s: Not enough memory to copy EDID data\n",
__func__);
return -ENOMEM;
}
memcpy(ucontrol->value.bytes.data,
edid_blk.audio_data_blk,
edid_blk.audio_data_blk_size);
memcpy((ucontrol->value.bytes.data +
edid_blk.audio_data_blk_size),
edid_blk.spk_alloc_data_blk,
edid_blk.spk_alloc_data_blk_size);
dev_dbg(codec->dev, "%s: data_blk_size:%d, spk_alloc_data_blk_size:%d\n",
__func__, edid_blk.audio_data_blk_size,
edid_blk.spk_alloc_data_blk_size);
}
return rc;
}
static int msm_ext_disp_audio_type_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct msm_ext_disp_audio_codec_rx_data *codec_data;
enum msm_ext_disp_cable_state cable_state;
enum msm_ext_disp_type disp_type;
struct msm_ext_disp_codec_id codec_info;
int rc = 0;
int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l;
codec_data = snd_soc_codec_get_drvdata(codec);
if (!codec_data) {
dev_err(codec->dev, "%s: codec_data is NULL\n",
__func__);
return -EINVAL;
}
dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.get_audio_edid_blk ||
!codec_data->ext_disp_ops.get_intf_id || rc) {
dev_err(codec->dev, "%s: get_audio_edid_blk() or get_intf_id is NULL\n",
__func__);
rc = -EINVAL;
goto cable_err;
}
cable_state = codec_data->ext_disp_ops.cable_status(
codec_data->ext_disp_core_pdev, 1);
if (cable_state < 0) {
dev_err(codec->dev, "%s: Error retrieving cable state from ext_disp, err:%d\n",
__func__, cable_state);
rc = cable_state;
goto cable_err;
}
codec_data->cable_status[dai_id] = cable_state;
if (cable_state == EXT_DISPLAY_CABLE_DISCONNECT) {
dev_err(codec->dev, "%s: Display cable disconnected\n",
__func__);
ucontrol->value.integer.value[0] = 0;
rc = 0;
goto cable_err;
}
disp_type = codec_data->ext_disp_ops.get_intf_id(
codec_data->ext_disp_core_pdev);
mutex_unlock(&codec_data->dp_ops_lock);
if (disp_type >= 0) {
switch (disp_type) {
case EXT_DISPLAY_TYPE_DP:
ucontrol->value.integer.value[0] = 2;
rc = 0;
break;
case EXT_DISPLAY_TYPE_HDMI:
ucontrol->value.integer.value[0] = 1;
rc = 0;
break;
default:
rc = -EINVAL;
dev_err(codec->dev, "%s: Invalid disp_type:%d\n",
__func__, disp_type);
goto done;
}
dev_dbg(codec->dev, "%s: Display type: %d\n",
__func__, disp_type);
} else {
dev_err(codec->dev, "%s: Error retrieving disp_type from ext_disp, err:%d\n",
__func__, disp_type);
rc = disp_type;
}
return rc;
cable_err:
mutex_unlock(&codec_data->dp_ops_lock);
done:
return rc;
}
static int msm_ext_disp_audio_ack_set(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct msm_ext_disp_audio_codec_rx_data *codec_data;
u32 ack_state = 0;
struct msm_ext_disp_codec_id codec_info;
int rc = 0;
int dai_id = ((struct soc_enum *) kcontrol->private_value)->shift_l;
codec_data = snd_soc_codec_get_drvdata(codec);
if (!codec_data) {
dev_err(codec->dev,
"%s: codec_data is NULL\n",
__func__);
return -EINVAL;
}
dev_dbg(codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai_id], codec_data->stream[dai_id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai_id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.acknowledge || rc) {
dev_err(codec->dev,
"%s: codec_data ops acknowledge() is NULL\n",
__func__);
rc = -EINVAL;
goto err;
}
switch (ucontrol->value.enumerated.item[0]) {
case 0:
ack_state = AUD_EXT_DISP_ACK_DISCONNECT;
break;
case 1:
ack_state = AUD_EXT_DISP_ACK_CONNECT;
break;
case 2:
ack_state = AUD_EXT_DISP_ACK_ENABLE;
break;
default:
rc = -EINVAL;
dev_err(codec->dev,
"%s: invalid value %d for mixer ctl\n",
__func__, ucontrol->value.enumerated.item[0]);
goto err;
}
dev_dbg(codec->dev, "%s: control %d, ack set value 0x%x\n",
__func__, ucontrol->value.enumerated.item[0], ack_state);
rc = codec_data->ext_disp_ops.acknowledge(
codec_data->ext_disp_core_pdev, ack_state);
mutex_unlock(&codec_data->dp_ops_lock);
if (rc < 0) {
dev_err(codec->dev, "%s: error from acknowledge(), err:%d\n",
__func__, rc);
}
return rc;
err:
mutex_unlock(&codec_data->dp_ops_lock);
return rc;
}
static int msm_ext_disp_audio_device_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec =
snd_soc_kcontrol_codec(kcontrol);
struct msm_ext_disp_audio_codec_rx_data *codec_data;
int rc = 0;
int dai_id = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
if (dai_id < 0 || dai_id > DP_DAI2) {
dev_err(codec->dev,
"%s: invalid dai id: %d\n", __func__, dai_id);
rc = -EINVAL;
goto done;
}
codec_data = snd_soc_codec_get_drvdata(codec);
if (!codec_data) {
dev_err(codec->dev,
"%s: codec_data or ops acknowledge() is NULL\n",
__func__);
rc = -EINVAL;
goto done;
}
ucontrol->value.integer.value[0] = codec_data->ctl[dai_id];
ucontrol->value.integer.value[1] = codec_data->stream[dai_id];
done:
return rc;
}
static int msm_ext_disp_audio_device_set(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct msm_ext_disp_audio_codec_rx_data *codec_data;
int rc = 0;
int dai_id = ((struct soc_multi_mixer_control *)
kcontrol->private_value)->shift;
if (dai_id < 0 || dai_id > DP_DAI2) {
dev_err(codec->dev,
"%s: invalid dai id: %d\n", __func__, dai_id);
rc = -EINVAL;
goto done;
}
codec_data = snd_soc_codec_get_drvdata(codec);
if (!codec_data) {
dev_err(codec->dev,
"%s: codec_data or ops acknowledge() is NULL\n",
__func__);
rc = -EINVAL;
goto done;
}
if ((ucontrol->value.integer.value[0] > (DP_CONTROLLER_MAX - 1)) ||
(ucontrol->value.integer.value[1] > (DP_STREAM_MAX - 1)) ||
(ucontrol->value.integer.value[0] < 0) ||
(ucontrol->value.integer.value[1] < 0)) {
dev_err(codec->dev,
"%s: DP audio control index invalid\n",
__func__);
rc = -EINVAL;
goto done;
}
mutex_lock(&codec_data->dp_ops_lock);
codec_data->ctl[dai_id] = ucontrol->value.integer.value[0];
codec_data->stream[dai_id] = ucontrol->value.integer.value[1];
mutex_unlock(&codec_data->dp_ops_lock);
done:
return rc;
}
static const struct snd_kcontrol_new msm_ext_disp_codec_rx_controls[] = {
{
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "HDMI EDID",
.info = msm_ext_disp_edid_ctl_info,
.get = msm_ext_disp_edid_get,
.private_value = HDMI_DAI,
},
{
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Display Port EDID",
.info = msm_ext_disp_edid_ctl_info,
.get = msm_ext_disp_edid_get,
.private_value = DP_DAI1,
},
{
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "Display Port1 EDID",
.info = msm_ext_disp_edid_ctl_info,
.get = msm_ext_disp_edid_get,
.private_value = DP_DAI2,
},
SOC_ENUM_EXT("External Display Type",
ext_disp_audio_type1,
msm_ext_disp_audio_type_get, NULL),
SOC_ENUM_EXT("External Display1 Type",
ext_disp_audio_type2,
msm_ext_disp_audio_type_get, NULL),
SOC_ENUM_EXT("External Display Audio Ack",
ext_disp_audio_ack_state1,
NULL, msm_ext_disp_audio_ack_set),
SOC_ENUM_EXT("External Display1 Audio Ack",
ext_disp_audio_ack_state2,
NULL, msm_ext_disp_audio_ack_set),
SOC_SINGLE_MULTI_EXT("External Display Audio Device",
SND_SOC_NOPM, DP_DAI1, DP_STREAM_MAX - 1, 0, 2,
msm_ext_disp_audio_device_get,
msm_ext_disp_audio_device_set),
SOC_SINGLE_MULTI_EXT("External Display1 Audio Device",
SND_SOC_NOPM, DP_DAI2, DP_STREAM_MAX - 1, 0, 2,
msm_ext_disp_audio_device_get,
msm_ext_disp_audio_device_set),
};
static int msm_ext_disp_audio_codec_rx_dai_startup(
struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int ret = 0, rc = 0;
struct msm_ext_disp_codec_id codec_info;
struct msm_ext_disp_audio_codec_rx_data *codec_data =
dev_get_drvdata(dai->codec->dev);
if (!codec_data) {
dev_err(dai->dev, "%s() codec_data is null\n",
__func__);
return -EINVAL;
}
dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.cable_status || rc) {
dev_err(dai->dev, "%s() cable_status is null\n",
__func__);
mutex_unlock(&codec_data->dp_ops_lock);
return -EINVAL;
}
codec_data->cable_status[dai->id] =
codec_data->ext_disp_ops.cable_status(
codec_data->ext_disp_core_pdev, 1);
mutex_unlock(&codec_data->dp_ops_lock);
if (codec_data->cable_status[dai->id] < 0) {
dev_err(dai->dev,
"%s() ext disp core is not ready (ret val = %d)\n",
__func__, codec_data->cable_status[dai->id]);
ret = codec_data->cable_status[dai->id];
} else if (!codec_data->cable_status[dai->id]) {
dev_err(dai->dev,
"%s() ext disp cable is not connected (ret val = %d)\n",
__func__, codec_data->cable_status[dai->id]);
ret = -ENODEV;
}
return ret;
}
static int msm_ext_disp_audio_codec_rx_dai_hw_params(
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
u32 channel_allocation = 0;
u32 level_shift = 0; /* 0dB */
bool down_mix = 0;
u32 num_channels = params_channels(params);
struct msm_ext_disp_codec_id codec_info;
int rc = 0;
struct msm_ext_disp_audio_setup_params audio_setup_params = {0};
struct msm_ext_disp_audio_codec_rx_data *codec_data =
dev_get_drvdata(dai->codec->dev);
if (!codec_data) {
dev_err(dai->dev, "%s() codec_data is null\n",
__func__);
return -EINVAL;
}
dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.audio_info_setup || rc) {
dev_err(dai->dev, "%s: audio_info_setup is null\n",
__func__);
mutex_unlock(&codec_data->dp_ops_lock);
return -EINVAL;
}
mutex_unlock(&codec_data->dp_ops_lock);
if (codec_data->cable_status[dai->id] < 0) {
dev_err_ratelimited(dai->dev,
"%s() ext disp core is not ready (ret val = %d)\n",
__func__, codec_data->cable_status[dai->id]);
return codec_data->cable_status[dai->id];
} else if (!codec_data->cable_status[dai->id]) {
dev_err_ratelimited(dai->dev,
"%s() ext disp cable is not connected (ret val = %d)\n",
__func__, codec_data->cable_status[dai->id]);
return -ENODEV;
}
/*refer to HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4*/
switch (num_channels) {
case 2:
channel_allocation = 0;
break;
case 3:
channel_allocation = 0x02;/*default to FL/FR/FC*/
audio_setup_params.sample_present = 0x3;
break;
case 4:
channel_allocation = 0x06;/*default to FL/FR/FC/RC*/
audio_setup_params.sample_present = 0x7;
break;
case 5:
channel_allocation = 0x0A;/*default to FL/FR/FC/RR/RL*/
audio_setup_params.sample_present = 0x7;
break;
case 6:
channel_allocation = 0x0B;
audio_setup_params.sample_present = 0x7;
break;
case 7:
channel_allocation = 0x12;/*default to FL/FR/FC/RL/RR/RRC/RLC*/
audio_setup_params.sample_present = 0xf;
break;
case 8:
channel_allocation = 0x13;
audio_setup_params.sample_present = 0xf;
break;
default:
dev_err(dai->dev, "invalid Channels = %u\n", num_channels);
return -EINVAL;
}
dev_dbg(dai->dev,
"%s() num_ch %u samplerate %u channel_allocation = %u\n",
__func__, num_channels, params_rate(params),
channel_allocation);
audio_setup_params.sample_rate_hz = params_rate(params);
audio_setup_params.num_of_channels = num_channels;
audio_setup_params.channel_allocation = channel_allocation;
audio_setup_params.level_shift = level_shift;
audio_setup_params.down_mix = down_mix;
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (rc)
goto end;
rc = codec_data->ext_disp_ops.audio_info_setup(
codec_data->ext_disp_core_pdev, &audio_setup_params);
end:
mutex_unlock(&codec_data->dp_ops_lock);
if (rc < 0) {
dev_err_ratelimited(dai->dev,
"%s() ext disp core is not ready, rc: %d\n",
__func__, rc);
}
return rc;
}
static void msm_ext_disp_audio_codec_rx_dai_shutdown(
struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
int rc = 0;
struct msm_ext_disp_codec_id codec_info;
struct msm_ext_disp_audio_codec_rx_data *codec_data =
dev_get_drvdata(dai->codec->dev);
if (!codec_data) {
dev_err(dai->dev, "%s() codec_data is null\n",
__func__);
return;
}
dev_dbg(dai->codec->dev, "%s: DP ctl id %d Stream id %d\n", __func__,
codec_data->ctl[dai->id], codec_data->stream[dai->id]);
mutex_lock(&codec_data->dp_ops_lock);
SWITCH_DP_CODEC(codec_info, codec_data, dai->id);
rc = msm_ext_disp_select_audio_codec(codec_data->ext_disp_core_pdev,
&codec_info);
if (!codec_data->ext_disp_ops.teardown_done ||
!codec_data->ext_disp_ops.cable_status || rc) {
dev_err(dai->dev, "%s: teardown_done or cable_status is null\n",
__func__);
mutex_unlock(&codec_data->dp_ops_lock);
return;
}
rc = codec_data->ext_disp_ops.cable_status(
codec_data->ext_disp_core_pdev, 0);
if (rc < 0) {
dev_err(dai->dev,
"%s: ext disp core had problems releasing audio flag\n",
__func__);
}
codec_data->ext_disp_ops.teardown_done(
codec_data->ext_disp_core_pdev);
mutex_unlock(&codec_data->dp_ops_lock);
}
static int msm_ext_disp_audio_codec_rx_probe(struct snd_soc_codec *codec)
{
struct msm_ext_disp_audio_codec_rx_data *codec_data;
struct device_node *of_node_parent = NULL;
codec_data = kzalloc(sizeof(struct msm_ext_disp_audio_codec_rx_data),
GFP_KERNEL);
if (!codec_data) {
dev_err(codec->dev, "%s(): fail to allocate dai data\n",
__func__);
return -ENOMEM;
}
of_node_parent = of_get_parent(codec->dev->of_node);
if (!of_node_parent) {
dev_err(codec->dev, "%s(): Parent device tree node not found\n",
__func__);
kfree(codec_data);
return -ENODEV;
}
codec_data->ext_disp_core_pdev = of_find_device_by_node(of_node_parent);
if (!codec_data->ext_disp_core_pdev) {
dev_err(codec->dev, "%s(): can't get parent pdev\n", __func__);
kfree(codec_data);
return -ENODEV;
}
if (msm_ext_disp_register_audio_codec(codec_data->ext_disp_core_pdev,
&codec_data->ext_disp_ops)) {
dev_err(codec->dev, "%s(): can't register with ext disp core",
__func__);
kfree(codec_data);
return -ENODEV;
}
mutex_init(&codec_data->dp_ops_lock);
dev_set_drvdata(codec->dev, codec_data);
dev_dbg(codec->dev, "%s(): registered %s with ext disp core\n",
__func__, codec->component.name);
return 0;
}
static int msm_ext_disp_audio_codec_rx_remove(struct snd_soc_codec *codec)
{
struct msm_ext_disp_audio_codec_rx_data *codec_data;
codec_data = dev_get_drvdata(codec->dev);
mutex_destroy(&codec_data->dp_ops_lock);
kfree(codec_data);
return 0;
}
static struct snd_soc_dai_ops msm_ext_disp_audio_codec_rx_dai_ops = {
.startup = msm_ext_disp_audio_codec_rx_dai_startup,
.hw_params = msm_ext_disp_audio_codec_rx_dai_hw_params,
.shutdown = msm_ext_disp_audio_codec_rx_dai_shutdown
};
static struct snd_soc_dai_driver msm_ext_disp_audio_codec_rx_dais[] = {
{
.name = "msm_hdmi_audio_codec_rx_dai",
.id = HDMI_DAI,
.playback = {
.stream_name = "HDMI Playback",
.channels_min = 1,
.channels_max = 8,
.rate_min = 48000,
.rate_max = 48000,
.rates = MSM_EXT_DISP_PCM_RATES,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
.ops = &msm_ext_disp_audio_codec_rx_dai_ops,
},
{
.name = "msm_dp_audio_codec_rx_dai",
.id = DP_DAI1,
.playback = {
.stream_name = "Display Port Playback",
.channels_min = 1,
.channels_max = 8,
.rate_min = 48000,
.rate_max = 192000,
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE,
},
.ops = &msm_ext_disp_audio_codec_rx_dai_ops,
},
{
.name = "msm_dp_audio_codec_rx1_dai",
.id = DP_DAI2,
.playback = {
.stream_name = "Display Port1 Playback",
.channels_min = 1,
.channels_max = 8,
.rate_min = 48000,
.rate_max = 192000,
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE,
},
.ops = &msm_ext_disp_audio_codec_rx_dai_ops,
},
};
static struct snd_soc_codec_driver msm_ext_disp_audio_codec_rx_soc_driver = {
.probe = msm_ext_disp_audio_codec_rx_probe,
.remove = msm_ext_disp_audio_codec_rx_remove,
.component_driver = {
.controls = msm_ext_disp_codec_rx_controls,
.num_controls = ARRAY_SIZE(msm_ext_disp_codec_rx_controls),
},
};
static int msm_ext_disp_audio_codec_rx_plat_probe(
struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "%s(): dev name %s\n", __func__,
dev_name(&pdev->dev));
return snd_soc_register_codec(&pdev->dev,
&msm_ext_disp_audio_codec_rx_soc_driver,
msm_ext_disp_audio_codec_rx_dais,
ARRAY_SIZE(msm_ext_disp_audio_codec_rx_dais));
}
static int msm_ext_disp_audio_codec_rx_plat_remove(
struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static const struct of_device_id msm_ext_disp_audio_codec_rx_dt_match[] = {
{ .compatible = "qcom,msm-ext-disp-audio-codec-rx", },
{}
};
MODULE_DEVICE_TABLE(of, msm_ext_disp_audio_codec_rx_dt_match);
static struct platform_driver msm_ext_disp_audio_codec_rx_driver = {
.driver = {
.name = "msm-ext-disp-audio-codec-rx",
.owner = THIS_MODULE,
.of_match_table = msm_ext_disp_audio_codec_rx_dt_match,
.suppress_bind_attrs = true,
},
.probe = msm_ext_disp_audio_codec_rx_plat_probe,
.remove = msm_ext_disp_audio_codec_rx_plat_remove,
};
static int __init msm_ext_disp_audio_codec_rx_init(void)
{
int rc = 0;
rc = platform_driver_register(&msm_ext_disp_audio_codec_rx_driver);
if (rc) {
pr_err("%s: failed to register ext disp codec driver err:%d\n",
__func__, rc);
}
return rc;
}
module_init(msm_ext_disp_audio_codec_rx_init);
static void __exit msm_ext_disp_audio_codec_rx_exit(void)
{
platform_driver_unregister(&msm_ext_disp_audio_codec_rx_driver);
}
module_exit(msm_ext_disp_audio_codec_rx_exit);
MODULE_DESCRIPTION("MSM External Display Audio CODEC Driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,81 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2011-2014, 2017-2019 The Linux Foundation. All rights reserved.
*/
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
/* A dummy driver useful only to advertise hardware parameters */
static struct snd_soc_dai_driver msm_stub_dais[] = {
{
.name = "msm-stub-rx",
.playback = { /* Support maximum range */
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
},
},
{
.name = "msm-stub-tx",
.capture = { /* Support maximum range */
.stream_name = "Record",
.channels_min = 1,
.channels_max = 8,
.rates = SNDRV_PCM_RATE_8000_48000,
.formats = (SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE),
},
},
};
static struct snd_soc_codec_driver soc_msm_stub = {};
static int msm_stub_dev_probe(struct platform_device *pdev)
{
dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
return snd_soc_register_codec(&pdev->dev,
&soc_msm_stub, msm_stub_dais, ARRAY_SIZE(msm_stub_dais));
}
static int msm_stub_dev_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
return 0;
}
static const struct of_device_id msm_stub_codec_dt_match[] = {
{ .compatible = "qcom,msm-stub-codec", },
{}
};
static struct platform_driver msm_stub_driver = {
.driver = {
.name = "msm-stub-codec",
.owner = THIS_MODULE,
.of_match_table = msm_stub_codec_dt_match,
.suppress_bind_attrs = true,
},
.probe = msm_stub_dev_probe,
.remove = msm_stub_dev_remove,
};
static int __init msm_stub_init(void)
{
return platform_driver_register(&msm_stub_driver);
}
module_init(msm_stub_init);
static void __exit msm_stub_exit(void)
{
platform_driver_unregister(&msm_stub_driver);
}
module_exit(msm_stub_exit);
MODULE_DESCRIPTION("Generic MSM CODEC driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,588 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <sound/soc.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <asoc/wcd9xxx_registers.h>
#include <asoc/wcd-clsh.h>
#define WCD_USLEEP_RANGE 50
static void (*clsh_state_fp[NUM_CLSH_STATES])(struct snd_soc_codec *,
struct wcd_clsh_cdc_info *,
u8 req_state, bool en, int mode);
static const char *mode_to_str(int mode)
{
switch (mode) {
case CLS_H_NORMAL:
return WCD_CLSH_STRINGIFY(CLS_H_NORMAL);
case CLS_H_HIFI:
return WCD_CLSH_STRINGIFY(CLS_H_HIFI);
case CLS_H_LOHIFI:
return WCD_CLSH_STRINGIFY(CLS_H_LOHIFI);
case CLS_H_LP:
return WCD_CLSH_STRINGIFY(CLS_H_LP);
case CLS_H_ULP:
return WCD_CLSH_STRINGIFY(CLS_H_ULP);
case CLS_AB:
return WCD_CLSH_STRINGIFY(CLS_AB);
case CLS_AB_HIFI:
return WCD_CLSH_STRINGIFY(CLS_AB_HIFI);
case CLS_AB_LP:
return WCD_CLSH_STRINGIFY(CLS_AB_LP);
case CLS_AB_LOHIFI:
return WCD_CLSH_STRINGIFY(CLS_AB_LOHIFI);
default:
return WCD_CLSH_STRINGIFY(CLS_H_INVALID);
};
}
static const char *state_to_str(u8 state, char *buf, size_t buflen)
{
int i;
int cnt = 0;
/*
* This array of strings should match with enum wcd_clsh_state_bit.
*/
static const char *const states[] = {
"STATE_EAR",
"STATE_HPH_L",
"STATE_HPH_R",
"STATE_AUX",
};
if (state == WCD_CLSH_STATE_IDLE) {
snprintf(buf, buflen, "[STATE_IDLE]");
goto done;
}
buf[0] = '\0';
for (i = 0; i < ARRAY_SIZE(states); i++) {
if (!(state & (1 << i)))
continue;
cnt = snprintf(buf, buflen - cnt - 1, "%s%s%s", buf,
buf[0] == '\0' ? "[" : "|",
states[i]);
}
if (cnt > 0)
strlcat(buf + cnt, "]", buflen);
done:
if (buf[0] == '\0')
snprintf(buf, buflen, "[STATE_UNKNOWN]");
return buf;
}
static inline int wcd_clsh_get_int_mode(struct wcd_clsh_cdc_info *clsh_d,
int clsh_state)
{
int mode;
if ((clsh_state != WCD_CLSH_STATE_EAR) &&
(clsh_state != WCD_CLSH_STATE_HPHL) &&
(clsh_state != WCD_CLSH_STATE_HPHR) &&
(clsh_state != WCD_CLSH_STATE_AUX))
mode = CLS_NONE;
else
mode = clsh_d->interpolator_modes[ffs(clsh_state)];
return mode;
}
static inline void wcd_clsh_set_int_mode(struct wcd_clsh_cdc_info *clsh_d,
int clsh_state, int mode)
{
if ((clsh_state != WCD_CLSH_STATE_EAR) &&
(clsh_state != WCD_CLSH_STATE_HPHL) &&
(clsh_state != WCD_CLSH_STATE_HPHR) &&
(clsh_state != WCD_CLSH_STATE_AUX))
return;
clsh_d->interpolator_modes[ffs(clsh_state)] = mode;
}
static inline void wcd_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_LOHIFI)
snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES,
0x08, 0x08); /* set to HIFI */
else
snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES,
0x08, 0x00); /* set to default */
}
static inline void wcd_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_LOHIFI) {
snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES,
0x04, 0x04);
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4,
0xF0, 0x80);
} else {
snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES,
0x04, 0x00); /* set to Default */
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEG_CTRL_4,
0xF0, 0x70);
}
}
static inline void wcd_clsh_force_iq_ctl(struct snd_soc_codec *codec,
int mode, bool enable)
{
if (enable) {
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2,
0xE0, 0xA0);
/* 100usec delay is needed as per HW requirement */
usleep_range(100, 110);
snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_3,
0x02, 0x02);
snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_2,
0xFF, 0x1C);
if (mode == CLS_H_LOHIFI || mode == CLS_AB_LOHIFI) {
snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2,
0x20, 0x20);
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER,
0xF0, 0xC0);
snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1,
0x0E, 0x02);
}
} else {
snd_soc_update_bits(codec, WCD9XXX_HPH_NEW_INT_PA_MISC2,
0x20, 0x00);
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_HPH_LOWPOWER,
0xF0, 0x80);
snd_soc_update_bits(codec, WCD9XXX_HPH_PA_CTL1,
0x0E, 0x06);
}
}
static void wcd_clsh_buck_ctrl(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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, WCD9XXX_ANA_RX_SUPPLIES,
(1 << 7), (enable << 7));
/*
* 500us sleep is required after buck enable/disable
* as per HW requirement
*/
usleep_range(500, 510);
if (mode == CLS_H_LOHIFI || mode == CLS_H_ULP ||
mode == CLS_H_HIFI || mode == CLS_H_LP)
snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_3,
0x02, 0x00);
snd_soc_update_bits(codec, WCD9XXX_CLASSH_MODE_2, 0xFF, 0x3A);
/* 500usec delay is needed as per HW requirement */
usleep_range(500, 500 + WCD_USLEEP_RANGE);
}
dev_dbg(codec->dev, "%s: buck_users %d, enable %d, mode: %s\n",
__func__, clsh_d->buck_users, enable, mode_to_str(mode));
}
static void wcd_clsh_flyback_ctrl(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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,
WCD9XXX_FLYBACK_VNEG_CTRL_1,
0xE0, 0xE0);
snd_soc_update_bits(codec,
WCD9XXX_ANA_RX_SUPPLIES,
(1 << 6), (enable << 6));
/*
* 100us sleep is required after flyback enable/disable
* as per HW requirement
*/
usleep_range(100, 110);
snd_soc_update_bits(codec, WCD9XXX_FLYBACK_VNEGDAC_CTRL_2,
0xE0, 0xE0);
/* 500usec delay is needed as per HW requirement */
usleep_range(500, 500 + WCD_USLEEP_RANGE);
}
dev_dbg(codec->dev, "%s: flyback_users %d, enable %d, mode: %s\n",
__func__, clsh_d->flyback_users, enable, mode_to_str(mode));
}
/*
* Function: wcd_clsh_set_hph_mode
* Params: soc component, hph mode class
* Description:
* This function updates class H mode configuration based on
* the input mode.
*/
void wcd_clsh_set_hph_mode(struct snd_soc_codec *codec,
int mode)
{
u8 val = 0;
switch (mode) {
case CLS_H_NORMAL:
val = 0x00;
break;
case CLS_AB:
case CLS_H_ULP:
val = 0x0C;
break;
case CLS_AB_HIFI:
case CLS_H_HIFI:
val = 0x08;
break;
case CLS_H_LP:
case CLS_H_LOHIFI:
case CLS_AB_LP:
case CLS_AB_LOHIFI:
val = 0x04;
break;
default:
dev_err(codec->dev, "%s:Invalid mode %d\n", __func__, mode);
return;
};
snd_soc_update_bits(codec, WCD9XXX_ANA_HPH, 0x0C, val);
}
EXPORT_SYMBOL(wcd_clsh_set_hph_mode);
static void wcd_clsh_set_flyback_current(struct snd_soc_codec *codec, int mode)
{
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0x0F, 0x0A);
snd_soc_update_bits(codec, WCD9XXX_RX_BIAS_FLYB_BUFF, 0xF0, 0xA0);
/* Sleep needed to avoid click and pop as per HW requirement */
usleep_range(100, 110);
}
static void wcd_clsh_set_buck_regulator_mode(struct snd_soc_codec *codec,
int mode)
{
snd_soc_update_bits(codec, WCD9XXX_ANA_RX_SUPPLIES,
0x02, 0x00);
}
static void wcd_clsh_state_ear_aux(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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");
}
static void wcd_clsh_state_hph_aux(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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");
}
static void wcd_clsh_state_hph_ear(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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");
}
static void wcd_clsh_state_hph_st(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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");
}
static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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_dbg(codec->dev, "%s: Normal mode not applicable for hph_r\n",
__func__);
return;
}
if (is_enable) {
wcd_clsh_set_buck_regulator_mode(codec, mode);
wcd_clsh_set_flyback_mode(codec, mode);
wcd_clsh_force_iq_ctl(codec, mode, true);
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_flyback_current(codec, mode);
wcd_clsh_set_buck_mode(codec, mode);
wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_hph_mode(codec, mode);
} else {
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
/* buck and flyback set to default mode and disable */
wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false);
wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL);
}
}
static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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_dbg(codec->dev, "%s: Normal mode not applicable for hph_l\n",
__func__);
return;
}
if (is_enable) {
wcd_clsh_set_buck_regulator_mode(codec, mode);
wcd_clsh_set_flyback_mode(codec, mode);
wcd_clsh_force_iq_ctl(codec, mode, true);
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_flyback_current(codec, mode);
wcd_clsh_set_buck_mode(codec, mode);
wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_hph_mode(codec, mode);
} else {
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
/* set buck and flyback to Default Mode */
wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false);
wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL);
}
}
static void wcd_clsh_state_aux(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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 (is_enable) {
wcd_clsh_set_buck_mode(codec, mode);
wcd_clsh_set_flyback_mode(codec, mode);
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_flyback_current(codec, mode);
wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
} else {
wcd_clsh_buck_ctrl(codec, clsh_d, mode, false);
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, false);
wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL);
}
}
static void wcd_clsh_state_ear(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *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 (is_enable) {
wcd_clsh_set_buck_regulator_mode(codec, mode);
wcd_clsh_set_flyback_mode(codec, mode);
wcd_clsh_force_iq_ctl(codec, mode, true);
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_flyback_current(codec, mode);
wcd_clsh_set_buck_mode(codec, mode);
wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
wcd_clsh_set_hph_mode(codec, mode);
} else {
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
/* set buck and flyback to Default Mode */
wcd_clsh_flyback_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
wcd_clsh_buck_ctrl(codec, clsh_d, CLS_H_NORMAL, false);
wcd_clsh_force_iq_ctl(codec, CLS_H_NORMAL, false);
wcd_clsh_set_flyback_mode(codec, CLS_H_NORMAL);
wcd_clsh_set_buck_mode(codec, CLS_H_NORMAL);
}
}
static void wcd_clsh_state_err(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *clsh_d,
u8 req_state, bool is_enable, int mode)
{
char msg[128];
dev_err(codec->dev,
"%s Wrong request for class H state machine requested to %s %s\n",
__func__, is_enable ? "enable" : "disable",
state_to_str(req_state, msg, sizeof(msg)));
}
/*
* Function: wcd_clsh_is_state_valid
* Params: state
* Description:
* Provides information on valid states of Class H configuration
*/
static bool wcd_clsh_is_state_valid(u8 state)
{
switch (state) {
case WCD_CLSH_STATE_IDLE:
case WCD_CLSH_STATE_EAR:
case WCD_CLSH_STATE_HPHL:
case WCD_CLSH_STATE_HPHR:
case WCD_CLSH_STATE_HPH_ST:
case WCD_CLSH_STATE_AUX:
case WCD_CLSH_STATE_HPHL_AUX:
case WCD_CLSH_STATE_HPHR_AUX:
case WCD_CLSH_STATE_HPH_ST_AUX:
case WCD_CLSH_STATE_EAR_AUX:
case WCD_CLSH_STATE_HPHL_EAR:
case WCD_CLSH_STATE_HPHR_EAR:
case WCD_CLSH_STATE_HPH_ST_EAR:
return true;
default:
return false;
};
}
/*
* Function: wcd_cls_h_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 wcd_cls_h_fsm(struct snd_soc_codec *codec,
struct wcd_clsh_cdc_info *cdc_clsh_d,
u8 clsh_event, u8 req_state,
int int_mode)
{
u8 old_state, new_state;
char msg0[128], msg1[128];
switch (clsh_event) {
case WCD_CLSH_EVENT_PRE_DAC:
old_state = cdc_clsh_d->state;
new_state = old_state | req_state;
if (!wcd_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, msg0, sizeof(msg0)));
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, msg0, sizeof(msg0)));
return;
}
cdc_clsh_d->state = new_state;
wcd_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, msg0, sizeof(msg0)),
state_to_str(cdc_clsh_d->state, msg1, sizeof(msg1)));
break;
case WCD_CLSH_EVENT_POST_PA:
old_state = cdc_clsh_d->state;
new_state = old_state & (~req_state);
if (new_state < NUM_CLSH_STATES) {
if (!wcd_clsh_is_state_valid(old_state)) {
dev_err(codec->dev,
"%s:Invalid old state:%s\n",
__func__,
state_to_str(old_state, msg0,
sizeof(msg0)));
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, msg0,
sizeof(msg0)));
return;
}
(*clsh_state_fp[old_state]) (codec, cdc_clsh_d,
req_state, CLSH_REQ_DISABLE,
int_mode);
cdc_clsh_d->state = new_state;
wcd_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, msg0,
sizeof(msg0)),
state_to_str(cdc_clsh_d->state, msg1,
sizeof(msg1)));
}
break;
};
}
EXPORT_SYMBOL(wcd_cls_h_fsm);
/*
* wcd_cls_h_init: Called to init clsh info
*
* @clsh: pointer for clsh state information.
*/
void wcd_cls_h_init(struct wcd_clsh_cdc_info *clsh)
{
int i;
clsh->state = WCD_CLSH_STATE_IDLE;
for (i = 0; i < NUM_CLSH_STATES; i++)
clsh_state_fp[i] = wcd_clsh_state_err;
clsh_state_fp[WCD_CLSH_STATE_EAR] = wcd_clsh_state_ear;
clsh_state_fp[WCD_CLSH_STATE_HPHL] = wcd_clsh_state_hph_l;
clsh_state_fp[WCD_CLSH_STATE_HPHR] = wcd_clsh_state_hph_r;
clsh_state_fp[WCD_CLSH_STATE_HPH_ST] = wcd_clsh_state_hph_st;
clsh_state_fp[WCD_CLSH_STATE_AUX] = wcd_clsh_state_aux;
clsh_state_fp[WCD_CLSH_STATE_HPHL_AUX] = wcd_clsh_state_hph_aux;
clsh_state_fp[WCD_CLSH_STATE_HPHR_AUX] = wcd_clsh_state_hph_aux;
clsh_state_fp[WCD_CLSH_STATE_HPH_ST_AUX] =
wcd_clsh_state_hph_aux;
clsh_state_fp[WCD_CLSH_STATE_EAR_AUX] = wcd_clsh_state_ear_aux;
clsh_state_fp[WCD_CLSH_STATE_HPHL_EAR] = wcd_clsh_state_hph_ear;
clsh_state_fp[WCD_CLSH_STATE_HPHR_EAR] = wcd_clsh_state_hph_ear;
clsh_state_fp[WCD_CLSH_STATE_HPH_ST_EAR] = wcd_clsh_state_hph_ear;
/* Set interpolaotr modes to NONE */
wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_EAR, CLS_NONE);
wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_HPHL, CLS_NONE);
wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_HPHR, CLS_NONE);
wcd_clsh_set_int_mode(clsh, WCD_CLSH_STATE_AUX, CLS_NONE);
clsh->flyback_users = 0;
clsh->buck_users = 0;
}
EXPORT_SYMBOL(wcd_cls_h_init);
MODULE_DESCRIPTION("WCD Class-H Driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,224 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
#include <linux/device.h>
#include <linux/err.h>
#include <linux/firmware.h>
#include <linux/elf.h>
#include <linux/slab.h>
#include <linux/list.h>
#include "wcd-dsp-utils.h"
static bool wdsp_is_valid_elf_hdr(const struct elf32_hdr *ehdr,
size_t fw_size)
{
if (fw_size < sizeof(*ehdr)) {
pr_err("%s: Firmware too small\n", __func__);
goto elf_check_fail;
}
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
pr_err("%s: Not an ELF file\n", __func__);
goto elf_check_fail;
}
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
pr_err("%s: Not an executable image\n", __func__);
goto elf_check_fail;
}
if (ehdr->e_phnum == 0) {
pr_err("%s: no segments to load\n", __func__);
goto elf_check_fail;
}
if (sizeof(struct elf32_phdr) * ehdr->e_phnum +
sizeof(struct elf32_hdr) > fw_size) {
pr_err("%s: Too small MDT file\n", __func__);
goto elf_check_fail;
}
return true;
elf_check_fail:
return false;
}
static int wdsp_add_segment_to_list(struct device *dev,
const char *img_fname,
const struct elf32_phdr *phdr,
int phdr_idx,
struct list_head *seg_list)
{
struct wdsp_img_segment *seg;
int ret = 0;
/* Do not load segments with zero size */
if (phdr->p_filesz == 0 || phdr->p_memsz == 0)
goto done;
seg = kzalloc(sizeof(*seg), GFP_KERNEL);
if (!seg) {
ret = -ENOMEM;
goto done;
}
snprintf(seg->split_fname, sizeof(seg->split_fname),
"%s.b%02d", img_fname, phdr_idx);
ret = request_firmware(&seg->split_fw, seg->split_fname, dev);
if (ret < 0) {
dev_err(dev, "%s: firmware %s not found\n",
__func__, seg->split_fname);
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;
list_add_tail(&seg->list, seg_list);
done:
return ret;
bad_elf:
release_firmware(seg->split_fw);
bad_seg:
kfree(seg);
return ret;
}
/*
* wdsp_flush_segment_list: Flush the list of segments
* @seg_list: List of segments to be flushed
* This API will traverse through the list of segments provided in
* seg_list, release the firmware for each segment and delete the
* segment from the list.
*/
void wdsp_flush_segment_list(struct list_head *seg_list)
{
struct wdsp_img_segment *seg, *next;
list_for_each_entry_safe(seg, next, seg_list, list) {
release_firmware(seg->split_fw);
list_del(&seg->list);
kfree(seg);
}
}
EXPORT_SYMBOL(wdsp_flush_segment_list);
/*
* wdsp_get_segment_list: Get the list of requested segments
* @dev: struct device pointer of caller
* @img_fname: Image name for the mdt and split firmware files
* @segment_type: Requested segment type, should be either
* WDSP_ELF_FLAG_RE or WDSP_ELF_FLAG_WRITE
* @seg_list: An initialized head for list of segmented to be returned
* @entry_point: Pointer to return the entry point of the image
* This API will parse the mdt file for img_fname and create
* an struct wdsp_img_segment for each segment that matches segment_type
* and add this structure to list pointed by seg_list
*/
int wdsp_get_segment_list(struct device *dev,
const char *img_fname,
unsigned int segment_type,
struct list_head *seg_list,
u32 *entry_point)
{
const struct firmware *fw;
const struct elf32_hdr *ehdr;
const struct elf32_phdr *phdr;
const u8 *elf_ptr;
char mdt_name[WDSP_IMG_NAME_LEN_MAX];
int ret, phdr_idx;
bool segment_match;
if (!dev) {
ret = -EINVAL;
pr_err("%s: Invalid device handle\n", __func__);
goto done;
}
if (!img_fname || !seg_list || !entry_point) {
ret = -EINVAL;
dev_err(dev, "%s: Invalid input params\n",
__func__);
goto done;
}
if (segment_type != WDSP_ELF_FLAG_RE &&
segment_type != WDSP_ELF_FLAG_WRITE) {
dev_err(dev, "%s: Invalid request for segment_type %d\n",
__func__, segment_type);
ret = -EINVAL;
goto done;
}
snprintf(mdt_name, sizeof(mdt_name), "%s.mdt", img_fname);
ret = request_firmware(&fw, mdt_name, dev);
if (ret < 0) {
dev_err(dev, "%s: firmware %s not found\n",
__func__, mdt_name);
goto done;
}
ehdr = (struct elf32_hdr *) fw->data;
*entry_point = ehdr->e_entry;
if (!wdsp_is_valid_elf_hdr(ehdr, fw->size)) {
dev_err(dev, "%s: fw mdt %s is invalid\n",
__func__, mdt_name);
ret = -EINVAL;
goto bad_elf;
}
elf_ptr = fw->data + sizeof(*ehdr);
for (phdr_idx = 0; phdr_idx < ehdr->e_phnum; phdr_idx++) {
phdr = (struct elf32_phdr *) elf_ptr;
segment_match = false;
switch (segment_type) {
case WDSP_ELF_FLAG_RE:
/*
* Flag can be READ or EXECUTE or both but
* WRITE flag should not be set.
*/
if ((phdr->p_flags & segment_type) &&
!(phdr->p_flags & WDSP_ELF_FLAG_WRITE))
segment_match = true;
break;
case WDSP_ELF_FLAG_WRITE:
/*
* If WRITE flag is set, other flags do not
* matter.
*/
if (phdr->p_flags & segment_type)
segment_match = true;
break;
}
if (segment_match) {
ret = wdsp_add_segment_to_list(dev, img_fname, phdr,
phdr_idx, seg_list);
if (ret < 0) {
wdsp_flush_segment_list(seg_list);
goto bad_elf;
}
}
elf_ptr = elf_ptr + sizeof(*phdr);
}
bad_elf:
release_firmware(fw);
done:
return ret;
}
EXPORT_SYMBOL(wdsp_get_segment_list);

View File

@@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD_DSP_UTILS_H__
#define __WCD_DSP_UTILS_H__
#define WDSP_IMG_NAME_LEN_MAX 64
#define WDSP_ELF_FLAG_EXECUTE (1 << 0)
#define WDSP_ELF_FLAG_WRITE (1 << 1)
#define WDSP_ELF_FLAG_READ (1 << 2)
#define WDSP_ELF_FLAG_RE (WDSP_ELF_FLAG_READ | WDSP_ELF_FLAG_EXECUTE)
struct wdsp_img_segment {
/* Firmware for the slit image */
const struct firmware *split_fw;
/* Name of the split firmware file */
char split_fname[WDSP_IMG_NAME_LEN_MAX];
/* Address where the segment is to be loaded */
u32 load_addr;
/* Buffer to hold the data to be loaded */
u8 *data;
/* Size of the data to be loaded */
size_t size;
/* List node pointing to next segment */
struct list_head list;
};
int wdsp_get_segment_list(struct device *dev, const char *img_fname,
unsigned int segment_type, struct list_head *seg_list,
u32 *entry_point);
void wdsp_flush_segment_list(struct list_head *seg_list);
#endif /* __WCD_DSP_UTILS_H__ */

View File

@@ -0,0 +1,183 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/irqdomain.h>
#include <linux/regmap.h>
#include <asoc/wcd-irq.h>
static int wcd_map_irq(struct wcd_irq_info *irq_info, int irq)
{
if (!irq_info) {
pr_err("%s: Null IRQ handle\n", __func__);
return -EINVAL;
}
return regmap_irq_get_virq(irq_info->irq_chip, irq);
}
/**
* wcd_request_irq: Request a thread handler for the given IRQ
* @irq_info: pointer to IRQ info 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 wcd_request_irq(struct wcd_irq_info *irq_info, int irq, const char *name,
irq_handler_t handler, void *data)
{
if (!irq_info) {
pr_err("%s: Null IRQ handle\n", __func__);
return -EINVAL;
}
irq = wcd_map_irq(irq_info, irq);
if (irq < 0)
return irq;
return request_threaded_irq(irq, NULL, handler,
IRQF_ONESHOT | IRQF_TRIGGER_RISING,
name, data);
}
EXPORT_SYMBOL(wcd_request_irq);
/**
* wcd_free_irq: Free the IRQ resources allocated during request_irq
* @irq_info: pointer to IRQ info structure
* @irq: irq number
* @data: data pointer
*/
void wcd_free_irq(struct wcd_irq_info *irq_info, int irq, void *data)
{
if (!irq_info) {
pr_err("%s: Null IRQ handle\n", __func__);
return;
}
irq = wcd_map_irq(irq_info, irq);
if (irq < 0)
return;
free_irq(irq, data);
}
EXPORT_SYMBOL(wcd_free_irq);
/**
* wcd_enable_irq: Enable the given IRQ
* @irq_info: pointer to IRQ info structure
* @irq: irq number
*/
void wcd_enable_irq(struct wcd_irq_info *irq_info, int irq)
{
if (!irq_info)
pr_err("%s: Null IRQ handle\n", __func__);
else
enable_irq(wcd_map_irq(irq_info, irq));
}
EXPORT_SYMBOL(wcd_enable_irq);
/**
* wcd_disable_irq: Disable the given IRQ
* @irq_info: pointer to IRQ info structure
* @irq: irq number
*/
void wcd_disable_irq(struct wcd_irq_info *irq_info, int irq)
{
if (!irq_info)
pr_err("%s: Null IRQ handle\n", __func__);
else
disable_irq_nosync(wcd_map_irq(irq_info, irq));
}
EXPORT_SYMBOL(wcd_disable_irq);
static void wcd_irq_chip_disable(struct irq_data *data)
{
}
static void wcd_irq_chip_enable(struct irq_data *data)
{
}
static struct irq_chip wcd_irq_chip = {
.name = NULL,
.irq_disable = wcd_irq_chip_disable,
.irq_enable = wcd_irq_chip_enable,
};
static struct lock_class_key wcd_irq_lock_class;
static int wcd_irq_chip_map(struct irq_domain *irqd, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(virq, &wcd_irq_chip, handle_simple_irq);
irq_set_lockdep_class(virq, &wcd_irq_lock_class);
irq_set_nested_thread(virq, 1);
irq_set_noprobe(virq);
return 0;
}
static const struct irq_domain_ops wcd_domain_ops = {
.map = wcd_irq_chip_map,
};
/**
* wcd_irq_init: Initializes IRQ module
* @irq_info: pointer to IRQ info structure
*
* Returns 0 on success or error on failure
*/
int wcd_irq_init(struct wcd_irq_info *irq_info, struct irq_domain **virq)
{
int ret = 0;
if (!irq_info) {
pr_err("%s: Null IRQ handle\n", __func__);
return -EINVAL;
}
wcd_irq_chip.name = irq_info->codec_name;
*virq = irq_domain_add_linear(NULL, 1, &wcd_domain_ops, NULL);
if (!(*virq)) {
pr_err("%s: Failed to add IRQ domain\n", __func__);
return -EINVAL;
}
ret = devm_regmap_add_irq_chip(irq_info->dev, irq_info->regmap,
irq_create_mapping(*virq, 0),
IRQF_ONESHOT, 0, irq_info->wcd_regmap_irq_chip,
&irq_info->irq_chip);
if (ret)
pr_err("%s: Failed to add IRQs: %d\n",
__func__, ret);
return ret;
}
EXPORT_SYMBOL(wcd_irq_init);
/**
* wcd_irq_exit: Uninitialize regmap IRQ and free IRQ resources
* @irq_info: pointer to IRQ info structure
*
* Returns 0 on success or error on failure
*/
int wcd_irq_exit(struct wcd_irq_info *irq_info, struct irq_domain *virq)
{
if (!irq_info) {
pr_err("%s: Null pointer handle\n", __func__);
return -EINVAL;
}
regmap_del_irq_chip(irq_find_mapping(virq, 0), irq_info->irq_chip);
return 0;
}
EXPORT_SYMBOL(wcd_irq_exit);

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD_MBHC_ADC_H__
#define __WCD_MBHC_ADC_H__
#include <asoc/wcd-mbhc-v2.h>
enum wcd_mbhc_adc_mux_ctl {
MUX_CTL_AUTO = 0,
MUX_CTL_IN2P,
MUX_CTL_IN3P,
MUX_CTL_IN4P,
MUX_CTL_HPH_L,
MUX_CTL_HPH_R,
MUX_CTL_NONE,
};
#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC_ADC)
void wcd_mbhc_adc_init(struct wcd_mbhc *mbhc);
#else
static inline void wcd_mbhc_adc_init(struct wcd_mbhc *mbhc)
{
}
#endif
#endif /* __WCD_MBHC_ADC_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD_MBHC_LEGACY_H__
#define __WCD_MBHC_LEGACY_H__
#include <asoc/wcdcal-hwdep.h>
#include <asoc/wcd-mbhc-v2.h>
#if IS_ENABLED(CONFIG_SND_SOC_WCD_MBHC_LEGACY)
void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc);
#else
static inline void wcd_mbhc_legacy_init(struct wcd_mbhc *mbhc)
{
}
#endif
#endif /* __WCD_MBHC_LEGACY_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD_SPI_REGISTERS_H__
#define __WCD_SPI_REGISTERS_H__
#include <linux/regmap.h>
#define WCD_SPI_SLAVE_SANITY (0x00)
#define WCD_SPI_SLAVE_DEVICE_ID (0x04)
#define WCD_SPI_SLAVE_STATUS (0x08)
#define WCD_SPI_SLAVE_CONFIG (0x0c)
#define WCD_SPI_SLAVE_SW_RESET (0x10)
#define WCD_SPI_SLAVE_IRQ_STATUS (0x14)
#define WCD_SPI_SLAVE_IRQ_EN (0x18)
#define WCD_SPI_SLAVE_IRQ_CLR (0x1c)
#define WCD_SPI_SLAVE_IRQ_FORCE (0x20)
#define WCD_SPI_SLAVE_TX (0x24)
#define WCD_SPI_SLAVE_TEST_BUS_DATA (0x2c)
#define WCD_SPI_SLAVE_TEST_BUS_CTRL (0x30)
#define WCD_SPI_SLAVE_SW_RST_IRQ (0x34)
#define WCD_SPI_SLAVE_CHAR_CFG (0x38)
#define WCD_SPI_SLAVE_CHAR_DATA_MOSI (0x3c)
#define WCD_SPI_SLAVE_CHAR_DATA_CS_N (0x40)
#define WCD_SPI_SLAVE_CHAR_DATA_MISO (0x44)
#define WCD_SPI_SLAVE_TRNS_BYTE_CNT (0x4c)
#define WCD_SPI_SLAVE_TRNS_LEN (0x50)
#define WCD_SPI_SLAVE_FIFO_LEVEL (0x54)
#define WCD_SPI_SLAVE_GENERICS (0x58)
#define WCD_SPI_SLAVE_EXT_BASE_ADDR (0x5c)
#define WCD_SPI_MAX_REGISTER (0x5F)
#endif /* End __WCD_SPI_REGISTERS_H__ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,61 @@
# 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,$(MSMSTEPPE) $(TRINKET)),true)
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
ifeq ($(call is-board-platform,atoll),true)
AUDIO_SELECT := CONFIG_SND_SOC_ATOLL=m
endif
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) atoll),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 := $(shell pwd)/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=wcd937x_dlkm
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
KBUILD_OPTIONS += $(AUDIO_SELECT)
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd937x.ko
LOCAL_MODULE_KBUILD_NAME := wcd937x_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd937x_slave.ko
LOCAL_MODULE_KBUILD_NAME := wcd937x_slave_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

View File

@@ -0,0 +1,132 @@
# 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.19
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_ATOLL), y)
include $(AUDIO_ROOT)/4.0/config/atollauto.conf
export
INCS += -include $(AUDIO_ROOT)/4.0/config/atollautoconf.h
endif
ifeq ($(CONFIG_ARCH_TRINKET), y)
include $(AUDIO_ROOT)/config/sm6150auto.conf
export
INCS += -include $(AUDIO_ROOT)/config/sm6150autoconf.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
UAPI_DIR := uapi
UAPI_INC := -I$(AUDIO_ROOT)/4.0/include/$(UAPI_DIR)
COMMON_DIR := include
COMMON_INC := -I$(AUDIO_ROOT)/4.0/$(COMMON_DIR)
endif
############ WCD937X ############
# for WCD937X Codec
ifdef CONFIG_SND_SOC_WCD937X
WCD937X_OBJS += wcd937x.o
WCD937X_OBJS += wcd937x-regmap.o
WCD937X_OBJS += wcd937x-tables.o
WCD937X_OBJS += wcd937x-mbhc.o
endif
ifdef CONFIG_SND_SOC_WCD937X_SLAVE
WCD937X_SLAVE_OBJS += wcd937x_slave.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/ipc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/soc/Module.symvers
else
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
endif
# Module information used by KBuild framework
obj-$(CONFIG_SND_SOC_WCD937X) += wcd937x_dlkm.o
wcd937x_dlkm-y := $(WCD937X_OBJS)
obj-$(CONFIG_SND_SOC_WCD937X_SLAVE) += wcd937x_slave_dlkm.o
wcd937x_slave_dlkm-y := $(WCD937X_SLAVE_OBJS)
# inject some build related information

View File

@@ -0,0 +1,178 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD937X_INTERNAL_H
#define _WCD937X_INTERNAL_H
#include <asoc/wcd-clsh.h>
#include <asoc/wcd-mbhc-v2.h>
#include <asoc/wcd-irq.h>
#include "wcd937x-mbhc.h"
#define WCD937X_MAX_MICBIAS 3
/* Convert from vout ctl to micbias voltage in mV */
#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
#define MAX_PORT 8
#define MAX_CH_PER_PORT 8
extern struct regmap_config wcd937x_regmap_config;
struct codec_port_info {
u32 slave_port_type;
u32 master_port_type;
u32 ch_mask;
u32 num_ch;
u32 ch_rate;
};
struct wcd937x_priv {
struct device *dev;
int variant;
struct snd_soc_codec *codec;
struct device_node *rst_np;
struct regmap *regmap;
struct swr_device *rx_swr_dev;
struct swr_device *tx_swr_dev;
s32 micb_ref[WCD937X_MAX_MICBIAS];
s32 pullup_ref[WCD937X_MAX_MICBIAS];
struct fw_info *fw_data;
struct device_node *wcd_rst_np;
struct mutex micb_lock;
s32 dmic_0_1_clk_cnt;
s32 dmic_2_3_clk_cnt;
s32 dmic_4_5_clk_cnt;
/* class h specific info */
struct wcd_clsh_cdc_info clsh_info;
/* mbhc module */
struct wcd937x_mbhc *mbhc;
u32 hph_mode;
bool comp1_enable;
bool comp2_enable;
struct irq_domain *virq;
struct wcd_irq_info irq_info;
u32 rx_clk_cnt;
int num_irq_regs;
/* to track the status */
unsigned long status_mask;
u8 num_tx_ports;
u8 num_rx_ports;
struct codec_port_info
tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
struct codec_port_info
rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
struct regulator_bulk_data *supplies;
struct notifier_block nblock;
/* wcd callback to bolero */
void *handle;
int (*update_wcd_event)(void *handle, u16 event, u32 data);
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
int (*wakeup)(void *handle, bool enable);
u32 version;
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
/*Entry for Variant info*/
struct snd_info_entry *variant_entry;
int ear_rx_path;
int ana_clk_count;
struct mutex ana_tx_clk_lock;
};
struct wcd937x_micbias_setting {
u8 ldoh_v;
u32 cfilt1_mv;
u32 micb1_mv;
u32 micb2_mv;
u32 micb3_mv;
u8 bias1_cfilt_sel;
};
struct wcd937x_pdata {
struct device_node *rst_np;
struct device_node *rx_slave;
struct device_node *tx_slave;
struct wcd937x_micbias_setting micbias;
struct cdc_regulator *regulator;
int num_supplies;
};
struct wcd_ctrl_platform_data {
void *handle;
int (*update_wcd_event)(void *handle, u16 event, u32 data);
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
};
enum {
WCD_RX1,
WCD_RX2,
WCD_RX3
};
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
};
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
};
enum {
/* INTR_CTRL_INT_MASK_0 */
WCD937X_IRQ_MBHC_BUTTON_PRESS_DET = 0,
WCD937X_IRQ_MBHC_BUTTON_RELEASE_DET,
WCD937X_IRQ_MBHC_ELECT_INS_REM_DET,
WCD937X_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
WCD937X_IRQ_MBHC_SW_DET,
WCD937X_IRQ_HPHR_OCP_INT,
WCD937X_IRQ_HPHR_CNP_INT,
WCD937X_IRQ_HPHL_OCP_INT,
/* INTR_CTRL_INT_MASK_1 */
WCD937X_IRQ_HPHL_CNP_INT,
WCD937X_IRQ_EAR_CNP_INT,
WCD937X_IRQ_EAR_SCD_INT,
WCD937X_IRQ_AUX_CNP_INT,
WCD937X_IRQ_AUX_SCD_INT,
WCD937X_IRQ_HPHL_PDM_WD_INT,
WCD937X_IRQ_HPHR_PDM_WD_INT,
WCD937X_IRQ_AUX_PDM_WD_INT,
/* INTR_CTRL_INT_MASK_2 */
WCD937X_IRQ_LDORT_SCD_INT,
WCD937X_IRQ_MBHC_MOISTURE_INT,
WCD937X_IRQ_HPHL_SURGE_DET_INT,
WCD937X_IRQ_HPHR_SURGE_DET_INT,
WCD937X_NUM_IRQS,
};
extern void wcd937x_disable_bcs_before_slow_insert(
struct snd_soc_codec *codec,
bool bcs_disable);
extern struct wcd937x_mbhc *wcd937x_soc_get_mbhc(struct snd_soc_codec *codec);
extern int wcd937x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
int volt, int micb_num);
extern int wcd937x_get_micb_vout_ctl_val(u32 micb_mv);
extern int wcd937x_micbias_control(struct snd_soc_codec *codec, int micb_num,
int req, bool is_dapm);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD937X_MBHC_H__
#define __WCD937X_MBHC_H__
#include <asoc/wcd-mbhc-v2.h>
struct wcd937x_mbhc {
struct wcd_mbhc wcd_mbhc;
struct blocking_notifier_head notifier;
struct fw_info *fw_data;
};
#if IS_ENABLED(CONFIG_SND_SOC_WCD937X)
extern int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc,
struct snd_soc_codec *codec,
struct fw_info *fw_data);
extern void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec);
extern int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec,
struct wcd_mbhc_config *mbhc_cfg);
extern void wcd937x_mbhc_deinit(struct snd_soc_codec *codec);
extern int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc,
struct snd_soc_codec *codec);
extern void wcd937x_mbhc_ssr_down(struct wcd937x_mbhc *mbhc,
struct snd_soc_codec *codec);
extern int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc,
uint32_t *zl, uint32_t *zr);
#else
static inline int wcd937x_mbhc_init(struct wcd937x_mbhc **mbhc,
struct snd_soc_codec *codec,
struct fw_info *fw_data)
{
return 0;
}
static inline void wcd937x_mbhc_hs_detect_exit(struct snd_soc_codec *codec)
{
}
static inline int wcd937x_mbhc_hs_detect(struct snd_soc_codec *codec,
struct wcd_mbhc_config *mbhc_cfg)
{
return 0;
}
static inline void wcd937x_mbhc_deinit(struct snd_soc_codec *codec)
{
}
static inline int wcd937x_mbhc_post_ssr_init(struct wcd937x_mbhc *mbhc,
struct snd_soc_codec *codec)
{
return 0;
}
static inline void wcd937x_mbhc_ssr_down(struct wcd937x_mbhc *mbhc,
struct snd_soc_component *component)
{
}
static inline int wcd937x_mbhc_get_impedance(struct wcd937x_mbhc *wcd937x_mbhc,
uint32_t *zl, uint32_t *zr)
{
if (zl)
*zl = 0;
if (zr)
*zr = 0;
return -EINVAL;
}
#endif
#endif /* __WCD937X_MBHC_H__ */

View File

@@ -0,0 +1,438 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD937X_REGISTERS_H
#define _WCD937X_REGISTERS_H
#define WCD937X_BASE_ADDRESS 0x3000
#define WCD937X_REG(reg) (reg - WCD937X_BASE_ADDRESS)
enum {
REG_NO_ACCESS,
RD_REG,
WR_REG,
RD_WR_REG
};
#define WCD937X_ANA_BIAS (WCD937X_BASE_ADDRESS+0x001)
#define WCD937X_ANA_RX_SUPPLIES (WCD937X_BASE_ADDRESS+0x008)
#define WCD937X_ANA_HPH (WCD937X_BASE_ADDRESS+0x009)
#define WCD937X_ANA_EAR (WCD937X_BASE_ADDRESS+0x00A)
#define WCD937X_ANA_EAR_COMPANDER_CTL (WCD937X_BASE_ADDRESS+0x00B)
#define WCD937X_ANA_TX_CH1 (WCD937X_BASE_ADDRESS+0x00E)
#define WCD937X_ANA_TX_CH2 (WCD937X_BASE_ADDRESS+0x00F)
#define WCD937X_ANA_TX_CH3 (WCD937X_BASE_ADDRESS+0x010)
#define WCD937X_ANA_TX_CH3_HPF (WCD937X_BASE_ADDRESS+0x011)
#define WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC (WCD937X_BASE_ADDRESS+0x012)
#define WCD937X_ANA_MICB3_DSP_EN_LOGIC (WCD937X_BASE_ADDRESS+0x013)
#define WCD937X_ANA_MBHC_MECH (WCD937X_BASE_ADDRESS+0x014)
#define WCD937X_ANA_MBHC_ELECT (WCD937X_BASE_ADDRESS+0x015)
#define WCD937X_ANA_MBHC_ZDET (WCD937X_BASE_ADDRESS+0x016)
#define WCD937X_ANA_MBHC_RESULT_1 (WCD937X_BASE_ADDRESS+0x017)
#define WCD937X_ANA_MBHC_RESULT_2 (WCD937X_BASE_ADDRESS+0x018)
#define WCD937X_ANA_MBHC_RESULT_3 (WCD937X_BASE_ADDRESS+0x019)
#define WCD937X_ANA_MBHC_BTN0 (WCD937X_BASE_ADDRESS+0x01A)
#define WCD937X_ANA_MBHC_BTN1 (WCD937X_BASE_ADDRESS+0x01B)
#define WCD937X_ANA_MBHC_BTN2 (WCD937X_BASE_ADDRESS+0x01C)
#define WCD937X_ANA_MBHC_BTN3 (WCD937X_BASE_ADDRESS+0x01D)
#define WCD937X_ANA_MBHC_BTN4 (WCD937X_BASE_ADDRESS+0x01E)
#define WCD937X_ANA_MBHC_BTN5 (WCD937X_BASE_ADDRESS+0x01F)
#define WCD937X_ANA_MBHC_BTN6 (WCD937X_BASE_ADDRESS+0x020)
#define WCD937X_ANA_MBHC_BTN7 (WCD937X_BASE_ADDRESS+0x021)
#define WCD937X_ANA_MICB1 (WCD937X_BASE_ADDRESS+0x022)
#define WCD937X_ANA_MICB2 (WCD937X_BASE_ADDRESS+0x023)
#define WCD937X_ANA_MICB2_RAMP (WCD937X_BASE_ADDRESS+0x024)
#define WCD937X_ANA_MICB3 (WCD937X_BASE_ADDRESS+0x025)
#define WCD937X_BIAS_CTL (WCD937X_BASE_ADDRESS+0x028)
#define WCD937X_BIAS_VBG_FINE_ADJ (WCD937X_BASE_ADDRESS+0x029)
#define WCD937X_LDOL_VDDCX_ADJUST (WCD937X_BASE_ADDRESS+0x040)
#define WCD937X_LDOL_DISABLE_LDOL (WCD937X_BASE_ADDRESS+0x041)
#define WCD937X_MBHC_CTL_CLK (WCD937X_BASE_ADDRESS+0x056)
#define WCD937X_MBHC_CTL_ANA (WCD937X_BASE_ADDRESS+0x057)
#define WCD937X_MBHC_CTL_SPARE_1 (WCD937X_BASE_ADDRESS+0x058)
#define WCD937X_MBHC_CTL_SPARE_2 (WCD937X_BASE_ADDRESS+0x059)
#define WCD937X_MBHC_CTL_BCS (WCD937X_BASE_ADDRESS+0x05A)
#define WCD937X_MBHC_MOISTURE_DET_FSM_STATUS (WCD937X_BASE_ADDRESS+0x05B)
#define WCD937X_MBHC_TEST_CTL (WCD937X_BASE_ADDRESS+0x05C)
#define WCD937X_LDOH_MODE (WCD937X_BASE_ADDRESS+0x067)
#define WCD937X_LDOH_BIAS (WCD937X_BASE_ADDRESS+0x068)
#define WCD937X_LDOH_STB_LOADS (WCD937X_BASE_ADDRESS+0x069)
#define WCD937X_LDOH_SLOWRAMP (WCD937X_BASE_ADDRESS+0x06A)
#define WCD937X_MICB1_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x06B)
#define WCD937X_MICB1_TEST_CTL_2 (WCD937X_BASE_ADDRESS+0x06C)
#define WCD937X_MICB1_TEST_CTL_3 (WCD937X_BASE_ADDRESS+0x06D)
#define WCD937X_MICB2_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x06E)
#define WCD937X_MICB2_TEST_CTL_2 (WCD937X_BASE_ADDRESS+0x06F)
#define WCD937X_MICB2_TEST_CTL_3 (WCD937X_BASE_ADDRESS+0x070)
#define WCD937X_MICB3_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x071)
#define WCD937X_MICB3_TEST_CTL_2 (WCD937X_BASE_ADDRESS+0x072)
#define WCD937X_MICB3_TEST_CTL_3 (WCD937X_BASE_ADDRESS+0x073)
#define WCD937X_TX_COM_ADC_VCM (WCD937X_BASE_ADDRESS+0x077)
#define WCD937X_TX_COM_BIAS_ATEST (WCD937X_BASE_ADDRESS+0x078)
#define WCD937X_TX_COM_ADC_INT1_IB (WCD937X_BASE_ADDRESS+0x079)
#define WCD937X_TX_COM_ADC_INT2_IB (WCD937X_BASE_ADDRESS+0x07A)
#define WCD937X_TX_COM_TXFE_DIV_CTL (WCD937X_BASE_ADDRESS+0x07B)
#define WCD937X_TX_COM_TXFE_DIV_START (WCD937X_BASE_ADDRESS+0x07C)
#define WCD937X_TX_COM_TXFE_DIV_STOP_9P6M (WCD937X_BASE_ADDRESS+0x07D)
#define WCD937X_TX_COM_TXFE_DIV_STOP_12P288M (WCD937X_BASE_ADDRESS+0x07E)
#define WCD937X_TX_1_2_TEST_EN (WCD937X_BASE_ADDRESS+0x07F)
#define WCD937X_TX_1_2_ADC_IB (WCD937X_BASE_ADDRESS+0x080)
#define WCD937X_TX_1_2_ATEST_REFCTL (WCD937X_BASE_ADDRESS+0x081)
#define WCD937X_TX_1_2_TEST_CTL (WCD937X_BASE_ADDRESS+0x082)
#define WCD937X_TX_1_2_TEST_BLK_EN (WCD937X_BASE_ADDRESS+0x083)
#define WCD937X_TX_1_2_TXFE_CLKDIV (WCD937X_BASE_ADDRESS+0x084)
#define WCD937X_TX_1_2_SAR2_ERR (WCD937X_BASE_ADDRESS+0x085)
#define WCD937X_TX_1_2_SAR1_ERR (WCD937X_BASE_ADDRESS+0x086)
#define WCD937X_TX_3_TEST_EN (WCD937X_BASE_ADDRESS+0x087)
#define WCD937X_TX_3_ADC_IB (WCD937X_BASE_ADDRESS+0x088)
#define WCD937X_TX_3_ATEST_REFCTL (WCD937X_BASE_ADDRESS+0x089)
#define WCD937X_TX_3_TEST_CTL (WCD937X_BASE_ADDRESS+0x08A)
#define WCD937X_TX_3_TEST_BLK_EN (WCD937X_BASE_ADDRESS+0x08B)
#define WCD937X_TX_3_TXFE_CLKDIV (WCD937X_BASE_ADDRESS+0x08C)
#define WCD937X_TX_3_SPARE_MONO (WCD937X_BASE_ADDRESS+0x08D)
#define WCD937X_TX_3_SAR1_ERR (WCD937X_BASE_ADDRESS+0x08E)
#define WCD937X_CLASSH_MODE_1 (WCD937X_BASE_ADDRESS+0x097)
#define WCD937X_CLASSH_MODE_2 (WCD937X_BASE_ADDRESS+0x098)
#define WCD937X_CLASSH_MODE_3 (WCD937X_BASE_ADDRESS+0x099)
#define WCD937X_CLASSH_CTRL_VCL_1 (WCD937X_BASE_ADDRESS+0x09A)
#define WCD937X_CLASSH_CTRL_VCL_2 (WCD937X_BASE_ADDRESS+0x09B)
#define WCD937X_CLASSH_CTRL_CCL_1 (WCD937X_BASE_ADDRESS+0x09C)
#define WCD937X_CLASSH_CTRL_CCL_2 (WCD937X_BASE_ADDRESS+0x09D)
#define WCD937X_CLASSH_CTRL_CCL_3 (WCD937X_BASE_ADDRESS+0x09E)
#define WCD937X_CLASSH_CTRL_CCL_4 (WCD937X_BASE_ADDRESS+0x09F)
#define WCD937X_CLASSH_CTRL_CCL_5 (WCD937X_BASE_ADDRESS+0x0A0)
#define WCD937X_CLASSH_BUCK_TMUX_A_D (WCD937X_BASE_ADDRESS+0x0A1)
#define WCD937X_CLASSH_BUCK_SW_DRV_CNTL (WCD937X_BASE_ADDRESS+0x0A2)
#define WCD937X_CLASSH_SPARE (WCD937X_BASE_ADDRESS+0x0A3)
#define WCD937X_FLYBACK_EN (WCD937X_BASE_ADDRESS+0x0A4)
#define WCD937X_FLYBACK_VNEG_CTRL_1 (WCD937X_BASE_ADDRESS+0x0A5)
#define WCD937X_FLYBACK_VNEG_CTRL_2 (WCD937X_BASE_ADDRESS+0x0A6)
#define WCD937X_FLYBACK_VNEG_CTRL_3 (WCD937X_BASE_ADDRESS+0x0A7)
#define WCD937X_FLYBACK_VNEG_CTRL_4 (WCD937X_BASE_ADDRESS+0x0A8)
#define WCD937X_FLYBACK_VNEG_CTRL_5 (WCD937X_BASE_ADDRESS+0x0A9)
#define WCD937X_FLYBACK_VNEG_CTRL_6 (WCD937X_BASE_ADDRESS+0x0AA)
#define WCD937X_FLYBACK_VNEG_CTRL_7 (WCD937X_BASE_ADDRESS+0x0AB)
#define WCD937X_FLYBACK_VNEG_CTRL_8 (WCD937X_BASE_ADDRESS+0x0AC)
#define WCD937X_FLYBACK_VNEG_CTRL_9 (WCD937X_BASE_ADDRESS+0x0AD)
#define WCD937X_FLYBACK_VNEGDAC_CTRL_1 (WCD937X_BASE_ADDRESS+0x0AE)
#define WCD937X_FLYBACK_VNEGDAC_CTRL_2 (WCD937X_BASE_ADDRESS+0x0AF)
#define WCD937X_FLYBACK_VNEGDAC_CTRL_3 (WCD937X_BASE_ADDRESS+0x0B0)
#define WCD937X_FLYBACK_CTRL_1 (WCD937X_BASE_ADDRESS+0x0B1)
#define WCD937X_FLYBACK_TEST_CTL (WCD937X_BASE_ADDRESS+0x0B2)
#define WCD937X_RX_AUX_SW_CTL (WCD937X_BASE_ADDRESS+0x0B3)
#define WCD937X_RX_PA_AUX_IN_CONN (WCD937X_BASE_ADDRESS+0x0B4)
#define WCD937X_RX_TIMER_DIV (WCD937X_BASE_ADDRESS+0x0B5)
#define WCD937X_RX_OCP_CTL (WCD937X_BASE_ADDRESS+0x0B6)
#define WCD937X_RX_OCP_COUNT (WCD937X_BASE_ADDRESS+0x0B7)
#define WCD937X_RX_BIAS_EAR_DAC (WCD937X_BASE_ADDRESS+0x0B8)
#define WCD937X_RX_BIAS_EAR_AMP (WCD937X_BASE_ADDRESS+0x0B9)
#define WCD937X_RX_BIAS_HPH_LDO (WCD937X_BASE_ADDRESS+0x0BA)
#define WCD937X_RX_BIAS_HPH_PA (WCD937X_BASE_ADDRESS+0x0BB)
#define WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2 (WCD937X_BASE_ADDRESS+0x0BC)
#define WCD937X_RX_BIAS_HPH_RDAC_LDO (WCD937X_BASE_ADDRESS+0x0BD)
#define WCD937X_RX_BIAS_HPH_CNP1 (WCD937X_BASE_ADDRESS+0x0BE)
#define WCD937X_RX_BIAS_HPH_LOWPOWER (WCD937X_BASE_ADDRESS+0x0BF)
#define WCD937X_RX_BIAS_AUX_DAC (WCD937X_BASE_ADDRESS+0x0C0)
#define WCD937X_RX_BIAS_AUX_AMP (WCD937X_BASE_ADDRESS+0x0C1)
#define WCD937X_RX_BIAS_VNEGDAC_BLEEDER (WCD937X_BASE_ADDRESS+0x0C2)
#define WCD937X_RX_BIAS_MISC (WCD937X_BASE_ADDRESS+0x0C3)
#define WCD937X_RX_BIAS_BUCK_RST (WCD937X_BASE_ADDRESS+0x0C4)
#define WCD937X_RX_BIAS_BUCK_VREF_ERRAMP (WCD937X_BASE_ADDRESS+0x0C5)
#define WCD937X_RX_BIAS_FLYB_ERRAMP (WCD937X_BASE_ADDRESS+0x0C6)
#define WCD937X_RX_BIAS_FLYB_BUFF (WCD937X_BASE_ADDRESS+0x0C7)
#define WCD937X_RX_BIAS_FLYB_MID_RST (WCD937X_BASE_ADDRESS+0x0C8)
#define WCD937X_HPH_L_STATUS (WCD937X_BASE_ADDRESS+0x0C9)
#define WCD937X_HPH_R_STATUS (WCD937X_BASE_ADDRESS+0x0CA)
#define WCD937X_HPH_CNP_EN (WCD937X_BASE_ADDRESS+0x0CB)
#define WCD937X_HPH_CNP_WG_CTL (WCD937X_BASE_ADDRESS+0x0CC)
#define WCD937X_HPH_CNP_WG_TIME (WCD937X_BASE_ADDRESS+0x0CD)
#define WCD937X_HPH_OCP_CTL (WCD937X_BASE_ADDRESS+0x0CE)
#define WCD937X_HPH_AUTO_CHOP (WCD937X_BASE_ADDRESS+0x0CF)
#define WCD937X_HPH_CHOP_CTL (WCD937X_BASE_ADDRESS+0x0D0)
#define WCD937X_HPH_PA_CTL1 (WCD937X_BASE_ADDRESS+0x0D1)
#define WCD937X_HPH_PA_CTL2 (WCD937X_BASE_ADDRESS+0x0D2)
#define WCD937X_HPH_L_EN (WCD937X_BASE_ADDRESS+0x0D3)
#define WCD937X_HPH_L_TEST (WCD937X_BASE_ADDRESS+0x0D4)
#define WCD937X_HPH_L_ATEST (WCD937X_BASE_ADDRESS+0x0D5)
#define WCD937X_HPH_R_EN (WCD937X_BASE_ADDRESS+0x0D6)
#define WCD937X_HPH_R_TEST (WCD937X_BASE_ADDRESS+0x0D7)
#define WCD937X_HPH_R_ATEST (WCD937X_BASE_ADDRESS+0x0D8)
#define WCD937X_HPH_RDAC_CLK_CTL1 (WCD937X_BASE_ADDRESS+0x0D9)
#define WCD937X_HPH_RDAC_CLK_CTL2 (WCD937X_BASE_ADDRESS+0x0DA)
#define WCD937X_HPH_RDAC_LDO_CTL (WCD937X_BASE_ADDRESS+0x0DB)
#define WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL (WCD937X_BASE_ADDRESS+0x0DC)
#define WCD937X_HPH_REFBUFF_UHQA_CTL (WCD937X_BASE_ADDRESS+0x0DD)
#define WCD937X_HPH_REFBUFF_LP_CTL (WCD937X_BASE_ADDRESS+0x0DE)
#define WCD937X_HPH_L_DAC_CTL (WCD937X_BASE_ADDRESS+0x0DF)
#define WCD937X_HPH_R_DAC_CTL (WCD937X_BASE_ADDRESS+0x0E0)
#define WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL (WCD937X_BASE_ADDRESS+0x0E1)
#define WCD937X_HPH_SURGE_HPHLR_SURGE_EN (WCD937X_BASE_ADDRESS+0x0E2)
#define WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1 (WCD937X_BASE_ADDRESS+0x0E3)
#define WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS (WCD937X_BASE_ADDRESS+0x0E4)
#define WCD937X_EAR_EAR_EN_REG (WCD937X_BASE_ADDRESS+0x0E9)
#define WCD937X_EAR_EAR_PA_CON (WCD937X_BASE_ADDRESS+0x0EA)
#define WCD937X_EAR_EAR_SP_CON (WCD937X_BASE_ADDRESS+0x0EB)
#define WCD937X_EAR_EAR_DAC_CON (WCD937X_BASE_ADDRESS+0x0EC)
#define WCD937X_EAR_EAR_CNP_FSM_CON (WCD937X_BASE_ADDRESS+0x0ED)
#define WCD937X_EAR_TEST_CTL (WCD937X_BASE_ADDRESS+0x0EE)
#define WCD937X_EAR_STATUS_REG_1 (WCD937X_BASE_ADDRESS+0x0EF)
#define WCD937X_EAR_STATUS_REG_2 (WCD937X_BASE_ADDRESS+0x0F0)
#define WCD937X_ANA_NEW_PAGE_REGISTER (WCD937X_BASE_ADDRESS+0x100)
#define WCD937X_HPH_NEW_ANA_HPH2 (WCD937X_BASE_ADDRESS+0x101)
#define WCD937X_HPH_NEW_ANA_HPH3 (WCD937X_BASE_ADDRESS+0x102)
#define WCD937X_SLEEP_CTL (WCD937X_BASE_ADDRESS+0x103)
#define WCD937X_SLEEP_WATCHDOG_CTL (WCD937X_BASE_ADDRESS+0x104)
#define WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL (WCD937X_BASE_ADDRESS+0x11F)
#define WCD937X_MBHC_NEW_CTL_1 (WCD937X_BASE_ADDRESS+0x120)
#define WCD937X_MBHC_NEW_CTL_2 (WCD937X_BASE_ADDRESS+0x121)
#define WCD937X_MBHC_NEW_PLUG_DETECT_CTL (WCD937X_BASE_ADDRESS+0x122)
#define WCD937X_MBHC_NEW_ZDET_ANA_CTL (WCD937X_BASE_ADDRESS+0x123)
#define WCD937X_MBHC_NEW_ZDET_RAMP_CTL (WCD937X_BASE_ADDRESS+0x124)
#define WCD937X_MBHC_NEW_FSM_STATUS (WCD937X_BASE_ADDRESS+0x125)
#define WCD937X_MBHC_NEW_ADC_RESULT (WCD937X_BASE_ADDRESS+0x126)
#define WCD937X_TX_NEW_TX_CH2_SEL (WCD937X_BASE_ADDRESS+0x127)
#define WCD937X_AUX_AUXPA (WCD937X_BASE_ADDRESS+0x128)
#define WCD937X_LDORXTX_MODE (WCD937X_BASE_ADDRESS+0x129)
#define WCD937X_LDORXTX_CONFIG (WCD937X_BASE_ADDRESS+0x12A)
#define WCD937X_DIE_CRACK_DIE_CRK_DET_EN (WCD937X_BASE_ADDRESS+0x12C)
#define WCD937X_DIE_CRACK_DIE_CRK_DET_OUT (WCD937X_BASE_ADDRESS+0x12D)
#define WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL (WCD937X_BASE_ADDRESS+0x132)
#define WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L (WCD937X_BASE_ADDRESS+0x133)
#define WCD937X_HPH_NEW_INT_RDAC_VREF_CTL (WCD937X_BASE_ADDRESS+0x134)
#define WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL (WCD937X_BASE_ADDRESS+0x135)
#define WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R (WCD937X_BASE_ADDRESS+0x136)
#define WCD937X_HPH_NEW_INT_PA_MISC1 (WCD937X_BASE_ADDRESS+0x137)
#define WCD937X_HPH_NEW_INT_PA_MISC2 (WCD937X_BASE_ADDRESS+0x138)
#define WCD937X_HPH_NEW_INT_PA_RDAC_MISC (WCD937X_BASE_ADDRESS+0x139)
#define WCD937X_HPH_NEW_INT_HPH_TIMER1 (WCD937X_BASE_ADDRESS+0x13A)
#define WCD937X_HPH_NEW_INT_HPH_TIMER2 (WCD937X_BASE_ADDRESS+0x13B)
#define WCD937X_HPH_NEW_INT_HPH_TIMER3 (WCD937X_BASE_ADDRESS+0x13C)
#define WCD937X_HPH_NEW_INT_HPH_TIMER4 (WCD937X_BASE_ADDRESS+0x13D)
#define WCD937X_HPH_NEW_INT_PA_RDAC_MISC2 (WCD937X_BASE_ADDRESS+0x13E)
#define WCD937X_HPH_NEW_INT_PA_RDAC_MISC3 (WCD937X_BASE_ADDRESS+0x13F)
#define WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (WCD937X_BASE_ADDRESS+0x145)
#define WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP (WCD937X_BASE_ADDRESS+0x146)
#define WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP (WCD937X_BASE_ADDRESS+0x147)
#define WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL (WCD937X_BASE_ADDRESS+0x1AF)
#define WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL \
(WCD937X_BASE_ADDRESS+0x1B0)
#define WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT (WCD937X_BASE_ADDRESS+0x1B1)
#define WCD937X_MBHC_NEW_INT_SPARE_2 (WCD937X_BASE_ADDRESS+0x1B2)
#define WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON (WCD937X_BASE_ADDRESS+0x1B7)
#define WCD937X_EAR_INT_NEW_CNP_VCM_CON1 (WCD937X_BASE_ADDRESS+0x1B8)
#define WCD937X_EAR_INT_NEW_CNP_VCM_CON2 (WCD937X_BASE_ADDRESS+0x1B9)
#define WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS (WCD937X_BASE_ADDRESS+0x1BA)
#define WCD937X_AUX_INT_EN_REG (WCD937X_BASE_ADDRESS+0x1BD)
#define WCD937X_AUX_INT_PA_CTRL (WCD937X_BASE_ADDRESS+0x1BE)
#define WCD937X_AUX_INT_SP_CTRL (WCD937X_BASE_ADDRESS+0x1BF)
#define WCD937X_AUX_INT_DAC_CTRL (WCD937X_BASE_ADDRESS+0x1C0)
#define WCD937X_AUX_INT_CLK_CTRL (WCD937X_BASE_ADDRESS+0x1C1)
#define WCD937X_AUX_INT_TEST_CTRL (WCD937X_BASE_ADDRESS+0x1C2)
#define WCD937X_AUX_INT_STATUS_REG (WCD937X_BASE_ADDRESS+0x1C3)
#define WCD937X_AUX_INT_MISC (WCD937X_BASE_ADDRESS+0x1C4)
#define WCD937X_LDORXTX_INT_BIAS (WCD937X_BASE_ADDRESS+0x1C5)
#define WCD937X_LDORXTX_INT_STB_LOADS_DTEST (WCD937X_BASE_ADDRESS+0x1C6)
#define WCD937X_LDORXTX_INT_TEST0 (WCD937X_BASE_ADDRESS+0x1C7)
#define WCD937X_LDORXTX_INT_STARTUP_TIMER (WCD937X_BASE_ADDRESS+0x1C8)
#define WCD937X_LDORXTX_INT_TEST1 (WCD937X_BASE_ADDRESS+0x1C9)
#define WCD937X_LDORXTX_INT_STATUS (WCD937X_BASE_ADDRESS+0x1CA)
#define WCD937X_SLEEP_INT_WATCHDOG_CTL_1 (WCD937X_BASE_ADDRESS+0x1D0)
#define WCD937X_SLEEP_INT_WATCHDOG_CTL_2 (WCD937X_BASE_ADDRESS+0x1D1)
#define WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1 (WCD937X_BASE_ADDRESS+0x1D3)
#define WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2 (WCD937X_BASE_ADDRESS+0x1D4)
#define WCD937X_DIGITAL_PAGE_REGISTER (WCD937X_BASE_ADDRESS+0x400)
#define WCD937X_DIGITAL_CHIP_ID0 (WCD937X_BASE_ADDRESS+0x401)
#define WCD937X_DIGITAL_CHIP_ID1 (WCD937X_BASE_ADDRESS+0x402)
#define WCD937X_DIGITAL_CHIP_ID2 (WCD937X_BASE_ADDRESS+0x403)
#define WCD937X_DIGITAL_CHIP_ID3 (WCD937X_BASE_ADDRESS+0x404)
#define WCD937X_DIGITAL_CDC_RST_CTL (WCD937X_BASE_ADDRESS+0x406)
#define WCD937X_DIGITAL_TOP_CLK_CFG (WCD937X_BASE_ADDRESS+0x407)
#define WCD937X_DIGITAL_CDC_ANA_CLK_CTL (WCD937X_BASE_ADDRESS+0x408)
#define WCD937X_DIGITAL_CDC_DIG_CLK_CTL (WCD937X_BASE_ADDRESS+0x409)
#define WCD937X_DIGITAL_SWR_RST_EN (WCD937X_BASE_ADDRESS+0x40A)
#define WCD937X_DIGITAL_CDC_PATH_MODE (WCD937X_BASE_ADDRESS+0x40B)
#define WCD937X_DIGITAL_CDC_RX_RST (WCD937X_BASE_ADDRESS+0x40C)
#define WCD937X_DIGITAL_CDC_RX0_CTL (WCD937X_BASE_ADDRESS+0x40D)
#define WCD937X_DIGITAL_CDC_RX1_CTL (WCD937X_BASE_ADDRESS+0x40E)
#define WCD937X_DIGITAL_CDC_RX2_CTL (WCD937X_BASE_ADDRESS+0x40F)
#define WCD937X_DIGITAL_DEM_BYPASS_DATA0 (WCD937X_BASE_ADDRESS+0x410)
#define WCD937X_DIGITAL_DEM_BYPASS_DATA1 (WCD937X_BASE_ADDRESS+0x411)
#define WCD937X_DIGITAL_DEM_BYPASS_DATA2 (WCD937X_BASE_ADDRESS+0x412)
#define WCD937X_DIGITAL_DEM_BYPASS_DATA3 (WCD937X_BASE_ADDRESS+0x413)
#define WCD937X_DIGITAL_CDC_COMP_CTL_0 (WCD937X_BASE_ADDRESS+0x414)
#define WCD937X_DIGITAL_CDC_RX_DELAY_CTL (WCD937X_BASE_ADDRESS+0x417)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A1_0 (WCD937X_BASE_ADDRESS+0x418)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A1_1 (WCD937X_BASE_ADDRESS+0x419)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A2_0 (WCD937X_BASE_ADDRESS+0x41A)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A2_1 (WCD937X_BASE_ADDRESS+0x41B)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A3_0 (WCD937X_BASE_ADDRESS+0x41C)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A3_1 (WCD937X_BASE_ADDRESS+0x41D)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A4_0 (WCD937X_BASE_ADDRESS+0x41E)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A4_1 (WCD937X_BASE_ADDRESS+0x41F)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A5_0 (WCD937X_BASE_ADDRESS+0x420)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A5_1 (WCD937X_BASE_ADDRESS+0x421)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A6_0 (WCD937X_BASE_ADDRESS+0x422)
#define WCD937X_DIGITAL_CDC_HPH_DSM_A7_0 (WCD937X_BASE_ADDRESS+0x423)
#define WCD937X_DIGITAL_CDC_HPH_DSM_C_0 (WCD937X_BASE_ADDRESS+0x424)
#define WCD937X_DIGITAL_CDC_HPH_DSM_C_1 (WCD937X_BASE_ADDRESS+0x425)
#define WCD937X_DIGITAL_CDC_HPH_DSM_C_2 (WCD937X_BASE_ADDRESS+0x426)
#define WCD937X_DIGITAL_CDC_HPH_DSM_C_3 (WCD937X_BASE_ADDRESS+0x427)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R1 (WCD937X_BASE_ADDRESS+0x428)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R2 (WCD937X_BASE_ADDRESS+0x429)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R3 (WCD937X_BASE_ADDRESS+0x42A)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R4 (WCD937X_BASE_ADDRESS+0x42B)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R5 (WCD937X_BASE_ADDRESS+0x42C)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R6 (WCD937X_BASE_ADDRESS+0x42D)
#define WCD937X_DIGITAL_CDC_HPH_DSM_R7 (WCD937X_BASE_ADDRESS+0x42E)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A1_0 (WCD937X_BASE_ADDRESS+0x42F)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A1_1 (WCD937X_BASE_ADDRESS+0x430)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A2_0 (WCD937X_BASE_ADDRESS+0x431)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A2_1 (WCD937X_BASE_ADDRESS+0x432)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A3_0 (WCD937X_BASE_ADDRESS+0x433)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A3_1 (WCD937X_BASE_ADDRESS+0x434)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A4_0 (WCD937X_BASE_ADDRESS+0x435)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A4_1 (WCD937X_BASE_ADDRESS+0x436)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A5_0 (WCD937X_BASE_ADDRESS+0x437)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A5_1 (WCD937X_BASE_ADDRESS+0x438)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A6_0 (WCD937X_BASE_ADDRESS+0x439)
#define WCD937X_DIGITAL_CDC_AUX_DSM_A7_0 (WCD937X_BASE_ADDRESS+0x43A)
#define WCD937X_DIGITAL_CDC_AUX_DSM_C_0 (WCD937X_BASE_ADDRESS+0x43B)
#define WCD937X_DIGITAL_CDC_AUX_DSM_C_1 (WCD937X_BASE_ADDRESS+0x43C)
#define WCD937X_DIGITAL_CDC_AUX_DSM_C_2 (WCD937X_BASE_ADDRESS+0x43D)
#define WCD937X_DIGITAL_CDC_AUX_DSM_C_3 (WCD937X_BASE_ADDRESS+0x43E)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R1 (WCD937X_BASE_ADDRESS+0x43F)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R2 (WCD937X_BASE_ADDRESS+0x440)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R3 (WCD937X_BASE_ADDRESS+0x441)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R4 (WCD937X_BASE_ADDRESS+0x442)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R5 (WCD937X_BASE_ADDRESS+0x443)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R6 (WCD937X_BASE_ADDRESS+0x444)
#define WCD937X_DIGITAL_CDC_AUX_DSM_R7 (WCD937X_BASE_ADDRESS+0x445)
#define WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0 (WCD937X_BASE_ADDRESS+0x446)
#define WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1 (WCD937X_BASE_ADDRESS+0x447)
#define WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0 (WCD937X_BASE_ADDRESS+0x448)
#define WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1 (WCD937X_BASE_ADDRESS+0x449)
#define WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2 (WCD937X_BASE_ADDRESS+0x44A)
#define WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0 (WCD937X_BASE_ADDRESS+0x44B)
#define WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1 (WCD937X_BASE_ADDRESS+0x44C)
#define WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2 (WCD937X_BASE_ADDRESS+0x44D)
#define WCD937X_DIGITAL_CDC_HPH_GAIN_CTL (WCD937X_BASE_ADDRESS+0x44E)
#define WCD937X_DIGITAL_CDC_AUX_GAIN_CTL (WCD937X_BASE_ADDRESS+0x44F)
#define WCD937X_DIGITAL_CDC_EAR_PATH_CTL (WCD937X_BASE_ADDRESS+0x450)
#define WCD937X_DIGITAL_CDC_SWR_CLH (WCD937X_BASE_ADDRESS+0x451)
#define WCD937X_DIGITAL_SWR_CLH_BYP (WCD937X_BASE_ADDRESS+0x452)
#define WCD937X_DIGITAL_CDC_TX0_CTL (WCD937X_BASE_ADDRESS+0x453)
#define WCD937X_DIGITAL_CDC_TX1_CTL (WCD937X_BASE_ADDRESS+0x454)
#define WCD937X_DIGITAL_CDC_TX2_CTL (WCD937X_BASE_ADDRESS+0x455)
#define WCD937X_DIGITAL_CDC_TX_RST (WCD937X_BASE_ADDRESS+0x456)
#define WCD937X_DIGITAL_CDC_REQ_CTL (WCD937X_BASE_ADDRESS+0x457)
#define WCD937X_DIGITAL_CDC_AMIC_CTL (WCD937X_BASE_ADDRESS+0x45A)
#define WCD937X_DIGITAL_CDC_DMIC_CTL (WCD937X_BASE_ADDRESS+0x45B)
#define WCD937X_DIGITAL_CDC_DMIC1_CTL (WCD937X_BASE_ADDRESS+0x45C)
#define WCD937X_DIGITAL_CDC_DMIC2_CTL (WCD937X_BASE_ADDRESS+0x45D)
#define WCD937X_DIGITAL_CDC_DMIC3_CTL (WCD937X_BASE_ADDRESS+0x45E)
#define WCD937X_DIGITAL_EFUSE_CTL (WCD937X_BASE_ADDRESS+0x45F)
#define WCD937X_DIGITAL_EFUSE_PRG_CTL (WCD937X_BASE_ADDRESS+0x460)
#define WCD937X_DIGITAL_EFUSE_TEST_CTL_0 (WCD937X_BASE_ADDRESS+0x461)
#define WCD937X_DIGITAL_EFUSE_TEST_CTL_1 (WCD937X_BASE_ADDRESS+0x462)
#define WCD937X_DIGITAL_EFUSE_T_DATA_0 (WCD937X_BASE_ADDRESS+0x463)
#define WCD937X_DIGITAL_EFUSE_T_DATA_1 (WCD937X_BASE_ADDRESS+0x464)
#define WCD937X_DIGITAL_PDM_WD_CTL0 (WCD937X_BASE_ADDRESS+0x465)
#define WCD937X_DIGITAL_PDM_WD_CTL1 (WCD937X_BASE_ADDRESS+0x466)
#define WCD937X_DIGITAL_PDM_WD_CTL2 (WCD937X_BASE_ADDRESS+0x467)
#define WCD937X_DIGITAL_INTR_MODE (WCD937X_BASE_ADDRESS+0x46A)
#define WCD937X_DIGITAL_INTR_MASK_0 (WCD937X_BASE_ADDRESS+0x46B)
#define WCD937X_DIGITAL_INTR_MASK_1 (WCD937X_BASE_ADDRESS+0x46C)
#define WCD937X_DIGITAL_INTR_MASK_2 (WCD937X_BASE_ADDRESS+0x46D)
#define WCD937X_DIGITAL_INTR_STATUS_0 (WCD937X_BASE_ADDRESS+0x46E)
#define WCD937X_DIGITAL_INTR_STATUS_1 (WCD937X_BASE_ADDRESS+0x46F)
#define WCD937X_DIGITAL_INTR_STATUS_2 (WCD937X_BASE_ADDRESS+0x470)
#define WCD937X_DIGITAL_INTR_CLEAR_0 (WCD937X_BASE_ADDRESS+0x471)
#define WCD937X_DIGITAL_INTR_CLEAR_1 (WCD937X_BASE_ADDRESS+0x472)
#define WCD937X_DIGITAL_INTR_CLEAR_2 (WCD937X_BASE_ADDRESS+0x473)
#define WCD937X_DIGITAL_INTR_LEVEL_0 (WCD937X_BASE_ADDRESS+0x474)
#define WCD937X_DIGITAL_INTR_LEVEL_1 (WCD937X_BASE_ADDRESS+0x475)
#define WCD937X_DIGITAL_INTR_LEVEL_2 (WCD937X_BASE_ADDRESS+0x476)
#define WCD937X_DIGITAL_INTR_SET_0 (WCD937X_BASE_ADDRESS+0x477)
#define WCD937X_DIGITAL_INTR_SET_1 (WCD937X_BASE_ADDRESS+0x478)
#define WCD937X_DIGITAL_INTR_SET_2 (WCD937X_BASE_ADDRESS+0x479)
#define WCD937X_DIGITAL_INTR_TEST_0 (WCD937X_BASE_ADDRESS+0x47A)
#define WCD937X_DIGITAL_INTR_TEST_1 (WCD937X_BASE_ADDRESS+0x47B)
#define WCD937X_DIGITAL_INTR_TEST_2 (WCD937X_BASE_ADDRESS+0x47C)
#define WCD937X_DIGITAL_CDC_CONN_RX0_CTL (WCD937X_BASE_ADDRESS+0x47F)
#define WCD937X_DIGITAL_CDC_CONN_RX1_CTL (WCD937X_BASE_ADDRESS+0x480)
#define WCD937X_DIGITAL_CDC_CONN_RX2_CTL (WCD937X_BASE_ADDRESS+0x481)
#define WCD937X_DIGITAL_CDC_CONN_TX_CTL (WCD937X_BASE_ADDRESS+0x482)
#define WCD937X_DIGITAL_LOOP_BACK_MODE (WCD937X_BASE_ADDRESS+0x483)
#define WCD937X_DIGITAL_SWR_DAC_TEST (WCD937X_BASE_ADDRESS+0x484)
#define WCD937X_DIGITAL_SWR_HM_TEST_RX_0 (WCD937X_BASE_ADDRESS+0x485)
#define WCD937X_DIGITAL_SWR_HM_TEST_TX_0 (WCD937X_BASE_ADDRESS+0x491)
#define WCD937X_DIGITAL_SWR_HM_TEST_RX_1 (WCD937X_BASE_ADDRESS+0x492)
#define WCD937X_DIGITAL_SWR_HM_TEST_TX_1 (WCD937X_BASE_ADDRESS+0x493)
#define WCD937X_DIGITAL_SWR_HM_TEST (WCD937X_BASE_ADDRESS+0x494)
#define WCD937X_DIGITAL_PAD_CTL_PDM_RX0 (WCD937X_BASE_ADDRESS+0x495)
#define WCD937X_DIGITAL_PAD_CTL_PDM_RX1 (WCD937X_BASE_ADDRESS+0x496)
#define WCD937X_DIGITAL_PAD_CTL_PDM_TX0 (WCD937X_BASE_ADDRESS+0x497)
#define WCD937X_DIGITAL_PAD_CTL_PDM_TX1 (WCD937X_BASE_ADDRESS+0x498)
#define WCD937X_DIGITAL_PAD_INP_DIS_0 (WCD937X_BASE_ADDRESS+0x499)
#define WCD937X_DIGITAL_PAD_INP_DIS_1 (WCD937X_BASE_ADDRESS+0x49A)
#define WCD937X_DIGITAL_DRIVE_STRENGTH_0 (WCD937X_BASE_ADDRESS+0x49B)
#define WCD937X_DIGITAL_DRIVE_STRENGTH_1 (WCD937X_BASE_ADDRESS+0x49C)
#define WCD937X_DIGITAL_DRIVE_STRENGTH_2 (WCD937X_BASE_ADDRESS+0x49D)
#define WCD937X_DIGITAL_RX_DATA_EDGE_CTL (WCD937X_BASE_ADDRESS+0x49E)
#define WCD937X_DIGITAL_TX_DATA_EDGE_CTL (WCD937X_BASE_ADDRESS+0x49F)
#define WCD937X_DIGITAL_GPIO_MODE (WCD937X_BASE_ADDRESS+0x4A0)
#define WCD937X_DIGITAL_PIN_CTL_OE (WCD937X_BASE_ADDRESS+0x4A1)
#define WCD937X_DIGITAL_PIN_CTL_DATA_0 (WCD937X_BASE_ADDRESS+0x4A2)
#define WCD937X_DIGITAL_PIN_CTL_DATA_1 (WCD937X_BASE_ADDRESS+0x4A3)
#define WCD937X_DIGITAL_PIN_STATUS_0 (WCD937X_BASE_ADDRESS+0x4A4)
#define WCD937X_DIGITAL_PIN_STATUS_1 (WCD937X_BASE_ADDRESS+0x4A5)
#define WCD937X_DIGITAL_DIG_DEBUG_CTL (WCD937X_BASE_ADDRESS+0x4A6)
#define WCD937X_DIGITAL_DIG_DEBUG_EN (WCD937X_BASE_ADDRESS+0x4A7)
#define WCD937X_DIGITAL_ANA_CSR_DBG_ADD (WCD937X_BASE_ADDRESS+0x4A8)
#define WCD937X_DIGITAL_ANA_CSR_DBG_CTL (WCD937X_BASE_ADDRESS+0x4A9)
#define WCD937X_DIGITAL_SSP_DBG (WCD937X_BASE_ADDRESS+0x4AA)
#define WCD937X_DIGITAL_MODE_STATUS_0 (WCD937X_BASE_ADDRESS+0x4AB)
#define WCD937X_DIGITAL_MODE_STATUS_1 (WCD937X_BASE_ADDRESS+0x4AC)
#define WCD937X_DIGITAL_SPARE_0 (WCD937X_BASE_ADDRESS+0x4AD)
#define WCD937X_DIGITAL_SPARE_1 (WCD937X_BASE_ADDRESS+0x4AE)
#define WCD937X_DIGITAL_SPARE_2 (WCD937X_BASE_ADDRESS+0x4AF)
#define WCD937X_DIGITAL_EFUSE_REG_0 (WCD937X_BASE_ADDRESS+0x4B0)
#define WCD937X_DIGITAL_EFUSE_REG_1 (WCD937X_BASE_ADDRESS+0x4B1)
#define WCD937X_DIGITAL_EFUSE_REG_2 (WCD937X_BASE_ADDRESS+0x4B2)
#define WCD937X_DIGITAL_EFUSE_REG_3 (WCD937X_BASE_ADDRESS+0x4B3)
#define WCD937X_DIGITAL_EFUSE_REG_4 (WCD937X_BASE_ADDRESS+0x4B4)
#define WCD937X_DIGITAL_EFUSE_REG_5 (WCD937X_BASE_ADDRESS+0x4B5)
#define WCD937X_DIGITAL_EFUSE_REG_6 (WCD937X_BASE_ADDRESS+0x4B6)
#define WCD937X_DIGITAL_EFUSE_REG_7 (WCD937X_BASE_ADDRESS+0x4B7)
#define WCD937X_DIGITAL_EFUSE_REG_8 (WCD937X_BASE_ADDRESS+0x4B8)
#define WCD937X_DIGITAL_EFUSE_REG_9 (WCD937X_BASE_ADDRESS+0x4B9)
#define WCD937X_DIGITAL_EFUSE_REG_10 (WCD937X_BASE_ADDRESS+0x4BA)
#define WCD937X_DIGITAL_EFUSE_REG_11 (WCD937X_BASE_ADDRESS+0x4BB)
#define WCD937X_DIGITAL_EFUSE_REG_12 (WCD937X_BASE_ADDRESS+0x4BC)
#define WCD937X_DIGITAL_EFUSE_REG_13 (WCD937X_BASE_ADDRESS+0x4BD)
#define WCD937X_DIGITAL_EFUSE_REG_14 (WCD937X_BASE_ADDRESS+0x4BE)
#define WCD937X_DIGITAL_EFUSE_REG_15 (WCD937X_BASE_ADDRESS+0x4BF)
#define WCD937X_DIGITAL_EFUSE_REG_16 (WCD937X_BASE_ADDRESS+0x4C0)
#define WCD937X_DIGITAL_EFUSE_REG_17 (WCD937X_BASE_ADDRESS+0x4C1)
#define WCD937X_DIGITAL_EFUSE_REG_18 (WCD937X_BASE_ADDRESS+0x4C2)
#define WCD937X_DIGITAL_EFUSE_REG_19 (WCD937X_BASE_ADDRESS+0x4C3)
#define WCD937X_DIGITAL_EFUSE_REG_20 (WCD937X_BASE_ADDRESS+0x4C4)
#define WCD937X_DIGITAL_EFUSE_REG_21 (WCD937X_BASE_ADDRESS+0x4C5)
#define WCD937X_DIGITAL_EFUSE_REG_22 (WCD937X_BASE_ADDRESS+0x4C6)
#define WCD937X_DIGITAL_EFUSE_REG_23 (WCD937X_BASE_ADDRESS+0x4C7)
#define WCD937X_DIGITAL_EFUSE_REG_24 (WCD937X_BASE_ADDRESS+0x4C8)
#define WCD937X_DIGITAL_EFUSE_REG_25 (WCD937X_BASE_ADDRESS+0x4C9)
#define WCD937X_DIGITAL_EFUSE_REG_26 (WCD937X_BASE_ADDRESS+0x4CA)
#define WCD937X_DIGITAL_EFUSE_REG_27 (WCD937X_BASE_ADDRESS+0x4CB)
#define WCD937X_DIGITAL_EFUSE_REG_28 (WCD937X_BASE_ADDRESS+0x4CC)
#define WCD937X_DIGITAL_EFUSE_REG_29 (WCD937X_BASE_ADDRESS+0x4CD)
#define WCD937X_DIGITAL_EFUSE_REG_30 (WCD937X_BASE_ADDRESS+0x4CE)
#define WCD937X_DIGITAL_EFUSE_REG_31 (WCD937X_BASE_ADDRESS+0x4CF)
#define WCD937X_REGISTERS_MAX_SIZE (WCD937X_BASE_ADDRESS+0x4D0)
#define WCD937X_MAX_REGISTER (WCD937X_REGISTERS_MAX_SIZE - 1)
#endif

View File

@@ -0,0 +1,464 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
#include <linux/device.h>
#include "wcd937x-registers.h"
extern const u8 wcd937x_reg_access[WCD937X_REGISTERS_MAX_SIZE];
static const struct reg_default wcd937x_defaults[] = {
{ WCD937X_ANA_BIAS, 0x00 },
{ WCD937X_ANA_RX_SUPPLIES, 0x00 },
{ WCD937X_ANA_HPH, 0x0C },
{ WCD937X_ANA_EAR, 0x00 },
{ WCD937X_ANA_EAR_COMPANDER_CTL, 0x02 },
{ WCD937X_ANA_TX_CH1, 0x20 },
{ WCD937X_ANA_TX_CH2, 0x00 },
{ WCD937X_ANA_TX_CH3, 0x20 },
{ WCD937X_ANA_TX_CH3_HPF, 0x00 },
{ WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC, 0x00 },
{ WCD937X_ANA_MICB3_DSP_EN_LOGIC, 0x00 },
{ WCD937X_ANA_MBHC_MECH, 0x39 },
{ WCD937X_ANA_MBHC_ELECT, 0x08 },
{ WCD937X_ANA_MBHC_ZDET, 0x00 },
{ WCD937X_ANA_MBHC_RESULT_1, 0x00 },
{ WCD937X_ANA_MBHC_RESULT_2, 0x00 },
{ WCD937X_ANA_MBHC_RESULT_3, 0x00 },
{ WCD937X_ANA_MBHC_BTN0, 0x00 },
{ WCD937X_ANA_MBHC_BTN1, 0x10 },
{ WCD937X_ANA_MBHC_BTN2, 0x20 },
{ WCD937X_ANA_MBHC_BTN3, 0x30 },
{ WCD937X_ANA_MBHC_BTN4, 0x40 },
{ WCD937X_ANA_MBHC_BTN5, 0x50 },
{ WCD937X_ANA_MBHC_BTN6, 0x60 },
{ WCD937X_ANA_MBHC_BTN7, 0x70 },
{ WCD937X_ANA_MICB1, 0x10 },
{ WCD937X_ANA_MICB2, 0x10 },
{ WCD937X_ANA_MICB2_RAMP, 0x00 },
{ WCD937X_ANA_MICB3, 0x10 },
{ WCD937X_BIAS_CTL, 0x2A },
{ WCD937X_BIAS_VBG_FINE_ADJ, 0x55 },
{ WCD937X_LDOL_VDDCX_ADJUST, 0x01 },
{ WCD937X_LDOL_DISABLE_LDOL, 0x00 },
{ WCD937X_MBHC_CTL_CLK, 0x00 },
{ WCD937X_MBHC_CTL_ANA, 0x00 },
{ WCD937X_MBHC_CTL_SPARE_1, 0x00 },
{ WCD937X_MBHC_CTL_SPARE_2, 0x00 },
{ WCD937X_MBHC_CTL_BCS, 0x00 },
{ WCD937X_MBHC_MOISTURE_DET_FSM_STATUS, 0x00 },
{ WCD937X_MBHC_TEST_CTL, 0x00 },
{ WCD937X_LDOH_MODE, 0x2B },
{ WCD937X_LDOH_BIAS, 0x68 },
{ WCD937X_LDOH_STB_LOADS, 0x00 },
{ WCD937X_LDOH_SLOWRAMP, 0x50 },
{ WCD937X_MICB1_TEST_CTL_1, 0x1A },
{ WCD937X_MICB1_TEST_CTL_2, 0x18 },
{ WCD937X_MICB1_TEST_CTL_3, 0xA4 },
{ WCD937X_MICB2_TEST_CTL_1, 0x1A },
{ WCD937X_MICB2_TEST_CTL_2, 0x18 },
{ WCD937X_MICB2_TEST_CTL_3, 0xA4 },
{ WCD937X_MICB3_TEST_CTL_1, 0x1A },
{ WCD937X_MICB3_TEST_CTL_2, 0x18 },
{ WCD937X_MICB3_TEST_CTL_3, 0xA4 },
{ WCD937X_TX_COM_ADC_VCM, 0x39 },
{ WCD937X_TX_COM_BIAS_ATEST, 0xC0 },
{ WCD937X_TX_COM_ADC_INT1_IB, 0x6F },
{ WCD937X_TX_COM_ADC_INT2_IB, 0x4F },
{ WCD937X_TX_COM_TXFE_DIV_CTL, 0x2E },
{ WCD937X_TX_COM_TXFE_DIV_START, 0x00 },
{ WCD937X_TX_COM_TXFE_DIV_STOP_9P6M, 0xC7 },
{ WCD937X_TX_COM_TXFE_DIV_STOP_12P288M, 0xFF },
{ WCD937X_TX_1_2_TEST_EN, 0xCC },
{ WCD937X_TX_1_2_ADC_IB, 0x09 },
{ WCD937X_TX_1_2_ATEST_REFCTL, 0x0A },
{ WCD937X_TX_1_2_TEST_CTL, 0x38 },
{ WCD937X_TX_1_2_TEST_BLK_EN, 0xFF },
{ WCD937X_TX_1_2_TXFE_CLKDIV, 0x00 },
{ WCD937X_TX_1_2_SAR2_ERR, 0x00 },
{ WCD937X_TX_1_2_SAR1_ERR, 0x00 },
{ WCD937X_TX_3_TEST_EN, 0xCC },
{ WCD937X_TX_3_ADC_IB, 0x09 },
{ WCD937X_TX_3_ATEST_REFCTL, 0x0A },
{ WCD937X_TX_3_TEST_CTL, 0x38 },
{ WCD937X_TX_3_TEST_BLK_EN, 0xFF },
{ WCD937X_TX_3_TXFE_CLKDIV, 0x00 },
{ WCD937X_TX_3_SPARE_MONO, 0x00 },
{ WCD937X_TX_3_SAR1_ERR, 0x00 },
{ WCD937X_CLASSH_MODE_1, 0x40 },
{ WCD937X_CLASSH_MODE_2, 0x3A },
{ WCD937X_CLASSH_MODE_3, 0x00 },
{ WCD937X_CLASSH_CTRL_VCL_1, 0x70 },
{ WCD937X_CLASSH_CTRL_VCL_2, 0x82 },
{ WCD937X_CLASSH_CTRL_CCL_1, 0x31 },
{ WCD937X_CLASSH_CTRL_CCL_2, 0x80 },
{ WCD937X_CLASSH_CTRL_CCL_3, 0x80 },
{ WCD937X_CLASSH_CTRL_CCL_4, 0x51 },
{ WCD937X_CLASSH_CTRL_CCL_5, 0x00 },
{ WCD937X_CLASSH_BUCK_TMUX_A_D, 0x00 },
{ WCD937X_CLASSH_BUCK_SW_DRV_CNTL, 0x77 },
{ WCD937X_CLASSH_SPARE, 0x00 },
{ WCD937X_FLYBACK_EN, 0x4E },
{ WCD937X_FLYBACK_VNEG_CTRL_1, 0x0B },
{ WCD937X_FLYBACK_VNEG_CTRL_2, 0x45 },
{ WCD937X_FLYBACK_VNEG_CTRL_3, 0x74 },
{ WCD937X_FLYBACK_VNEG_CTRL_4, 0x7F },
{ WCD937X_FLYBACK_VNEG_CTRL_5, 0x83 },
{ WCD937X_FLYBACK_VNEG_CTRL_6, 0x98 },
{ WCD937X_FLYBACK_VNEG_CTRL_7, 0xA9 },
{ WCD937X_FLYBACK_VNEG_CTRL_8, 0x68 },
{ WCD937X_FLYBACK_VNEG_CTRL_9, 0x64 },
{ WCD937X_FLYBACK_VNEGDAC_CTRL_1, 0xED },
{ WCD937X_FLYBACK_VNEGDAC_CTRL_2, 0xF0 },
{ WCD937X_FLYBACK_VNEGDAC_CTRL_3, 0xA6 },
{ WCD937X_FLYBACK_CTRL_1, 0x65 },
{ WCD937X_FLYBACK_TEST_CTL, 0x00 },
{ WCD937X_RX_AUX_SW_CTL, 0x00 },
{ WCD937X_RX_PA_AUX_IN_CONN, 0x00 },
{ WCD937X_RX_TIMER_DIV, 0x32 },
{ WCD937X_RX_OCP_CTL, 0x1F },
{ WCD937X_RX_OCP_COUNT, 0x77 },
{ WCD937X_RX_BIAS_EAR_DAC, 0xA0 },
{ WCD937X_RX_BIAS_EAR_AMP, 0xAA },
{ WCD937X_RX_BIAS_HPH_LDO, 0xA9 },
{ WCD937X_RX_BIAS_HPH_PA, 0xAA },
{ WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A },
{ WCD937X_RX_BIAS_HPH_RDAC_LDO, 0x88 },
{ WCD937X_RX_BIAS_HPH_CNP1, 0x82 },
{ WCD937X_RX_BIAS_HPH_LOWPOWER, 0x82 },
{ WCD937X_RX_BIAS_AUX_DAC, 0xA0 },
{ WCD937X_RX_BIAS_AUX_AMP, 0xAA },
{ WCD937X_RX_BIAS_VNEGDAC_BLEEDER, 0x50 },
{ WCD937X_RX_BIAS_MISC, 0x00 },
{ WCD937X_RX_BIAS_BUCK_RST, 0x08 },
{ WCD937X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44 },
{ WCD937X_RX_BIAS_FLYB_ERRAMP, 0x40 },
{ WCD937X_RX_BIAS_FLYB_BUFF, 0xAA },
{ WCD937X_RX_BIAS_FLYB_MID_RST, 0x14 },
{ WCD937X_HPH_L_STATUS, 0x04 },
{ WCD937X_HPH_R_STATUS, 0x04 },
{ WCD937X_HPH_CNP_EN, 0x80 },
{ WCD937X_HPH_CNP_WG_CTL, 0x9A },
{ WCD937X_HPH_CNP_WG_TIME, 0x14 },
{ WCD937X_HPH_OCP_CTL, 0x28 },
{ WCD937X_HPH_AUTO_CHOP, 0x16 },
{ WCD937X_HPH_CHOP_CTL, 0x83 },
{ WCD937X_HPH_PA_CTL1, 0x46 },
{ WCD937X_HPH_PA_CTL2, 0x50 },
{ WCD937X_HPH_L_EN, 0x80 },
{ WCD937X_HPH_L_TEST, 0xE0 },
{ WCD937X_HPH_L_ATEST, 0x50 },
{ WCD937X_HPH_R_EN, 0x80 },
{ WCD937X_HPH_R_TEST, 0xE0 },
{ WCD937X_HPH_R_ATEST, 0x54 },
{ WCD937X_HPH_RDAC_CLK_CTL1, 0x99 },
{ WCD937X_HPH_RDAC_CLK_CTL2, 0x9B },
{ WCD937X_HPH_RDAC_LDO_CTL, 0x33 },
{ WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00 },
{ WCD937X_HPH_REFBUFF_UHQA_CTL, 0xA8 },
{ WCD937X_HPH_REFBUFF_LP_CTL, 0x0E },
{ WCD937X_HPH_L_DAC_CTL, 0x20 },
{ WCD937X_HPH_R_DAC_CTL, 0x20 },
{ WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL, 0x55 },
{ WCD937X_HPH_SURGE_HPHLR_SURGE_EN, 0x19 },
{ WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1, 0xA0 },
{ WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS, 0x00 },
{ WCD937X_EAR_EAR_EN_REG, 0x22 },
{ WCD937X_EAR_EAR_PA_CON, 0x44 },
{ WCD937X_EAR_EAR_SP_CON, 0xDB },
{ WCD937X_EAR_EAR_DAC_CON, 0x80 },
{ WCD937X_EAR_EAR_CNP_FSM_CON, 0xB2 },
{ WCD937X_EAR_TEST_CTL, 0x00 },
{ WCD937X_EAR_STATUS_REG_1, 0x00 },
{ WCD937X_EAR_STATUS_REG_2, 0x00 },
{ WCD937X_ANA_NEW_PAGE_REGISTER, 0x00 },
{ WCD937X_HPH_NEW_ANA_HPH2, 0x00 },
{ WCD937X_HPH_NEW_ANA_HPH3, 0x00 },
{ WCD937X_SLEEP_CTL, 0x16 },
{ WCD937X_SLEEP_WATCHDOG_CTL, 0x00 },
{ WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00 },
{ WCD937X_MBHC_NEW_CTL_1, 0x02 },
{ WCD937X_MBHC_NEW_CTL_2, 0x05 },
{ WCD937X_MBHC_NEW_PLUG_DETECT_CTL, 0xE9 },
{ WCD937X_MBHC_NEW_ZDET_ANA_CTL, 0x0F },
{ WCD937X_MBHC_NEW_ZDET_RAMP_CTL, 0x00 },
{ WCD937X_MBHC_NEW_FSM_STATUS, 0x00 },
{ WCD937X_MBHC_NEW_ADC_RESULT, 0x00 },
{ WCD937X_TX_NEW_TX_CH2_SEL, 0x00 },
{ WCD937X_AUX_AUXPA, 0x00 },
{ WCD937X_LDORXTX_MODE, 0x0C },
{ WCD937X_LDORXTX_CONFIG, 0x10 },
{ WCD937X_DIE_CRACK_DIE_CRK_DET_EN, 0x00 },
{ WCD937X_DIE_CRACK_DIE_CRK_DET_OUT, 0x00 },
{ WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40 },
{ WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81 },
{ WCD937X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10 },
{ WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00 },
{ WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81 },
{ WCD937X_HPH_NEW_INT_PA_MISC1, 0x22 },
{ WCD937X_HPH_NEW_INT_PA_MISC2, 0x00 },
{ WCD937X_HPH_NEW_INT_PA_RDAC_MISC, 0x00 },
{ WCD937X_HPH_NEW_INT_HPH_TIMER1, 0xFE },
{ WCD937X_HPH_NEW_INT_HPH_TIMER2, 0x02 },
{ WCD937X_HPH_NEW_INT_HPH_TIMER3, 0x4E },
{ WCD937X_HPH_NEW_INT_HPH_TIMER4, 0x54 },
{ WCD937X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00 },
{ WCD937X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00 },
{ WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62 },
{ WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01 },
{ WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11 },
{ WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57 },
{ WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01 },
{ WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00 },
{ WCD937X_MBHC_NEW_INT_SPARE_2, 0x00 },
{ WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8 },
{ WCD937X_EAR_INT_NEW_CNP_VCM_CON1, 0x42 },
{ WCD937X_EAR_INT_NEW_CNP_VCM_CON2, 0x22 },
{ WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00 },
{ WCD937X_AUX_INT_EN_REG, 0x00 },
{ WCD937X_AUX_INT_PA_CTRL, 0x06 },
{ WCD937X_AUX_INT_SP_CTRL, 0xD2 },
{ WCD937X_AUX_INT_DAC_CTRL, 0x80 },
{ WCD937X_AUX_INT_CLK_CTRL, 0x50 },
{ WCD937X_AUX_INT_TEST_CTRL, 0x00 },
{ WCD937X_AUX_INT_STATUS_REG, 0x00 },
{ WCD937X_AUX_INT_MISC, 0x00 },
{ WCD937X_LDORXTX_INT_BIAS, 0x6E },
{ WCD937X_LDORXTX_INT_STB_LOADS_DTEST, 0x50 },
{ WCD937X_LDORXTX_INT_TEST0, 0x1C },
{ WCD937X_LDORXTX_INT_STARTUP_TIMER, 0xFF },
{ WCD937X_LDORXTX_INT_TEST1, 0x1F },
{ WCD937X_LDORXTX_INT_STATUS, 0x00 },
{ WCD937X_SLEEP_INT_WATCHDOG_CTL_1, 0x0A },
{ WCD937X_SLEEP_INT_WATCHDOG_CTL_2, 0x0A },
{ WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1, 0x02 },
{ WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2, 0x60 },
{ WCD937X_DIGITAL_PAGE_REGISTER, 0x00 },
{ WCD937X_DIGITAL_CHIP_ID0, 0x01 },
{ WCD937X_DIGITAL_CHIP_ID1, 0x00 },
{ WCD937X_DIGITAL_CHIP_ID2, 0x0A },
{ WCD937X_DIGITAL_CHIP_ID3, 0x01 },
{ WCD937X_DIGITAL_CDC_RST_CTL, 0x03 },
{ WCD937X_DIGITAL_TOP_CLK_CFG, 0x00 },
{ WCD937X_DIGITAL_CDC_ANA_CLK_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_DIG_CLK_CTL, 0x00 },
{ WCD937X_DIGITAL_SWR_RST_EN, 0x00 },
{ WCD937X_DIGITAL_CDC_PATH_MODE, 0x55 },
{ WCD937X_DIGITAL_CDC_RX_RST, 0x00 },
{ WCD937X_DIGITAL_CDC_RX0_CTL, 0xFC },
{ WCD937X_DIGITAL_CDC_RX1_CTL, 0xFC },
{ WCD937X_DIGITAL_CDC_RX2_CTL, 0xFC },
{ WCD937X_DIGITAL_DEM_BYPASS_DATA0, 0x55 },
{ WCD937X_DIGITAL_DEM_BYPASS_DATA1, 0x55 },
{ WCD937X_DIGITAL_DEM_BYPASS_DATA2, 0x55 },
{ WCD937X_DIGITAL_DEM_BYPASS_DATA3, 0x01 },
{ WCD937X_DIGITAL_CDC_COMP_CTL_0, 0x00 },
{ WCD937X_DIGITAL_CDC_RX_DELAY_CTL, 0x66 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A1_0, 0x00 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A1_1, 0x01 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A2_0, 0x63 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A2_1, 0x04 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A3_0, 0xAC },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A3_1, 0x04 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A4_0, 0x1A },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A4_1, 0x03 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A5_0, 0xBC },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A5_1, 0x02 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A6_0, 0xC7 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_A7_0, 0xF8 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_C_0, 0x47 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_C_1, 0x43 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_C_2, 0xB1 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_C_3, 0x17 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R1, 0x4B },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R2, 0x26 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R3, 0x32 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R4, 0x57 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R5, 0x63 },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R6, 0x7C },
{ WCD937X_DIGITAL_CDC_HPH_DSM_R7, 0x57 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A1_0, 0x00 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A1_1, 0x01 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A2_0, 0x96 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A2_1, 0x09 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A3_0, 0xAB },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A3_1, 0x05 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A4_0, 0x1C },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A4_1, 0x02 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A5_0, 0x17 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A5_1, 0x02 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A6_0, 0xAA },
{ WCD937X_DIGITAL_CDC_AUX_DSM_A7_0, 0xE3 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_C_0, 0x69 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_C_1, 0x54 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_C_2, 0x02 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_C_3, 0x15 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R1, 0xA4 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R2, 0xB5 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R3, 0x86 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R4, 0x85 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R5, 0xAA },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R6, 0xE2 },
{ WCD937X_DIGITAL_CDC_AUX_DSM_R7, 0x62 },
{ WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0, 0x55 },
{ WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1, 0xA9 },
{ WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0, 0x3D },
{ WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1, 0x2E },
{ WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2, 0x01 },
{ WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0, 0x00 },
{ WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1, 0xFC },
{ WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2, 0x01 },
{ WCD937X_DIGITAL_CDC_HPH_GAIN_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_AUX_GAIN_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_EAR_PATH_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_SWR_CLH, 0x00 },
{ WCD937X_DIGITAL_SWR_CLH_BYP, 0x00 },
{ WCD937X_DIGITAL_CDC_TX0_CTL, 0x68 },
{ WCD937X_DIGITAL_CDC_TX1_CTL, 0x68 },
{ WCD937X_DIGITAL_CDC_TX2_CTL, 0x68 },
{ WCD937X_DIGITAL_CDC_TX_RST, 0x00 },
{ WCD937X_DIGITAL_CDC_REQ_CTL, 0x01 },
{ WCD937X_DIGITAL_CDC_AMIC_CTL, 0x07 },
{ WCD937X_DIGITAL_CDC_DMIC_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_DMIC1_CTL, 0x01 },
{ WCD937X_DIGITAL_CDC_DMIC2_CTL, 0x01 },
{ WCD937X_DIGITAL_CDC_DMIC3_CTL, 0x01 },
{ WCD937X_DIGITAL_EFUSE_CTL, 0x2B },
{ WCD937X_DIGITAL_EFUSE_PRG_CTL, 0x00 },
{ WCD937X_DIGITAL_EFUSE_TEST_CTL_0, 0x00 },
{ WCD937X_DIGITAL_EFUSE_TEST_CTL_1, 0x00 },
{ WCD937X_DIGITAL_EFUSE_T_DATA_0, 0x00 },
{ WCD937X_DIGITAL_EFUSE_T_DATA_1, 0x00 },
{ WCD937X_DIGITAL_PDM_WD_CTL0, 0x00 },
{ WCD937X_DIGITAL_PDM_WD_CTL1, 0x00 },
{ WCD937X_DIGITAL_PDM_WD_CTL2, 0x00 },
{ WCD937X_DIGITAL_INTR_MODE, 0x00 },
{ WCD937X_DIGITAL_INTR_MASK_0, 0xFF },
{ WCD937X_DIGITAL_INTR_MASK_1, 0xFF },
{ WCD937X_DIGITAL_INTR_MASK_2, 0x0F },
{ WCD937X_DIGITAL_INTR_STATUS_0, 0x00 },
{ WCD937X_DIGITAL_INTR_STATUS_1, 0x00 },
{ WCD937X_DIGITAL_INTR_STATUS_2, 0x00 },
{ WCD937X_DIGITAL_INTR_CLEAR_0, 0x00 },
{ WCD937X_DIGITAL_INTR_CLEAR_1, 0x00 },
{ WCD937X_DIGITAL_INTR_CLEAR_2, 0x00 },
{ WCD937X_DIGITAL_INTR_LEVEL_0, 0x00 },
{ WCD937X_DIGITAL_INTR_LEVEL_1, 0x00 },
{ WCD937X_DIGITAL_INTR_LEVEL_2, 0x00 },
{ WCD937X_DIGITAL_INTR_SET_0, 0x00 },
{ WCD937X_DIGITAL_INTR_SET_1, 0x00 },
{ WCD937X_DIGITAL_INTR_SET_2, 0x00 },
{ WCD937X_DIGITAL_INTR_TEST_0, 0x00 },
{ WCD937X_DIGITAL_INTR_TEST_1, 0x00 },
{ WCD937X_DIGITAL_INTR_TEST_2, 0x00 },
{ WCD937X_DIGITAL_CDC_CONN_RX0_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_CONN_RX1_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_CONN_RX2_CTL, 0x00 },
{ WCD937X_DIGITAL_CDC_CONN_TX_CTL, 0x00 },
{ WCD937X_DIGITAL_LOOP_BACK_MODE, 0x00 },
{ WCD937X_DIGITAL_SWR_DAC_TEST, 0x00 },
{ WCD937X_DIGITAL_SWR_HM_TEST_RX_0, 0x40 },
{ WCD937X_DIGITAL_SWR_HM_TEST_TX_0, 0x40 },
{ WCD937X_DIGITAL_SWR_HM_TEST_RX_1, 0x00 },
{ WCD937X_DIGITAL_SWR_HM_TEST_TX_1, 0x00 },
{ WCD937X_DIGITAL_SWR_HM_TEST, 0x00 },
{ WCD937X_DIGITAL_PAD_CTL_PDM_RX0, 0xF1 },
{ WCD937X_DIGITAL_PAD_CTL_PDM_RX1, 0xF1 },
{ WCD937X_DIGITAL_PAD_CTL_PDM_TX0, 0xF1 },
{ WCD937X_DIGITAL_PAD_CTL_PDM_TX1, 0xF1 },
{ WCD937X_DIGITAL_PAD_INP_DIS_0, 0x00 },
{ WCD937X_DIGITAL_PAD_INP_DIS_1, 0x00 },
{ WCD937X_DIGITAL_DRIVE_STRENGTH_0, 0x00 },
{ WCD937X_DIGITAL_DRIVE_STRENGTH_1, 0x00 },
{ WCD937X_DIGITAL_DRIVE_STRENGTH_2, 0x00 },
{ WCD937X_DIGITAL_RX_DATA_EDGE_CTL, 0x1F },
{ WCD937X_DIGITAL_TX_DATA_EDGE_CTL, 0x10 },
{ WCD937X_DIGITAL_GPIO_MODE, 0x00 },
{ WCD937X_DIGITAL_PIN_CTL_OE, 0x00 },
{ WCD937X_DIGITAL_PIN_CTL_DATA_0, 0x00 },
{ WCD937X_DIGITAL_PIN_CTL_DATA_1, 0x00 },
{ WCD937X_DIGITAL_PIN_STATUS_0, 0x00 },
{ WCD937X_DIGITAL_PIN_STATUS_1, 0x00 },
{ WCD937X_DIGITAL_DIG_DEBUG_CTL, 0x00 },
{ WCD937X_DIGITAL_DIG_DEBUG_EN, 0x00 },
{ WCD937X_DIGITAL_ANA_CSR_DBG_ADD, 0x00 },
{ WCD937X_DIGITAL_ANA_CSR_DBG_CTL, 0x48 },
{ WCD937X_DIGITAL_SSP_DBG, 0x00 },
{ WCD937X_DIGITAL_MODE_STATUS_0, 0x00 },
{ WCD937X_DIGITAL_MODE_STATUS_1, 0x00 },
{ WCD937X_DIGITAL_SPARE_0, 0x00 },
{ WCD937X_DIGITAL_SPARE_1, 0x00 },
{ WCD937X_DIGITAL_SPARE_2, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_0, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_1, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_2, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_3, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_4, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_5, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_6, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_7, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_8, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_9, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_10, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_11, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_12, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_13, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_14, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_15, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_16, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_17, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_18, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_19, 0xFF },
{ WCD937X_DIGITAL_EFUSE_REG_20, 0x0E },
{ WCD937X_DIGITAL_EFUSE_REG_21, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_22, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_23, 0xF8 },
{ WCD937X_DIGITAL_EFUSE_REG_24, 0x16 },
{ WCD937X_DIGITAL_EFUSE_REG_25, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_26, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_27, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_28, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_29, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_30, 0x00 },
{ WCD937X_DIGITAL_EFUSE_REG_31, 0x00 },
};
static bool wcd937x_readable_register(struct device *dev, unsigned int reg)
{
if(reg <= WCD937X_BASE_ADDRESS)
return 0;
return wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG;
}
static bool wcd937x_writeable_register(struct device *dev, unsigned int reg)
{
if(reg <= WCD937X_BASE_ADDRESS)
return 0;
return wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG;
}
static bool wcd937x_volatile_register(struct device *dev, unsigned int reg)
{
if(reg <= WCD937X_BASE_ADDRESS)
return 0;
if ((wcd937x_reg_access[WCD937X_REG(reg)] & RD_REG)
&& !(wcd937x_reg_access[WCD937X_REG(reg)] & WR_REG))
return true;
return false;
}
struct regmap_config wcd937x_regmap_config = {
.name = "wcd937x_csr",
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wcd937x_defaults,
.num_reg_defaults = ARRAY_SIZE(wcd937x_defaults),
.max_register = WCD937X_MAX_REGISTER,
.readable_reg = wcd937x_readable_register,
.writeable_reg = wcd937x_writeable_register,
.volatile_reg = wcd937x_volatile_register,
.can_multi_write = true,
};

View File

@@ -0,0 +1,422 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2019 , The Linux Foundation. All rights reserved.
*/
#include <linux/types.h>
#include "wcd937x-registers.h"
const u8 wcd937x_reg_access[WCD937X_REG(WCD937X_REGISTERS_MAX_SIZE)] = {
[WCD937X_REG(WCD937X_ANA_BIAS)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_RX_SUPPLIES)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_HPH)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_EAR)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_EAR_COMPANDER_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_TX_CH1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_TX_CH2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_TX_CH3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_TX_CH3_HPF)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MICB1_MICB2_DSP_EN_LOGIC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MICB3_DSP_EN_LOGIC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_MECH)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_ELECT)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_ZDET)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_RESULT_1)] = RD_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_RESULT_2)] = RD_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_RESULT_3)] = RD_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN4)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN5)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN6)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MBHC_BTN7)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MICB1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MICB2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MICB2_RAMP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_ANA_MICB3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_BIAS_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_BIAS_VBG_FINE_ADJ)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDOL_VDDCX_ADJUST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDOL_DISABLE_LDOL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_CTL_CLK)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_CTL_ANA)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_CTL_SPARE_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_CTL_SPARE_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_CTL_BCS)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_MOISTURE_DET_FSM_STATUS)] = RD_REG,
[WCD937X_REG(WCD937X_MBHC_TEST_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDOH_MODE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDOH_BIAS)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDOH_STB_LOADS)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDOH_SLOWRAMP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB1_TEST_CTL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB1_TEST_CTL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB1_TEST_CTL_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB2_TEST_CTL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB2_TEST_CTL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB2_TEST_CTL_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB3_TEST_CTL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB3_TEST_CTL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MICB3_TEST_CTL_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_ADC_VCM)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_BIAS_ATEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_ADC_INT1_IB)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_ADC_INT2_IB)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_START)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_STOP_9P6M)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_COM_TXFE_DIV_STOP_12P288M)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_TEST_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_ADC_IB)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_ATEST_REFCTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_TEST_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_TEST_BLK_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_TXFE_CLKDIV)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_1_2_SAR2_ERR)] = RD_REG,
[WCD937X_REG(WCD937X_TX_1_2_SAR1_ERR)] = RD_REG,
[WCD937X_REG(WCD937X_TX_3_TEST_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_3_ADC_IB)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_3_ATEST_REFCTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_3_TEST_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_3_TEST_BLK_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_3_TXFE_CLKDIV)] = RD_WR_REG,
[WCD937X_REG(WCD937X_TX_3_SPARE_MONO)] = RD_REG,
[WCD937X_REG(WCD937X_TX_3_SAR1_ERR)] = RD_REG,
[WCD937X_REG(WCD937X_CLASSH_MODE_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_MODE_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_MODE_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_VCL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_VCL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_4)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_CTRL_CCL_5)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_BUCK_TMUX_A_D)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_BUCK_SW_DRV_CNTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_CLASSH_SPARE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_4)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_5)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_6)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_7)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_8)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEG_CTRL_9)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEGDAC_CTRL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEGDAC_CTRL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_VNEGDAC_CTRL_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_CTRL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_FLYBACK_TEST_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_AUX_SW_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_PA_AUX_IN_CONN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_TIMER_DIV)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_OCP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_OCP_COUNT)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_EAR_DAC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_EAR_AMP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_HPH_LDO)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_HPH_PA)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_HPH_RDACBUFF_CNP2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_HPH_RDAC_LDO)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_HPH_CNP1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_HPH_LOWPOWER)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_AUX_DAC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_AUX_AMP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_VNEGDAC_BLEEDER)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_MISC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_BUCK_RST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_BUCK_VREF_ERRAMP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_FLYB_ERRAMP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_FLYB_BUFF)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_BIAS_FLYB_MID_RST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_L_STATUS)] = RD_REG,
[WCD937X_REG(WCD937X_HPH_R_STATUS)] = RD_REG,
[WCD937X_REG(WCD937X_HPH_CNP_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_CNP_WG_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_CNP_WG_TIME)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_OCP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_AUTO_CHOP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_CHOP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_PA_CTL1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_PA_CTL2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_L_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_L_TEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_L_ATEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_R_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_R_TEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_R_ATEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_RDAC_CLK_CTL1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_RDAC_CLK_CTL2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_RDAC_LDO_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_RDAC_CHOP_CLK_LP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_REFBUFF_UHQA_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_REFBUFF_LP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_L_DAC_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_R_DAC_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_COMP_SEL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_MISC1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_SURGE_HPHLR_SURGE_STATUS)] = RD_REG,
[WCD937X_REG(WCD937X_EAR_EAR_EN_REG)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_EAR_PA_CON)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_EAR_SP_CON)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_EAR_DAC_CON)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_EAR_CNP_FSM_CON)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_TEST_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_STATUS_REG_1)] = RD_REG,
[WCD937X_REG(WCD937X_EAR_STATUS_REG_2)] = RD_REG,
[WCD937X_REG(WCD937X_HPH_NEW_ANA_HPH2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_ANA_HPH3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_SLEEP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_SLEEP_WATCHDOG_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_CTL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_CTL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_PLUG_DETECT_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_ZDET_ANA_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_ZDET_RAMP_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_FSM_STATUS)] = RD_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_ADC_RESULT)] = RD_REG,
[WCD937X_REG(WCD937X_TX_NEW_TX_CH2_SEL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_AUXPA)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_MODE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_CONFIG)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIE_CRACK_DIE_CRK_DET_OUT)] = RD_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_GAIN_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_L)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_VREF_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_RDAC_HD2_CTL_R)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_PA_MISC1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_PA_MISC2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_PA_RDAC_MISC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_HPH_TIMER4)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_PA_RDAC_MISC2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_HPH_NEW_INT_PA_RDAC_MISC3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_RX_NEW_INT_HPH_RDAC_LDO_LP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)]
= RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_INT_MECH_DET_CURRENT)] = RD_WR_REG,
[WCD937X_REG(WCD937X_MBHC_NEW_INT_SPARE_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_INT_NEW_EAR_CHOPPER_CON)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_INT_NEW_CNP_VCM_CON1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_INT_NEW_CNP_VCM_CON2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_EN_REG)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_PA_CTRL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_SP_CTRL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_DAC_CTRL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_CLK_CTRL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_TEST_CTRL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_AUX_INT_STATUS_REG)] = RD_REG,
[WCD937X_REG(WCD937X_AUX_INT_MISC)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_INT_BIAS)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_INT_STB_LOADS_DTEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_INT_TEST0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_INT_STARTUP_TIMER)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_INT_TEST1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_LDORXTX_INT_STATUS)] = RD_REG,
[WCD937X_REG(WCD937X_SLEEP_INT_WATCHDOG_CTL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_SLEEP_INT_WATCHDOG_CTL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIE_CRACK_INT_DIE_CRK_DET_INT2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CHIP_ID0)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_CHIP_ID1)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_CHIP_ID2)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_CHIP_ID3)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_RST_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_TOP_CLK_CFG)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_ANA_CLK_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_DIG_CLK_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_RST_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_PATH_MODE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_RX_RST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_RX0_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_RX1_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_RX2_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DEM_BYPASS_DATA3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_COMP_CTL_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_RX_DELAY_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A1_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A1_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A2_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A2_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A3_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A3_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A4_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A4_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A5_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A5_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A6_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_A7_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_C_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R5)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R6)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_DSM_R7)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A1_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A1_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A2_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A2_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A3_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A3_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A4_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A4_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A5_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A5_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A6_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_A7_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_C_3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R3)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R4)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R5)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R6)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_DSM_R7)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_RX_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_RX_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_DSD_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_DSD_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_HPH_GAIN_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AUX_GAIN_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_EAR_PATH_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_SWR_CLH)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_CLH_BYP)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_TX0_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_TX1_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_TX2_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_TX_RST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_REQ_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_AMIC_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC1_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC2_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_DMIC3_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_PRG_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_TEST_CTL_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_TEST_CTL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_T_DATA_0)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_T_DATA_1)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_PDM_WD_CTL0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PDM_WD_CTL1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PDM_WD_CTL2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_MODE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_MASK_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_MASK_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_MASK_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_STATUS_0)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_STATUS_1)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_STATUS_2)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_CLEAR_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_CLEAR_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_CLEAR_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_LEVEL_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_LEVEL_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_LEVEL_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_SET_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_SET_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_SET_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_TEST_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_TEST_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_INTR_TEST_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_RX0_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_RX1_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_RX2_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_CDC_CONN_TX_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_LOOP_BACK_MODE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_DAC_TEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_RX_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_TX_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_RX_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST_TX_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SWR_HM_TEST)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_RX1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PAD_CTL_PDM_TX1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PAD_INP_DIS_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DRIVE_STRENGTH_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_RX_DATA_EDGE_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_TX_DATA_EDGE_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_GPIO_MODE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PIN_CTL_OE)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PIN_CTL_DATA_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PIN_CTL_DATA_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PIN_STATUS_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_PIN_STATUS_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DIG_DEBUG_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_DIG_DEBUG_EN)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_ANA_CSR_DBG_ADD)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_ANA_CSR_DBG_CTL)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SSP_DBG)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_MODE_STATUS_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_MODE_STATUS_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SPARE_0)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SPARE_1)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_SPARE_2)] = RD_WR_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_0)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_1)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_2)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_3)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_4)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_5)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_6)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_7)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_8)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_9)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_10)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_11)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_12)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_13)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_14)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_15)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_16)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_17)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_18)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_19)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_20)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_21)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_22)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_23)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_24)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_25)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_26)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_27)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_28)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_29)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_30)] = RD_REG,
[WCD937X_REG(WCD937X_DIGITAL_EFUSE_REG_31)] = RD_REG,
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD937X_H
#define _WCD937X_H
#ifdef CONFIG_SND_SOC_WCD937X
extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root,
struct snd_soc_codec *codec);
#else
extern int wcd937x_info_create_codec_entry(struct snd_info_entry *codec_root,
struct snd_soc_codec *codec)
{
return 0;
}
#endif /* CONFIG_SND_SOC_WCD937X */
#endif

View File

@@ -0,0 +1,144 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/component.h>
#include <soc/soundwire.h>
struct wcd937x_slave_priv {
struct swr_device *swr_slave;
};
static int wcd937x_slave_bind(struct device *dev,
struct device *master, void *data)
{
int ret = 0;
struct wcd937x_slave_priv *wcd937x_slave = NULL;
uint8_t devnum = 0;
struct swr_device *pdev = to_swr_device(dev);
if (pdev == NULL) {
dev_err(dev, "%s: pdev is NULL\n", __func__);
return -EINVAL;
}
wcd937x_slave = devm_kzalloc(&pdev->dev,
sizeof(struct wcd937x_slave_priv), GFP_KERNEL);
if (!wcd937x_slave)
return -ENOMEM;
swr_set_dev_data(pdev, wcd937x_slave);
wcd937x_slave->swr_slave = pdev;
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
if (ret) {
dev_dbg(&pdev->dev,
"%s get devnum %d for dev addr %lx failed\n",
__func__, devnum, pdev->addr);
swr_remove_device(pdev);
return ret;
}
pdev->dev_num = devnum;
return ret;
}
static void wcd937x_slave_unbind(struct device *dev,
struct device *master, void *data)
{
struct wcd937x_slave_priv *wcd937x_slave = NULL;
struct swr_device *pdev = to_swr_device(dev);
if (pdev == NULL) {
dev_err(dev, "%s: pdev is NULL\n", __func__);
return;
}
wcd937x_slave = swr_get_dev_data(pdev);
if (!wcd937x_slave) {
dev_err(&pdev->dev, "%s: wcd937x_slave is NULL\n", __func__);
return;
}
swr_set_dev_data(pdev, NULL);
}
static const struct swr_device_id wcd937x_swr_id[] = {
{"wcd937x-slave", 0},
{}
};
static const struct of_device_id wcd937x_swr_dt_match[] = {
{
.compatible = "qcom,wcd937x-slave",
},
{}
};
static const struct component_ops wcd937x_slave_comp_ops = {
.bind = wcd937x_slave_bind,
.unbind = wcd937x_slave_unbind,
};
static int wcd937x_swr_up(struct swr_device *pdev)
{
return 0;
}
static int wcd937x_swr_down(struct swr_device *pdev)
{
return 0;
}
static int wcd937x_swr_reset(struct swr_device *pdev)
{
return 0;
}
static int wcd937x_swr_probe(struct swr_device *pdev)
{
return component_add(&pdev->dev, &wcd937x_slave_comp_ops);
}
static int wcd937x_swr_remove(struct swr_device *pdev)
{
component_del(&pdev->dev, &wcd937x_slave_comp_ops);
return 0;
}
static struct swr_driver wcd937x_slave_driver = {
.driver = {
.name = "wcd937x-slave",
.owner = THIS_MODULE,
.of_match_table = wcd937x_swr_dt_match,
},
.probe = wcd937x_swr_probe,
.remove = wcd937x_swr_remove,
.id_table = wcd937x_swr_id,
.device_up = wcd937x_swr_up,
.device_down = wcd937x_swr_down,
.reset_device = wcd937x_swr_reset,
};
static int __init wcd937x_slave_init(void)
{
return swr_driver_register(&wcd937x_slave_driver);
}
static void __exit wcd937x_slave_exit(void)
{
swr_driver_unregister(&wcd937x_slave_driver);
}
module_init(wcd937x_slave_init);
module_exit(wcd937x_slave_exit);
MODULE_DESCRIPTION("WCD937X Swr Slave driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,69 @@
# 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,kona),true)
AUDIO_SELECT := CONFIG_SND_SOC_KONA=m
endif
ifeq ($(call is-board-platform,lito),true)
AUDIO_SELECT := CONFIG_SND_SOC_LITO=m
endif
ifeq ($(call is-board-platform,atoll),true)
AUDIO_SELECT := CONFIG_SND_SOC_ATOLL=m
endif
ifeq ($(call is-board-platform,$(MSMSTEPPE)),true)
AUDIO_SELECT := CONFIG_SND_SOC_SM6150=m
endif
AUDIO_CHIPSET := audio
# Build/Package only in case of supported target
ifeq ($(call is-board-platform-in-list,kona lito atoll $(MSMSTEPPE)),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 := $(shell pwd)/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=wcd938x_dlkm
KBUILD_OPTIONS += BOARD_PLATFORM=$(TARGET_BOARD_PLATFORM)
KBUILD_OPTIONS += $(AUDIO_SELECT)
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd938x.ko
LOCAL_MODULE_KBUILD_NAME := wcd938x_dlkm.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_DEBUG_ENABLE := true
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk
###########################################################
include $(CLEAR_VARS)
LOCAL_MODULE := $(AUDIO_CHIPSET)_wcd938x_slave.ko
LOCAL_MODULE_KBUILD_NAME := wcd938x_slave_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

View File

@@ -0,0 +1,135 @@
# 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 := $(shell pwd)/kernel/msm-4.19
AUDIO_ROOT := $(AUDIO_BLD_DIR)/techpack/audio
endif
ifeq ($(KERNEL_BUILD), 0)
ifeq ($(CONFIG_ARCH_KONA), y)
include $(AUDIO_ROOT)/config/konaauto.conf
INCS += -include $(AUDIO_ROOT)/config/konaautoconf.h
endif
ifeq ($(CONFIG_ARCH_LITO), y)
include $(AUDIO_ROOT)/config/litoauto.conf
export
INCS += -include $(AUDIO_ROOT)/config/litoautoconf.h
endif
ifeq ($(CONFIG_ARCH_ATOLL), y)
include $(AUDIO_ROOT)/4.0/config/atollauto.conf
export
INCS += -include $(AUDIO_ROOT)/4.0/config/atollautoconf.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
UAPI_DIR := uapi
UAPI_INC := -I$(AUDIO_ROOT)/4.0/include/$(UAPI_DIR)
COMMON_DIR := include
COMMON_INC := -I$(AUDIO_ROOT)/4.0/$(COMMON_DIR)
endif
############ WCD938X ############
# for WCD938X Codec
ifdef CONFIG_SND_SOC_WCD938X
WCD938X_OBJS += wcd938x.o
WCD938X_OBJS += wcd938x-regmap.o
WCD938X_OBJS += wcd938x-tables.o
WCD938X_OBJS += wcd938x-mbhc.o
endif
ifdef CONFIG_SND_SOC_WCD938X_SLAVE
WCD938X_SLAVE_OBJS += wcd938x-slave.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)
ifeq ($(CONFIG_ARCH_ATOLL), y)
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/ipc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/dsp/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/asoc/codecs/Module.symvers
KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/4.0/soc/Module.symvers
else
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
endif
# Module information used by KBuild framework
obj-$(CONFIG_SND_SOC_WCD938X) += wcd938x_dlkm.o
wcd938x_dlkm-y := $(WCD938X_OBJS)
obj-$(CONFIG_SND_SOC_WCD938X_SLAVE) += wcd938x_slave_dlkm.o
wcd938x_slave_dlkm-y := $(WCD938X_SLAVE_OBJS)
# inject some build related information

View File

@@ -0,0 +1,195 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD938X_INTERNAL_H
#define _WCD938X_INTERNAL_H
#include <asoc/wcd-mbhc-v2.h>
#include <asoc/wcd-irq.h>
#include <asoc/wcd-clsh.h>
#include "wcd938x-mbhc.h"
#define SWR_SCP_CONTROL 0x44
#define SWR_SCP_HOST_CLK_DIV2_CTL_BANK 0xE0
#define WCD938X_MAX_MICBIAS 4
/* Convert from vout ctl to micbias voltage in mV */
#define WCD_VOUT_CTL_TO_MICB(v) (1000 + v * 50)
#define MAX_PORT 8
#define MAX_CH_PER_PORT 8
#define TX_ADC_MAX 4
enum {
TX_HDR12 = 0,
TX_HDR34,
TX_HDR_MAX,
};
extern struct regmap_config wcd938x_regmap_config;
struct codec_port_info {
u32 slave_port_type;
u32 master_port_type;
u32 ch_mask;
u32 num_ch;
u32 ch_rate;
};
struct wcd938x_priv {
struct device *dev;
int variant;
struct snd_soc_codec *codec;
struct device_node *rst_np;
struct regmap *regmap;
struct swr_device *rx_swr_dev;
struct swr_device *tx_swr_dev;
s32 micb_ref[WCD938X_MAX_MICBIAS];
s32 pullup_ref[WCD938X_MAX_MICBIAS];
struct fw_info *fw_data;
struct device_node *wcd_rst_np;
struct mutex micb_lock;
s32 dmic_0_1_clk_cnt;
s32 dmic_2_3_clk_cnt;
s32 dmic_4_5_clk_cnt;
s32 dmic_6_7_clk_cnt;
int hdr_en[TX_HDR_MAX];
/* class h specific info */
struct wcd_clsh_cdc_info clsh_info;
/* mbhc module */
struct wcd938x_mbhc *mbhc;
u32 hph_mode;
u32 tx_mode[TX_ADC_MAX];
bool comp1_enable;
bool comp2_enable;
bool ldoh;
bool bcs_dis;
struct irq_domain *virq;
struct wcd_irq_info irq_info;
u32 rx_clk_cnt;
int num_irq_regs;
/* to track the status */
unsigned long status_mask;
u8 num_tx_ports;
u8 num_rx_ports;
struct codec_port_info
tx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
struct codec_port_info
rx_port_mapping[MAX_PORT][MAX_CH_PER_PORT];
struct regulator_bulk_data *supplies;
struct notifier_block nblock;
/* wcd callback to bolero */
void *handle;
int (*update_wcd_event)(void *handle, u16 event, u32 data);
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
int (*wakeup)(void *handle, bool enable);
u32 version;
/* Entry for version info */
struct snd_info_entry *entry;
struct snd_info_entry *version_entry;
struct snd_info_entry *variant_entry;
int flyback_cur_det_disable;
int ear_rx_path;
bool dev_up;
};
struct wcd938x_micbias_setting {
u8 ldoh_v;
u32 cfilt1_mv;
u32 micb1_mv;
u32 micb2_mv;
u32 micb3_mv;
u32 micb4_mv;
u8 bias1_cfilt_sel;
};
struct wcd938x_pdata {
struct device_node *rst_np;
struct device_node *rx_slave;
struct device_node *tx_slave;
struct wcd938x_micbias_setting micbias;
struct cdc_regulator *regulator;
int num_supplies;
};
struct wcd_ctrl_platform_data {
void *handle;
int (*update_wcd_event)(void *handle, u16 event, u32 data);
int (*register_notifier)(void *handle,
struct notifier_block *nblock,
bool enable);
};
enum {
WCD_RX1,
WCD_RX2,
WCD_RX3
};
enum {
BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR = 1,
BOLERO_WCD_EVT_PA_OFF_PRE_SSR,
BOLERO_WCD_EVT_SSR_DOWN,
BOLERO_WCD_EVT_SSR_UP,
BOLERO_WCD_EVT_CLK_NOTIFY,
};
enum {
WCD_BOLERO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
WCD_BOLERO_EVT_BCS_CLK_OFF,
};
enum {
/* INTR_CTRL_INT_MASK_0 */
WCD938X_IRQ_MBHC_BUTTON_RELEASE_DET = 0,
WCD938X_IRQ_MBHC_BUTTON_PRESS_DET,
WCD938X_IRQ_MBHC_ELECT_INS_REM_DET,
WCD938X_IRQ_MBHC_ELECT_INS_REM_LEG_DET,
WCD938X_IRQ_MBHC_SW_DET,
WCD938X_IRQ_HPHR_OCP_INT,
WCD938X_IRQ_HPHR_CNP_INT,
WCD938X_IRQ_HPHL_OCP_INT,
/* INTR_CTRL_INT_MASK_1 */
WCD938X_IRQ_HPHL_CNP_INT,
WCD938X_IRQ_EAR_CNP_INT,
WCD938X_IRQ_EAR_SCD_INT,
WCD938X_IRQ_AUX_CNP_INT,
WCD938X_IRQ_AUX_SCD_INT,
WCD938X_IRQ_HPHL_PDM_WD_INT,
WCD938X_IRQ_HPHR_PDM_WD_INT,
WCD938X_IRQ_AUX_PDM_WD_INT,
/* INTR_CTRL_INT_MASK_2 */
WCD938X_IRQ_LDORT_SCD_INT,
WCD938X_IRQ_MBHC_MOISTURE_INT,
WCD938X_IRQ_HPHL_SURGE_DET_INT,
WCD938X_IRQ_HPHR_SURGE_DET_INT,
WCD938X_NUM_IRQS,
};
extern struct wcd938x_mbhc *wcd938x_soc_get_mbhc(
struct snd_soc_codec *codec);
extern void wcd938x_disable_bcs_before_slow_insert(
struct snd_soc_codec *codec,
bool bcs_disable);
extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_codec *codec,
int volt, int micb_num);
extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv);
extern int wcd938x_micbias_control(struct snd_soc_codec *codec,
int micb_num, int req, bool is_dapm);
#endif /* _WCD938X_INTERNAL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,69 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD938X_MBHC_H__
#define __WCD938X_MBHC_H__
#include <asoc/wcd-mbhc-v2.h>
struct wcd938x_mbhc {
struct wcd_mbhc wcd_mbhc;
struct blocking_notifier_head notifier;
struct fw_info *fw_data;
};
#if IS_ENABLED(CONFIG_SND_SOC_WCD938X)
extern int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc,
struct snd_soc_codec *codec,
struct fw_info *fw_data);
extern void wcd938x_mbhc_hs_detect_exit(struct snd_soc_codec *codec);
extern int wcd938x_mbhc_hs_detect(struct snd_soc_codec *codec,
struct wcd_mbhc_config *mbhc_cfg);
extern void wcd938x_mbhc_deinit(struct snd_soc_codec *codec);
extern void wcd938x_mbhc_ssr_down(struct wcd938x_mbhc *mbhc,
struct snd_soc_codec *codec);
extern int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc,
struct snd_soc_codec *codec);
extern int wcd938x_mbhc_get_impedance(struct wcd938x_mbhc *wcd938x_mbhc,
uint32_t *zl, uint32_t *zr);
#else
static inline int wcd938x_mbhc_init(struct wcd938x_mbhc **mbhc,
struct snd_soc_codec *codec,
struct fw_info *fw_data)
{
return 0;
}
static inline void wcd938x_mbhc_hs_detect_exit(
struct snd_soc_codec *codec)
{
}
static inline int wcd938x_mbhc_hs_detect(struct snd_soc_codec *codec,
struct wcd_mbhc_config *mbhc_cfg)
{
return 0;
}
static inline void wcd938x_mbhc_deinit(struct snd_soc_codec *codec)
{
}
static inline void wcd938x_mbhc_ssr_down(struct wcd938x_mbhc *mbhc,
struct snd_soc_codec *codec)
{
}
static inline int wcd938x_mbhc_post_ssr_init(struct wcd938x_mbhc *mbhc,
struct snd_soc_codec *codec)
{
return 0;
}
static inline int wcd938x_mbhc_get_impedance(struct wcd938x_mbhc *wcd938x_mbhc,
uint32_t *zl, uint32_t *zr)
{
if (zl)
*zl = 0;
if (zr)
*zr = 0;
return -EINVAL;
}
#endif
#endif /* __WCD938X_MBHC_H__ */

View File

@@ -0,0 +1,502 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD938X_REGISTERS_H
#define _WCD938X_REGISTERS_H
#define WCD938X_BASE_ADDRESS 0x3000
#define WCD938X_REG(reg) (reg - WCD938X_BASE_ADDRESS)
enum {
REG_NO_ACCESS,
RD_REG,
WR_REG,
RD_WR_REG
};
#define WCD938X_ANA_PAGE_REGISTER (WCD938X_BASE_ADDRESS + 0x0000)
#define WCD938X_ANA_BIAS (WCD938X_BASE_ADDRESS + 0x0001)
#define WCD938X_ANA_RX_SUPPLIES (WCD938X_BASE_ADDRESS + 0x0008)
#define WCD938X_ANA_HPH (WCD938X_BASE_ADDRESS + 0x0009)
#define WCD938X_ANA_EAR (WCD938X_BASE_ADDRESS + 0x000A)
#define WCD938X_ANA_EAR_COMPANDER_CTL (WCD938X_BASE_ADDRESS + 0x000B)
#define WCD938X_ANA_TX_CH1 (WCD938X_BASE_ADDRESS + 0x000E)
#define WCD938X_ANA_TX_CH2 (WCD938X_BASE_ADDRESS + 0x000F)
#define WCD938X_ANA_TX_CH3 (WCD938X_BASE_ADDRESS + 0x0010)
#define WCD938X_ANA_TX_CH4 (WCD938X_BASE_ADDRESS + 0x0011)
#define WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC (WCD938X_BASE_ADDRESS + 0x0012)
#define WCD938X_ANA_MICB3_DSP_EN_LOGIC (WCD938X_BASE_ADDRESS + 0x0013)
#define WCD938X_ANA_MBHC_MECH (WCD938X_BASE_ADDRESS + 0x0014)
#define WCD938X_ANA_MBHC_ELECT (WCD938X_BASE_ADDRESS + 0x0015)
#define WCD938X_ANA_MBHC_ZDET (WCD938X_BASE_ADDRESS + 0x0016)
#define WCD938X_ANA_MBHC_RESULT_1 (WCD938X_BASE_ADDRESS + 0x0017)
#define WCD938X_ANA_MBHC_RESULT_2 (WCD938X_BASE_ADDRESS + 0x0018)
#define WCD938X_ANA_MBHC_RESULT_3 (WCD938X_BASE_ADDRESS + 0x0019)
#define WCD938X_ANA_MBHC_BTN0 (WCD938X_BASE_ADDRESS + 0x001A)
#define WCD938X_ANA_MBHC_BTN1 (WCD938X_BASE_ADDRESS + 0x001B)
#define WCD938X_ANA_MBHC_BTN2 (WCD938X_BASE_ADDRESS + 0x001C)
#define WCD938X_ANA_MBHC_BTN3 (WCD938X_BASE_ADDRESS + 0x001D)
#define WCD938X_ANA_MBHC_BTN4 (WCD938X_BASE_ADDRESS + 0x001E)
#define WCD938X_ANA_MBHC_BTN5 (WCD938X_BASE_ADDRESS + 0x001F)
#define WCD938X_ANA_MBHC_BTN6 (WCD938X_BASE_ADDRESS + 0x0020)
#define WCD938X_ANA_MBHC_BTN7 (WCD938X_BASE_ADDRESS + 0x0021)
#define WCD938X_ANA_MICB1 (WCD938X_BASE_ADDRESS + 0x0022)
#define WCD938X_ANA_MICB2 (WCD938X_BASE_ADDRESS + 0x0023)
#define WCD938X_ANA_MICB2_RAMP (WCD938X_BASE_ADDRESS + 0x0024)
#define WCD938X_ANA_MICB3 (WCD938X_BASE_ADDRESS + 0x0025)
#define WCD938X_ANA_MICB4 (WCD938X_BASE_ADDRESS + 0x0026)
#define WCD938X_BIAS_CTL (WCD938X_BASE_ADDRESS + 0x0028)
#define WCD938X_BIAS_VBG_FINE_ADJ (WCD938X_BASE_ADDRESS + 0x0029)
#define WCD938X_LDOL_VDDCX_ADJUST (WCD938X_BASE_ADDRESS + 0x0040)
#define WCD938X_LDOL_DISABLE_LDOL (WCD938X_BASE_ADDRESS + 0x0041)
#define WCD938X_MBHC_CTL_CLK (WCD938X_BASE_ADDRESS + 0x0056)
#define WCD938X_MBHC_CTL_ANA (WCD938X_BASE_ADDRESS + 0x0057)
#define WCD938X_MBHC_CTL_SPARE_1 (WCD938X_BASE_ADDRESS + 0x0058)
#define WCD938X_MBHC_CTL_SPARE_2 (WCD938X_BASE_ADDRESS + 0x0059)
#define WCD938X_MBHC_CTL_BCS (WCD938X_BASE_ADDRESS + 0x005A)
#define WCD938X_MBHC_MOISTURE_DET_FSM_STATUS (WCD938X_BASE_ADDRESS + 0x005B)
#define WCD938X_MBHC_TEST_CTL (WCD938X_BASE_ADDRESS + 0x005C)
#define WCD938X_LDOH_MODE (WCD938X_BASE_ADDRESS + 0x0067)
#define WCD938X_LDOH_BIAS (WCD938X_BASE_ADDRESS + 0x0068)
#define WCD938X_LDOH_STB_LOADS (WCD938X_BASE_ADDRESS + 0x0069)
#define WCD938X_LDOH_SLOWRAMP (WCD938X_BASE_ADDRESS + 0x006A)
#define WCD938X_MICB1_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x006B)
#define WCD938X_MICB1_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x006C)
#define WCD938X_MICB1_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x006D)
#define WCD938X_MICB2_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x006E)
#define WCD938X_MICB2_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x006F)
#define WCD938X_MICB2_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x0070)
#define WCD938X_MICB3_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x0071)
#define WCD938X_MICB3_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x0072)
#define WCD938X_MICB3_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x0073)
#define WCD938X_MICB4_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x0074)
#define WCD938X_MICB4_TEST_CTL_2 (WCD938X_BASE_ADDRESS + 0x0075)
#define WCD938X_MICB4_TEST_CTL_3 (WCD938X_BASE_ADDRESS + 0x0076)
#define WCD938X_TX_COM_ADC_VCM (WCD938X_BASE_ADDRESS + 0x0077)
#define WCD938X_TX_COM_BIAS_ATEST (WCD938X_BASE_ADDRESS + 0x0078)
#define WCD938X_TX_COM_SPARE1 (WCD938X_BASE_ADDRESS + 0x0079)
#define WCD938X_TX_COM_SPARE2 (WCD938X_BASE_ADDRESS + 0x007A)
#define WCD938X_TX_COM_TXFE_DIV_CTL (WCD938X_BASE_ADDRESS + 0x007B)
#define WCD938X_TX_COM_TXFE_DIV_START (WCD938X_BASE_ADDRESS + 0x007C)
#define WCD938X_TX_COM_SPARE3 (WCD938X_BASE_ADDRESS + 0x007D)
#define WCD938X_TX_COM_SPARE4 (WCD938X_BASE_ADDRESS + 0x007E)
#define WCD938X_TX_1_2_TEST_EN (WCD938X_BASE_ADDRESS + 0x007F)
#define WCD938X_TX_1_2_ADC_IB (WCD938X_BASE_ADDRESS + 0x0080)
#define WCD938X_TX_1_2_ATEST_REFCTL (WCD938X_BASE_ADDRESS + 0x0081)
#define WCD938X_TX_1_2_TEST_CTL (WCD938X_BASE_ADDRESS + 0x0082)
#define WCD938X_TX_1_2_TEST_BLK_EN1 (WCD938X_BASE_ADDRESS + 0x0083)
#define WCD938X_TX_1_2_TXFE1_CLKDIV (WCD938X_BASE_ADDRESS + 0x0084)
#define WCD938X_TX_1_2_SAR2_ERR (WCD938X_BASE_ADDRESS + 0x0085)
#define WCD938X_TX_1_2_SAR1_ERR (WCD938X_BASE_ADDRESS + 0x0086)
#define WCD938X_TX_3_4_TEST_EN (WCD938X_BASE_ADDRESS + 0x0087)
#define WCD938X_TX_3_4_ADC_IB (WCD938X_BASE_ADDRESS + 0x0088)
#define WCD938X_TX_3_4_ATEST_REFCTL (WCD938X_BASE_ADDRESS + 0x0089)
#define WCD938X_TX_3_4_TEST_CTL (WCD938X_BASE_ADDRESS + 0x008A)
#define WCD938X_TX_3_4_TEST_BLK_EN3 (WCD938X_BASE_ADDRESS + 0x008B)
#define WCD938X_TX_3_4_TXFE3_CLKDIV (WCD938X_BASE_ADDRESS + 0x008C)
#define WCD938X_TX_3_4_SAR4_ERR (WCD938X_BASE_ADDRESS + 0x008D)
#define WCD938X_TX_3_4_SAR3_ERR (WCD938X_BASE_ADDRESS + 0x008E)
#define WCD938X_TX_3_4_TEST_BLK_EN2 (WCD938X_BASE_ADDRESS + 0x008F)
#define WCD938X_TX_3_4_TXFE2_CLKDIV (WCD938X_BASE_ADDRESS + 0x0090)
#define WCD938X_TX_3_4_SPARE1 (WCD938X_BASE_ADDRESS + 0x0091)
#define WCD938X_TX_3_4_TEST_BLK_EN4 (WCD938X_BASE_ADDRESS + 0x0092)
#define WCD938X_TX_3_4_TXFE4_CLKDIV (WCD938X_BASE_ADDRESS + 0x0093)
#define WCD938X_TX_3_4_SPARE2 (WCD938X_BASE_ADDRESS + 0x0094)
#define WCD938X_CLASSH_MODE_1 (WCD938X_BASE_ADDRESS + 0x0097)
#define WCD938X_CLASSH_MODE_2 (WCD938X_BASE_ADDRESS + 0x0098)
#define WCD938X_CLASSH_MODE_3 (WCD938X_BASE_ADDRESS + 0x0099)
#define WCD938X_CLASSH_CTRL_VCL_1 (WCD938X_BASE_ADDRESS + 0x009A)
#define WCD938X_CLASSH_CTRL_VCL_2 (WCD938X_BASE_ADDRESS + 0x009B)
#define WCD938X_CLASSH_CTRL_CCL_1 (WCD938X_BASE_ADDRESS + 0x009C)
#define WCD938X_CLASSH_CTRL_CCL_2 (WCD938X_BASE_ADDRESS + 0x009D)
#define WCD938X_CLASSH_CTRL_CCL_3 (WCD938X_BASE_ADDRESS + 0x009E)
#define WCD938X_CLASSH_CTRL_CCL_4 (WCD938X_BASE_ADDRESS + 0x009F)
#define WCD938X_CLASSH_CTRL_CCL_5 (WCD938X_BASE_ADDRESS + 0x00A0)
#define WCD938X_CLASSH_BUCK_TMUX_A_D (WCD938X_BASE_ADDRESS + 0x00A1)
#define WCD938X_CLASSH_BUCK_SW_DRV_CNTL (WCD938X_BASE_ADDRESS + 0x00A2)
#define WCD938X_CLASSH_SPARE (WCD938X_BASE_ADDRESS + 0x00A3)
#define WCD938X_FLYBACK_EN (WCD938X_BASE_ADDRESS + 0x00A4)
#define WCD938X_FLYBACK_VNEG_CTRL_1 (WCD938X_BASE_ADDRESS + 0x00A5)
#define WCD938X_FLYBACK_VNEG_CTRL_2 (WCD938X_BASE_ADDRESS + 0x00A6)
#define WCD938X_FLYBACK_VNEG_CTRL_3 (WCD938X_BASE_ADDRESS + 0x00A7)
#define WCD938X_FLYBACK_VNEG_CTRL_4 (WCD938X_BASE_ADDRESS + 0x00A8)
#define WCD938X_FLYBACK_VNEG_CTRL_5 (WCD938X_BASE_ADDRESS + 0x00A9)
#define WCD938X_FLYBACK_VNEG_CTRL_6 (WCD938X_BASE_ADDRESS + 0x00AA)
#define WCD938X_FLYBACK_VNEG_CTRL_7 (WCD938X_BASE_ADDRESS + 0x00AB)
#define WCD938X_FLYBACK_VNEG_CTRL_8 (WCD938X_BASE_ADDRESS + 0x00AC)
#define WCD938X_FLYBACK_VNEG_CTRL_9 (WCD938X_BASE_ADDRESS + 0x00AD)
#define WCD938X_FLYBACK_VNEGDAC_CTRL_1 (WCD938X_BASE_ADDRESS + 0x00AE)
#define WCD938X_FLYBACK_VNEGDAC_CTRL_2 (WCD938X_BASE_ADDRESS + 0x00AF)
#define WCD938X_FLYBACK_VNEGDAC_CTRL_3 (WCD938X_BASE_ADDRESS + 0x00B0)
#define WCD938X_FLYBACK_CTRL_1 (WCD938X_BASE_ADDRESS + 0x00B1)
#define WCD938X_FLYBACK_TEST_CTL (WCD938X_BASE_ADDRESS + 0x00B2)
#define WCD938X_RX_AUX_SW_CTL (WCD938X_BASE_ADDRESS + 0x00B3)
#define WCD938X_RX_PA_AUX_IN_CONN (WCD938X_BASE_ADDRESS + 0x00B4)
#define WCD938X_RX_TIMER_DIV (WCD938X_BASE_ADDRESS + 0x00B5)
#define WCD938X_RX_OCP_CTL (WCD938X_BASE_ADDRESS + 0x00B6)
#define WCD938X_RX_OCP_COUNT (WCD938X_BASE_ADDRESS + 0x00B7)
#define WCD938X_RX_BIAS_EAR_DAC (WCD938X_BASE_ADDRESS + 0x00B8)
#define WCD938X_RX_BIAS_EAR_AMP (WCD938X_BASE_ADDRESS + 0x00B9)
#define WCD938X_RX_BIAS_HPH_LDO (WCD938X_BASE_ADDRESS + 0x00BA)
#define WCD938X_RX_BIAS_HPH_PA (WCD938X_BASE_ADDRESS + 0x00BB)
#define WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2 (WCD938X_BASE_ADDRESS + 0x00BC)
#define WCD938X_RX_BIAS_HPH_RDAC_LDO (WCD938X_BASE_ADDRESS + 0x00BD)
#define WCD938X_RX_BIAS_HPH_CNP1 (WCD938X_BASE_ADDRESS + 0x00BE)
#define WCD938X_RX_BIAS_HPH_LOWPOWER (WCD938X_BASE_ADDRESS + 0x00BF)
#define WCD938X_RX_BIAS_AUX_DAC (WCD938X_BASE_ADDRESS + 0x00C0)
#define WCD938X_RX_BIAS_AUX_AMP (WCD938X_BASE_ADDRESS + 0x00C1)
#define WCD938X_RX_BIAS_VNEGDAC_BLEEDER (WCD938X_BASE_ADDRESS + 0x00C2)
#define WCD938X_RX_BIAS_MISC (WCD938X_BASE_ADDRESS + 0x00C3)
#define WCD938X_RX_BIAS_BUCK_RST (WCD938X_BASE_ADDRESS + 0x00C4)
#define WCD938X_RX_BIAS_BUCK_VREF_ERRAMP (WCD938X_BASE_ADDRESS + 0x00C5)
#define WCD938X_RX_BIAS_FLYB_ERRAMP (WCD938X_BASE_ADDRESS + 0x00C6)
#define WCD938X_RX_BIAS_FLYB_BUFF (WCD938X_BASE_ADDRESS + 0x00C7)
#define WCD938X_RX_BIAS_FLYB_MID_RST (WCD938X_BASE_ADDRESS + 0x00C8)
#define WCD938X_HPH_L_STATUS (WCD938X_BASE_ADDRESS + 0x00C9)
#define WCD938X_HPH_R_STATUS (WCD938X_BASE_ADDRESS + 0x00CA)
#define WCD938X_HPH_CNP_EN (WCD938X_BASE_ADDRESS + 0x00CB)
#define WCD938X_HPH_CNP_WG_CTL (WCD938X_BASE_ADDRESS + 0x00CC)
#define WCD938X_HPH_CNP_WG_TIME (WCD938X_BASE_ADDRESS + 0x00CD)
#define WCD938X_HPH_OCP_CTL (WCD938X_BASE_ADDRESS + 0x00CE)
#define WCD938X_HPH_AUTO_CHOP (WCD938X_BASE_ADDRESS + 0x00CF)
#define WCD938X_HPH_CHOP_CTL (WCD938X_BASE_ADDRESS + 0x00D0)
#define WCD938X_HPH_PA_CTL1 (WCD938X_BASE_ADDRESS + 0x00D1)
#define WCD938X_HPH_PA_CTL2 (WCD938X_BASE_ADDRESS + 0x00D2)
#define WCD938X_HPH_L_EN (WCD938X_BASE_ADDRESS + 0x00D3)
#define WCD938X_HPH_L_TEST (WCD938X_BASE_ADDRESS + 0x00D4)
#define WCD938X_HPH_L_ATEST (WCD938X_BASE_ADDRESS + 0x00D5)
#define WCD938X_HPH_R_EN (WCD938X_BASE_ADDRESS + 0x00D6)
#define WCD938X_HPH_R_TEST (WCD938X_BASE_ADDRESS + 0x00D7)
#define WCD938X_HPH_R_ATEST (WCD938X_BASE_ADDRESS + 0x00D8)
#define WCD938X_HPH_RDAC_CLK_CTL1 (WCD938X_BASE_ADDRESS + 0x00D9)
#define WCD938X_HPH_RDAC_CLK_CTL2 (WCD938X_BASE_ADDRESS + 0x00DA)
#define WCD938X_HPH_RDAC_LDO_CTL (WCD938X_BASE_ADDRESS + 0x00DB)
#define WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL (WCD938X_BASE_ADDRESS + 0x00DC)
#define WCD938X_HPH_REFBUFF_UHQA_CTL (WCD938X_BASE_ADDRESS + 0x00DD)
#define WCD938X_HPH_REFBUFF_LP_CTL (WCD938X_BASE_ADDRESS + 0x00DE)
#define WCD938X_HPH_L_DAC_CTL (WCD938X_BASE_ADDRESS + 0x00DF)
#define WCD938X_HPH_R_DAC_CTL (WCD938X_BASE_ADDRESS + 0x00E0)
#define WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL (WCD938X_BASE_ADDRESS + 0x00E1)
#define WCD938X_HPH_SURGE_HPHLR_SURGE_EN (WCD938X_BASE_ADDRESS + 0x00E2)
#define WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1 (WCD938X_BASE_ADDRESS + 0x00E3)
#define WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS (WCD938X_BASE_ADDRESS + 0x00E4)
#define WCD938X_EAR_EAR_EN_REG (WCD938X_BASE_ADDRESS + 0x00E9)
#define WCD938X_EAR_EAR_PA_CON (WCD938X_BASE_ADDRESS + 0x00EA)
#define WCD938X_EAR_EAR_SP_CON (WCD938X_BASE_ADDRESS + 0x00EB)
#define WCD938X_EAR_EAR_DAC_CON (WCD938X_BASE_ADDRESS + 0x00EC)
#define WCD938X_EAR_EAR_CNP_FSM_CON (WCD938X_BASE_ADDRESS + 0x00ED)
#define WCD938X_EAR_TEST_CTL (WCD938X_BASE_ADDRESS + 0x00EE)
#define WCD938X_EAR_STATUS_REG_1 (WCD938X_BASE_ADDRESS + 0x00EF)
#define WCD938X_EAR_STATUS_REG_2 (WCD938X_BASE_ADDRESS + 0x00F0)
#define WCD938X_ANA_NEW_PAGE_REGISTER (WCD938X_BASE_ADDRESS + 0x0100)
#define WCD938X_HPH_NEW_ANA_HPH2 (WCD938X_BASE_ADDRESS + 0x0101)
#define WCD938X_HPH_NEW_ANA_HPH3 (WCD938X_BASE_ADDRESS + 0x0102)
#define WCD938X_SLEEP_CTL (WCD938X_BASE_ADDRESS + 0x0103)
#define WCD938X_SLEEP_WATCHDOG_CTL (WCD938X_BASE_ADDRESS + 0x0104)
#define WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL (WCD938X_BASE_ADDRESS + 0x011F)
#define WCD938X_MBHC_NEW_CTL_1 (WCD938X_BASE_ADDRESS + 0x0120)
#define WCD938X_MBHC_NEW_CTL_2 (WCD938X_BASE_ADDRESS + 0x0121)
#define WCD938X_MBHC_NEW_PLUG_DETECT_CTL (WCD938X_BASE_ADDRESS + 0x0122)
#define WCD938X_MBHC_NEW_ZDET_ANA_CTL (WCD938X_BASE_ADDRESS + 0x0123)
#define WCD938X_MBHC_NEW_ZDET_RAMP_CTL (WCD938X_BASE_ADDRESS + 0x0124)
#define WCD938X_MBHC_NEW_FSM_STATUS (WCD938X_BASE_ADDRESS + 0x0125)
#define WCD938X_MBHC_NEW_ADC_RESULT (WCD938X_BASE_ADDRESS + 0x0126)
#define WCD938X_TX_NEW_AMIC_MUX_CFG (WCD938X_BASE_ADDRESS + 0x0127)
#define WCD938X_AUX_AUXPA (WCD938X_BASE_ADDRESS + 0x0128)
#define WCD938X_LDORXTX_MODE (WCD938X_BASE_ADDRESS + 0x0129)
#define WCD938X_LDORXTX_CONFIG (WCD938X_BASE_ADDRESS + 0x012A)
#define WCD938X_DIE_CRACK_DIE_CRK_DET_EN (WCD938X_BASE_ADDRESS + 0x012C)
#define WCD938X_DIE_CRACK_DIE_CRK_DET_OUT (WCD938X_BASE_ADDRESS + 0x012D)
#define WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL (WCD938X_BASE_ADDRESS + 0x0132)
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L (WCD938X_BASE_ADDRESS + 0x0133)
#define WCD938X_HPH_NEW_INT_RDAC_VREF_CTL (WCD938X_BASE_ADDRESS + 0x0134)
#define WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL (WCD938X_BASE_ADDRESS + 0x0135)
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R (WCD938X_BASE_ADDRESS + 0x0136)
#define WCD938X_HPH_NEW_INT_PA_MISC1 (WCD938X_BASE_ADDRESS + 0x0137)
#define WCD938X_HPH_NEW_INT_PA_MISC2 (WCD938X_BASE_ADDRESS + 0x0138)
#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC (WCD938X_BASE_ADDRESS + 0x0139)
#define WCD938X_HPH_NEW_INT_HPH_TIMER1 (WCD938X_BASE_ADDRESS + 0x013A)
#define WCD938X_HPH_NEW_INT_HPH_TIMER2 (WCD938X_BASE_ADDRESS + 0x013B)
#define WCD938X_HPH_NEW_INT_HPH_TIMER3 (WCD938X_BASE_ADDRESS + 0x013C)
#define WCD938X_HPH_NEW_INT_HPH_TIMER4 (WCD938X_BASE_ADDRESS + 0x013D)
#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC2 (WCD938X_BASE_ADDRESS + 0x013E)
#define WCD938X_HPH_NEW_INT_PA_RDAC_MISC3 (WCD938X_BASE_ADDRESS + 0x013F)
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW (WCD938X_BASE_ADDRESS + 0x0140)
#define WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW (WCD938X_BASE_ADDRESS + 0x0141)
#define WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI (WCD938X_BASE_ADDRESS + 0x0145)
#define WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP (WCD938X_BASE_ADDRESS + 0x0146)
#define WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP (WCD938X_BASE_ADDRESS + 0x0147)
#define WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL \
(WCD938X_BASE_ADDRESS + 0x01AF)
#define WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL \
(WCD938X_BASE_ADDRESS + 0x01B0)
#define WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT (WCD938X_BASE_ADDRESS + 0x01B1)
#define WCD938X_MBHC_NEW_INT_SPARE_2 (WCD938X_BASE_ADDRESS + 0x01B2)
#define WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON (WCD938X_BASE_ADDRESS + 0x01B7)
#define WCD938X_EAR_INT_NEW_CNP_VCM_CON1 (WCD938X_BASE_ADDRESS + 0x01B8)
#define WCD938X_EAR_INT_NEW_CNP_VCM_CON2 (WCD938X_BASE_ADDRESS + 0x01B9)
#define WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS (WCD938X_BASE_ADDRESS + 0x01BA)
#define WCD938X_AUX_INT_EN_REG (WCD938X_BASE_ADDRESS + 0x01BD)
#define WCD938X_AUX_INT_PA_CTRL (WCD938X_BASE_ADDRESS + 0x01BE)
#define WCD938X_AUX_INT_SP_CTRL (WCD938X_BASE_ADDRESS + 0x01BF)
#define WCD938X_AUX_INT_DAC_CTRL (WCD938X_BASE_ADDRESS + 0x01C0)
#define WCD938X_AUX_INT_CLK_CTRL (WCD938X_BASE_ADDRESS + 0x01C1)
#define WCD938X_AUX_INT_TEST_CTRL (WCD938X_BASE_ADDRESS + 0x01C2)
#define WCD938X_AUX_INT_STATUS_REG (WCD938X_BASE_ADDRESS + 0x01C3)
#define WCD938X_AUX_INT_MISC (WCD938X_BASE_ADDRESS + 0x01C4)
#define WCD938X_LDORXTX_INT_BIAS (WCD938X_BASE_ADDRESS + 0x01C5)
#define WCD938X_LDORXTX_INT_STB_LOADS_DTEST (WCD938X_BASE_ADDRESS + 0x01C6)
#define WCD938X_LDORXTX_INT_TEST0 (WCD938X_BASE_ADDRESS + 0x01C7)
#define WCD938X_LDORXTX_INT_STARTUP_TIMER (WCD938X_BASE_ADDRESS + 0x01C8)
#define WCD938X_LDORXTX_INT_TEST1 (WCD938X_BASE_ADDRESS + 0x01C9)
#define WCD938X_LDORXTX_INT_STATUS (WCD938X_BASE_ADDRESS + 0x01CA)
#define WCD938X_SLEEP_INT_WATCHDOG_CTL_1 (WCD938X_BASE_ADDRESS + 0x01D0)
#define WCD938X_SLEEP_INT_WATCHDOG_CTL_2 (WCD938X_BASE_ADDRESS + 0x01D1)
#define WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1 (WCD938X_BASE_ADDRESS + 0x01D3)
#define WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2 (WCD938X_BASE_ADDRESS + 0x01D4)
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2 (WCD938X_BASE_ADDRESS + 0x01D5)
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1 (WCD938X_BASE_ADDRESS + 0x01D6)
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0 (WCD938X_BASE_ADDRESS + 0x01D7)
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M \
(WCD938X_BASE_ADDRESS + 0x01D8)
#define WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M \
(WCD938X_BASE_ADDRESS + 0x01D9)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1 \
(WCD938X_BASE_ADDRESS + 0x01DA)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0 \
(WCD938X_BASE_ADDRESS + 0x01DB)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP \
(WCD938X_BASE_ADDRESS + 0x01DC)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1 \
(WCD938X_BASE_ADDRESS + 0x01DD)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0 \
(WCD938X_BASE_ADDRESS + 0x01DE)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP \
(WCD938X_BASE_ADDRESS + 0x01DF)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0 \
(WCD938X_BASE_ADDRESS + 0x01E0)
#define WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP \
(WCD938X_BASE_ADDRESS + 0x01E1)
#define WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1 \
(WCD938X_BASE_ADDRESS + 0x01E2)
#define WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP \
(WCD938X_BASE_ADDRESS + 0x01E3)
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L2 (WCD938X_BASE_ADDRESS + 0x01E4)
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L1 (WCD938X_BASE_ADDRESS + 0x01E5)
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_L0 (WCD938X_BASE_ADDRESS + 0x01E6)
#define WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP (WCD938X_BASE_ADDRESS + 0x01E7)
#define WCD938X_DIGITAL_PAGE_REGISTER (WCD938X_BASE_ADDRESS + 0x0400)
#define WCD938X_DIGITAL_CHIP_ID0 (WCD938X_BASE_ADDRESS + 0x0401)
#define WCD938X_DIGITAL_CHIP_ID1 (WCD938X_BASE_ADDRESS + 0x0402)
#define WCD938X_DIGITAL_CHIP_ID2 (WCD938X_BASE_ADDRESS + 0x0403)
#define WCD938X_DIGITAL_CHIP_ID3 (WCD938X_BASE_ADDRESS + 0x0404)
#define WCD938X_DIGITAL_SWR_TX_CLK_RATE (WCD938X_BASE_ADDRESS + 0x0405)
#define WCD938X_DIGITAL_CDC_RST_CTL (WCD938X_BASE_ADDRESS + 0x0406)
#define WCD938X_DIGITAL_TOP_CLK_CFG (WCD938X_BASE_ADDRESS + 0x0407)
#define WCD938X_DIGITAL_CDC_ANA_CLK_CTL (WCD938X_BASE_ADDRESS + 0x0408)
#define WCD938X_DIGITAL_CDC_DIG_CLK_CTL (WCD938X_BASE_ADDRESS + 0x0409)
#define WCD938X_DIGITAL_SWR_RST_EN (WCD938X_BASE_ADDRESS + 0x040A)
#define WCD938X_DIGITAL_CDC_PATH_MODE (WCD938X_BASE_ADDRESS + 0x040B)
#define WCD938X_DIGITAL_CDC_RX_RST (WCD938X_BASE_ADDRESS + 0x040C)
#define WCD938X_DIGITAL_CDC_RX0_CTL (WCD938X_BASE_ADDRESS + 0x040D)
#define WCD938X_DIGITAL_CDC_RX1_CTL (WCD938X_BASE_ADDRESS + 0x040E)
#define WCD938X_DIGITAL_CDC_RX2_CTL (WCD938X_BASE_ADDRESS + 0x040F)
#define WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1 (WCD938X_BASE_ADDRESS + 0x0410)
#define WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3 (WCD938X_BASE_ADDRESS + 0x0411)
#define WCD938X_DIGITAL_CDC_COMP_CTL_0 (WCD938X_BASE_ADDRESS + 0x0414)
#define WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL (WCD938X_BASE_ADDRESS + 0x0417)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A1_0 (WCD938X_BASE_ADDRESS + 0x0418)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A1_1 (WCD938X_BASE_ADDRESS + 0x0419)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A2_0 (WCD938X_BASE_ADDRESS + 0x041A)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A2_1 (WCD938X_BASE_ADDRESS + 0x041B)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A3_0 (WCD938X_BASE_ADDRESS + 0x041C)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A3_1 (WCD938X_BASE_ADDRESS + 0x041D)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A4_0 (WCD938X_BASE_ADDRESS + 0x041E)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A4_1 (WCD938X_BASE_ADDRESS + 0x041F)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A5_0 (WCD938X_BASE_ADDRESS + 0x0420)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A5_1 (WCD938X_BASE_ADDRESS + 0x0421)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A6_0 (WCD938X_BASE_ADDRESS + 0x0422)
#define WCD938X_DIGITAL_CDC_HPH_DSM_A7_0 (WCD938X_BASE_ADDRESS + 0x0423)
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_0 (WCD938X_BASE_ADDRESS + 0x0424)
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_1 (WCD938X_BASE_ADDRESS + 0x0425)
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_2 (WCD938X_BASE_ADDRESS + 0x0426)
#define WCD938X_DIGITAL_CDC_HPH_DSM_C_3 (WCD938X_BASE_ADDRESS + 0x0427)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R1 (WCD938X_BASE_ADDRESS + 0x0428)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R2 (WCD938X_BASE_ADDRESS + 0x0429)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R3 (WCD938X_BASE_ADDRESS + 0x042A)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R4 (WCD938X_BASE_ADDRESS + 0x042B)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R5 (WCD938X_BASE_ADDRESS + 0x042C)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R6 (WCD938X_BASE_ADDRESS + 0x042D)
#define WCD938X_DIGITAL_CDC_HPH_DSM_R7 (WCD938X_BASE_ADDRESS + 0x042E)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A1_0 (WCD938X_BASE_ADDRESS + 0x042F)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A1_1 (WCD938X_BASE_ADDRESS + 0x0430)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A2_0 (WCD938X_BASE_ADDRESS + 0x0431)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A2_1 (WCD938X_BASE_ADDRESS + 0x0432)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A3_0 (WCD938X_BASE_ADDRESS + 0x0433)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A3_1 (WCD938X_BASE_ADDRESS + 0x0434)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A4_0 (WCD938X_BASE_ADDRESS + 0x0435)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A4_1 (WCD938X_BASE_ADDRESS + 0x0436)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A5_0 (WCD938X_BASE_ADDRESS + 0x0437)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A5_1 (WCD938X_BASE_ADDRESS + 0x0438)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A6_0 (WCD938X_BASE_ADDRESS + 0x0439)
#define WCD938X_DIGITAL_CDC_AUX_DSM_A7_0 (WCD938X_BASE_ADDRESS + 0x043A)
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_0 (WCD938X_BASE_ADDRESS + 0x043B)
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_1 (WCD938X_BASE_ADDRESS + 0x043C)
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_2 (WCD938X_BASE_ADDRESS + 0x043D)
#define WCD938X_DIGITAL_CDC_AUX_DSM_C_3 (WCD938X_BASE_ADDRESS + 0x043E)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R1 (WCD938X_BASE_ADDRESS + 0x043F)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R2 (WCD938X_BASE_ADDRESS + 0x0440)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R3 (WCD938X_BASE_ADDRESS + 0x0441)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R4 (WCD938X_BASE_ADDRESS + 0x0442)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R5 (WCD938X_BASE_ADDRESS + 0x0443)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R6 (WCD938X_BASE_ADDRESS + 0x0444)
#define WCD938X_DIGITAL_CDC_AUX_DSM_R7 (WCD938X_BASE_ADDRESS + 0x0445)
#define WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0 (WCD938X_BASE_ADDRESS + 0x0446)
#define WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1 (WCD938X_BASE_ADDRESS + 0x0447)
#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0 (WCD938X_BASE_ADDRESS + 0x0448)
#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1 (WCD938X_BASE_ADDRESS + 0x0449)
#define WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2 (WCD938X_BASE_ADDRESS + 0x044A)
#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0 (WCD938X_BASE_ADDRESS + 0x044B)
#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1 (WCD938X_BASE_ADDRESS + 0x044C)
#define WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2 (WCD938X_BASE_ADDRESS + 0x044D)
#define WCD938X_DIGITAL_CDC_HPH_GAIN_CTL (WCD938X_BASE_ADDRESS + 0x044E)
#define WCD938X_DIGITAL_CDC_AUX_GAIN_CTL (WCD938X_BASE_ADDRESS + 0x044F)
#define WCD938X_DIGITAL_CDC_EAR_PATH_CTL (WCD938X_BASE_ADDRESS + 0x0450)
#define WCD938X_DIGITAL_CDC_SWR_CLH (WCD938X_BASE_ADDRESS + 0x0451)
#define WCD938X_DIGITAL_SWR_CLH_BYP (WCD938X_BASE_ADDRESS + 0x0452)
#define WCD938X_DIGITAL_CDC_TX0_CTL (WCD938X_BASE_ADDRESS + 0x0453)
#define WCD938X_DIGITAL_CDC_TX1_CTL (WCD938X_BASE_ADDRESS + 0x0454)
#define WCD938X_DIGITAL_CDC_TX2_CTL (WCD938X_BASE_ADDRESS + 0x0455)
#define WCD938X_DIGITAL_CDC_TX_RST (WCD938X_BASE_ADDRESS + 0x0456)
#define WCD938X_DIGITAL_CDC_REQ_CTL (WCD938X_BASE_ADDRESS + 0x0457)
#define WCD938X_DIGITAL_CDC_RST (WCD938X_BASE_ADDRESS + 0x0458)
#define WCD938X_DIGITAL_CDC_AMIC_CTL (WCD938X_BASE_ADDRESS + 0x045A)
#define WCD938X_DIGITAL_CDC_DMIC_CTL (WCD938X_BASE_ADDRESS + 0x045B)
#define WCD938X_DIGITAL_CDC_DMIC1_CTL (WCD938X_BASE_ADDRESS + 0x045C)
#define WCD938X_DIGITAL_CDC_DMIC2_CTL (WCD938X_BASE_ADDRESS + 0x045D)
#define WCD938X_DIGITAL_CDC_DMIC3_CTL (WCD938X_BASE_ADDRESS + 0x045E)
#define WCD938X_DIGITAL_CDC_DMIC4_CTL (WCD938X_BASE_ADDRESS + 0x045F)
#define WCD938X_DIGITAL_EFUSE_PRG_CTL (WCD938X_BASE_ADDRESS + 0x0460)
#define WCD938X_DIGITAL_EFUSE_CTL (WCD938X_BASE_ADDRESS + 0x0461)
#define WCD938X_DIGITAL_CDC_DMIC_RATE_1_2 (WCD938X_BASE_ADDRESS + 0x0462)
#define WCD938X_DIGITAL_CDC_DMIC_RATE_3_4 (WCD938X_BASE_ADDRESS + 0x0463)
#define WCD938X_DIGITAL_PDM_WD_CTL0 (WCD938X_BASE_ADDRESS + 0x0465)
#define WCD938X_DIGITAL_PDM_WD_CTL1 (WCD938X_BASE_ADDRESS + 0x0466)
#define WCD938X_DIGITAL_PDM_WD_CTL2 (WCD938X_BASE_ADDRESS + 0x0467)
#define WCD938X_DIGITAL_INTR_MODE (WCD938X_BASE_ADDRESS + 0x046A)
#define WCD938X_DIGITAL_INTR_MASK_0 (WCD938X_BASE_ADDRESS + 0x046B)
#define WCD938X_DIGITAL_INTR_MASK_1 (WCD938X_BASE_ADDRESS + 0x046C)
#define WCD938X_DIGITAL_INTR_MASK_2 (WCD938X_BASE_ADDRESS + 0x046D)
#define WCD938X_DIGITAL_INTR_STATUS_0 (WCD938X_BASE_ADDRESS + 0x046E)
#define WCD938X_DIGITAL_INTR_STATUS_1 (WCD938X_BASE_ADDRESS + 0x046F)
#define WCD938X_DIGITAL_INTR_STATUS_2 (WCD938X_BASE_ADDRESS + 0x0470)
#define WCD938X_DIGITAL_INTR_CLEAR_0 (WCD938X_BASE_ADDRESS + 0x0471)
#define WCD938X_DIGITAL_INTR_CLEAR_1 (WCD938X_BASE_ADDRESS + 0x0472)
#define WCD938X_DIGITAL_INTR_CLEAR_2 (WCD938X_BASE_ADDRESS + 0x0473)
#define WCD938X_DIGITAL_INTR_LEVEL_0 (WCD938X_BASE_ADDRESS + 0x0474)
#define WCD938X_DIGITAL_INTR_LEVEL_1 (WCD938X_BASE_ADDRESS + 0x0475)
#define WCD938X_DIGITAL_INTR_LEVEL_2 (WCD938X_BASE_ADDRESS + 0x0476)
#define WCD938X_DIGITAL_INTR_SET_0 (WCD938X_BASE_ADDRESS + 0x0477)
#define WCD938X_DIGITAL_INTR_SET_1 (WCD938X_BASE_ADDRESS + 0x0478)
#define WCD938X_DIGITAL_INTR_SET_2 (WCD938X_BASE_ADDRESS + 0x0479)
#define WCD938X_DIGITAL_INTR_TEST_0 (WCD938X_BASE_ADDRESS + 0x047A)
#define WCD938X_DIGITAL_INTR_TEST_1 (WCD938X_BASE_ADDRESS + 0x047B)
#define WCD938X_DIGITAL_INTR_TEST_2 (WCD938X_BASE_ADDRESS + 0x047C)
#define WCD938X_DIGITAL_TX_MODE_DBG_EN (WCD938X_BASE_ADDRESS + 0x047F)
#define WCD938X_DIGITAL_TX_MODE_DBG_0_1 (WCD938X_BASE_ADDRESS + 0x0480)
#define WCD938X_DIGITAL_TX_MODE_DBG_2_3 (WCD938X_BASE_ADDRESS + 0x0481)
#define WCD938X_DIGITAL_LB_IN_SEL_CTL (WCD938X_BASE_ADDRESS + 0x0482)
#define WCD938X_DIGITAL_LOOP_BACK_MODE (WCD938X_BASE_ADDRESS + 0x0483)
#define WCD938X_DIGITAL_SWR_DAC_TEST (WCD938X_BASE_ADDRESS + 0x0484)
#define WCD938X_DIGITAL_SWR_HM_TEST_RX_0 (WCD938X_BASE_ADDRESS + 0x0485)
#define WCD938X_DIGITAL_SWR_HM_TEST_TX_0 (WCD938X_BASE_ADDRESS + 0x0486)
#define WCD938X_DIGITAL_SWR_HM_TEST_RX_1 (WCD938X_BASE_ADDRESS + 0x0487)
#define WCD938X_DIGITAL_SWR_HM_TEST_TX_1 (WCD938X_BASE_ADDRESS + 0x0488)
#define WCD938X_DIGITAL_SWR_HM_TEST_TX_2 (WCD938X_BASE_ADDRESS + 0x0489)
#define WCD938X_DIGITAL_SWR_HM_TEST_0 (WCD938X_BASE_ADDRESS + 0x048A)
#define WCD938X_DIGITAL_SWR_HM_TEST_1 (WCD938X_BASE_ADDRESS + 0x048B)
#define WCD938X_DIGITAL_PAD_CTL_SWR_0 (WCD938X_BASE_ADDRESS + 0x048C)
#define WCD938X_DIGITAL_PAD_CTL_SWR_1 (WCD938X_BASE_ADDRESS + 0x048D)
#define WCD938X_DIGITAL_I2C_CTL (WCD938X_BASE_ADDRESS + 0x048E)
#define WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE (WCD938X_BASE_ADDRESS + 0x048F)
#define WCD938X_DIGITAL_EFUSE_TEST_CTL_0 (WCD938X_BASE_ADDRESS + 0x0490)
#define WCD938X_DIGITAL_EFUSE_TEST_CTL_1 (WCD938X_BASE_ADDRESS + 0x0491)
#define WCD938X_DIGITAL_EFUSE_T_DATA_0 (WCD938X_BASE_ADDRESS + 0x0492)
#define WCD938X_DIGITAL_EFUSE_T_DATA_1 (WCD938X_BASE_ADDRESS + 0x0493)
#define WCD938X_DIGITAL_PAD_CTL_PDM_RX0 (WCD938X_BASE_ADDRESS + 0x0494)
#define WCD938X_DIGITAL_PAD_CTL_PDM_RX1 (WCD938X_BASE_ADDRESS + 0x0495)
#define WCD938X_DIGITAL_PAD_CTL_PDM_TX0 (WCD938X_BASE_ADDRESS + 0x0496)
#define WCD938X_DIGITAL_PAD_CTL_PDM_TX1 (WCD938X_BASE_ADDRESS + 0x0497)
#define WCD938X_DIGITAL_PAD_CTL_PDM_TX2 (WCD938X_BASE_ADDRESS + 0x0498)
#define WCD938X_DIGITAL_PAD_INP_DIS_0 (WCD938X_BASE_ADDRESS + 0x0499)
#define WCD938X_DIGITAL_PAD_INP_DIS_1 (WCD938X_BASE_ADDRESS + 0x049A)
#define WCD938X_DIGITAL_DRIVE_STRENGTH_0 (WCD938X_BASE_ADDRESS + 0x049B)
#define WCD938X_DIGITAL_DRIVE_STRENGTH_1 (WCD938X_BASE_ADDRESS + 0x049C)
#define WCD938X_DIGITAL_DRIVE_STRENGTH_2 (WCD938X_BASE_ADDRESS + 0x049D)
#define WCD938X_DIGITAL_RX_DATA_EDGE_CTL (WCD938X_BASE_ADDRESS + 0x049E)
#define WCD938X_DIGITAL_TX_DATA_EDGE_CTL (WCD938X_BASE_ADDRESS + 0x049F)
#define WCD938X_DIGITAL_GPIO_MODE (WCD938X_BASE_ADDRESS + 0x04A0)
#define WCD938X_DIGITAL_PIN_CTL_OE (WCD938X_BASE_ADDRESS + 0x04A1)
#define WCD938X_DIGITAL_PIN_CTL_DATA_0 (WCD938X_BASE_ADDRESS + 0x04A2)
#define WCD938X_DIGITAL_PIN_CTL_DATA_1 (WCD938X_BASE_ADDRESS + 0x04A3)
#define WCD938X_DIGITAL_PIN_STATUS_0 (WCD938X_BASE_ADDRESS + 0x04A4)
#define WCD938X_DIGITAL_PIN_STATUS_1 (WCD938X_BASE_ADDRESS + 0x04A5)
#define WCD938X_DIGITAL_DIG_DEBUG_CTL (WCD938X_BASE_ADDRESS + 0x04A6)
#define WCD938X_DIGITAL_DIG_DEBUG_EN (WCD938X_BASE_ADDRESS + 0x04A7)
#define WCD938X_DIGITAL_ANA_CSR_DBG_ADD (WCD938X_BASE_ADDRESS + 0x04A8)
#define WCD938X_DIGITAL_ANA_CSR_DBG_CTL (WCD938X_BASE_ADDRESS + 0x04A9)
#define WCD938X_DIGITAL_SSP_DBG (WCD938X_BASE_ADDRESS + 0x04AA)
#define WCD938X_DIGITAL_MODE_STATUS_0 (WCD938X_BASE_ADDRESS + 0x04AB)
#define WCD938X_DIGITAL_MODE_STATUS_1 (WCD938X_BASE_ADDRESS + 0x04AC)
#define WCD938X_DIGITAL_SPARE_0 (WCD938X_BASE_ADDRESS + 0x04AD)
#define WCD938X_DIGITAL_SPARE_1 (WCD938X_BASE_ADDRESS + 0x04AE)
#define WCD938X_DIGITAL_SPARE_2 (WCD938X_BASE_ADDRESS + 0x04AF)
#define WCD938X_DIGITAL_EFUSE_REG_0 (WCD938X_BASE_ADDRESS + 0x04B0)
#define WCD938X_DIGITAL_EFUSE_REG_1 (WCD938X_BASE_ADDRESS + 0x04B1)
#define WCD938X_DIGITAL_EFUSE_REG_2 (WCD938X_BASE_ADDRESS + 0x04B2)
#define WCD938X_DIGITAL_EFUSE_REG_3 (WCD938X_BASE_ADDRESS + 0x04B3)
#define WCD938X_DIGITAL_EFUSE_REG_4 (WCD938X_BASE_ADDRESS + 0x04B4)
#define WCD938X_DIGITAL_EFUSE_REG_5 (WCD938X_BASE_ADDRESS + 0x04B5)
#define WCD938X_DIGITAL_EFUSE_REG_6 (WCD938X_BASE_ADDRESS + 0x04B6)
#define WCD938X_DIGITAL_EFUSE_REG_7 (WCD938X_BASE_ADDRESS + 0x04B7)
#define WCD938X_DIGITAL_EFUSE_REG_8 (WCD938X_BASE_ADDRESS + 0x04B8)
#define WCD938X_DIGITAL_EFUSE_REG_9 (WCD938X_BASE_ADDRESS + 0x04B9)
#define WCD938X_DIGITAL_EFUSE_REG_10 (WCD938X_BASE_ADDRESS + 0x04BA)
#define WCD938X_DIGITAL_EFUSE_REG_11 (WCD938X_BASE_ADDRESS + 0x04BB)
#define WCD938X_DIGITAL_EFUSE_REG_12 (WCD938X_BASE_ADDRESS + 0x04BC)
#define WCD938X_DIGITAL_EFUSE_REG_13 (WCD938X_BASE_ADDRESS + 0x04BD)
#define WCD938X_DIGITAL_EFUSE_REG_14 (WCD938X_BASE_ADDRESS + 0x04BE)
#define WCD938X_DIGITAL_EFUSE_REG_15 (WCD938X_BASE_ADDRESS + 0x04BF)
#define WCD938X_DIGITAL_EFUSE_REG_16 (WCD938X_BASE_ADDRESS + 0x04C0)
#define WCD938X_DIGITAL_EFUSE_REG_17 (WCD938X_BASE_ADDRESS + 0x04C1)
#define WCD938X_DIGITAL_EFUSE_REG_18 (WCD938X_BASE_ADDRESS + 0x04C2)
#define WCD938X_DIGITAL_EFUSE_REG_19 (WCD938X_BASE_ADDRESS + 0x04C3)
#define WCD938X_DIGITAL_EFUSE_REG_20 (WCD938X_BASE_ADDRESS + 0x04C4)
#define WCD938X_DIGITAL_EFUSE_REG_21 (WCD938X_BASE_ADDRESS + 0x04C5)
#define WCD938X_DIGITAL_EFUSE_REG_22 (WCD938X_BASE_ADDRESS + 0x04C6)
#define WCD938X_DIGITAL_EFUSE_REG_23 (WCD938X_BASE_ADDRESS + 0x04C7)
#define WCD938X_DIGITAL_EFUSE_REG_24 (WCD938X_BASE_ADDRESS + 0x04C8)
#define WCD938X_DIGITAL_EFUSE_REG_25 (WCD938X_BASE_ADDRESS + 0x04C9)
#define WCD938X_DIGITAL_EFUSE_REG_26 (WCD938X_BASE_ADDRESS + 0x04CA)
#define WCD938X_DIGITAL_EFUSE_REG_27 (WCD938X_BASE_ADDRESS + 0x04CB)
#define WCD938X_DIGITAL_EFUSE_REG_28 (WCD938X_BASE_ADDRESS + 0x04CC)
#define WCD938X_DIGITAL_EFUSE_REG_29 (WCD938X_BASE_ADDRESS + 0x04CD)
#define WCD938X_DIGITAL_EFUSE_REG_30 (WCD938X_BASE_ADDRESS + 0x04CE)
#define WCD938X_DIGITAL_EFUSE_REG_31 (WCD938X_BASE_ADDRESS + 0x04CF)
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_0 (WCD938X_BASE_ADDRESS + 0x04D0)
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_1 (WCD938X_BASE_ADDRESS + 0x04D1)
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_2 (WCD938X_BASE_ADDRESS + 0x04D2)
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_3 (WCD938X_BASE_ADDRESS + 0x04D3)
#define WCD938X_DIGITAL_TX_REQ_FB_CTL_4 (WCD938X_BASE_ADDRESS + 0x04D4)
#define WCD938X_DIGITAL_DEM_BYPASS_DATA0 (WCD938X_BASE_ADDRESS + 0x04D5)
#define WCD938X_DIGITAL_DEM_BYPASS_DATA1 (WCD938X_BASE_ADDRESS + 0x04D6)
#define WCD938X_DIGITAL_DEM_BYPASS_DATA2 (WCD938X_BASE_ADDRESS + 0x04D7)
#define WCD938X_DIGITAL_DEM_BYPASS_DATA3 (WCD938X_BASE_ADDRESS + 0x04D8)
#define WCD938X_REGISTERS_MAX_SIZE (WCD938X_DIGITAL_DEM_BYPASS_DATA3 + 1)
#define WCD938X_MAX_REGISTER (WCD938X_REGISTERS_MAX_SIZE - 1)
#endif /*_WCD938X_REGISTERS_H*/

View File

@@ -0,0 +1,515 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
#include <linux/device.h>
#include "wcd938x-registers.h"
extern const u8 wcd938x_reg_access[WCD938X_REGISTERS_MAX_SIZE];
static const struct reg_default wcd938x_defaults[] = {
{WCD938X_ANA_PAGE_REGISTER, 0x00},
{WCD938X_ANA_BIAS, 0x00},
{WCD938X_ANA_RX_SUPPLIES, 0x00},
{WCD938X_ANA_HPH, 0x0C},
{WCD938X_ANA_EAR, 0x00},
{WCD938X_ANA_EAR_COMPANDER_CTL, 0x02},
{WCD938X_ANA_TX_CH1, 0x20},
{WCD938X_ANA_TX_CH2, 0x00},
{WCD938X_ANA_TX_CH3, 0x20},
{WCD938X_ANA_TX_CH4, 0x00},
{WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC, 0x00},
{WCD938X_ANA_MICB3_DSP_EN_LOGIC, 0x00},
{WCD938X_ANA_MBHC_MECH, 0x39},
{WCD938X_ANA_MBHC_ELECT, 0x08},
{WCD938X_ANA_MBHC_ZDET, 0x00},
{WCD938X_ANA_MBHC_RESULT_1, 0x00},
{WCD938X_ANA_MBHC_RESULT_2, 0x00},
{WCD938X_ANA_MBHC_RESULT_3, 0x00},
{WCD938X_ANA_MBHC_BTN0, 0x00},
{WCD938X_ANA_MBHC_BTN1, 0x10},
{WCD938X_ANA_MBHC_BTN2, 0x20},
{WCD938X_ANA_MBHC_BTN3, 0x30},
{WCD938X_ANA_MBHC_BTN4, 0x40},
{WCD938X_ANA_MBHC_BTN5, 0x50},
{WCD938X_ANA_MBHC_BTN6, 0x60},
{WCD938X_ANA_MBHC_BTN7, 0x70},
{WCD938X_ANA_MICB1, 0x10},
{WCD938X_ANA_MICB2, 0x10},
{WCD938X_ANA_MICB2_RAMP, 0x00},
{WCD938X_ANA_MICB3, 0x10},
{WCD938X_ANA_MICB4, 0x10},
{WCD938X_BIAS_CTL, 0x2A},
{WCD938X_BIAS_VBG_FINE_ADJ, 0x55},
{WCD938X_LDOL_VDDCX_ADJUST, 0x01},
{WCD938X_LDOL_DISABLE_LDOL, 0x00},
{WCD938X_MBHC_CTL_CLK, 0x00},
{WCD938X_MBHC_CTL_ANA, 0x00},
{WCD938X_MBHC_CTL_SPARE_1, 0x00},
{WCD938X_MBHC_CTL_SPARE_2, 0x00},
{WCD938X_MBHC_CTL_BCS, 0x00},
{WCD938X_MBHC_MOISTURE_DET_FSM_STATUS, 0x00},
{WCD938X_MBHC_TEST_CTL, 0x00},
{WCD938X_LDOH_MODE, 0x2B},
{WCD938X_LDOH_BIAS, 0x68},
{WCD938X_LDOH_STB_LOADS, 0x00},
{WCD938X_LDOH_SLOWRAMP, 0x50},
{WCD938X_MICB1_TEST_CTL_1, 0x1A},
{WCD938X_MICB1_TEST_CTL_2, 0x00},
{WCD938X_MICB1_TEST_CTL_3, 0xA4},
{WCD938X_MICB2_TEST_CTL_1, 0x1A},
{WCD938X_MICB2_TEST_CTL_2, 0x00},
{WCD938X_MICB2_TEST_CTL_3, 0x24},
{WCD938X_MICB3_TEST_CTL_1, 0x1A},
{WCD938X_MICB3_TEST_CTL_2, 0x00},
{WCD938X_MICB3_TEST_CTL_3, 0xA4},
{WCD938X_MICB4_TEST_CTL_1, 0x1A},
{WCD938X_MICB4_TEST_CTL_2, 0x00},
{WCD938X_MICB4_TEST_CTL_3, 0xA4},
{WCD938X_TX_COM_ADC_VCM, 0x39},
{WCD938X_TX_COM_BIAS_ATEST, 0xE0},
{WCD938X_TX_COM_SPARE1, 0x00},
{WCD938X_TX_COM_SPARE2, 0x00},
{WCD938X_TX_COM_TXFE_DIV_CTL, 0x22},
{WCD938X_TX_COM_TXFE_DIV_START, 0x00},
{WCD938X_TX_COM_SPARE3, 0x00},
{WCD938X_TX_COM_SPARE4, 0x00},
{WCD938X_TX_1_2_TEST_EN, 0xCC},
{WCD938X_TX_1_2_ADC_IB, 0xE9},
{WCD938X_TX_1_2_ATEST_REFCTL, 0x0A},
{WCD938X_TX_1_2_TEST_CTL, 0x38},
{WCD938X_TX_1_2_TEST_BLK_EN1, 0xFF},
{WCD938X_TX_1_2_TXFE1_CLKDIV, 0x00},
{WCD938X_TX_1_2_SAR2_ERR, 0x00},
{WCD938X_TX_1_2_SAR1_ERR, 0x00},
{WCD938X_TX_3_4_TEST_EN, 0xCC},
{WCD938X_TX_3_4_ADC_IB, 0xE9},
{WCD938X_TX_3_4_ATEST_REFCTL, 0x0A},
{WCD938X_TX_3_4_TEST_CTL, 0x38},
{WCD938X_TX_3_4_TEST_BLK_EN3, 0xFF},
{WCD938X_TX_3_4_TXFE3_CLKDIV, 0x00},
{WCD938X_TX_3_4_SAR4_ERR, 0x00},
{WCD938X_TX_3_4_SAR3_ERR, 0x00},
{WCD938X_TX_3_4_TEST_BLK_EN2, 0xFB},
{WCD938X_TX_3_4_TXFE2_CLKDIV, 0x00},
{WCD938X_TX_3_4_SPARE1, 0x00},
{WCD938X_TX_3_4_TEST_BLK_EN4, 0xFB},
{WCD938X_TX_3_4_TXFE4_CLKDIV, 0x00},
{WCD938X_TX_3_4_SPARE2, 0x00},
{WCD938X_CLASSH_MODE_1, 0x40},
{WCD938X_CLASSH_MODE_2, 0x3A},
{WCD938X_CLASSH_MODE_3, 0x00},
{WCD938X_CLASSH_CTRL_VCL_1, 0x70},
{WCD938X_CLASSH_CTRL_VCL_2, 0x82},
{WCD938X_CLASSH_CTRL_CCL_1, 0x31},
{WCD938X_CLASSH_CTRL_CCL_2, 0x80},
{WCD938X_CLASSH_CTRL_CCL_3, 0x80},
{WCD938X_CLASSH_CTRL_CCL_4, 0x51},
{WCD938X_CLASSH_CTRL_CCL_5, 0x00},
{WCD938X_CLASSH_BUCK_TMUX_A_D, 0x00},
{WCD938X_CLASSH_BUCK_SW_DRV_CNTL, 0x77},
{WCD938X_CLASSH_SPARE, 0x00},
{WCD938X_FLYBACK_EN, 0x4E},
{WCD938X_FLYBACK_VNEG_CTRL_1, 0x0B},
{WCD938X_FLYBACK_VNEG_CTRL_2, 0x45},
{WCD938X_FLYBACK_VNEG_CTRL_3, 0x74},
{WCD938X_FLYBACK_VNEG_CTRL_4, 0x7F},
{WCD938X_FLYBACK_VNEG_CTRL_5, 0x83},
{WCD938X_FLYBACK_VNEG_CTRL_6, 0x98},
{WCD938X_FLYBACK_VNEG_CTRL_7, 0xA9},
{WCD938X_FLYBACK_VNEG_CTRL_8, 0x68},
{WCD938X_FLYBACK_VNEG_CTRL_9, 0x64},
{WCD938X_FLYBACK_VNEGDAC_CTRL_1, 0xED},
{WCD938X_FLYBACK_VNEGDAC_CTRL_2, 0xF0},
{WCD938X_FLYBACK_VNEGDAC_CTRL_3, 0xA6},
{WCD938X_FLYBACK_CTRL_1, 0x65},
{WCD938X_FLYBACK_TEST_CTL, 0x00},
{WCD938X_RX_AUX_SW_CTL, 0x00},
{WCD938X_RX_PA_AUX_IN_CONN, 0x01},
{WCD938X_RX_TIMER_DIV, 0x32},
{WCD938X_RX_OCP_CTL, 0x1F},
{WCD938X_RX_OCP_COUNT, 0x77},
{WCD938X_RX_BIAS_EAR_DAC, 0xA0},
{WCD938X_RX_BIAS_EAR_AMP, 0xAA},
{WCD938X_RX_BIAS_HPH_LDO, 0xA9},
{WCD938X_RX_BIAS_HPH_PA, 0xAA},
{WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A},
{WCD938X_RX_BIAS_HPH_RDAC_LDO, 0x88},
{WCD938X_RX_BIAS_HPH_CNP1, 0x82},
{WCD938X_RX_BIAS_HPH_LOWPOWER, 0x82},
{WCD938X_RX_BIAS_AUX_DAC, 0xA0},
{WCD938X_RX_BIAS_AUX_AMP, 0xAA},
{WCD938X_RX_BIAS_VNEGDAC_BLEEDER, 0x50},
{WCD938X_RX_BIAS_MISC, 0x00},
{WCD938X_RX_BIAS_BUCK_RST, 0x08},
{WCD938X_RX_BIAS_BUCK_VREF_ERRAMP, 0x44},
{WCD938X_RX_BIAS_FLYB_ERRAMP, 0x40},
{WCD938X_RX_BIAS_FLYB_BUFF, 0xAA},
{WCD938X_RX_BIAS_FLYB_MID_RST, 0x14},
{WCD938X_HPH_L_STATUS, 0x04},
{WCD938X_HPH_R_STATUS, 0x04},
{WCD938X_HPH_CNP_EN, 0x80},
{WCD938X_HPH_CNP_WG_CTL, 0x9A},
{WCD938X_HPH_CNP_WG_TIME, 0x14},
{WCD938X_HPH_OCP_CTL, 0x28},
{WCD938X_HPH_AUTO_CHOP, 0x16},
{WCD938X_HPH_CHOP_CTL, 0x83},
{WCD938X_HPH_PA_CTL1, 0x46},
{WCD938X_HPH_PA_CTL2, 0x50},
{WCD938X_HPH_L_EN, 0x80},
{WCD938X_HPH_L_TEST, 0xE0},
{WCD938X_HPH_L_ATEST, 0x50},
{WCD938X_HPH_R_EN, 0x80},
{WCD938X_HPH_R_TEST, 0xE0},
{WCD938X_HPH_R_ATEST, 0x54},
{WCD938X_HPH_RDAC_CLK_CTL1, 0x99},
{WCD938X_HPH_RDAC_CLK_CTL2, 0x9B},
{WCD938X_HPH_RDAC_LDO_CTL, 0x33},
{WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL, 0x00},
{WCD938X_HPH_REFBUFF_UHQA_CTL, 0x68},
{WCD938X_HPH_REFBUFF_LP_CTL, 0x0E},
{WCD938X_HPH_L_DAC_CTL, 0x20},
{WCD938X_HPH_R_DAC_CTL, 0x20},
{WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL, 0x55},
{WCD938X_HPH_SURGE_HPHLR_SURGE_EN, 0x19},
{WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1, 0xA0},
{WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS, 0x00},
{WCD938X_EAR_EAR_EN_REG, 0x22},
{WCD938X_EAR_EAR_PA_CON, 0x44},
{WCD938X_EAR_EAR_SP_CON, 0xDB},
{WCD938X_EAR_EAR_DAC_CON, 0x80},
{WCD938X_EAR_EAR_CNP_FSM_CON, 0xB2},
{WCD938X_EAR_TEST_CTL, 0x00},
{WCD938X_EAR_STATUS_REG_1, 0x00},
{WCD938X_EAR_STATUS_REG_2, 0x08},
{WCD938X_ANA_NEW_PAGE_REGISTER, 0x00},
{WCD938X_HPH_NEW_ANA_HPH2, 0x00},
{WCD938X_HPH_NEW_ANA_HPH3, 0x00},
{WCD938X_SLEEP_CTL, 0x16},
{WCD938X_SLEEP_WATCHDOG_CTL, 0x00},
{WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL, 0x00},
{WCD938X_MBHC_NEW_CTL_1, 0x02},
{WCD938X_MBHC_NEW_CTL_2, 0x05},
{WCD938X_MBHC_NEW_PLUG_DETECT_CTL, 0xE9},
{WCD938X_MBHC_NEW_ZDET_ANA_CTL, 0x0F},
{WCD938X_MBHC_NEW_ZDET_RAMP_CTL, 0x00},
{WCD938X_MBHC_NEW_FSM_STATUS, 0x00},
{WCD938X_MBHC_NEW_ADC_RESULT, 0x00},
{WCD938X_TX_NEW_AMIC_MUX_CFG, 0x00},
{WCD938X_AUX_AUXPA, 0x00},
{WCD938X_LDORXTX_MODE, 0x0C},
{WCD938X_LDORXTX_CONFIG, 0x10},
{WCD938X_DIE_CRACK_DIE_CRK_DET_EN, 0x00},
{WCD938X_DIE_CRACK_DIE_CRK_DET_OUT, 0x00},
{WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL, 0x40},
{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L, 0x81},
{WCD938X_HPH_NEW_INT_RDAC_VREF_CTL, 0x10},
{WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL, 0x00},
{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R, 0x81},
{WCD938X_HPH_NEW_INT_PA_MISC1, 0x22},
{WCD938X_HPH_NEW_INT_PA_MISC2, 0x00},
{WCD938X_HPH_NEW_INT_PA_RDAC_MISC, 0x00},
{WCD938X_HPH_NEW_INT_HPH_TIMER1, 0xFE},
{WCD938X_HPH_NEW_INT_HPH_TIMER2, 0x02},
{WCD938X_HPH_NEW_INT_HPH_TIMER3, 0x4E},
{WCD938X_HPH_NEW_INT_HPH_TIMER4, 0x54},
{WCD938X_HPH_NEW_INT_PA_RDAC_MISC2, 0x00},
{WCD938X_HPH_NEW_INT_PA_RDAC_MISC3, 0x00},
{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW, 0x90},
{WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW, 0x90},
{WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI, 0x62},
{WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP, 0x01},
{WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP, 0x11},
{WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL, 0x57},
{WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL, 0x01},
{WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT, 0x00},
{WCD938X_MBHC_NEW_INT_SPARE_2, 0x00},
{WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON, 0xA8},
{WCD938X_EAR_INT_NEW_CNP_VCM_CON1, 0x42},
{WCD938X_EAR_INT_NEW_CNP_VCM_CON2, 0x22},
{WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS, 0x00},
{WCD938X_AUX_INT_EN_REG, 0x00},
{WCD938X_AUX_INT_PA_CTRL, 0x06},
{WCD938X_AUX_INT_SP_CTRL, 0xD2},
{WCD938X_AUX_INT_DAC_CTRL, 0x80},
{WCD938X_AUX_INT_CLK_CTRL, 0x50},
{WCD938X_AUX_INT_TEST_CTRL, 0x00},
{WCD938X_AUX_INT_STATUS_REG, 0x00},
{WCD938X_AUX_INT_MISC, 0x00},
{WCD938X_LDORXTX_INT_BIAS, 0x6E},
{WCD938X_LDORXTX_INT_STB_LOADS_DTEST, 0x50},
{WCD938X_LDORXTX_INT_TEST0, 0x1C},
{WCD938X_LDORXTX_INT_STARTUP_TIMER, 0xFF},
{WCD938X_LDORXTX_INT_TEST1, 0x1F},
{WCD938X_LDORXTX_INT_STATUS, 0x00},
{WCD938X_SLEEP_INT_WATCHDOG_CTL_1, 0x0A},
{WCD938X_SLEEP_INT_WATCHDOG_CTL_2, 0x0A},
{WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1, 0x02},
{WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2, 0x60},
{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2, 0xFF},
{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1, 0x7F},
{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0, 0x3F},
{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M, 0x1F},
{WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M, 0x0F},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1, 0xD7},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0, 0xC8},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP, 0xC6},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1, 0xD5},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0, 0xCA},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP, 0x05},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0, 0xA5},
{WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP, 0x13},
{WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1, 0x88},
{WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP, 0x42},
{WCD938X_TX_COM_NEW_INT_TXADC_INT_L2, 0xFF},
{WCD938X_TX_COM_NEW_INT_TXADC_INT_L1, 0x64},
{WCD938X_TX_COM_NEW_INT_TXADC_INT_L0, 0x64},
{WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP, 0x77},
{WCD938X_DIGITAL_PAGE_REGISTER, 0x00},
{WCD938X_DIGITAL_CHIP_ID0, 0x00},
{WCD938X_DIGITAL_CHIP_ID1, 0x00},
{WCD938X_DIGITAL_CHIP_ID2, 0x0D},
{WCD938X_DIGITAL_CHIP_ID3, 0x01},
{WCD938X_DIGITAL_SWR_TX_CLK_RATE, 0x00},
{WCD938X_DIGITAL_CDC_RST_CTL, 0x03},
{WCD938X_DIGITAL_TOP_CLK_CFG, 0x00},
{WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x00},
{WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0xF0},
{WCD938X_DIGITAL_SWR_RST_EN, 0x00},
{WCD938X_DIGITAL_CDC_PATH_MODE, 0x55},
{WCD938X_DIGITAL_CDC_RX_RST, 0x00},
{WCD938X_DIGITAL_CDC_RX0_CTL, 0xFC},
{WCD938X_DIGITAL_CDC_RX1_CTL, 0xFC},
{WCD938X_DIGITAL_CDC_RX2_CTL, 0xFC},
{WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x00},
{WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x00},
{WCD938X_DIGITAL_CDC_COMP_CTL_0, 0x00},
{WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL, 0x1E},
{WCD938X_DIGITAL_CDC_HPH_DSM_A1_0, 0x00},
{WCD938X_DIGITAL_CDC_HPH_DSM_A1_1, 0x01},
{WCD938X_DIGITAL_CDC_HPH_DSM_A2_0, 0x63},
{WCD938X_DIGITAL_CDC_HPH_DSM_A2_1, 0x04},
{WCD938X_DIGITAL_CDC_HPH_DSM_A3_0, 0xAC},
{WCD938X_DIGITAL_CDC_HPH_DSM_A3_1, 0x04},
{WCD938X_DIGITAL_CDC_HPH_DSM_A4_0, 0x1A},
{WCD938X_DIGITAL_CDC_HPH_DSM_A4_1, 0x03},
{WCD938X_DIGITAL_CDC_HPH_DSM_A5_0, 0xBC},
{WCD938X_DIGITAL_CDC_HPH_DSM_A5_1, 0x02},
{WCD938X_DIGITAL_CDC_HPH_DSM_A6_0, 0xC7},
{WCD938X_DIGITAL_CDC_HPH_DSM_A7_0, 0xF8},
{WCD938X_DIGITAL_CDC_HPH_DSM_C_0, 0x47},
{WCD938X_DIGITAL_CDC_HPH_DSM_C_1, 0x43},
{WCD938X_DIGITAL_CDC_HPH_DSM_C_2, 0xB1},
{WCD938X_DIGITAL_CDC_HPH_DSM_C_3, 0x17},
{WCD938X_DIGITAL_CDC_HPH_DSM_R1, 0x4D},
{WCD938X_DIGITAL_CDC_HPH_DSM_R2, 0x29},
{WCD938X_DIGITAL_CDC_HPH_DSM_R3, 0x34},
{WCD938X_DIGITAL_CDC_HPH_DSM_R4, 0x59},
{WCD938X_DIGITAL_CDC_HPH_DSM_R5, 0x66},
{WCD938X_DIGITAL_CDC_HPH_DSM_R6, 0x87},
{WCD938X_DIGITAL_CDC_HPH_DSM_R7, 0x64},
{WCD938X_DIGITAL_CDC_AUX_DSM_A1_0, 0x00},
{WCD938X_DIGITAL_CDC_AUX_DSM_A1_1, 0x01},
{WCD938X_DIGITAL_CDC_AUX_DSM_A2_0, 0x96},
{WCD938X_DIGITAL_CDC_AUX_DSM_A2_1, 0x09},
{WCD938X_DIGITAL_CDC_AUX_DSM_A3_0, 0xAB},
{WCD938X_DIGITAL_CDC_AUX_DSM_A3_1, 0x05},
{WCD938X_DIGITAL_CDC_AUX_DSM_A4_0, 0x1C},
{WCD938X_DIGITAL_CDC_AUX_DSM_A4_1, 0x02},
{WCD938X_DIGITAL_CDC_AUX_DSM_A5_0, 0x17},
{WCD938X_DIGITAL_CDC_AUX_DSM_A5_1, 0x02},
{WCD938X_DIGITAL_CDC_AUX_DSM_A6_0, 0xAA},
{WCD938X_DIGITAL_CDC_AUX_DSM_A7_0, 0xE3},
{WCD938X_DIGITAL_CDC_AUX_DSM_C_0, 0x69},
{WCD938X_DIGITAL_CDC_AUX_DSM_C_1, 0x54},
{WCD938X_DIGITAL_CDC_AUX_DSM_C_2, 0x02},
{WCD938X_DIGITAL_CDC_AUX_DSM_C_3, 0x15},
{WCD938X_DIGITAL_CDC_AUX_DSM_R1, 0xA4},
{WCD938X_DIGITAL_CDC_AUX_DSM_R2, 0xB5},
{WCD938X_DIGITAL_CDC_AUX_DSM_R3, 0x86},
{WCD938X_DIGITAL_CDC_AUX_DSM_R4, 0x85},
{WCD938X_DIGITAL_CDC_AUX_DSM_R5, 0xAA},
{WCD938X_DIGITAL_CDC_AUX_DSM_R6, 0xE2},
{WCD938X_DIGITAL_CDC_AUX_DSM_R7, 0x62},
{WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0, 0x55},
{WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1, 0xA9},
{WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0, 0x3D},
{WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1, 0x2E},
{WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2, 0x01},
{WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0, 0x00},
{WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1, 0xFC},
{WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2, 0x01},
{WCD938X_DIGITAL_CDC_HPH_GAIN_CTL, 0x00},
{WCD938X_DIGITAL_CDC_AUX_GAIN_CTL, 0x00},
{WCD938X_DIGITAL_CDC_EAR_PATH_CTL, 0x00},
{WCD938X_DIGITAL_CDC_SWR_CLH, 0x00},
{WCD938X_DIGITAL_SWR_CLH_BYP, 0x00},
{WCD938X_DIGITAL_CDC_TX0_CTL, 0x68},
{WCD938X_DIGITAL_CDC_TX1_CTL, 0x68},
{WCD938X_DIGITAL_CDC_TX2_CTL, 0x68},
{WCD938X_DIGITAL_CDC_TX_RST, 0x00},
{WCD938X_DIGITAL_CDC_REQ_CTL, 0x01},
{WCD938X_DIGITAL_CDC_RST, 0x00},
{WCD938X_DIGITAL_CDC_AMIC_CTL, 0x0F},
{WCD938X_DIGITAL_CDC_DMIC_CTL, 0x04},
{WCD938X_DIGITAL_CDC_DMIC1_CTL, 0x01},
{WCD938X_DIGITAL_CDC_DMIC2_CTL, 0x01},
{WCD938X_DIGITAL_CDC_DMIC3_CTL, 0x01},
{WCD938X_DIGITAL_CDC_DMIC4_CTL, 0x01},
{WCD938X_DIGITAL_EFUSE_PRG_CTL, 0x00},
{WCD938X_DIGITAL_EFUSE_CTL, 0x2B},
{WCD938X_DIGITAL_CDC_DMIC_RATE_1_2, 0x11},
{WCD938X_DIGITAL_CDC_DMIC_RATE_3_4, 0x11},
{WCD938X_DIGITAL_PDM_WD_CTL0, 0x00},
{WCD938X_DIGITAL_PDM_WD_CTL1, 0x00},
{WCD938X_DIGITAL_PDM_WD_CTL2, 0x00},
{WCD938X_DIGITAL_INTR_MODE, 0x00},
{WCD938X_DIGITAL_INTR_MASK_0, 0xFF},
{WCD938X_DIGITAL_INTR_MASK_1, 0xFF},
{WCD938X_DIGITAL_INTR_MASK_2, 0x3F},
{WCD938X_DIGITAL_INTR_STATUS_0, 0x00},
{WCD938X_DIGITAL_INTR_STATUS_1, 0x00},
{WCD938X_DIGITAL_INTR_STATUS_2, 0x00},
{WCD938X_DIGITAL_INTR_CLEAR_0, 0x00},
{WCD938X_DIGITAL_INTR_CLEAR_1, 0x00},
{WCD938X_DIGITAL_INTR_CLEAR_2, 0x00},
{WCD938X_DIGITAL_INTR_LEVEL_0, 0x00},
{WCD938X_DIGITAL_INTR_LEVEL_1, 0x00},
{WCD938X_DIGITAL_INTR_LEVEL_2, 0x00},
{WCD938X_DIGITAL_INTR_SET_0, 0x00},
{WCD938X_DIGITAL_INTR_SET_1, 0x00},
{WCD938X_DIGITAL_INTR_SET_2, 0x00},
{WCD938X_DIGITAL_INTR_TEST_0, 0x00},
{WCD938X_DIGITAL_INTR_TEST_1, 0x00},
{WCD938X_DIGITAL_INTR_TEST_2, 0x00},
{WCD938X_DIGITAL_TX_MODE_DBG_EN, 0x00},
{WCD938X_DIGITAL_TX_MODE_DBG_0_1, 0x00},
{WCD938X_DIGITAL_TX_MODE_DBG_2_3, 0x00},
{WCD938X_DIGITAL_LB_IN_SEL_CTL, 0x00},
{WCD938X_DIGITAL_LOOP_BACK_MODE, 0x00},
{WCD938X_DIGITAL_SWR_DAC_TEST, 0x00},
{WCD938X_DIGITAL_SWR_HM_TEST_RX_0, 0x40},
{WCD938X_DIGITAL_SWR_HM_TEST_TX_0, 0x40},
{WCD938X_DIGITAL_SWR_HM_TEST_RX_1, 0x00},
{WCD938X_DIGITAL_SWR_HM_TEST_TX_1, 0x00},
{WCD938X_DIGITAL_SWR_HM_TEST_TX_2, 0x00},
{WCD938X_DIGITAL_SWR_HM_TEST_0, 0x00},
{WCD938X_DIGITAL_SWR_HM_TEST_1, 0x00},
{WCD938X_DIGITAL_PAD_CTL_SWR_0, 0x8F},
{WCD938X_DIGITAL_PAD_CTL_SWR_1, 0x06},
{WCD938X_DIGITAL_I2C_CTL, 0x00},
{WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE, 0x00},
{WCD938X_DIGITAL_EFUSE_TEST_CTL_0, 0x00},
{WCD938X_DIGITAL_EFUSE_TEST_CTL_1, 0x00},
{WCD938X_DIGITAL_EFUSE_T_DATA_0, 0x00},
{WCD938X_DIGITAL_EFUSE_T_DATA_1, 0x00},
{WCD938X_DIGITAL_PAD_CTL_PDM_RX0, 0xF1},
{WCD938X_DIGITAL_PAD_CTL_PDM_RX1, 0xF1},
{WCD938X_DIGITAL_PAD_CTL_PDM_TX0, 0xF1},
{WCD938X_DIGITAL_PAD_CTL_PDM_TX1, 0xF1},
{WCD938X_DIGITAL_PAD_CTL_PDM_TX2, 0xF1},
{WCD938X_DIGITAL_PAD_INP_DIS_0, 0x00},
{WCD938X_DIGITAL_PAD_INP_DIS_1, 0x00},
{WCD938X_DIGITAL_DRIVE_STRENGTH_0, 0x00},
{WCD938X_DIGITAL_DRIVE_STRENGTH_1, 0x00},
{WCD938X_DIGITAL_DRIVE_STRENGTH_2, 0x00},
{WCD938X_DIGITAL_RX_DATA_EDGE_CTL, 0x1F},
{WCD938X_DIGITAL_TX_DATA_EDGE_CTL, 0x80},
{WCD938X_DIGITAL_GPIO_MODE, 0x00},
{WCD938X_DIGITAL_PIN_CTL_OE, 0x00},
{WCD938X_DIGITAL_PIN_CTL_DATA_0, 0x00},
{WCD938X_DIGITAL_PIN_CTL_DATA_1, 0x00},
{WCD938X_DIGITAL_PIN_STATUS_0, 0x00},
{WCD938X_DIGITAL_PIN_STATUS_1, 0x00},
{WCD938X_DIGITAL_DIG_DEBUG_CTL, 0x00},
{WCD938X_DIGITAL_DIG_DEBUG_EN, 0x00},
{WCD938X_DIGITAL_ANA_CSR_DBG_ADD, 0x00},
{WCD938X_DIGITAL_ANA_CSR_DBG_CTL, 0x48},
{WCD938X_DIGITAL_SSP_DBG, 0x00},
{WCD938X_DIGITAL_MODE_STATUS_0, 0x00},
{WCD938X_DIGITAL_MODE_STATUS_1, 0x00},
{WCD938X_DIGITAL_SPARE_0, 0x00},
{WCD938X_DIGITAL_SPARE_1, 0x00},
{WCD938X_DIGITAL_SPARE_2, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_0, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_1, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_2, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_3, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_4, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_5, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_6, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_7, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_8, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_9, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_10, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_11, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_12, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_13, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_14, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_15, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_16, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_17, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_18, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_19, 0xFF},
{WCD938X_DIGITAL_EFUSE_REG_20, 0x0E},
{WCD938X_DIGITAL_EFUSE_REG_21, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_22, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_23, 0xF8},
{WCD938X_DIGITAL_EFUSE_REG_24, 0x16},
{WCD938X_DIGITAL_EFUSE_REG_25, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_26, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_27, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_28, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_29, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_30, 0x00},
{WCD938X_DIGITAL_EFUSE_REG_31, 0x00},
{WCD938X_DIGITAL_TX_REQ_FB_CTL_0, 0x88},
{WCD938X_DIGITAL_TX_REQ_FB_CTL_1, 0x88},
{WCD938X_DIGITAL_TX_REQ_FB_CTL_2, 0x88},
{WCD938X_DIGITAL_TX_REQ_FB_CTL_3, 0x88},
{WCD938X_DIGITAL_TX_REQ_FB_CTL_4, 0x88},
{WCD938X_DIGITAL_DEM_BYPASS_DATA0, 0x55},
{WCD938X_DIGITAL_DEM_BYPASS_DATA1, 0x55},
{WCD938X_DIGITAL_DEM_BYPASS_DATA2, 0x55},
{WCD938X_DIGITAL_DEM_BYPASS_DATA3, 0x01},
};
static bool wcd938x_readable_register(struct device *dev, unsigned int reg)
{
if(reg <= WCD938X_BASE_ADDRESS)
return 0;
return wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG;
}
static bool wcd938x_writeable_register(struct device *dev, unsigned int reg)
{
if(reg <= WCD938X_BASE_ADDRESS)
return 0;
return wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG;
}
static bool wcd938x_volatile_register(struct device *dev, unsigned int reg)
{
if(reg <= WCD938X_BASE_ADDRESS)
return 0;
if ((wcd938x_reg_access[WCD938X_REG(reg)] & RD_REG)
&& !(wcd938x_reg_access[WCD938X_REG(reg)] & WR_REG))
return true;
return false;
}
struct regmap_config wcd938x_regmap_config = {
.name = "wcd938x_csr",
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wcd938x_defaults,
.num_reg_defaults = ARRAY_SIZE(wcd938x_defaults),
.max_register = WCD938X_MAX_REGISTER,
.readable_reg = wcd938x_readable_register,
.writeable_reg = wcd938x_writeable_register,
.volatile_reg = wcd938x_volatile_register,
.can_multi_write = true,
};

View File

@@ -0,0 +1,417 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/component.h>
#include <soc/soundwire.h>
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#define SWR_SLV_MAX_REG_ADDR 0x2009
#define SWR_SLV_START_REG_ADDR 0x40
#define SWR_SLV_MAX_BUF_LEN 20
#define BYTES_PER_LINE 12
#define SWR_SLV_RD_BUF_LEN 8
#define SWR_SLV_WR_BUF_LEN 32
#define SWR_SLV_MAX_DEVICES 2
#endif /* CONFIG_DEBUG_FS */
struct wcd938x_slave_priv {
struct swr_device *swr_slave;
#ifdef CONFIG_DEBUG_FS
struct dentry *debugfs_wcd938x_dent;
struct dentry *debugfs_peek;
struct dentry *debugfs_poke;
struct dentry *debugfs_reg_dump;
unsigned int read_data;
#endif
};
#ifdef CONFIG_DEBUG_FS
static int codec_debug_open(struct inode *inode, struct file *file)
{
file->private_data = inode->i_private;
return 0;
}
static int get_parameters(char *buf, u32 *param1, int num_of_par)
{
char *token = NULL;
int base = 0, cnt = 0;
token = strsep(&buf, " ");
for (cnt = 0; cnt < num_of_par; cnt++) {
if (token) {
if ((token[1] == 'x') || (token[1] == 'X'))
base = 16;
else
base = 10;
if (kstrtou32(token, base, &param1[cnt]) != 0)
return -EINVAL;
token = strsep(&buf, " ");
} else {
return -EINVAL;
}
}
return 0;
}
static bool is_swr_slv_reg_readable(int reg)
{
int ret = true;
if (((reg > 0x46) && (reg < 0x4A)) ||
((reg > 0x4A) && (reg < 0x50)) ||
((reg > 0x55) && (reg < 0xD0)) ||
((reg > 0xD0) && (reg < 0xE0)) ||
((reg > 0xE0) && (reg < 0xF0)) ||
((reg > 0xF0) && (reg < 0x100)) ||
((reg > 0x105) && (reg < 0x120)) ||
((reg > 0x205) && (reg < 0x220)) ||
((reg > 0x305) && (reg < 0x320)) ||
((reg > 0x405) && (reg < 0x420)) ||
((reg > 0x128) && (reg < 0x130)) ||
((reg > 0x228) && (reg < 0x230)) ||
((reg > 0x328) && (reg < 0x330)) ||
((reg > 0x428) && (reg < 0x430)) ||
((reg > 0x138) && (reg < 0x205)) ||
((reg > 0x238) && (reg < 0x305)) ||
((reg > 0x338) && (reg < 0x405)) ||
((reg > 0x405) && (reg < 0xF00)) ||
((reg > 0xF05) && (reg < 0xF20)) ||
((reg > 0xF25) && (reg < 0xF30)) ||
((reg > 0xF35) && (reg < 0x2000)))
ret = false;
return ret;
}
static ssize_t wcd938x_swrslave_reg_show(struct swr_device *pdev,
char __user *ubuf,
size_t count, loff_t *ppos)
{
int i, reg_val, len;
ssize_t total = 0;
char tmp_buf[SWR_SLV_MAX_BUF_LEN];
if (!ubuf || !ppos)
return 0;
for (i = (((int) *ppos/BYTES_PER_LINE) + SWR_SLV_START_REG_ADDR);
i <= SWR_SLV_MAX_REG_ADDR; i++) {
if (!is_swr_slv_reg_readable(i))
continue;
swr_read(pdev, pdev->dev_num, i, &reg_val, 1);
len = snprintf(tmp_buf, sizeof(tmp_buf), "0x%.3x: 0x%.2x\n", i,
(reg_val & 0xFF));
if (((total + len) >= count - 1) || (len < 0))
break;
if (copy_to_user((ubuf + total), tmp_buf, len)) {
pr_err("%s: fail to copy reg dump\n", __func__);
total = -EFAULT;
goto copy_err;
}
total += len;
*ppos += len;
}
copy_err:
*ppos = SWR_SLV_MAX_REG_ADDR * BYTES_PER_LINE;
return total;
}
static ssize_t codec_debug_dump(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
struct swr_device *pdev;
if (!count || !file || !ppos || !ubuf)
return -EINVAL;
pdev = file->private_data;
if (!pdev)
return -EINVAL;
if (*ppos < 0)
return -EINVAL;
return wcd938x_swrslave_reg_show(pdev, ubuf, count, ppos);
}
static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
size_t count, loff_t *ppos)
{
char lbuf[SWR_SLV_RD_BUF_LEN];
struct swr_device *pdev = NULL;
struct wcd938x_slave_priv *wcd938x_slave = NULL;
if (!count || !file || !ppos || !ubuf)
return -EINVAL;
pdev = file->private_data;
if (!pdev)
return -EINVAL;
wcd938x_slave = swr_get_dev_data(pdev);
if (!wcd938x_slave)
return -EINVAL;
if (*ppos < 0)
return -EINVAL;
snprintf(lbuf, sizeof(lbuf), "0x%x\n",
(wcd938x_slave->read_data & 0xFF));
return simple_read_from_buffer(ubuf, count, ppos, lbuf,
strnlen(lbuf, 7));
}
static ssize_t codec_debug_peek_write(struct file *file,
const char __user *ubuf, size_t cnt, loff_t *ppos)
{
char lbuf[SWR_SLV_WR_BUF_LEN];
int rc = 0;
u32 param[5];
struct swr_device *pdev = NULL;
struct wcd938x_slave_priv *wcd938x_slave = NULL;
if (!cnt || !file || !ppos || !ubuf)
return -EINVAL;
pdev = file->private_data;
if (!pdev)
return -EINVAL;
wcd938x_slave = swr_get_dev_data(pdev);
if (!wcd938x_slave)
return -EINVAL;
if (*ppos < 0)
return -EINVAL;
if (cnt > sizeof(lbuf) - 1)
return -EINVAL;
rc = copy_from_user(lbuf, ubuf, cnt);
if (rc)
return -EFAULT;
lbuf[cnt] = '\0';
rc = get_parameters(lbuf, param, 1);
if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) && (rc == 0)))
return -EINVAL;
swr_read(pdev, pdev->dev_num, param[0], &wcd938x_slave->read_data, 1);
if (rc == 0)
rc = cnt;
else
pr_err("%s: rc = %d\n", __func__, rc);
return rc;
}
static ssize_t codec_debug_write(struct file *file,
const char __user *ubuf, size_t cnt, loff_t *ppos)
{
char lbuf[SWR_SLV_WR_BUF_LEN];
int rc = 0;
u32 param[5];
struct swr_device *pdev;
if (!file || !ppos || !ubuf)
return -EINVAL;
pdev = file->private_data;
if (!pdev)
return -EINVAL;
if (cnt > sizeof(lbuf) - 1)
return -EINVAL;
rc = copy_from_user(lbuf, ubuf, cnt);
if (rc)
return -EFAULT;
lbuf[cnt] = '\0';
rc = get_parameters(lbuf, param, 2);
if (!((param[0] <= SWR_SLV_MAX_REG_ADDR) &&
(param[1] <= 0xFF) && (rc == 0)))
return -EINVAL;
swr_write(pdev, pdev->dev_num, param[0], &param[1]);
if (rc == 0)
rc = cnt;
else
pr_err("%s: rc = %d\n", __func__, rc);
return rc;
}
static const struct file_operations codec_debug_write_ops = {
.open = codec_debug_open,
.write = codec_debug_write,
};
static const struct file_operations codec_debug_read_ops = {
.open = codec_debug_open,
.read = codec_debug_read,
.write = codec_debug_peek_write,
};
static const struct file_operations codec_debug_dump_ops = {
.open = codec_debug_open,
.read = codec_debug_dump,
};
#endif
static int wcd938x_slave_bind(struct device *dev,
struct device *master, void *data)
{
int ret = 0;
uint8_t devnum = 0;
struct swr_device *pdev = to_swr_device(dev);
if (!pdev) {
pr_err("%s: invalid swr device handle\n", __func__);
return -EINVAL;
}
ret = swr_get_logical_dev_num(pdev, pdev->addr, &devnum);
if (ret) {
dev_dbg(&pdev->dev,
"%s get devnum %d for dev addr %lx failed\n",
__func__, devnum, pdev->addr);
return ret;
}
pdev->dev_num = devnum;
return ret;
}
static void wcd938x_slave_unbind(struct device *dev,
struct device *master, void *data)
{
struct wcd938x_slave_priv *wcd938x_slave = NULL;
struct swr_device *pdev = to_swr_device(dev);
wcd938x_slave = swr_get_dev_data(pdev);
if (!wcd938x_slave) {
dev_err(&pdev->dev, "%s: wcd938x_slave is NULL\n", __func__);
return;
}
}
static const struct swr_device_id wcd938x_swr_id[] = {
{"wcd938x-slave", 0},
{}
};
static const struct of_device_id wcd938x_swr_dt_match[] = {
{
.compatible = "qcom,wcd938x-slave",
},
{}
};
static const struct component_ops wcd938x_slave_comp_ops = {
.bind = wcd938x_slave_bind,
.unbind = wcd938x_slave_unbind,
};
static int wcd938x_swr_probe(struct swr_device *pdev)
{
struct wcd938x_slave_priv *wcd938x_slave = NULL;
wcd938x_slave = devm_kzalloc(&pdev->dev,
sizeof(struct wcd938x_slave_priv), GFP_KERNEL);
if (!wcd938x_slave)
return -ENOMEM;
swr_set_dev_data(pdev, wcd938x_slave);
wcd938x_slave->swr_slave = pdev;
#ifdef CONFIG_DEBUG_FS
if (!wcd938x_slave->debugfs_wcd938x_dent) {
wcd938x_slave->debugfs_wcd938x_dent = debugfs_create_dir(
dev_name(&pdev->dev), 0);
if (!IS_ERR(wcd938x_slave->debugfs_wcd938x_dent)) {
wcd938x_slave->debugfs_peek =
debugfs_create_file("swrslave_peek",
S_IFREG | 0444,
wcd938x_slave->debugfs_wcd938x_dent,
(void *) pdev,
&codec_debug_read_ops);
wcd938x_slave->debugfs_poke =
debugfs_create_file("swrslave_poke",
S_IFREG | 0444,
wcd938x_slave->debugfs_wcd938x_dent,
(void *) pdev,
&codec_debug_write_ops);
wcd938x_slave->debugfs_reg_dump =
debugfs_create_file(
"swrslave_reg_dump",
S_IFREG | 0444,
wcd938x_slave->debugfs_wcd938x_dent,
(void *) pdev,
&codec_debug_dump_ops);
}
}
#endif
return component_add(&pdev->dev, &wcd938x_slave_comp_ops);
}
static int wcd938x_swr_remove(struct swr_device *pdev)
{
#ifdef CONFIG_DEBUG_FS
struct wcd938x_slave_priv *wcd938x_slave = swr_get_dev_data(pdev);
if (wcd938x_slave) {
debugfs_remove_recursive(wcd938x_slave->debugfs_wcd938x_dent);
wcd938x_slave->debugfs_wcd938x_dent = NULL;
}
#endif
component_del(&pdev->dev, &wcd938x_slave_comp_ops);
swr_set_dev_data(pdev, NULL);
swr_remove_device(pdev);
return 0;
}
static struct swr_driver wcd938x_slave_driver = {
.driver = {
.name = "wcd938x-slave",
.owner = THIS_MODULE,
.of_match_table = wcd938x_swr_dt_match,
},
.probe = wcd938x_swr_probe,
.remove = wcd938x_swr_remove,
.id_table = wcd938x_swr_id,
};
static int __init wcd938x_slave_init(void)
{
return swr_driver_register(&wcd938x_slave_driver);
}
static void __exit wcd938x_slave_exit(void)
{
swr_driver_unregister(&wcd938x_slave_driver);
}
module_init(wcd938x_slave_init);
module_exit(wcd938x_slave_exit);
MODULE_DESCRIPTION("WCD938X Swr Slave driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,474 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2018 , The Linux Foundation. All rights reserved.
*/
#include <linux/types.h>
#include "wcd938x-registers.h"
const u8 wcd938x_reg_access[WCD938X_REG(WCD938X_REGISTERS_MAX_SIZE)] = {
[WCD938X_REG(WCD938X_ANA_PAGE_REGISTER)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_BIAS)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_RX_SUPPLIES)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_HPH)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_EAR)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_EAR_COMPANDER_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_TX_CH1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_TX_CH2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_TX_CH3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_TX_CH4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB1_MICB2_DSP_EN_LOGIC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB3_DSP_EN_LOGIC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_MECH)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_ELECT)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_ZDET)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_RESULT_1)] = RD_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_RESULT_2)] = RD_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_RESULT_3)] = RD_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN5)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN6)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MBHC_BTN7)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB2_RAMP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_ANA_MICB4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_BIAS_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_BIAS_VBG_FINE_ADJ)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDOL_VDDCX_ADJUST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDOL_DISABLE_LDOL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_CTL_CLK)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_CTL_ANA)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_CTL_SPARE_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_CTL_SPARE_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_CTL_BCS)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_MOISTURE_DET_FSM_STATUS)] = RD_REG,
[WCD938X_REG(WCD938X_MBHC_TEST_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDOH_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDOH_BIAS)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDOH_STB_LOADS)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDOH_SLOWRAMP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB1_TEST_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB1_TEST_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB1_TEST_CTL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB2_TEST_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB2_TEST_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB2_TEST_CTL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB3_TEST_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB3_TEST_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB3_TEST_CTL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB4_TEST_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB4_TEST_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MICB4_TEST_CTL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_ADC_VCM)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_BIAS_ATEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_SPARE1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_SPARE2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_TXFE_DIV_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_TXFE_DIV_START)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_SPARE3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_SPARE4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_TEST_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_ADC_IB)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_ATEST_REFCTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_TEST_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_TEST_BLK_EN1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_TXFE1_CLKDIV)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_1_2_SAR2_ERR)] = RD_REG,
[WCD938X_REG(WCD938X_TX_1_2_SAR1_ERR)] = RD_REG,
[WCD938X_REG(WCD938X_TX_3_4_TEST_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_ADC_IB)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_ATEST_REFCTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_TEST_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_TEST_BLK_EN3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_TXFE3_CLKDIV)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_SAR4_ERR)] = RD_REG,
[WCD938X_REG(WCD938X_TX_3_4_SAR3_ERR)] = RD_REG,
[WCD938X_REG(WCD938X_TX_3_4_TEST_BLK_EN2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_TXFE2_CLKDIV)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_SPARE1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_TEST_BLK_EN4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_TXFE4_CLKDIV)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_3_4_SPARE2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_MODE_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_MODE_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_MODE_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_VCL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_VCL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_CTRL_CCL_5)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_BUCK_TMUX_A_D)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_BUCK_SW_DRV_CNTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_CLASSH_SPARE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_5)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_6)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_7)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_8)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEG_CTRL_9)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEGDAC_CTRL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEGDAC_CTRL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_VNEGDAC_CTRL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_CTRL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_FLYBACK_TEST_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_AUX_SW_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_PA_AUX_IN_CONN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_TIMER_DIV)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_OCP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_OCP_COUNT)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_EAR_DAC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_EAR_AMP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_HPH_LDO)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_HPH_PA)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_HPH_RDACBUFF_CNP2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_HPH_RDAC_LDO)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_HPH_CNP1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_HPH_LOWPOWER)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_AUX_DAC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_AUX_AMP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_VNEGDAC_BLEEDER)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_MISC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_BUCK_RST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_BUCK_VREF_ERRAMP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_FLYB_ERRAMP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_FLYB_BUFF)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_BIAS_FLYB_MID_RST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_L_STATUS)] = RD_REG,
[WCD938X_REG(WCD938X_HPH_R_STATUS)] = RD_REG,
[WCD938X_REG(WCD938X_HPH_CNP_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_CNP_WG_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_CNP_WG_TIME)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_OCP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_AUTO_CHOP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_CHOP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_PA_CTL1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_PA_CTL2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_L_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_L_TEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_L_ATEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_R_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_R_TEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_R_ATEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_RDAC_CLK_CTL1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_RDAC_CLK_CTL2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_RDAC_LDO_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_RDAC_CHOP_CLK_LP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_REFBUFF_UHQA_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_REFBUFF_LP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_L_DAC_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_R_DAC_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_COMP_SEL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_MISC1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_SURGE_HPHLR_SURGE_STATUS)] = RD_REG,
[WCD938X_REG(WCD938X_EAR_EAR_EN_REG)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_EAR_PA_CON)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_EAR_SP_CON)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_EAR_DAC_CON)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_EAR_CNP_FSM_CON)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_TEST_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_STATUS_REG_1)] = RD_REG,
[WCD938X_REG(WCD938X_EAR_STATUS_REG_2)] = RD_REG,
[WCD938X_REG(WCD938X_ANA_NEW_PAGE_REGISTER)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_ANA_HPH2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_ANA_HPH3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_SLEEP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_SLEEP_WATCHDOG_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_ELECT_REM_CLAMP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_PLUG_DETECT_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_ZDET_ANA_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_ZDET_RAMP_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_FSM_STATUS)] = RD_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_ADC_RESULT)] = RD_REG,
[WCD938X_REG(WCD938X_TX_NEW_AMIC_MUX_CFG)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_AUXPA)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_CONFIG)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIE_CRACK_DIE_CRK_DET_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIE_CRACK_DIE_CRK_DET_OUT)] = RD_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_GAIN_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_VREF_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_OVERRIDE_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_PA_MISC1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_PA_MISC2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_PA_RDAC_MISC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_HPH_TIMER4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_PA_RDAC_MISC2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_PA_RDAC_MISC3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_L_NEW)] = RD_WR_REG,
[WCD938X_REG(WCD938X_HPH_NEW_INT_RDAC_HD2_CTL_R_NEW)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_LOHIFI)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_NEW_INT_HPH_RDAC_BIAS_ULP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_RX_NEW_INT_HPH_RDAC_LDO_LP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_INT_MOISTURE_DET_DC_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_INT_MOISTURE_DET_POLLING_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_INT_MECH_DET_CURRENT)] = RD_WR_REG,
[WCD938X_REG(WCD938X_MBHC_NEW_INT_SPARE_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_INT_NEW_EAR_CHOPPER_CON)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_INT_NEW_CNP_VCM_CON1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_INT_NEW_CNP_VCM_CON2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_EAR_INT_NEW_EAR_DYNAMIC_BIAS)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_EN_REG)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_PA_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_SP_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_DAC_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_CLK_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_TEST_CTRL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_AUX_INT_STATUS_REG)] = RD_REG,
[WCD938X_REG(WCD938X_AUX_INT_MISC)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_INT_BIAS)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_INT_STB_LOADS_DTEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_INT_TEST0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_INT_STARTUP_TIMER)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_INT_TEST1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_LDORXTX_INT_STATUS)] = RD_REG,
[WCD938X_REG(WCD938X_SLEEP_INT_WATCHDOG_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_SLEEP_INT_WATCHDOG_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIE_CRACK_INT_DIE_CRK_DET_INT2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_L0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP1P2M)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_DIVSTOP_ULP0P6M)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L2L1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_L0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG1_ULP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L2L1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_L0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2MAIN_ULP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_L2L1L0)]=RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXFE_ICTRL_STG2CASC_ULP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L2L1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_SCBIAS_L0ULP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_L2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_L1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_L0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_TX_COM_NEW_INT_TXADC_INT_ULP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAGE_REGISTER)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CHIP_ID0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_CHIP_ID1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_CHIP_ID2)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_CHIP_ID3)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_TX_CLK_RATE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_RST_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TOP_CLK_CFG)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_ANA_CLK_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DIG_CLK_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_RST_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_PATH_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_RX_RST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_RX0_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_RX1_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_RX2_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_COMP_CTL_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_ANA_TX_CLK_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A1_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A1_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A2_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A2_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A3_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A3_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A4_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A4_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A5_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A5_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A6_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_A7_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_C_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R5)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R6)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_DSM_R7)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A1_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A1_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A2_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A2_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A3_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A3_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A4_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A4_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A5_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A5_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A6_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_A7_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_C_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R5)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R6)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_DSM_R7)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_RX_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_RX_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_DSD_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_DSD_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_HPH_GAIN_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AUX_GAIN_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_EAR_PATH_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_SWR_CLH)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_CLH_BYP)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX0_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX1_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX2_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX_RST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_REQ_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_RST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_AMIC_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC1_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC2_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC3_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC4_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_PRG_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC_RATE_1_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_DMIC_RATE_3_4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PDM_WD_CTL0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PDM_WD_CTL1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PDM_WD_CTL2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_MASK_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_MASK_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_MASK_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_STATUS_0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_STATUS_1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_STATUS_2)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_CLEAR_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_CLEAR_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_CLEAR_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_LEVEL_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_LEVEL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_LEVEL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_SET_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_SET_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_SET_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_TEST_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_TEST_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_INTR_TEST_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_MODE_DBG_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_MODE_DBG_0_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_MODE_DBG_2_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_LB_IN_SEL_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_LOOP_BACK_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_DAC_TEST)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_RX_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_TX_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_RX_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_TX_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_TX_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_SWR_HM_TEST_1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_SWR_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_SWR_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_I2C_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_CDC_TX_TANGGU_SW_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_TEST_CTL_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_TEST_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_T_DATA_0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_T_DATA_1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_RX0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_RX1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_TX0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_TX1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_CTL_PDM_TX2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_INP_DIS_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PAD_INP_DIS_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DRIVE_STRENGTH_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DRIVE_STRENGTH_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DRIVE_STRENGTH_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_RX_DATA_EDGE_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_DATA_EDGE_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_GPIO_MODE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PIN_CTL_OE)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PIN_CTL_DATA_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PIN_CTL_DATA_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_PIN_STATUS_0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_PIN_STATUS_1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_DIG_DEBUG_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DIG_DEBUG_EN)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_ANA_CSR_DBG_ADD)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_ANA_CSR_DBG_CTL)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SSP_DBG)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_MODE_STATUS_0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_MODE_STATUS_1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_SPARE_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SPARE_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_SPARE_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_0)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_1)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_2)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_3)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_4)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_5)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_6)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_7)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_8)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_9)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_10)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_11)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_12)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_13)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_14)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_15)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_16)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_17)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_18)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_19)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_20)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_21)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_22)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_23)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_24)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_25)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_26)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_27)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_28)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_29)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_30)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_EFUSE_REG_31)] = RD_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_3)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_TX_REQ_FB_CTL_4)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA0)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA1)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA2)] = RD_WR_REG,
[WCD938X_REG(WCD938X_DIGITAL_DEM_BYPASS_DATA3)] = RD_WR_REG,
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _WCD938X_H
#define _WCD938X_H
enum {
WCD9380 = 0,
WCD9385 = 5,
};
#ifdef CONFIG_SND_SOC_WCD938X
extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root,
struct snd_soc_codec *codec);
extern int wcd938x_get_codec_variant(struct snd_soc_codec *codec);
#else
extern int wcd938x_info_create_codec_entry(struct snd_info_entry *codec_root,
struct snd_soc_codec *codec)
{
return 0;
}
extern int wcd938x_get_codec_variant(struct snd_soc_codec *codec)
{
return 0;
}
#endif /* CONFIG_SND_SOC_WCD938X */
#endif /* _WCD938X_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <asoc/msm-cdc-pinctrl.h>
#include <asoc/wcd9xxx-irq.h>
#include <asoc/core.h>
#define NUM_DRIVERS_REG_RET 3
static int __init wcd9xxx_core_init(void)
{
int ret[NUM_DRIVERS_REG_RET] = {0};
int i = 0;
ret[0] = msm_cdc_pinctrl_drv_init();
if (ret[0])
pr_err("%s: Failed init pinctrl drv: %d\n", __func__, ret[0]);
ret[1] = wcd9xxx_irq_drv_init();
if (ret[1])
pr_err("%s: Failed init irq drv: %d\n", __func__, ret[1]);
ret[2] = wcd9xxx_init();
if (ret[2])
pr_err("%s: Failed wcd core drv: %d\n", __func__, ret[2]);
for (i = 0; i < NUM_DRIVERS_REG_RET; i++) {
if (ret[i])
return ret[i];
}
return 0;
}
module_init(wcd9xxx_core_init);
static void __exit wcd9xxx_core_exit(void)
{
wcd9xxx_exit();
wcd9xxx_irq_drv_exit();
msm_cdc_pinctrl_drv_exit();
}
module_exit(wcd9xxx_core_exit);
MODULE_DESCRIPTION("WCD9XXX CODEC core init driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,894 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/ratelimit.h>
#include <soc/qcom/pm.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
#include <asoc/core.h>
#include <asoc/wcd9xxx-irq.h>
#define BYTE_BIT_MASK(nr) (1UL << ((nr) % BITS_PER_BYTE))
#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
#define WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS 100
#ifndef NO_IRQ
#define NO_IRQ (-1)
#endif
#ifdef CONFIG_OF
struct wcd9xxx_irq_drv_data {
struct irq_domain *domain;
int irq;
};
#endif
static int virq_to_phyirq(
struct wcd9xxx_core_resource *wcd9xxx_res, int virq);
static int phyirq_to_virq(
struct wcd9xxx_core_resource *wcd9xxx_res, int irq);
static unsigned int wcd9xxx_irq_get_upstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res);
static void wcd9xxx_irq_put_downstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res);
static void wcd9xxx_irq_put_upstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res);
static int wcd9xxx_map_irq(
struct wcd9xxx_core_resource *wcd9xxx_res, int irq);
static void wcd9xxx_irq_lock(struct irq_data *data)
{
struct wcd9xxx_core_resource *wcd9xxx_res =
irq_data_get_irq_chip_data(data);
mutex_lock(&wcd9xxx_res->irq_lock);
}
static void wcd9xxx_irq_sync_unlock(struct irq_data *data)
{
struct wcd9xxx_core_resource *wcd9xxx_res =
irq_data_get_irq_chip_data(data);
int i;
if ((ARRAY_SIZE(wcd9xxx_res->irq_masks_cur) >
WCD9XXX_MAX_IRQ_REGS) ||
(ARRAY_SIZE(wcd9xxx_res->irq_masks_cache) >
WCD9XXX_MAX_IRQ_REGS)) {
pr_err("%s: Array Size out of bound\n", __func__);
return;
}
if (!wcd9xxx_res->wcd_core_regmap) {
pr_err("%s: Codec core regmap not defined\n",
__func__);
return;
}
for (i = 0; i < ARRAY_SIZE(wcd9xxx_res->irq_masks_cur); i++) {
/* If there's been a change in the mask write it back
* to the hardware.
*/
if (wcd9xxx_res->irq_masks_cur[i] !=
wcd9xxx_res->irq_masks_cache[i]) {
wcd9xxx_res->irq_masks_cache[i] =
wcd9xxx_res->irq_masks_cur[i];
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_MASK_BASE] + i,
wcd9xxx_res->irq_masks_cur[i]);
}
}
mutex_unlock(&wcd9xxx_res->irq_lock);
}
static void wcd9xxx_irq_enable(struct irq_data *data)
{
struct wcd9xxx_core_resource *wcd9xxx_res =
irq_data_get_irq_chip_data(data);
int wcd9xxx_irq = virq_to_phyirq(wcd9xxx_res, data->irq);
int byte = BIT_BYTE(wcd9xxx_irq);
int size = ARRAY_SIZE(wcd9xxx_res->irq_masks_cur);
if ((byte < size) && (byte >= 0)) {
wcd9xxx_res->irq_masks_cur[byte] &=
~(BYTE_BIT_MASK(wcd9xxx_irq));
} else {
pr_err("%s: Array size is %d but index is %d: Out of range\n",
__func__, size, byte);
}
}
static void wcd9xxx_irq_disable(struct irq_data *data)
{
struct wcd9xxx_core_resource *wcd9xxx_res =
irq_data_get_irq_chip_data(data);
int wcd9xxx_irq = virq_to_phyirq(wcd9xxx_res, data->irq);
int byte = BIT_BYTE(wcd9xxx_irq);
int size = ARRAY_SIZE(wcd9xxx_res->irq_masks_cur);
if ((byte < size) && (byte >= 0)) {
wcd9xxx_res->irq_masks_cur[byte]
|= BYTE_BIT_MASK(wcd9xxx_irq);
} else {
pr_err("%s: Array size is %d but index is %d: Out of range\n",
__func__, size, byte);
}
}
static void wcd9xxx_irq_ack(struct irq_data *data)
{
int wcd9xxx_irq = 0;
struct wcd9xxx_core_resource *wcd9xxx_res =
irq_data_get_irq_chip_data(data);
if (wcd9xxx_res == NULL) {
pr_err("%s: wcd9xxx_res is NULL\n", __func__);
return;
}
wcd9xxx_irq = virq_to_phyirq(wcd9xxx_res, data->irq);
pr_debug("%s: IRQ_ACK called for WCD9XXX IRQ: %d\n",
__func__, wcd9xxx_irq);
}
static void wcd9xxx_irq_mask(struct irq_data *d)
{
/* do nothing but required as linux calls irq_mask without NULL check */
}
static struct irq_chip wcd9xxx_irq_chip = {
.name = "wcd9xxx",
.irq_bus_lock = wcd9xxx_irq_lock,
.irq_bus_sync_unlock = wcd9xxx_irq_sync_unlock,
.irq_disable = wcd9xxx_irq_disable,
.irq_enable = wcd9xxx_irq_enable,
.irq_mask = wcd9xxx_irq_mask,
.irq_ack = wcd9xxx_irq_ack,
};
bool wcd9xxx_lock_sleep(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
enum wcd9xxx_pm_state os;
/*
* wcd9xxx_{lock/unlock}_sleep will be called by wcd9xxx_irq_thread
* and its subroutines only motly.
* but btn0_lpress_fn is not wcd9xxx_irq_thread's subroutine and
* It can race with wcd9xxx_irq_thread.
* So need to embrace wlock_holders with mutex.
*
* If system didn't resume, we can simply return false so codec driver's
* IRQ handler can return without handling IRQ.
* As interrupt line is still active, codec will have another IRQ to
* retry shortly.
*/
mutex_lock(&wcd9xxx_res->pm_lock);
if (wcd9xxx_res->wlock_holders++ == 0) {
pr_debug("%s: holding wake lock\n", __func__);
pm_qos_update_request(&wcd9xxx_res->pm_qos_req,
msm_cpuidle_get_deep_idle_latency());
pm_stay_awake(wcd9xxx_res->dev);
}
mutex_unlock(&wcd9xxx_res->pm_lock);
if (!wait_event_timeout(wcd9xxx_res->pm_wq,
((os = wcd9xxx_pm_cmpxchg(wcd9xxx_res,
WCD9XXX_PM_SLEEPABLE,
WCD9XXX_PM_AWAKE)) ==
WCD9XXX_PM_SLEEPABLE ||
(os == WCD9XXX_PM_AWAKE)),
msecs_to_jiffies(
WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS))) {
pr_warn("%s: system didn't resume within %dms, s %d, w %d\n",
__func__,
WCD9XXX_SYSTEM_RESUME_TIMEOUT_MS, wcd9xxx_res->pm_state,
wcd9xxx_res->wlock_holders);
wcd9xxx_unlock_sleep(wcd9xxx_res);
return false;
}
wake_up_all(&wcd9xxx_res->pm_wq);
return true;
}
EXPORT_SYMBOL(wcd9xxx_lock_sleep);
void wcd9xxx_unlock_sleep(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
mutex_lock(&wcd9xxx_res->pm_lock);
if (--wcd9xxx_res->wlock_holders == 0) {
pr_debug("%s: releasing wake lock pm_state %d -> %d\n",
__func__, wcd9xxx_res->pm_state, WCD9XXX_PM_SLEEPABLE);
/*
* if wcd9xxx_lock_sleep failed, pm_state would be still
* WCD9XXX_PM_ASLEEP, don't overwrite
*/
if (likely(wcd9xxx_res->pm_state == WCD9XXX_PM_AWAKE))
wcd9xxx_res->pm_state = WCD9XXX_PM_SLEEPABLE;
pm_qos_update_request(&wcd9xxx_res->pm_qos_req,
PM_QOS_DEFAULT_VALUE);
pm_relax(wcd9xxx_res->dev);
}
mutex_unlock(&wcd9xxx_res->pm_lock);
wake_up_all(&wcd9xxx_res->pm_wq);
}
EXPORT_SYMBOL(wcd9xxx_unlock_sleep);
void wcd9xxx_nested_irq_lock(struct wcd9xxx_core_resource *wcd9xxx_res)
{
mutex_lock(&wcd9xxx_res->nested_irq_lock);
}
void wcd9xxx_nested_irq_unlock(struct wcd9xxx_core_resource *wcd9xxx_res)
{
mutex_unlock(&wcd9xxx_res->nested_irq_lock);
}
static void wcd9xxx_irq_dispatch(struct wcd9xxx_core_resource *wcd9xxx_res,
struct intr_data *irqdata)
{
int irqbit = irqdata->intr_num;
if (!wcd9xxx_res->wcd_core_regmap) {
pr_err("%s: codec core regmap not defined\n",
__func__);
return;
}
if (irqdata->clear_first) {
wcd9xxx_nested_irq_lock(wcd9xxx_res);
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE] +
BIT_BYTE(irqbit),
BYTE_BIT_MASK(irqbit));
if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT],
0x02);
handle_nested_irq(phyirq_to_virq(wcd9xxx_res, irqbit));
wcd9xxx_nested_irq_unlock(wcd9xxx_res);
} else {
wcd9xxx_nested_irq_lock(wcd9xxx_res);
handle_nested_irq(phyirq_to_virq(wcd9xxx_res, irqbit));
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE] +
BIT_BYTE(irqbit),
BYTE_BIT_MASK(irqbit));
if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT],
0x02);
wcd9xxx_nested_irq_unlock(wcd9xxx_res);
}
}
static irqreturn_t wcd9xxx_irq_thread(int irq, void *data)
{
int ret;
int i;
struct intr_data irqdata;
char linebuf[128];
static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 1);
struct wcd9xxx_core_resource *wcd9xxx_res = data;
int num_irq_regs = wcd9xxx_res->num_irq_regs;
struct wcd9xxx *wcd9xxx;
u8 status[4], status1[4] = {0}, unmask_status[4] = {0};
if (unlikely(wcd9xxx_lock_sleep(wcd9xxx_res) == false)) {
dev_err(wcd9xxx_res->dev, "Failed to hold suspend\n");
return IRQ_NONE;
}
if (!wcd9xxx_res->wcd_core_regmap) {
dev_err(wcd9xxx_res->dev,
"%s: Codec core regmap not supplied\n",
__func__);
goto err_disable_irq;
}
wcd9xxx = (struct wcd9xxx *)wcd9xxx_res->parent;
if (!wcd9xxx) {
dev_err(wcd9xxx_res->dev,
"%s: Codec core not supplied\n", __func__);
goto err_disable_irq;
}
if (!wcd9xxx->dev_up) {
dev_info_ratelimited(wcd9xxx_res->dev, "wcd9xxx dev not up\n");
/*
* sleep to not block the core when device is
* not up (slimbus will not be available) to
* process interrupts.
*/
msleep(10);
}
memset(status, 0, sizeof(status));
ret = regmap_bulk_read(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_STATUS_BASE],
status, num_irq_regs);
if (ret < 0) {
dev_err(wcd9xxx_res->dev,
"Failed to read interrupt status: %d\n", ret);
goto err_disable_irq;
}
/*
* If status is 0 return without clearing.
* status contains: HW status - masked interrupts
* status1 contains: unhandled interrupts - masked interrupts
* unmasked_status contains: unhandled interrupts
*/
if (unlikely(!memcmp(status, status1, sizeof(status)))) {
pr_debug("%s: status is 0\n", __func__);
wcd9xxx_unlock_sleep(wcd9xxx_res);
return IRQ_HANDLED;
}
/*
* Copy status to unmask_status before masking, otherwise SW may miss
* to clear masked interrupt in corner case.
*/
memcpy(unmask_status, status, sizeof(unmask_status));
/* Apply masking */
for (i = 0; i < num_irq_regs; i++)
status[i] &= ~wcd9xxx_res->irq_masks_cur[i];
memcpy(status1, status, sizeof(status1));
/* Find out which interrupt was triggered and call that interrupt's
* handler function
*
* Since codec has only one hardware irq line which is shared by
* codec's different internal interrupts, so it's possible master irq
* handler dispatches multiple nested irq handlers after breaking
* order. Dispatch interrupts in the order that is maintained by
* the interrupt table.
*/
for (i = 0; i < wcd9xxx_res->intr_table_size; i++) {
irqdata = wcd9xxx_res->intr_table[i];
if (status[BIT_BYTE(irqdata.intr_num)] &
BYTE_BIT_MASK(irqdata.intr_num)) {
wcd9xxx_irq_dispatch(wcd9xxx_res, &irqdata);
status1[BIT_BYTE(irqdata.intr_num)] &=
~BYTE_BIT_MASK(irqdata.intr_num);
unmask_status[BIT_BYTE(irqdata.intr_num)] &=
~BYTE_BIT_MASK(irqdata.intr_num);
}
}
/*
* As a failsafe if unhandled irq is found, clear it to prevent
* interrupt storm.
* Note that we can say there was an unhandled irq only when no irq
* handled by nested irq handler since Taiko supports qdsp as irqs'
* destination for few irqs. Therefore driver shouldn't clear pending
* irqs when few handled while few others not.
*/
if (unlikely(!memcmp(status, status1, sizeof(status)))) {
if (__ratelimit(&ratelimit)) {
pr_warn("%s: Unhandled irq found\n", __func__);
hex_dump_to_buffer(status, sizeof(status), 16, 1,
linebuf, sizeof(linebuf), false);
pr_warn("%s: status0 : %s\n", __func__, linebuf);
hex_dump_to_buffer(status1, sizeof(status1), 16, 1,
linebuf, sizeof(linebuf), false);
pr_warn("%s: status1 : %s\n", __func__, linebuf);
}
/*
* unmask_status contains unhandled interrupts, hence clear all
* unhandled interrupts.
*/
ret = regmap_bulk_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLEAR_BASE],
unmask_status, num_irq_regs);
if (wcd9xxx_get_intf_type() == WCD9XXX_INTERFACE_TYPE_I2C)
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_CLR_COMMIT],
0x02);
}
wcd9xxx_unlock_sleep(wcd9xxx_res);
return IRQ_HANDLED;
err_disable_irq:
dev_err(wcd9xxx_res->dev,
"Disable irq %d\n", wcd9xxx_res->irq);
disable_irq_wake(wcd9xxx_res->irq);
disable_irq_nosync(wcd9xxx_res->irq);
wcd9xxx_unlock_sleep(wcd9xxx_res);
return IRQ_NONE;
}
/**
* wcd9xxx_free_irq
*
* @wcd9xxx_res: pointer to core resource
* irq: irq number
* @data: data pointer
*
*/
void wcd9xxx_free_irq(struct wcd9xxx_core_resource *wcd9xxx_res,
int irq, void *data)
{
free_irq(phyirq_to_virq(wcd9xxx_res, irq), data);
}
EXPORT_SYMBOL(wcd9xxx_free_irq);
/**
* wcd9xxx_enable_irq
*
* @wcd9xxx_res: pointer to core resource
* irq: irq number
*
*/
void wcd9xxx_enable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq)
{
if (wcd9xxx_res->irq)
enable_irq(phyirq_to_virq(wcd9xxx_res, irq));
}
EXPORT_SYMBOL(wcd9xxx_enable_irq);
/**
* wcd9xxx_disable_irq
*
* @wcd9xxx_res: pointer to core resource
* irq: irq number
*
*/
void wcd9xxx_disable_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq)
{
if (wcd9xxx_res->irq)
disable_irq_nosync(phyirq_to_virq(wcd9xxx_res, irq));
}
EXPORT_SYMBOL(wcd9xxx_disable_irq);
/**
* wcd9xxx_disable_irq_sync
*
* @wcd9xxx_res: pointer to core resource
* irq: irq number
*
*/
void wcd9xxx_disable_irq_sync(
struct wcd9xxx_core_resource *wcd9xxx_res, int irq)
{
if (wcd9xxx_res->irq)
disable_irq(phyirq_to_virq(wcd9xxx_res, irq));
}
EXPORT_SYMBOL(wcd9xxx_disable_irq_sync);
static int wcd9xxx_irq_setup_downstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
int irq, virq, ret;
pr_debug("%s: enter\n", __func__);
for (irq = 0; irq < wcd9xxx_res->num_irqs; irq++) {
/* Map OF irq */
virq = wcd9xxx_map_irq(wcd9xxx_res, irq);
pr_debug("%s: irq %d -> %d\n", __func__, irq, virq);
if (virq == NO_IRQ) {
pr_err("%s, No interrupt specifier for irq %d\n",
__func__, irq);
return NO_IRQ;
}
ret = irq_set_chip_data(virq, wcd9xxx_res);
if (ret) {
pr_err("%s: Failed to configure irq %d (%d)\n",
__func__, irq, ret);
return ret;
}
if (wcd9xxx_res->irq_level_high[irq])
irq_set_chip_and_handler(virq, &wcd9xxx_irq_chip,
handle_level_irq);
else
irq_set_chip_and_handler(virq, &wcd9xxx_irq_chip,
handle_edge_irq);
irq_set_nested_thread(virq, 1);
}
pr_debug("%s: leave\n", __func__);
return 0;
}
/**
* wcd9xxx_irq_init
*
* @wcd9xxx_res: pointer to core resource
*
* Returns 0 on success, appropriate error code otherwise
*/
int wcd9xxx_irq_init(struct wcd9xxx_core_resource *wcd9xxx_res)
{
int i, ret;
u8 *irq_level = NULL;
struct irq_domain *domain;
struct device_node *pnode;
mutex_init(&wcd9xxx_res->irq_lock);
mutex_init(&wcd9xxx_res->nested_irq_lock);
pnode = of_irq_find_parent(wcd9xxx_res->dev->of_node);
if (unlikely(!pnode))
return -EINVAL;
domain = irq_find_host(pnode);
if (unlikely(!domain))
return -EINVAL;
wcd9xxx_res->domain = domain;
wcd9xxx_res->irq = wcd9xxx_irq_get_upstream_irq(wcd9xxx_res);
if (!wcd9xxx_res->irq) {
pr_warn("%s: irq driver is not yet initialized\n", __func__);
mutex_destroy(&wcd9xxx_res->irq_lock);
mutex_destroy(&wcd9xxx_res->nested_irq_lock);
return -EPROBE_DEFER;
}
pr_debug("%s: probed irq %d\n", __func__, wcd9xxx_res->irq);
/* Setup downstream IRQs */
ret = wcd9xxx_irq_setup_downstream_irq(wcd9xxx_res);
if (ret) {
pr_err("%s: Failed to setup downstream IRQ\n", __func__);
goto fail_irq_level;
return ret;
}
/* All other wcd9xxx interrupts are edge triggered */
wcd9xxx_res->irq_level_high[0] = true;
/* mask all the interrupts */
irq_level = kzalloc(wcd9xxx_res->num_irq_regs, GFP_KERNEL);
if (!irq_level) {
ret = -ENOMEM;
goto fail_irq_level;
}
for (i = 0; i < wcd9xxx_res->num_irqs; i++) {
wcd9xxx_res->irq_masks_cur[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
wcd9xxx_res->irq_masks_cache[BIT_BYTE(i)] |= BYTE_BIT_MASK(i);
irq_level[BIT_BYTE(i)] |=
wcd9xxx_res->irq_level_high[i] << (i % BITS_PER_BYTE);
}
if (!wcd9xxx_res->wcd_core_regmap) {
dev_err(wcd9xxx_res->dev,
"%s: Codec core regmap not defined\n",
__func__);
ret = -EINVAL;
goto fail_irq_init;
}
for (i = 0; i < wcd9xxx_res->num_irq_regs; i++) {
/* Initialize interrupt mask and level registers */
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_LEVEL_BASE] + i,
irq_level[i]);
regmap_write(wcd9xxx_res->wcd_core_regmap,
wcd9xxx_res->intr_reg[WCD9XXX_INTR_MASK_BASE] + i,
wcd9xxx_res->irq_masks_cur[i]);
}
ret = request_threaded_irq(wcd9xxx_res->irq, NULL, wcd9xxx_irq_thread,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"wcd9xxx", wcd9xxx_res);
if (ret != 0)
dev_err(wcd9xxx_res->dev, "Failed to request IRQ %d: %d\n",
wcd9xxx_res->irq, ret);
else {
ret = enable_irq_wake(wcd9xxx_res->irq);
if (ret)
dev_err(wcd9xxx_res->dev,
"Failed to set wake interrupt on IRQ %d: %d\n",
wcd9xxx_res->irq, ret);
if (ret)
free_irq(wcd9xxx_res->irq, wcd9xxx_res);
}
if (ret)
goto fail_irq_init;
kfree(irq_level);
return ret;
fail_irq_init:
dev_err(wcd9xxx_res->dev,
"%s: Failed to init wcd9xxx irq\n", __func__);
kfree(irq_level);
fail_irq_level:
wcd9xxx_irq_put_upstream_irq(wcd9xxx_res);
mutex_destroy(&wcd9xxx_res->irq_lock);
mutex_destroy(&wcd9xxx_res->nested_irq_lock);
return ret;
}
EXPORT_SYMBOL(wcd9xxx_irq_init);
int wcd9xxx_request_irq(struct wcd9xxx_core_resource *wcd9xxx_res,
int irq, irq_handler_t handler,
const char *name, void *data)
{
int virq;
virq = phyirq_to_virq(wcd9xxx_res, irq);
return request_threaded_irq(virq, NULL, handler, IRQF_TRIGGER_RISING,
name, data);
}
EXPORT_SYMBOL(wcd9xxx_request_irq);
void wcd9xxx_irq_exit(struct wcd9xxx_core_resource *wcd9xxx_res)
{
dev_dbg(wcd9xxx_res->dev, "%s: Cleaning up irq %d\n", __func__,
wcd9xxx_res->irq);
if (wcd9xxx_res->irq) {
disable_irq_wake(wcd9xxx_res->irq);
free_irq(wcd9xxx_res->irq, wcd9xxx_res);
wcd9xxx_res->irq = 0;
wcd9xxx_irq_put_downstream_irq(wcd9xxx_res);
wcd9xxx_irq_put_upstream_irq(wcd9xxx_res);
}
mutex_destroy(&wcd9xxx_res->irq_lock);
mutex_destroy(&wcd9xxx_res->nested_irq_lock);
}
#ifndef CONFIG_OF
static int phyirq_to_virq(
struct wcd9xxx_core_resource *wcd9xxx_res,
int offset)
{
return wcd9xxx_res->irq_base + offset;
}
static int virq_to_phyirq(
struct wcd9xxx_core_resource *wcd9xxx_res,
int virq)
{
return virq - wcd9xxx_res->irq_base;
}
static unsigned int wcd9xxx_irq_get_upstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
return wcd9xxx_res->irq;
}
static void wcd9xxx_irq_put_upstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
/* Do nothing */
}
static int wcd9xxx_map_irq(
struct wcd9xxx_core_resource *wcd9xxx_core_res, int irq)
{
return phyirq_to_virq(wcd9xxx_core_res, irq);
}
#else
static struct wcd9xxx_irq_drv_data *
wcd9xxx_irq_add_domain(struct device_node *node,
struct device_node *parent)
{
struct wcd9xxx_irq_drv_data *data = NULL;
pr_debug("%s: node %s, node parent %s\n", __func__,
node->name, node->parent->name);
data = kzalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return NULL;
/*
* wcd9xxx_intc interrupt controller supports N to N irq mapping with
* single cell binding with irq numbers(offsets) only.
* Use irq_domain_simple_ops that has irq_domain_simple_map and
* irq_domain_xlate_onetwocell.
*/
data->domain = irq_domain_add_linear(node, WCD9XXX_MAX_NUM_IRQS,
&irq_domain_simple_ops, data);
if (!data->domain) {
kfree(data);
return NULL;
}
return data;
}
static struct wcd9xxx_irq_drv_data *
wcd9xxx_get_irq_drv_d(const struct wcd9xxx_core_resource *wcd9xxx_res)
{
struct irq_domain *domain;
domain = wcd9xxx_res->domain;
if (domain)
return domain->host_data;
else
return NULL;
}
static int phyirq_to_virq(struct wcd9xxx_core_resource *wcd9xxx_res, int offset)
{
struct wcd9xxx_irq_drv_data *data;
data = wcd9xxx_get_irq_drv_d(wcd9xxx_res);
if (!data) {
pr_warn("%s: not registered to interrupt controller\n",
__func__);
return -EINVAL;
}
return irq_linear_revmap(data->domain, offset);
}
static int virq_to_phyirq(struct wcd9xxx_core_resource *wcd9xxx_res, int virq)
{
struct irq_data *irq_data = irq_get_irq_data(virq);
if (unlikely(!irq_data)) {
pr_err("%s: irq_data is NULL", __func__);
return -EINVAL;
}
return irq_data->hwirq;
}
static unsigned int wcd9xxx_irq_get_upstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
struct wcd9xxx_irq_drv_data *data;
data = wcd9xxx_get_irq_drv_d(wcd9xxx_res);
if (!data) {
pr_err("%s: interrupt controller is not registered\n",
__func__);
return 0;
}
/* Make sure data is updated before return. */
rmb();
return data->irq;
}
static void wcd9xxx_irq_put_downstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
int irq, virq, ret;
/*
* IRQ migration hits error if the chip data and handles
* are not made NULL. make associated data and handles
* to NULL at irq_exit
*/
for (irq = 0; irq < wcd9xxx_res->num_irqs; irq++) {
virq = wcd9xxx_map_irq(wcd9xxx_res, irq);
pr_debug("%s: irq %d -> %d\n", __func__, irq, virq);
ret = irq_set_chip_data(virq, NULL);
if (ret) {
pr_err("%s: Failed to configure irq %d (%d)\n",
__func__, irq, ret);
return;
}
irq_set_chip_and_handler(virq, NULL, NULL);
}
}
static void wcd9xxx_irq_put_upstream_irq(
struct wcd9xxx_core_resource *wcd9xxx_res)
{
wcd9xxx_res->domain = NULL;
}
static int wcd9xxx_map_irq(struct wcd9xxx_core_resource *wcd9xxx_res, int irq)
{
return of_irq_to_resource(wcd9xxx_res->dev->of_node, irq, NULL);
}
static int wcd9xxx_irq_probe(struct platform_device *pdev)
{
int irq, dir_apps_irq = -EINVAL;
struct wcd9xxx_irq_drv_data *data;
struct device_node *node = pdev->dev.of_node;
int ret = -EINVAL;
irq = of_get_named_gpio(node, "qcom,gpio-connect", 0);
if (!gpio_is_valid(irq))
dir_apps_irq = platform_get_irq_byname(pdev, "wcd_irq");
if (!gpio_is_valid(irq) && dir_apps_irq < 0) {
dev_err(&pdev->dev, "TLMM connect gpio not found\n");
return -EPROBE_DEFER;
}
if (dir_apps_irq > 0) {
irq = dir_apps_irq;
} else {
irq = gpio_to_irq(irq);
if (irq < 0) {
dev_err(&pdev->dev, "Unable to configure irq\n");
return irq;
}
}
dev_dbg(&pdev->dev, "%s: virq = %d\n", __func__, irq);
data = wcd9xxx_irq_add_domain(node, node->parent);
if (!data) {
pr_err("%s: irq_add_domain failed\n", __func__);
return -EINVAL;
}
data->irq = irq;
/* Make sure irq is saved before return. */
wmb();
ret = 0;
return ret;
}
static int wcd9xxx_irq_remove(struct platform_device *pdev)
{
struct irq_domain *domain;
struct wcd9xxx_irq_drv_data *data;
domain = irq_find_host(pdev->dev.of_node);
if (unlikely(!domain)) {
pr_err("%s: domain is NULL", __func__);
return -EINVAL;
}
data = (struct wcd9xxx_irq_drv_data *)domain->host_data;
data->irq = 0;
/* Make sure irq variable is updated in data, before irq removal. */
wmb();
irq_domain_remove(data->domain);
kfree(data);
return 0;
}
static const struct of_device_id of_match[] = {
{ .compatible = "qcom,wcd9xxx-irq" },
{ }
};
static struct platform_driver wcd9xxx_irq_driver = {
.probe = wcd9xxx_irq_probe,
.remove = wcd9xxx_irq_remove,
.driver = {
.name = "wcd9xxx_intc",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(of_match),
.suppress_bind_attrs = true,
},
};
int wcd9xxx_irq_drv_init(void)
{
return platform_driver_register(&wcd9xxx_irq_driver);
}
void wcd9xxx_irq_drv_exit(void)
{
platform_driver_unregister(&wcd9xxx_irq_driver);
}
#endif /* CONFIG_OF */

View File

@@ -0,0 +1,686 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <sound/soc.h>
#include <asoc/wcd9xxx-resmgr-v2.h>
#include <asoc/core.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)
{
if (clk_type == WCD_CLK_OFF)
return "WCD_CLK_OFF";
else if (clk_type == WCD_CLK_RCO)
return "WCD_CLK_RCO";
else if (clk_type == WCD_CLK_MCLK)
return "WCD_CLK_MCLK";
else
return "WCD_CLK_UNDEFINED";
}
static int wcd_resmgr_codec_reg_update_bits(struct wcd9xxx_resmgr_v2 *resmgr,
u16 reg, u8 mask, u8 val)
{
bool change;
int ret;
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 == WCD93XX_CLK_SYS_MCLK_PRG)
return 0;
}
if (resmgr->codec) {
ret = snd_soc_update_bits(resmgr->codec, reg, mask, val);
} else if (resmgr->core_res->wcd_core_regmap) {
ret = regmap_update_bits_check(
resmgr->core_res->wcd_core_regmap,
reg, mask, val, &change);
if (!ret)
ret = change;
} else {
pr_err("%s: codec/regmap not defined\n", __func__);
ret = -EINVAL;
}
return ret;
}
static int wcd_resmgr_codec_reg_read(struct wcd9xxx_resmgr_v2 *resmgr,
unsigned int reg)
{
int val, ret;
if (resmgr->codec_type != WCD9335) {
if (reg == WCD93XX_ANA_CLK_TOP)
return 0;
} else {
if (reg == WCD93XX_CLK_SYS_MCLK_PRG)
return 0;
}
if (resmgr->codec) {
val = snd_soc_read(resmgr->codec, reg);
} else if (resmgr->core_res->wcd_core_regmap) {
ret = regmap_read(resmgr->core_res->wcd_core_regmap,
reg, &val);
if (ret)
val = ret;
} else {
pr_err("%s: wcd regmap is null\n", __func__);
return -EINVAL;
}
return val;
}
/*
* wcd_resmgr_get_clk_type()
* Returns clk type that is currently enabled
*/
int wcd_resmgr_get_clk_type(struct wcd9xxx_resmgr_v2 *resmgr)
{
if (!resmgr) {
pr_err("%s: resmgr not initialized\n", __func__);
return -EINVAL;
}
return resmgr->clk_type;
}
EXPORT_SYMBOL(wcd_resmgr_get_clk_type);
static void wcd_resmgr_cdc_specific_get_clk(struct wcd9xxx_resmgr_v2 *resmgr,
int clk_users)
{
/* Caller of this function should have acquired BG_CLK lock */
if (clk_users) {
if (resmgr->resmgr_cb &&
resmgr->resmgr_cb->cdc_rco_ctrl) {
while (clk_users--)
resmgr->resmgr_cb->cdc_rco_ctrl(resmgr->codec,
true);
}
}
}
/*
* wcd_resmgr_post_ssr_v2
* @resmgr: handle to struct wcd9xxx_resmgr_v2
*/
void wcd_resmgr_post_ssr_v2(struct wcd9xxx_resmgr_v2 *resmgr)
{
int old_bg_audio_users;
int old_clk_rco_users, old_clk_mclk_users;
WCD9XXX_V2_BG_CLK_LOCK(resmgr);
old_bg_audio_users = resmgr->master_bias_users;
old_clk_mclk_users = resmgr->clk_mclk_users;
old_clk_rco_users = resmgr->clk_rco_users;
resmgr->master_bias_users = 0;
resmgr->clk_mclk_users = 0;
resmgr->clk_rco_users = 0;
resmgr->clk_type = WCD_CLK_OFF;
pr_debug("%s: old_bg_audio_users=%d old_clk_mclk_users=%d old_clk_rco_users=%d\n",
__func__, old_bg_audio_users,
old_clk_mclk_users, old_clk_rco_users);
if (old_bg_audio_users) {
while (old_bg_audio_users--)
wcd_resmgr_enable_master_bias(resmgr);
}
if (old_clk_mclk_users) {
while (old_clk_mclk_users--)
wcd_resmgr_enable_clk_block(resmgr, WCD_CLK_MCLK);
}
if (old_clk_rco_users)
wcd_resmgr_cdc_specific_get_clk(resmgr, old_clk_rco_users);
WCD9XXX_V2_BG_CLK_UNLOCK(resmgr);
}
EXPORT_SYMBOL(wcd_resmgr_post_ssr_v2);
/*
* wcd_resmgr_enable_master_bias: enable codec master bias
* @resmgr: handle to struct wcd9xxx_resmgr_v2
*/
int wcd_resmgr_enable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr)
{
mutex_lock(&resmgr->master_bias_lock);
resmgr->master_bias_users++;
if (resmgr->master_bias_users == 1) {
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS,
0x80, 0x80);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS,
0x40, 0x40);
/*
* 1ms delay is required after pre-charge is enabled
* as per HW requirement
*/
usleep_range(1000, 1100);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS,
0x40, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_BIAS, 0x20, 0x00);
}
pr_debug("%s: current master bias users: %d\n", __func__,
resmgr->master_bias_users);
mutex_unlock(&resmgr->master_bias_lock);
return 0;
}
EXPORT_SYMBOL(wcd_resmgr_enable_master_bias);
/*
* wcd_resmgr_disable_master_bias: disable codec master bias
* @resmgr: handle to struct wcd9xxx_resmgr_v2
*/
int wcd_resmgr_disable_master_bias(struct wcd9xxx_resmgr_v2 *resmgr)
{
mutex_lock(&resmgr->master_bias_lock);
if (resmgr->master_bias_users <= 0) {
mutex_unlock(&resmgr->master_bias_lock);
return -EINVAL;
}
resmgr->master_bias_users--;
if (resmgr->master_bias_users == 0) {
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BIAS,
0x80, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_BIAS, 0x20, 0x00);
}
mutex_unlock(&resmgr->master_bias_lock);
return 0;
}
EXPORT_SYMBOL(wcd_resmgr_disable_master_bias);
static int wcd_resmgr_enable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
{
/* Enable mclk requires master bias to be enabled first */
if (resmgr->master_bias_users <= 0) {
pr_err("%s: Cannot turn on MCLK, BG is not enabled\n",
__func__);
return -EINVAL;
}
if (((resmgr->clk_mclk_users == 0) &&
(resmgr->clk_type == WCD_CLK_MCLK)) ||
((resmgr->clk_mclk_users > 0) &&
(resmgr->clk_type != WCD_CLK_MCLK))) {
pr_err("%s: Error enabling MCLK, clk_type: %s\n",
__func__,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
return -EINVAL;
}
if (++resmgr->clk_mclk_users == 1) {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_CLK_TOP, 0x80, 0x80);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_CLK_TOP, 0x08, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
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,
WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x80);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x30, 0x10);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x01, 0x01);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_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,
WCD93XX_CODEC_RPM_CLK_GATE, 0x03, 0x00);
} else {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x01);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CDC_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x01);
}
/*
* 10us sleep is required after clock is enabled
* as per HW requirement
*/
usleep_range(10, 15);
}
resmgr->clk_type = WCD_CLK_MCLK;
pr_debug("%s: mclk_users: %d, clk_type: %s\n", __func__,
resmgr->clk_mclk_users,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
return 0;
}
static int wcd_resmgr_disable_clk_mclk(struct wcd9xxx_resmgr_v2 *resmgr)
{
if (resmgr->clk_mclk_users <= 0) {
pr_err("%s: No mclk users, cannot disable mclk\n", __func__);
return -EINVAL;
}
if (--resmgr->clk_mclk_users == 0) {
if (resmgr->clk_rco_users > 0) {
/* MCLK to RCO switch */
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_CLK_TOP,
0x08, 0x08);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x02, 0x02);
/* Disable clock buffer */
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x80, 0x00);
resmgr->clk_type = WCD_CLK_RCO;
} else {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_CLK_TOP,
0x04, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG, 0x81, 0x00);
resmgr->clk_type = WCD_CLK_OFF;
}
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
0x80, 0x00);
}
if ((resmgr->codec_type != WCD9335) &&
(resmgr->clk_type == WCD_CLK_OFF))
wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
pr_debug("%s: mclk_users: %d, clk_type: %s\n", __func__,
resmgr->clk_mclk_users,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
return 0;
}
static void wcd_resmgr_set_buck_accuracy(struct wcd9xxx_resmgr_v2 *resmgr)
{
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, 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, WCD93XX_ANA_BUCK_CTL,
0x04, 0x04);
/* 100us sleep needed after HIGH_ACCURACY_EN */
usleep_range(100, 110);
}
static int wcd_resmgr_enable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
{
bool rco_cal_done = true;
resmgr->clk_rco_users++;
if ((resmgr->clk_rco_users == 1) &&
((resmgr->clk_type == WCD_CLK_OFF) ||
(resmgr->clk_mclk_users == 0))) {
pr_warn("%s: RCO enable requires MCLK to be ON first\n",
__func__);
resmgr->clk_rco_users--;
return -EINVAL;
} else if ((resmgr->clk_rco_users == 1) &&
(resmgr->clk_mclk_users)) {
/* RCO Enable */
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL) {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_RCO,
0x80, 0x80);
if (resmgr->codec_type != WCD9335)
wcd_resmgr_set_buck_accuracy(resmgr);
}
/*
* 20us required after RCO BG is enabled as per HW
* requirements
*/
usleep_range(20, 25);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x40, 0x40);
/*
* 20us required after RCO is enabled as per HW
* requirements
*/
usleep_range(20, 25);
/* RCO Calibration */
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x04, 0x04);
if (resmgr->codec_type != WCD9335)
/*
* For wcd934x and wcd936x codecs, 20us sleep is needed
* after enabling RCO calibration
*/
usleep_range(20, 25);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_RCO,
0x04, 0x00);
if (resmgr->codec_type != WCD9335)
/*
* For wcd934x and wcd936x codecs, 20us sleep is needed
* after disabling RCO calibration
*/
usleep_range(20, 25);
/* 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, WCD93XX_ANA_RCO) & 0x02)
rco_cal_done = false;
WARN((!rco_cal_done), "RCO Calibration failed\n");
/* Switch MUX to RCO */
if (resmgr->clk_mclk_users == 1) {
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_CLK_TOP,
0x08, 0x08);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG,
0x02, 0x02);
resmgr->clk_type = WCD_CLK_RCO;
}
}
pr_debug("%s: rco clk users: %d, clk_type: %s\n", __func__,
resmgr->clk_rco_users,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
return 0;
}
static int wcd_resmgr_disable_clk_rco(struct wcd9xxx_resmgr_v2 *resmgr)
{
if ((resmgr->clk_rco_users <= 0) ||
(resmgr->clk_type == WCD_CLK_OFF)) {
pr_err("%s: rco_clk_users = %d, clk_type = %d, cannot disable\n",
__func__, resmgr->clk_rco_users, resmgr->clk_type);
return -EINVAL;
}
resmgr->clk_rco_users--;
if ((resmgr->clk_rco_users == 0) &&
(resmgr->clk_type == WCD_CLK_RCO)) {
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
0x08, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_CLK_SYS_MCLK_PRG,
0x02, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_CLK_TOP,
0x04, 0x00);
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,
WCD93XX_ANA_RCO,
0x80, 0x00);
wcd_resmgr_codec_reg_update_bits(resmgr,
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, WCD93XX_ANA_RCO,
0x40, 0x00);
if (resmgr->sido_input_src == SIDO_SOURCE_INTERNAL)
wcd_resmgr_codec_reg_update_bits(resmgr,
WCD93XX_ANA_RCO,
0x80, 0x00);
}
if ((resmgr->codec_type != WCD9335) &&
(resmgr->clk_type == WCD_CLK_OFF))
wcd_resmgr_set_sido_input_src(resmgr, SIDO_SOURCE_INTERNAL);
pr_debug("%s: rco clk users: %d, clk_type: %s\n", __func__,
resmgr->clk_rco_users,
wcd_resmgr_clk_type_to_str(resmgr->clk_type));
return 0;
}
/*
* wcd_resmgr_enable_clk_block: enable MCLK or RCO
* @resmgr: handle to struct wcd9xxx_resmgr_v2
* @type: Clock type to enable
*/
int wcd_resmgr_enable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr,
enum wcd_clock_type type)
{
int ret;
switch (type) {
case WCD_CLK_MCLK:
ret = wcd_resmgr_enable_clk_mclk(resmgr);
break;
case WCD_CLK_RCO:
ret = wcd_resmgr_enable_clk_rco(resmgr);
break;
default:
pr_err("%s: Unknown Clock type: %s\n", __func__,
wcd_resmgr_clk_type_to_str(type));
ret = -EINVAL;
break;
};
if (ret)
pr_err("%s: Enable clock %s failed\n", __func__,
wcd_resmgr_clk_type_to_str(type));
return ret;
}
EXPORT_SYMBOL(wcd_resmgr_enable_clk_block);
void wcd_resmgr_set_sido_input_src(struct wcd9xxx_resmgr_v2 *resmgr,
int sido_src)
{
if (!resmgr)
return;
if (sido_src == resmgr->sido_input_src)
return;
if (sido_src == SIDO_SOURCE_INTERNAL) {
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x04, 0x00);
usleep_range(100, 110);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x03, 0x00);
usleep_range(100, 110);
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, WCD93XX_ANA_RCO,
0x80, 0x80);
usleep_range(100, 110);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x02, 0x02);
usleep_range(100, 110);
wcd_resmgr_codec_reg_update_bits(resmgr, WCD93XX_ANA_BUCK_CTL,
0x01, 0x01);
usleep_range(100, 110);
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;
pr_debug("%s: sido input src to external\n", __func__);
}
}
EXPORT_SYMBOL(wcd_resmgr_set_sido_input_src);
/*
* wcd_resmgr_set_sido_input_src_locked:
* Set SIDO input in BG_CLK locked context
*
* @resmgr: handle to struct wcd9xxx_resmgr_v2
* @sido_src: Select the SIDO input source
*/
void wcd_resmgr_set_sido_input_src_locked(struct wcd9xxx_resmgr_v2 *resmgr,
int sido_src)
{
if (!resmgr)
return;
WCD9XXX_V2_BG_CLK_LOCK(resmgr);
wcd_resmgr_set_sido_input_src(resmgr, sido_src);
WCD9XXX_V2_BG_CLK_UNLOCK(resmgr);
}
EXPORT_SYMBOL(wcd_resmgr_set_sido_input_src_locked);
/*
* wcd_resmgr_disable_clk_block: disable MCLK or RCO
* @resmgr: handle to struct wcd9xxx_resmgr_v2
* @type: Clock type to disable
*/
int wcd_resmgr_disable_clk_block(struct wcd9xxx_resmgr_v2 *resmgr,
enum wcd_clock_type type)
{
int ret;
switch (type) {
case WCD_CLK_MCLK:
ret = wcd_resmgr_disable_clk_mclk(resmgr);
break;
case WCD_CLK_RCO:
ret = wcd_resmgr_disable_clk_rco(resmgr);
break;
default:
pr_err("%s: Unknown Clock type: %s\n", __func__,
wcd_resmgr_clk_type_to_str(type));
ret = -EINVAL;
break;
};
if (ret)
pr_err("%s: Disable clock %s failed\n", __func__,
wcd_resmgr_clk_type_to_str(type));
return ret;
}
EXPORT_SYMBOL(wcd_resmgr_disable_clk_block);
/*
* wcd_resmgr_init: initialize wcd resource manager
* @core_res: handle to struct wcd9xxx_core_resource
*
* Early init call without a handle to snd_soc_codec *
*/
struct wcd9xxx_resmgr_v2 *wcd_resmgr_init(
struct wcd9xxx_core_resource *core_res,
struct snd_soc_codec *codec)
{
struct wcd9xxx_resmgr_v2 *resmgr;
struct wcd9xxx *wcd9xxx;
resmgr = kzalloc(sizeof(struct wcd9xxx_resmgr_v2), GFP_KERNEL);
if (!resmgr)
return ERR_PTR(-ENOMEM);
wcd9xxx = container_of(core_res, struct wcd9xxx, core_res);
if (!wcd9xxx) {
kfree(resmgr);
pr_err("%s: Cannot get wcd9xx pointer\n", __func__);
return ERR_PTR(-EINVAL);
}
mutex_init(&resmgr->codec_bg_clk_lock);
mutex_init(&resmgr->master_bias_lock);
resmgr->master_bias_users = 0;
resmgr->clk_mclk_users = 0;
resmgr->clk_rco_users = 0;
resmgr->master_bias_users = 0;
resmgr->codec = codec;
resmgr->core_res = core_res;
resmgr->sido_input_src = SIDO_SOURCE_INTERNAL;
resmgr->codec_type = wcd9xxx->type;
return resmgr;
}
EXPORT_SYMBOL(wcd_resmgr_init);
/*
* wcd_resmgr_remove: Clean-up wcd resource manager
* @resmgr: handle to struct wcd9xxx_resmgr_v2
*/
void wcd_resmgr_remove(struct wcd9xxx_resmgr_v2 *resmgr)
{
mutex_destroy(&resmgr->master_bias_lock);
kfree(resmgr);
}
EXPORT_SYMBOL(wcd_resmgr_remove);
/*
* wcd_resmgr_post_init: post init call to assign codec handle
* @resmgr: handle to struct wcd9xxx_resmgr_v2 created during early init
* @resmgr_cb: codec callback function for resmgr
* @codec: handle to struct snd_soc_codec
*/
int wcd_resmgr_post_init(struct wcd9xxx_resmgr_v2 *resmgr,
const struct wcd_resmgr_cb *resmgr_cb,
struct snd_soc_codec *codec)
{
if (!resmgr) {
pr_err("%s: resmgr not allocated\n", __func__);
return -EINVAL;
}
if (!codec) {
pr_err("%s: Codec memory is NULL, nothing to post init\n",
__func__);
return -EINVAL;
}
resmgr->codec = codec;
resmgr->resmgr_cb = resmgr_cb;
return 0;
}
EXPORT_SYMBOL(wcd_resmgr_post_init);
MODULE_DESCRIPTION("wcd9xxx resmgr v2 module");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,435 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <asoc/core.h>
#include <asoc/pdata.h>
#include "wcd9xxx-utils.h"
#include "wcd9335_registers.h"
#include "wcd9335_irq.h"
#include <asoc/wcd934x_registers.h>
#include "wcd934x/wcd934x_irq.h"
/* wcd9335 interrupt table */
static const struct intr_data wcd9335_intr_table[] = {
{WCD9XXX_IRQ_SLIMBUS, false},
{WCD9335_IRQ_MBHC_SW_DET, true},
{WCD9335_IRQ_MBHC_BUTTON_PRESS_DET, true},
{WCD9335_IRQ_MBHC_BUTTON_RELEASE_DET, true},
{WCD9335_IRQ_MBHC_ELECT_INS_REM_DET, true},
{WCD9335_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true},
{WCD9335_IRQ_FLL_LOCK_LOSS, false},
{WCD9335_IRQ_HPH_PA_CNPL_COMPLETE, false},
{WCD9335_IRQ_HPH_PA_CNPR_COMPLETE, false},
{WCD9335_IRQ_EAR_PA_CNP_COMPLETE, false},
{WCD9335_IRQ_LINE_PA1_CNP_COMPLETE, false},
{WCD9335_IRQ_LINE_PA2_CNP_COMPLETE, false},
{WCD9335_IRQ_LINE_PA3_CNP_COMPLETE, false},
{WCD9335_IRQ_LINE_PA4_CNP_COMPLETE, false},
{WCD9335_IRQ_HPH_PA_OCPL_FAULT, false},
{WCD9335_IRQ_HPH_PA_OCPR_FAULT, false},
{WCD9335_IRQ_EAR_PA_OCP_FAULT, false},
{WCD9335_IRQ_SOUNDWIRE, false},
{WCD9335_IRQ_VDD_DIG_RAMP_COMPLETE, false},
{WCD9335_IRQ_RCO_ERROR, false},
{WCD9335_IRQ_SVA_ERROR, false},
{WCD9335_IRQ_MAD_AUDIO, false},
{WCD9335_IRQ_MAD_BEACON, false},
{WCD9335_IRQ_SVA_OUTBOX1, true},
{WCD9335_IRQ_SVA_OUTBOX2, true},
{WCD9335_IRQ_MAD_ULTRASOUND, false},
{WCD9335_IRQ_VBAT_ATTACK, false},
{WCD9335_IRQ_VBAT_RESTORE, false},
};
static const struct intr_data wcd934x_intr_table[] = {
{WCD9XXX_IRQ_SLIMBUS, false},
{WCD934X_IRQ_MBHC_SW_DET, true},
{WCD934X_IRQ_MBHC_BUTTON_PRESS_DET, true},
{WCD934X_IRQ_MBHC_BUTTON_RELEASE_DET, true},
{WCD934X_IRQ_MBHC_ELECT_INS_REM_DET, true},
{WCD934X_IRQ_MBHC_ELECT_INS_REM_LEG_DET, true},
{WCD934X_IRQ_MISC, false},
{WCD934X_IRQ_HPH_PA_CNPL_COMPLETE, false},
{WCD934X_IRQ_HPH_PA_CNPR_COMPLETE, false},
{WCD934X_IRQ_EAR_PA_CNP_COMPLETE, false},
{WCD934X_IRQ_LINE_PA1_CNP_COMPLETE, false},
{WCD934X_IRQ_LINE_PA2_CNP_COMPLETE, false},
{WCD934X_IRQ_SLNQ_ANALOG_ERROR, false},
{WCD934X_IRQ_RESERVED_3, false},
{WCD934X_IRQ_HPH_PA_OCPL_FAULT, false},
{WCD934X_IRQ_HPH_PA_OCPR_FAULT, false},
{WCD934X_IRQ_EAR_PA_OCP_FAULT, false},
{WCD934X_IRQ_SOUNDWIRE, false},
{WCD934X_IRQ_VDD_DIG_RAMP_COMPLETE, false},
{WCD934X_IRQ_RCO_ERROR, false},
{WCD934X_IRQ_CPE_ERROR, false},
{WCD934X_IRQ_MAD_AUDIO, false},
{WCD934X_IRQ_MAD_BEACON, false},
{WCD934X_IRQ_CPE1_INTR, true},
{WCD934X_IRQ_RESERVED_4, false},
{WCD934X_IRQ_MAD_ULTRASOUND, false},
{WCD934X_IRQ_VBAT_ATTACK, false},
{WCD934X_IRQ_VBAT_RESTORE, false},
};
/*
* wcd9335_bring_down: Bringdown WCD Codec
*
* @wcd9xxx: Pointer to wcd9xxx structure
*
* Returns 0 for success or negative error code for failure
*/
static int wcd9335_bring_down(struct wcd9xxx *wcd9xxx)
{
if (!wcd9xxx || !wcd9xxx->regmap)
return -EINVAL;
regmap_write(wcd9xxx->regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x04);
return 0;
}
/*
* wcd9335_bring_up: Bringup WCD Codec
*
* @wcd9xxx: Pointer to the wcd9xxx structure
*
* Returns 0 for success or negative error code for failure
*/
static int wcd9335_bring_up(struct wcd9xxx *wcd9xxx)
{
int ret = 0;
int val, byte0;
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_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0, &val);
regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0, &byte0);
if ((val < 0) || (byte0 < 0)) {
dev_err(wcd9xxx->dev, "%s: tasha codec version detection fail!\n",
__func__);
return -EINVAL;
}
if ((val & 0x80) && (byte0 == 0x0)) {
dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.1\n",
__func__);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC);
regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x5);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x7);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x3);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
} else if (byte0 == 0x1) {
dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v2.0\n",
__func__);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_TEST_2, 0x00);
regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_8, 0x6F);
regmap_write(wcd_regmap, WCD9335_BIAS_VBG_FINE_ADJ, 0x65);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x5);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x7);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x3);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
} else if ((byte0 == 0) && (!(val & 0x80))) {
dev_info(wcd9xxx->dev, "%s: wcd9335 codec version is v1.0\n",
__func__);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x01);
regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_2, 0xFC);
regmap_write(wcd_regmap, WCD9335_SIDO_SIDO_CCL_4, 0x21);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x3);
regmap_write(wcd_regmap, WCD9335_CODEC_RPM_RST_CTL, 0x3);
} else {
dev_err(wcd9xxx->dev, "%s: tasha codec version unknown\n",
__func__);
ret = -EINVAL;
}
return ret;
}
/*
* wcd9335_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 wcd9335_get_cdc_info(struct wcd9xxx *wcd9xxx,
struct wcd9xxx_codec_type *wcd_type)
{
u16 id_minor, id_major;
struct regmap *wcd_regmap;
int rc, val, version = 0;
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, WCD9335_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
(u8 *)&id_minor, sizeof(u16));
if (rc)
return -EINVAL;
rc = regmap_bulk_read(wcd_regmap, WCD9335_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);
/* Version detection */
if (id_major == TASHA_MAJOR) {
regmap_read(wcd_regmap, WCD9335_CHIP_TIER_CTRL_EFUSE_VAL_OUT0,
&val);
version = ((u8)val & 0x80) >> 7;
} else if (id_major == TASHA2P0_MAJOR)
version = 2;
else
dev_err(wcd9xxx->dev, "%s: wcd9335 version unknown (major 0x%x, minor 0x%x)\n",
__func__, id_major, id_minor);
/* Fill codec type info */
wcd_type->id_major = id_major;
wcd_type->id_minor = id_minor;
wcd_type->num_irqs = WCD9335_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 = wcd9335_intr_table;
wcd_type->intr_tbl_size = ARRAY_SIZE(wcd9335_intr_table);
wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] =
WCD9335_INTR_PIN1_STATUS0;
wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] =
WCD9335_INTR_PIN1_CLEAR0;
wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] =
WCD9335_INTR_PIN1_MASK0;
wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] =
WCD9335_INTR_LEVEL0;
wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] =
WCD9335_INTR_CLR_COMMIT;
return rc;
}
/*
* wcd934x_bring_down: Bringdown WCD Codec
*
* @wcd9xxx: Pointer to wcd9xxx structure
*
* Returns 0 for success or negative error code for failure
*/
static int wcd934x_bring_down(struct wcd9xxx *wcd9xxx)
{
if (!wcd9xxx || !wcd9xxx->regmap)
return -EINVAL;
regmap_write(wcd9xxx->regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL,
0x04);
return 0;
}
/*
* wcd934x_bring_up: Bringup WCD Codec
*
* @wcd9xxx: Pointer to the wcd9xxx structure
*
* Returns 0 for success or negative error code for failure
*/
static int wcd934x_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, WCD934X_CODEC_RPM_RST_CTL, 0x01);
regmap_write(wcd_regmap, WCD934X_SIDO_NEW_VOUT_A_STARTUP, 0x19);
regmap_write(wcd_regmap, WCD934X_SIDO_NEW_VOUT_D_STARTUP, 0x15);
/* Add 1msec delay for VOUT to settle */
usleep_range(1000, 1100);
regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x3);
regmap_write(wcd_regmap, WCD934X_CODEC_RPM_RST_CTL, 0x7);
regmap_write(wcd_regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
return 0;
}
/*
* wcd934x_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 wcd934x_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, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
(u8 *)&id_minor, sizeof(u16));
if (rc)
return -EINVAL;
rc = regmap_bulk_read(wcd_regmap, WCD934X_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 != TAVIL_MAJOR)
goto version_unknown;
/*
* As fine version info cannot be retrieved before tavil probe.
* Assign coarse versions for possible future use before tavil probe.
*/
if (id_minor == cpu_to_le16(0))
version = TAVIL_VERSION_1_0;
else if (id_minor == cpu_to_le16(0x01))
version = TAVIL_VERSION_1_1;
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 = WCD934X_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 = wcd934x_intr_table;
wcd_type->intr_tbl_size = ARRAY_SIZE(wcd934x_intr_table);
wcd_type->intr_reg[WCD9XXX_INTR_STATUS_BASE] =
WCD934X_INTR_PIN1_STATUS0;
wcd_type->intr_reg[WCD9XXX_INTR_CLEAR_BASE] =
WCD934X_INTR_PIN1_CLEAR0;
wcd_type->intr_reg[WCD9XXX_INTR_MASK_BASE] =
WCD934X_INTR_PIN1_MASK0;
wcd_type->intr_reg[WCD9XXX_INTR_LEVEL_BASE] =
WCD934X_INTR_LEVEL0;
wcd_type->intr_reg[WCD9XXX_INTR_CLR_COMMIT] =
WCD934X_INTR_CLR_COMMIT;
return rc;
}
codec_bringdown_fn wcd9xxx_bringdown_fn(int type)
{
codec_bringdown_fn cdc_bdown_fn;
switch (type) {
case WCD934X:
cdc_bdown_fn = wcd934x_bring_down;
break;
case WCD9335:
cdc_bdown_fn = wcd9335_bring_down;
break;
default:
cdc_bdown_fn = NULL;
break;
}
return cdc_bdown_fn;
}
codec_bringup_fn wcd9xxx_bringup_fn(int type)
{
codec_bringup_fn cdc_bup_fn;
switch (type) {
case WCD934X:
cdc_bup_fn = wcd934x_bring_up;
break;
case WCD9335:
cdc_bup_fn = wcd9335_bring_up;
break;
default:
cdc_bup_fn = NULL;
break;
}
return cdc_bup_fn;
}
codec_type_fn wcd9xxx_get_codec_info_fn(int type)
{
codec_type_fn cdc_type_fn;
switch (type) {
case WCD934X:
cdc_type_fn = wcd934x_get_cdc_info;
break;
case WCD9335:
cdc_type_fn = wcd9335_get_cdc_info;
break;
default:
cdc_type_fn = NULL;
break;
}
return cdc_type_fn;
}

View File

@@ -0,0 +1,576 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
#include <asoc/wcd9xxx-slimslave.h>
struct wcd9xxx_slim_sch {
u16 rx_port_ch_reg_base;
u16 port_tx_cfg_reg_base;
u16 port_rx_cfg_reg_base;
};
static struct wcd9xxx_slim_sch sh_ch;
static int wcd9xxx_alloc_slim_sh_ch(struct wcd9xxx *wcd9xxx,
u8 wcd9xxx_pgd_la, u32 cnt,
struct wcd9xxx_ch *channels, u32 path);
static int wcd9xxx_dealloc_slim_sh_ch(struct slim_device *slim,
u32 cnt, struct wcd9xxx_ch *channels);
static int wcd9xxx_configure_ports(struct wcd9xxx *wcd9xxx)
{
if (wcd9xxx->codec_type->slim_slave_type ==
WCD9XXX_SLIM_SLAVE_ADDR_TYPE_0) {
sh_ch.rx_port_ch_reg_base = 0x180;
sh_ch.port_rx_cfg_reg_base = 0x040;
sh_ch.port_tx_cfg_reg_base = 0x040;
} else {
sh_ch.rx_port_ch_reg_base =
0x180 - (TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS * 4);
sh_ch.port_rx_cfg_reg_base =
0x040 - TAIKO_SB_PGD_OFFSET_OF_RX_SLAVE_DEV_PORTS;
sh_ch.port_tx_cfg_reg_base = 0x050;
}
return 0;
}
/**
* wcd9xxx_init_slimslave
*
* @wcd9xxx: pointer to wcd9xxx struct
* @wcd9xxx_pgd_la: pgd_la value
* @tx_num: tx number
* @rx_num: rx number
* @tx_slot: pointer to tx slot
* @rx_slot: pointer to rx slot
*
* Returns 0 on success, appropriate error code otherwise
*/
int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la,
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot)
{
int ret = 0;
int i;
ret = wcd9xxx_configure_ports(wcd9xxx);
if (ret) {
pr_err("%s: Failed to configure register address offset\n",
__func__);
goto err;
}
if (!rx_num || rx_num > wcd9xxx->num_rx_port) {
pr_err("%s: invalid rx num %d\n", __func__, rx_num);
return -EINVAL;
}
if (wcd9xxx->rx_chs) {
wcd9xxx->num_rx_port = rx_num;
for (i = 0; i < rx_num; i++) {
wcd9xxx->rx_chs[i].ch_num = rx_slot[i];
INIT_LIST_HEAD(&wcd9xxx->rx_chs[i].list);
}
ret = wcd9xxx_alloc_slim_sh_ch(wcd9xxx, wcd9xxx_pgd_la,
wcd9xxx->num_rx_port,
wcd9xxx->rx_chs,
SLIM_SINK);
if (ret) {
pr_err("%s: Failed to alloc %d rx slimbus channels\n",
__func__, wcd9xxx->num_rx_port);
kfree(wcd9xxx->rx_chs);
wcd9xxx->rx_chs = NULL;
wcd9xxx->num_rx_port = 0;
}
} else {
pr_err("Not able to allocate memory for %d slimbus rx ports\n",
wcd9xxx->num_rx_port);
}
if (!tx_num || tx_num > wcd9xxx->num_tx_port) {
pr_err("%s: invalid tx num %d\n", __func__, tx_num);
return -EINVAL;
}
if (wcd9xxx->tx_chs) {
wcd9xxx->num_tx_port = tx_num;
for (i = 0; i < tx_num; i++) {
wcd9xxx->tx_chs[i].ch_num = tx_slot[i];
INIT_LIST_HEAD(&wcd9xxx->tx_chs[i].list);
}
ret = wcd9xxx_alloc_slim_sh_ch(wcd9xxx, wcd9xxx_pgd_la,
wcd9xxx->num_tx_port,
wcd9xxx->tx_chs,
SLIM_SRC);
if (ret) {
pr_err("%s: Failed to alloc %d tx slimbus channels\n",
__func__, wcd9xxx->num_tx_port);
kfree(wcd9xxx->tx_chs);
wcd9xxx->tx_chs = NULL;
wcd9xxx->num_tx_port = 0;
}
} else {
pr_err("Not able to allocate memory for %d slimbus tx ports\n",
wcd9xxx->num_tx_port);
}
return 0;
err:
return ret;
}
EXPORT_SYMBOL(wcd9xxx_init_slimslave);
int wcd9xxx_deinit_slimslave(struct wcd9xxx *wcd9xxx)
{
if (wcd9xxx->num_rx_port) {
wcd9xxx_dealloc_slim_sh_ch(wcd9xxx->slim,
wcd9xxx->num_rx_port,
wcd9xxx->rx_chs);
wcd9xxx->num_rx_port = 0;
}
if (wcd9xxx->num_tx_port) {
wcd9xxx_dealloc_slim_sh_ch(wcd9xxx->slim,
wcd9xxx->num_tx_port,
wcd9xxx->tx_chs);
wcd9xxx->num_tx_port = 0;
}
return 0;
}
static int wcd9xxx_alloc_slim_sh_ch(struct wcd9xxx *wcd9xxx,
u8 wcd9xxx_pgd_la, u32 cnt,
struct wcd9xxx_ch *channels, u32 path)
{
int ret = 0;
u32 ch_idx;
/* The slimbus channel allocation seem take longer time
* so do the allocation up front to avoid delay in start of
* playback
*/
pr_debug("%s: pgd_la[%d]\n", __func__, wcd9xxx_pgd_la);
for (ch_idx = 0; ch_idx < cnt; ch_idx++) {
ret = slim_get_slaveport(wcd9xxx_pgd_la,
channels[ch_idx].port,
&channels[ch_idx].sph, path);
pr_debug("%s: pgd_la[%d] channels[%d].port[%d]\n"
"channels[%d].sph[%d] path[%d]\n",
__func__, wcd9xxx_pgd_la, ch_idx,
channels[ch_idx].port,
ch_idx, channels[ch_idx].sph, path);
if (ret < 0) {
pr_err("%s: slave port failure id[%d] ret[%d]\n",
__func__, channels[ch_idx].ch_num, ret);
goto err;
}
ret = slim_query_ch(wcd9xxx->slim,
channels[ch_idx].ch_num,
&channels[ch_idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_query_ch failed ch-num[%d] ret[%d]\n",
__func__, channels[ch_idx].ch_num, ret);
goto err;
}
}
err:
return ret;
}
static int wcd9xxx_dealloc_slim_sh_ch(struct slim_device *slim,
u32 cnt, struct wcd9xxx_ch *channels)
{
int idx = 0;
int ret = 0;
/* slim_dealloc_ch */
for (idx = 0; idx < cnt; idx++) {
ret = slim_dealloc_ch(slim, channels[idx].ch_h);
if (ret < 0) {
pr_err("%s: slim_dealloc_ch fail ret[%d] ch_h[%d]\n",
__func__, ret, channels[idx].ch_h);
}
}
return ret;
}
/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_rx(struct wcd9xxx *wcd9xxx,
struct list_head *wcd9xxx_ch_list,
unsigned int rate, unsigned int bit_width,
u16 *grph)
{
u8 ch_cnt = 0;
u16 ch_h[SLIM_MAX_RX_PORTS] = {0};
u8 payload = 0;
u16 codec_port = 0;
int ret;
struct slim_ch prop;
struct wcd9xxx_ch *rx;
int size = ARRAY_SIZE(ch_h);
/* Configure slave interface device */
list_for_each_entry(rx, wcd9xxx_ch_list, list) {
payload |= 1 << rx->shift;
if (ch_cnt < size) {
ch_h[ch_cnt] = rx->ch_h;
ch_cnt++;
pr_debug("list ch->ch_h %d ch->sph %d\n",
rx->ch_h, rx->sph);
} else {
pr_err("%s: allocated channel number %u is out of max rangae %d\n",
__func__, ch_cnt,
size);
ret = EINVAL;
goto err;
}
}
pr_debug("%s: ch_cnt[%d] rate=%d WATER_MARK_VAL %d\n",
__func__, ch_cnt, rate, WATER_MARK_VAL);
/* slim_define_ch api */
prop.prot = SLIM_AUTO_ISO;
if ((rate == 44100) || (rate == 88200) || (rate == 176400) ||
(rate == 352800)) {
prop.baser = SLIM_RATE_11025HZ;
prop.ratem = (rate/11025);
} else {
prop.baser = SLIM_RATE_4000HZ;
prop.ratem = (rate/4000);
}
prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
prop.sampleszbits = bit_width;
pr_debug("Before slim_define_ch:\n"
"ch_cnt %d,ch_h[0] %d ch_h[1] %d, grph %d\n",
ch_cnt, ch_h[0], ch_h[1], *grph);
ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
true, grph);
if (ret < 0) {
pr_err("%s: slim_define_ch failed ret[%d]\n",
__func__, ret);
goto err;
}
list_for_each_entry(rx, wcd9xxx_ch_list, list) {
codec_port = rx->port;
pr_debug("%s: codec_port %d rx 0x%p, payload %d\n"
"sh_ch.rx_port_ch_reg_base0 0x%x\n"
"sh_ch.port_rx_cfg_reg_base 0x%x\n",
__func__, codec_port, rx, payload,
sh_ch.rx_port_ch_reg_base,
sh_ch.port_rx_cfg_reg_base);
/* look for the valid port range and chose the
* payload accordingly
*/
/* write to interface device */
ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_RX_PORT_MULTI_CHANNEL_0(
sh_ch.rx_port_ch_reg_base, codec_port),
payload);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
__func__,
SB_PGD_RX_PORT_MULTI_CHANNEL_0(
sh_ch.rx_port_ch_reg_base, codec_port),
payload, ret);
goto err;
}
/* configure the slave port for water mark and enable*/
ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_PORT_CFG_BYTE_ADDR(
sh_ch.port_rx_cfg_reg_base, codec_port),
WATER_MARK_VAL);
if (ret < 0) {
pr_err("%s:watermark set failure for port[%d] ret[%d]",
__func__, codec_port, ret);
}
ret = slim_connect_sink(wcd9xxx->slim, &rx->sph, 1, rx->ch_h);
if (ret < 0) {
pr_err("%s: slim_connect_sink failed ret[%d]\n",
__func__, ret);
goto err_close_slim_sch;
}
}
/* slim_control_ch */
ret = slim_control_ch(wcd9xxx->slim, *grph, SLIM_CH_ACTIVATE,
true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
goto err_close_slim_sch;
}
return 0;
err_close_slim_sch:
/* release all acquired handles */
wcd9xxx_close_slim_sch_rx(wcd9xxx, wcd9xxx_ch_list, *grph);
err:
return ret;
}
EXPORT_SYMBOL(wcd9xxx_cfg_slim_sch_rx);
/* Enable slimbus slave device for RX path */
int wcd9xxx_cfg_slim_sch_tx(struct wcd9xxx *wcd9xxx,
struct list_head *wcd9xxx_ch_list,
unsigned int rate, unsigned int bit_width,
u16 *grph)
{
u16 ch_cnt = 0;
u16 payload = 0;
u16 ch_h[SLIM_MAX_TX_PORTS] = {0};
u16 codec_port;
int ret = 0;
struct wcd9xxx_ch *tx;
int size = ARRAY_SIZE(ch_h);
struct slim_ch prop;
list_for_each_entry(tx, wcd9xxx_ch_list, list) {
payload |= 1 << tx->shift;
if (ch_cnt < size) {
ch_h[ch_cnt] = tx->ch_h;
ch_cnt++;
} else {
pr_err("%s: allocated channel number %u is out of max rangae %d\n",
__func__, ch_cnt,
size);
ret = EINVAL;
goto err;
}
}
/* slim_define_ch api */
prop.prot = SLIM_AUTO_ISO;
prop.baser = SLIM_RATE_4000HZ;
prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
prop.ratem = (rate/4000);
prop.sampleszbits = bit_width;
ret = slim_define_ch(wcd9xxx->slim, &prop, ch_h, ch_cnt,
true, grph);
if (ret < 0) {
pr_err("%s: slim_define_ch failed ret[%d]\n",
__func__, ret);
goto err;
}
pr_debug("%s: ch_cnt[%d] rate[%d] bitwidth[%u]\n", __func__, ch_cnt,
rate, bit_width);
list_for_each_entry(tx, wcd9xxx_ch_list, list) {
codec_port = tx->port;
pr_debug("%s: codec_port %d tx 0x%p, payload 0x%x\n",
__func__, codec_port, tx, payload);
/* write to interface device */
ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_TX_PORT_MULTI_CHANNEL_0(codec_port),
payload & 0x00FF);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
__func__,
SB_PGD_TX_PORT_MULTI_CHANNEL_0(codec_port),
payload, ret);
goto err;
}
/* ports 8,9 */
ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_TX_PORT_MULTI_CHANNEL_1(codec_port),
(payload & 0xFF00)>>8);
if (ret < 0) {
pr_err("%s:Intf-dev fail reg[%d] payload[%d] ret[%d]\n",
__func__,
SB_PGD_TX_PORT_MULTI_CHANNEL_1(codec_port),
payload, ret);
goto err;
}
/* configure the slave port for water mark and enable*/
ret = wcd9xxx_interface_reg_write(wcd9xxx,
SB_PGD_PORT_CFG_BYTE_ADDR(
sh_ch.port_tx_cfg_reg_base, codec_port),
WATER_MARK_VAL);
if (ret < 0) {
pr_err("%s:watermark set failure for port[%d] ret[%d]",
__func__, codec_port, ret);
}
ret = slim_connect_src(wcd9xxx->slim, tx->sph, tx->ch_h);
if (ret < 0) {
pr_err("%s: slim_connect_src failed ret[%d]\n",
__func__, ret);
goto err;
}
}
/* slim_control_ch */
ret = slim_control_ch(wcd9xxx->slim, *grph, SLIM_CH_ACTIVATE,
true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
goto err;
}
return 0;
err:
/* release all acquired handles */
wcd9xxx_close_slim_sch_tx(wcd9xxx, wcd9xxx_ch_list, *grph);
return ret;
}
EXPORT_SYMBOL(wcd9xxx_cfg_slim_sch_tx);
int wcd9xxx_close_slim_sch_rx(struct wcd9xxx *wcd9xxx,
struct list_head *wcd9xxx_ch_list, u16 grph)
{
u32 sph[SLIM_MAX_RX_PORTS] = {0};
int ch_cnt = 0;
int ret = 0;
struct wcd9xxx_ch *rx;
list_for_each_entry(rx, wcd9xxx_ch_list, list)
sph[ch_cnt++] = rx->sph;
pr_debug("%s ch_cht %d, sph[0] %d sph[1] %d\n", __func__, ch_cnt,
sph[0], sph[1]);
/* slim_control_ch (REMOVE) */
pr_debug("%s before slim_control_ch grph %d\n", __func__, grph);
ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n", __func__, ret);
goto err;
}
err:
return ret;
}
EXPORT_SYMBOL(wcd9xxx_close_slim_sch_rx);
int wcd9xxx_close_slim_sch_tx(struct wcd9xxx *wcd9xxx,
struct list_head *wcd9xxx_ch_list,
u16 grph)
{
u32 sph[SLIM_MAX_TX_PORTS] = {0};
int ret = 0;
int ch_cnt = 0;
struct wcd9xxx_ch *tx;
pr_debug("%s\n", __func__);
list_for_each_entry(tx, wcd9xxx_ch_list, list)
sph[ch_cnt++] = tx->sph;
pr_debug("%s ch_cht %d, sph[0] %d sph[1] %d\n",
__func__, ch_cnt, sph[0], sph[1]);
/* slim_control_ch (REMOVE) */
ret = slim_control_ch(wcd9xxx->slim, grph, SLIM_CH_REMOVE, true);
if (ret < 0) {
pr_err("%s: slim_control_ch failed ret[%d]\n",
__func__, ret);
goto err;
}
err:
return ret;
}
EXPORT_SYMBOL(wcd9xxx_close_slim_sch_tx);
int wcd9xxx_get_slave_port(unsigned int ch_num)
{
int ret = 0;
ret = (ch_num - BASE_CH_NUM);
pr_debug("%s: ch_num[%d] slave port[%d]\n", __func__, ch_num, ret);
if (ret < 0) {
pr_err("%s: Error:- Invalid slave port found = %d\n",
__func__, ret);
return -EINVAL;
}
return ret;
}
EXPORT_SYMBOL(wcd9xxx_get_slave_port);
int wcd9xxx_disconnect_port(struct wcd9xxx *wcd9xxx,
struct list_head *wcd9xxx_ch_list, u16 grph)
{
u32 sph[SLIM_MAX_TX_PORTS + SLIM_MAX_RX_PORTS] = {0};
int ch_cnt = 0;
int ret = 0;
struct wcd9xxx_ch *slim_ch;
list_for_each_entry(slim_ch, wcd9xxx_ch_list, list)
sph[ch_cnt++] = slim_ch->sph;
/* slim_disconnect_port */
ret = slim_disconnect_ports(wcd9xxx->slim, sph, ch_cnt);
if (ret < 0) {
pr_err("%s: slim_disconnect_ports failed ret[%d]\n",
__func__, ret);
}
return ret;
}
EXPORT_SYMBOL(wcd9xxx_disconnect_port);
/* This function is called with mutex acquired */
int wcd9xxx_rx_vport_validation(u32 port_id,
struct list_head *codec_dai_list)
{
struct wcd9xxx_ch *ch;
int ret = 0;
pr_debug("%s: port_id %u\n", __func__, port_id);
list_for_each_entry(ch,
codec_dai_list, list) {
pr_debug("%s: ch->port %u\n", __func__, ch->port);
if (ch->port == port_id) {
ret = -EINVAL;
break;
}
}
return ret;
}
EXPORT_SYMBOL(wcd9xxx_rx_vport_validation);
/* This function is called with mutex acquired */
int wcd9xxx_tx_vport_validation(u32 table, u32 port_id,
struct wcd9xxx_codec_dai_data *codec_dai,
u32 num_codec_dais)
{
struct wcd9xxx_ch *ch;
int ret = 0;
u32 index;
unsigned long vtable = table;
u32 size = sizeof(table) * BITS_PER_BYTE;
pr_debug("%s: vtable 0x%lx port_id %u size %d\n", __func__,
vtable, port_id, size);
for_each_set_bit(index, &vtable, size) {
if (index < num_codec_dais) {
list_for_each_entry(ch,
&codec_dai[index].wcd9xxx_ch_list,
list) {
pr_debug("%s: index %u ch->port %u vtable 0x%lx\n",
__func__, index, ch->port,
vtable);
if (ch->port == port_id) {
pr_err("%s: TX%u is used by AIF%u_CAP Mixer\n",
__func__, port_id + 1,
(index + 1)/2);
ret = -EINVAL;
break;
}
}
} else {
pr_err("%s: Invalid index %d of codec dai",
__func__, index);
ret = -EINVAL;
}
if (ret)
break;
}
return ret;
}
EXPORT_SYMBOL(wcd9xxx_tx_vport_validation);

View File

@@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <sound/wcd-dsp-mgr.h>
#include "audio-ext-clk-up.h"
static int __init wcd9xxx_soc_init(void)
{
int ret = 0;
ret = wcd_dsp_mgr_init();
if (!ret) {
ret = audio_ref_clk_platform_init();
if (ret) {
pr_err("%s: init extclk fail: %d\n", __func__, ret);
wcd_dsp_mgr_exit();
}
} else {
pr_err("%s: init dsp mgr fail: %d\n", __func__, ret);
}
return ret;
}
module_init(wcd9xxx_soc_init);
static void __exit wcd9xxx_soc_exit(void)
{
audio_ref_clk_platform_exit();
wcd_dsp_mgr_exit();
}
module_exit(wcd9xxx_soc_exit);
MODULE_DESCRIPTION("WCD9XXX CODEC soc init driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
*/
#ifndef __WCD9XXX_UTILS_H__
#define __WCD9XXX_UTILS_H__
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/regmap.h>
#include "pdata.h"
#include "core.h"
struct wcd9xxx_pdata *wcd9xxx_populate_dt_data(struct device *dev);
int wcd9xxx_bringup(struct device *dev);
int wcd9xxx_bringdown(struct device *dev);
struct regmap *wcd9xxx_regmap_init(struct device *dev,
const struct regmap_config *config);
int wcd9xxx_reset(struct device *dev);
int wcd9xxx_reset_low(struct device *dev);
int wcd9xxx_get_codec_info(struct device *dev);
typedef int (*codec_bringup_fn)(struct wcd9xxx *dev);
typedef int (*codec_bringdown_fn)(struct wcd9xxx *dev);
typedef int (*codec_type_fn)(struct wcd9xxx *dev,
struct wcd9xxx_codec_type *wcd_type);
codec_bringdown_fn wcd9xxx_bringdown_fn(int type);
codec_bringup_fn wcd9xxx_bringup_fn(int type);
codec_type_fn wcd9xxx_get_codec_info_fn(int type);
#endif

View File

@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*/
#ifndef __CMI_API__
#define __CMI_API__
enum cmi_api_result {
CMI_API_FAILED = 1,
CMI_API_BUSY,
CMI_API_NO_MEMORY,
CMI_API_NOT_READY,
};
enum cmi_api_event {
CMI_API_MSG = 1,
CMI_API_OFFLINE,
CMI_API_ONLINE,
CMI_API_DEINITIALIZED,
};
struct cmi_api_notification {
enum cmi_api_event event;
enum cmi_api_result result;
void *message;
};
void *cmi_register(
void notification_callback
(const struct cmi_api_notification *parameter),
u32 service);
enum cmi_api_result cmi_deregister(void *reg_handle);
enum cmi_api_result cmi_send_msg(void *message);
#endif /*__CMI_API__*/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,235 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
*/
#ifndef WCD_CPE_CORE_H
#define WCD_CPE_CORE_H
#include <soc/qcom/ramdump.h>
#include <linux/dma-mapping.h>
#include "wcd_cpe_services.h"
#define WCD_CPE_LAB_MAX_LATENCY 250
#define WCD_CPE_MAD_SLIM_CHANNEL 140
/* Indicates CPE block is ready for image re-download */
#define WCD_CPE_BLK_READY (1 << 0)
/* Indicates the underlying bus is ready */
#define WCD_CPE_BUS_READY (1 << 1)
/*
* only when the underlying bus and CPE block both are ready,
* the state will be ready to download
*/
#define WCD_CPE_READY_TO_DLOAD \
(WCD_CPE_BLK_READY | WCD_CPE_BUS_READY)
#define WCD_CPE_LOAD_IMEM (1 << 0)
#define WCD_CPE_LOAD_DATA (1 << 1)
#define WCD_CPE_LOAD_ALL \
(WCD_CPE_LOAD_IMEM | WCD_CPE_LOAD_DATA)
#define WCD_CPE_IMAGE_FNAME_MAX 64
#define WCD_CPE_AFE_OUT_PORT_2 2
#define WCD_CPE_AFE_OUT_PORT_4 4
enum {
WCD_CPE_LSM_CAL_AFE = 0,
WCD_CPE_LSM_CAL_LSM,
WCD_CPE_LSM_CAL_TOPOLOGY_ID,
WCD_CPE_LSM_CAL_MAX,
};
enum cpe_err_irq_cntl_type {
CPE_ERR_IRQ_MASK = 0,
CPE_ERR_IRQ_UNMASK,
CPE_ERR_IRQ_CLEAR,
CPE_ERR_IRQ_STATUS,
};
struct wcd_cpe_cdc_cb {
/* codec provided callback to enable RCO */
int (*cdc_clk_en)(struct snd_soc_codec *, bool);
/* callback for FLL setup for codec */
int (*cpe_clk_en)(struct snd_soc_codec *, bool);
int (*cdc_ext_clk)(struct snd_soc_codec *codec, int enable, bool dapm);
int (*lab_cdc_ch_ctl)(struct snd_soc_codec *codec, u8 event);
int (*get_afe_out_port_id)(struct snd_soc_codec *codec, u16 *port_id);
int (*bus_vote_bw)(struct snd_soc_codec *codec,
bool vote);
/* Callback to control the cpe error interrupt mask/status/clear */
int (*cpe_err_irq_control)(struct snd_soc_codec *codec,
enum cpe_err_irq_cntl_type cntl_type,
u8 *status);
};
enum wcd_cpe_ssr_state_event {
/* Indicates CPE is initialized */
WCD_CPE_INITIALIZED = 0,
/* Indicates that IMEM is downloaded to CPE */
WCD_CPE_IMEM_DOWNLOADED,
/* Indicates CPE is enabled */
WCD_CPE_ENABLED,
/* Indicates that CPE is currently active */
WCD_CPE_ACTIVE,
/* Event from underlying bus notifying bus is down */
WCD_CPE_BUS_DOWN_EVENT,
/* Event from CPE block, notifying CPE is down */
WCD_CPE_SSR_EVENT,
/* Event from underlying bus notifying bus is up */
WCD_CPE_BUS_UP_EVENT,
};
struct wcd_cpe_ssr_entry {
int offline;
u32 offline_change;
wait_queue_head_t offline_poll_wait;
struct snd_info_entry *entry;
};
struct wcd_cpe_irq_info {
int cpe_engine_irq;
int cpe_err_irq;
u8 cpe_fatal_irqs;
};
struct wcd_cpe_hw_info {
u32 dram_offset;
size_t dram_size;
u32 iram_offset;
size_t iram_size;
};
struct wcd_cpe_core {
/* handle to cpe services */
void *cpe_handle;
/* registration handle to cpe services */
void *cpe_reg_handle;
/* cmi registration handle for afe service */
void *cmi_afe_handle;
/* handle to codec */
struct snd_soc_codec *codec;
/* codec device */
struct device *dev;
/* firmware image file name */
char fname[WCD_CPE_IMAGE_FNAME_MAX];
/* firmware image file name from sysfs */
char dyn_fname[WCD_CPE_IMAGE_FNAME_MAX];
/* codec information needed by cpe services */
struct cpe_svc_codec_info_v1 cdc_info;
/* work to perform image download */
struct work_struct load_fw_work;
/* flag to indicate mode in which cpe needs to be booted */
int cpe_debug_mode;
/* callbacks for codec specific implementation */
const struct wcd_cpe_cdc_cb *cpe_cdc_cb;
/* work to handle CPE SSR*/
struct work_struct ssr_work;
/* PM handle for suspend mode during SSR */
struct pm_qos_request pm_qos_req;
/* completion event indicating CPE OFFLINE */
struct completion offline_compl;
/* entry into snd card procfs indicating cpe status */
struct wcd_cpe_ssr_entry ssr_entry;
/*
* completion event to signal CPE is
* ready for image re-download
*/
struct completion ready_compl;
/* maintains the status for cpe ssr */
u8 ready_status;
/* Indicate SSR type */
enum wcd_cpe_ssr_state_event ssr_type;
/* 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];
/* completion event to signal CPE is online */
struct completion online_compl;
/* reference counter for cpe usage */
u8 cpe_users;
/* Ramdump support */
void *cpe_ramdump_dev;
struct ramdump_segment cpe_ramdump_seg;
dma_addr_t cpe_dump_addr;
void *cpe_dump_v_addr;
/* SFR support */
u32 sfr_buf_addr;
size_t sfr_buf_size;
/* IRQ information for CPE interrupts */
struct wcd_cpe_irq_info irq_info;
/* Kobject for sysfs entry */
struct kobject cpe_kobj;
/* Reference count for cpe clk*/
int cpe_clk_ref;
/* codec based hardware info */
struct wcd_cpe_hw_info hw_info;
};
struct wcd_cpe_params {
struct snd_soc_codec *codec;
struct wcd_cpe_core * (*get_cpe_core)(
struct snd_soc_codec *);
const struct wcd_cpe_cdc_cb *cdc_cb;
int dbg_mode;
u16 cdc_major_ver;
u16 cdc_minor_ver;
u32 cdc_id;
struct wcd_cpe_irq_info cdc_irq_info;
struct cpe_svc_init_param *cpe_svc_params;
};
#if IS_ENABLED(CONFIG_SND_SOC_WCD_CPE)
int wcd_cpe_ssr_event(void *core_handle,
enum wcd_cpe_ssr_state_event event);
struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,
struct snd_soc_codec *codec, struct wcd_cpe_params *params);
#else /* CONFIG_SND_SOC_WCD_CPE */
static inline int wcd_cpe_ssr_event(void *core_handle,
enum wcd_cpe_ssr_state_event event)
{
return 0;
}
static inline struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,
struct snd_soc_codec *codec,
struct wcd_cpe_params *params)
{
return NULL;
}
#endif /* CONFIG_SND_SOC_WCD_CPE */
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*/
#ifndef __CPE_SERVICES__
#define __CPE_SERVICES__
#define CPE_IRQ_OUTBOX_IRQ 0x01
#define CPE_IRQ_MEM_ACCESS_ERROR 0x02
#define CPE_IRQ_WDOG_BITE 0x04
#define CPE_IRQ_BUFFER_OVERFLOW 0x08
#define CPE_IRQ_LAB_OVFUNF 0x10
#define CPE_IRQ_FLL_LOCK_LOST 0x20
#define CPE_IRQ_RCO_WDOG_INT 0x40
#define EFAILED (MAX_ERRNO - 1)
#define ENOTREADY (MAX_ERRNO - 2)
#define MAX_SUPPORTED_CLKFREQ 8
#define CPE_SVC_INIT_PARAM_V1 1
enum cpe_svc_result {
CPE_SVC_SUCCESS = 0,
CPE_SVC_FAILED = -EFAILED,
CPE_SVC_NO_MEMORY = -ENOMEM,
CPE_SVC_INVALID_HANDLE = -EINVAL,
CPE_SVC_NOT_READY = -ENOTREADY,
CPE_SVC_SHUTTING_DOWN = -ESHUTDOWN,
CPE_SVC_BUSY = -EBUSY,
};
enum cpe_svc_event {
CPE_SVC_CMI_MSG = 0x01,
CPE_SVC_OFFLINE = 0x02,
CPE_SVC_ONLINE = 0x04,
CPE_SVC_BOOT_FAILED = 0x08,
CPE_SVC_READ_COMPLETE = 0x10,
CPE_SVC_READ_ERROR = 0x20,
CPE_SVC_BOOT = 0x40,
CPE_SVC_CMI_CLIENTS_DEREG = 0x100,
CPE_SVC_EVENT_ANCHOR = 0x7FFF
};
enum cpe_svc_module {
CPE_SVC_LISTEN_PROC = 1,
CPE_SVC_MODULE_ANCHOR = 0x7F
};
enum cpe_svc_route_dest {
CPE_SVC_EXTERNAL = 1,
CPE_SVC_INTERNAL = 2,
CPE_SVC_ROUTE_ANCHOR = 0x7F
};
enum cpe_svc_mem_type {
CPE_SVC_DATA_MEM = 1,
CPE_SVC_INSTRUCTION_MEM = 2,
CPE_SVC_IPC_MEM = 3,
CPE_SVC_MEM_TYPE_ANCHOR = 0x7F
};
enum cpe_svc_codec_id {
CPE_SVC_CODEC_TOMTOM = 5,
CPE_SVC_CODEC_WCD9335 = 7,
CPE_SVC_CODEC_WCD9326 = 8,
CPE_SVC_CODEC_ID_ANCHOR = 0x7ffffff
};
enum cpe_svc_codec_version {
CPE_SVC_CODEC_V1P0 = 1,
CPE_SVC_CODEC_VERSION_ANCHOR = 0x7fffffff
};
struct cpe_svc_codec_info_v1 {
u16 major_version;/*must be 1*/
u16 minor_version;/*must be 0*/
u32 id;
u32 version;
/*Add 1.1 version fields after this line*/
};
struct cpe_svc_notification {
enum cpe_svc_event event;
enum cpe_svc_result result;
void *payload;
void *private_data;
};
struct cpe_svc_msg_payload {
u8 *cmi_msg;
};
struct cpe_svc_read_complete {
u8 *buffer;
size_t size;
};
struct cpe_svc_boot_event {
u32 debug_address;
size_t debug_buffer_size;
u32 status;
};
struct cpe_svc_mem_segment {
enum cpe_svc_mem_type type;
u32 cpe_addr;
size_t size;
u8 *data;
};
struct cpe_svc_hw_cfg {
size_t DRAM_size;
u32 DRAM_offset;
size_t IRAM_size;
u32 IRAM_offset;
u8 inbox_size;
u8 outbox_size;
};
struct cpe_svc_cfg_clk_plan {
u32 current_clk_feq;
u32 num_clk_freqs;
u32 clk_freqs[MAX_SUPPORTED_CLKFREQ];
};
struct cpe_svc_init_param {
void *context;
u32 version;
void (*query_freq_plans_cb)(void *cdc_priv,
struct cpe_svc_cfg_clk_plan *clk_freq);
void (*change_freq_plan_cb)(void *cdc_priv,
u32 clk_freq);
};
void *cpe_svc_initialize(
void irq_control_callback(u32 enable),
const void *codec_info, void *context);
enum cpe_svc_result cpe_svc_deinitialize(void *cpe_handle);
void *cpe_svc_register(void *cpe_handle,
void (*notification_callback)(
const struct cpe_svc_notification *parameter),
u32 mask, const char *name);
enum cpe_svc_result cpe_svc_deregister(void *cpe_handle, void *reg_handle);
enum cpe_svc_result cpe_svc_download_segment(void *cpe_handle,
const struct cpe_svc_mem_segment *segment);
enum cpe_svc_result cpe_svc_boot(void *cpe_handle, int debug_mode);
enum cpe_svc_result cpe_svc_shutdown(void *cpe_handle);
enum cpe_svc_result cpe_svc_reset(void *cpe_handle);
enum cpe_svc_result cpe_svc_process_irq(void *cpe_handle, u32 cpe_irq);
enum cpe_svc_result
cpe_svc_route_notification(void *cpe_handle, enum cpe_svc_module module,
enum cpe_svc_route_dest dest);
enum cpe_svc_result cpe_svc_ramdump(void *cpe_handle,
struct cpe_svc_mem_segment *buffer);
enum cpe_svc_result cpe_svc_set_debug_mode(void *cpe_handle, u32 mode);
const struct cpe_svc_hw_cfg *cpe_svc_get_hw_cfg(void *cpe_handle);
enum cpe_svc_result cpe_svc_toggle_lab(void *cpe_handle, bool enable);
enum cpe_svc_result cpe_svc_ftm_test(void *cpe_handle, u32 *status);
#endif /*__CPE_SERVICES__*/

View File

@@ -0,0 +1,215 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015, 2017-2018 The Linux Foundation. All rights reserved.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/bitops.h>
#include <sound/hwdep.h>
#include <sound/msmcal-hwdep.h>
#include <sound/soc.h>
#include <asoc/wcdcal-hwdep.h>
const int cal_size_info[WCD9XXX_MAX_CAL] = {
[WCD9XXX_ANC_CAL] = 16384,
[WCD9XXX_MBHC_CAL] = 4096,
[WCD9XXX_MAD_CAL] = 4096,
[WCD9XXX_VBAT_CAL] = 72,
};
const char *cal_name_info[WCD9XXX_MAX_CAL] = {
[WCD9XXX_ANC_CAL] = "anc",
[WCD9XXX_MBHC_CAL] = "mbhc",
[WCD9XXX_MAD_CAL] = "mad",
[WCD9XXX_VBAT_CAL] = "vbat",
};
struct firmware_cal *wcdcal_get_fw_cal(struct fw_info *fw_data,
enum wcd_cal_type type)
{
if (!fw_data) {
pr_err("%s: fw_data is NULL\n", __func__);
return NULL;
}
if (type >= WCD9XXX_MAX_CAL ||
type < WCD9XXX_MIN_CAL) {
pr_err("%s: wrong cal type sent %d\n", __func__, type);
return NULL;
}
mutex_lock(&fw_data->lock);
if (!test_bit(WCDCAL_RECIEVED,
&fw_data->wcdcal_state[type])) {
pr_err("%s: cal not sent by userspace %d\n",
__func__, type);
mutex_unlock(&fw_data->lock);
return NULL;
}
mutex_unlock(&fw_data->lock);
return fw_data->fw[type];
}
EXPORT_SYMBOL(wcdcal_get_fw_cal);
static int wcdcal_hwdep_ioctl_shared(struct snd_hwdep *hw,
struct wcdcal_ioctl_buffer fw_user)
{
struct fw_info *fw_data = hw->private_data;
struct firmware_cal **fw = fw_data->fw;
void *data;
if (!test_bit(fw_user.cal_type, fw_data->cal_bit)) {
pr_err("%s: codec didn't set this %d!!\n",
__func__, fw_user.cal_type);
return -EFAULT;
}
if (fw_user.cal_type >= WCD9XXX_MAX_CAL ||
fw_user.cal_type < WCD9XXX_MIN_CAL) {
pr_err("%s: wrong cal type sent %d\n",
__func__, fw_user.cal_type);
return -EFAULT;
}
if (fw_user.size > cal_size_info[fw_user.cal_type] ||
fw_user.size <= 0) {
pr_err("%s: incorrect firmware size %d for %s\n",
__func__, fw_user.size,
cal_name_info[fw_user.cal_type]);
return -EFAULT;
}
data = fw[fw_user.cal_type]->data;
if (copy_from_user(data, fw_user.buffer, fw_user.size))
return -EFAULT;
fw[fw_user.cal_type]->size = fw_user.size;
mutex_lock(&fw_data->lock);
set_bit(WCDCAL_RECIEVED, &fw_data->wcdcal_state[fw_user.cal_type]);
mutex_unlock(&fw_data->lock);
return 0;
}
#ifdef CONFIG_COMPAT
struct wcdcal_ioctl_buffer32 {
u32 size;
compat_uptr_t buffer;
enum wcd_cal_type cal_type;
};
enum {
SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32 =
_IOW('U', 0x1, struct wcdcal_ioctl_buffer32),
};
static int wcdcal_hwdep_ioctl_compat(struct snd_hwdep *hw, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct wcdcal_ioctl_buffer __user *argp = (void __user *)arg;
struct wcdcal_ioctl_buffer32 fw_user32;
struct wcdcal_ioctl_buffer fw_user_compat;
if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE32) {
pr_err("%s: wrong ioctl command sent %u!\n", __func__, cmd);
return -ENOIOCTLCMD;
}
if (copy_from_user(&fw_user32, argp, sizeof(fw_user32))) {
pr_err("%s: failed to copy\n", __func__);
return -EFAULT;
}
fw_user_compat.size = fw_user32.size;
fw_user_compat.buffer = compat_ptr(fw_user32.buffer);
fw_user_compat.cal_type = fw_user32.cal_type;
return wcdcal_hwdep_ioctl_shared(hw, fw_user_compat);
}
#else
#define wcdcal_hwdep_ioctl_compat NULL
#endif
static int wcdcal_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct wcdcal_ioctl_buffer __user *argp = (void __user *)arg;
struct wcdcal_ioctl_buffer fw_user;
if (cmd != SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE) {
pr_err("%s: wrong ioctl command sent %d!\n", __func__, cmd);
return -ENOIOCTLCMD;
}
if (copy_from_user(&fw_user, argp, sizeof(fw_user))) {
pr_err("%s: failed to copy\n", __func__);
return -EFAULT;
}
return wcdcal_hwdep_ioctl_shared(hw, fw_user);
}
static int wcdcal_hwdep_release(struct snd_hwdep *hw, struct file *file)
{
struct fw_info *fw_data = hw->private_data;
mutex_lock(&fw_data->lock);
/* clear all the calibrations */
memset(fw_data->wcdcal_state, 0,
sizeof(fw_data->wcdcal_state));
mutex_unlock(&fw_data->lock);
return 0;
}
int wcd_cal_create_hwdep(void *data, int node, struct snd_soc_codec *codec)
{
char hwname[40];
struct snd_hwdep *hwdep;
struct firmware_cal **fw;
struct fw_info *fw_data = data;
int err, cal_bit;
if (!fw_data || !codec) {
pr_err("%s: wrong arguments passed\n", __func__);
return -EINVAL;
}
fw = fw_data->fw;
snprintf(hwname, strlen("Codec %s"), "Codec %s",
codec->component.name);
err = snd_hwdep_new(codec->component.card->snd_card,
hwname, node, &hwdep);
if (err < 0) {
dev_err(codec->dev, "%s: new hwdep failed %d\n",
__func__, err);
return err;
}
snprintf(hwdep->name, strlen("Codec %s"), "Codec %s",
codec->component.name);
hwdep->iface = SNDRV_HWDEP_IFACE_AUDIO_CODEC;
hwdep->private_data = fw_data;
hwdep->ops.ioctl_compat = wcdcal_hwdep_ioctl_compat;
hwdep->ops.ioctl = wcdcal_hwdep_ioctl;
hwdep->ops.release = wcdcal_hwdep_release;
mutex_init(&fw_data->lock);
for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
set_bit(WCDCAL_UNINITIALISED,
&fw_data->wcdcal_state[cal_bit]);
fw[cal_bit] = kzalloc(sizeof *(fw[cal_bit]), GFP_KERNEL);
if (!fw[cal_bit])
goto end;
}
for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
fw[cal_bit]->data = kzalloc(cal_size_info[cal_bit],
GFP_KERNEL);
if (!fw[cal_bit]->data)
goto exit;
set_bit(WCDCAL_INITIALISED,
&fw_data->wcdcal_state[cal_bit]);
}
return 0;
exit:
for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
kfree(fw[cal_bit]->data);
fw[cal_bit]->data = NULL;
}
end:
for_each_set_bit(cal_bit, fw_data->cal_bit, WCD9XXX_MAX_CAL) {
kfree(fw[cal_bit]);
fw[cal_bit] = NULL;
}
return -ENOMEM;
}
EXPORT_SYMBOL(wcd_cal_create_hwdep);

View File

@@ -0,0 +1,170 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/
#ifndef WSA881X_REGISTERS_H
#define WSA881X_REGISTERS_H
#define WSA881X_DIGITAL_BASE 0x3000
#define WSA881X_ANALOG_BASE 0x3100
/* Digital register address space */
#define WSA881X_CHIP_ID0 (WSA881X_DIGITAL_BASE+0x0000)
#define WSA881X_CHIP_ID1 (WSA881X_DIGITAL_BASE+0x0001)
#define WSA881X_CHIP_ID2 (WSA881X_DIGITAL_BASE+0x0002)
#define WSA881X_CHIP_ID3 (WSA881X_DIGITAL_BASE+0x0003)
#define WSA881X_BUS_ID (WSA881X_DIGITAL_BASE+0x0004)
#define WSA881X_CDC_RST_CTL (WSA881X_DIGITAL_BASE+0x0005)
#define WSA881X_CDC_TOP_CLK_CTL (WSA881X_DIGITAL_BASE+0x0006)
#define WSA881X_CDC_ANA_CLK_CTL (WSA881X_DIGITAL_BASE+0x0007)
#define WSA881X_CDC_DIG_CLK_CTL (WSA881X_DIGITAL_BASE+0x0008)
#define WSA881X_CLOCK_CONFIG (WSA881X_DIGITAL_BASE+0x0009)
#define WSA881X_ANA_CTL (WSA881X_DIGITAL_BASE+0x000A)
#define WSA881X_SWR_RESET_EN (WSA881X_DIGITAL_BASE+0x000B)
#define WSA881X_RESET_CTL (WSA881X_DIGITAL_BASE+0x000C)
#define WSA881X_TADC_VALUE_CTL (WSA881X_DIGITAL_BASE+0x000F)
#define WSA881X_TEMP_DETECT_CTL (WSA881X_DIGITAL_BASE+0x0010)
#define WSA881X_TEMP_MSB (WSA881X_DIGITAL_BASE+0x0011)
#define WSA881X_TEMP_LSB (WSA881X_DIGITAL_BASE+0x0012)
#define WSA881X_TEMP_CONFIG0 (WSA881X_DIGITAL_BASE+0x0013)
#define WSA881X_TEMP_CONFIG1 (WSA881X_DIGITAL_BASE+0x0014)
#define WSA881X_CDC_CLIP_CTL (WSA881X_DIGITAL_BASE+0x0015)
#define WSA881X_SDM_PDM9_LSB (WSA881X_DIGITAL_BASE+0x0016)
#define WSA881X_SDM_PDM9_MSB (WSA881X_DIGITAL_BASE+0x0017)
#define WSA881X_CDC_RX_CTL (WSA881X_DIGITAL_BASE+0x0018)
#define WSA881X_DEM_BYPASS_DATA0 (WSA881X_DIGITAL_BASE+0x0019)
#define WSA881X_DEM_BYPASS_DATA1 (WSA881X_DIGITAL_BASE+0x001A)
#define WSA881X_DEM_BYPASS_DATA2 (WSA881X_DIGITAL_BASE+0x001B)
#define WSA881X_DEM_BYPASS_DATA3 (WSA881X_DIGITAL_BASE+0x001C)
#define WSA881X_OTP_CTRL0 (WSA881X_DIGITAL_BASE+0x001D)
#define WSA881X_OTP_CTRL1 (WSA881X_DIGITAL_BASE+0x001E)
#define WSA881X_HDRIVE_CTL_GROUP1 (WSA881X_DIGITAL_BASE+0x001F)
#define WSA881X_INTR_MODE (WSA881X_DIGITAL_BASE+0x0020)
#define WSA881X_INTR_MASK (WSA881X_DIGITAL_BASE+0x0021)
#define WSA881X_INTR_STATUS (WSA881X_DIGITAL_BASE+0x0022)
#define WSA881X_INTR_CLEAR (WSA881X_DIGITAL_BASE+0x0023)
#define WSA881X_INTR_LEVEL (WSA881X_DIGITAL_BASE+0x0024)
#define WSA881X_INTR_SET (WSA881X_DIGITAL_BASE+0x0025)
#define WSA881X_INTR_TEST (WSA881X_DIGITAL_BASE+0x0026)
#define WSA881X_PDM_TEST_MODE (WSA881X_DIGITAL_BASE+0x0030)
#define WSA881X_ATE_TEST_MODE (WSA881X_DIGITAL_BASE+0x0031)
#define WSA881X_PIN_CTL_MODE (WSA881X_DIGITAL_BASE+0x0032)
#define WSA881X_PIN_CTL_OE (WSA881X_DIGITAL_BASE+0x0033)
#define WSA881X_PIN_WDATA_IOPAD (WSA881X_DIGITAL_BASE+0x0034)
#define WSA881X_PIN_STATUS (WSA881X_DIGITAL_BASE+0x0035)
#define WSA881X_DIG_DEBUG_MODE (WSA881X_DIGITAL_BASE+0x0037)
#define WSA881X_DIG_DEBUG_SEL (WSA881X_DIGITAL_BASE+0x0038)
#define WSA881X_DIG_DEBUG_EN (WSA881X_DIGITAL_BASE+0x0039)
#define WSA881X_SWR_HM_TEST1 (WSA881X_DIGITAL_BASE+0x003B)
#define WSA881X_SWR_HM_TEST2 (WSA881X_DIGITAL_BASE+0x003C)
#define WSA881X_TEMP_DETECT_DBG_CTL (WSA881X_DIGITAL_BASE+0x003D)
#define WSA881X_TEMP_DEBUG_MSB (WSA881X_DIGITAL_BASE+0x003E)
#define WSA881X_TEMP_DEBUG_LSB (WSA881X_DIGITAL_BASE+0x003F)
#define WSA881X_SAMPLE_EDGE_SEL (WSA881X_DIGITAL_BASE+0x0044)
#define WSA881X_IOPAD_CTL (WSA881X_DIGITAL_BASE+0x0045)
#define WSA881X_SPARE_0 (WSA881X_DIGITAL_BASE+0x0050)
#define WSA881X_SPARE_1 (WSA881X_DIGITAL_BASE+0x0051)
#define WSA881X_SPARE_2 (WSA881X_DIGITAL_BASE+0x0052)
#define WSA881X_OTP_REG_0 (WSA881X_DIGITAL_BASE+0x0080)
#define WSA881X_OTP_REG_1 (WSA881X_DIGITAL_BASE+0x0081)
#define WSA881X_OTP_REG_2 (WSA881X_DIGITAL_BASE+0x0082)
#define WSA881X_OTP_REG_3 (WSA881X_DIGITAL_BASE+0x0083)
#define WSA881X_OTP_REG_4 (WSA881X_DIGITAL_BASE+0x0084)
#define WSA881X_OTP_REG_5 (WSA881X_DIGITAL_BASE+0x0085)
#define WSA881X_OTP_REG_6 (WSA881X_DIGITAL_BASE+0x0086)
#define WSA881X_OTP_REG_7 (WSA881X_DIGITAL_BASE+0x0087)
#define WSA881X_OTP_REG_8 (WSA881X_DIGITAL_BASE+0x0088)
#define WSA881X_OTP_REG_9 (WSA881X_DIGITAL_BASE+0x0089)
#define WSA881X_OTP_REG_10 (WSA881X_DIGITAL_BASE+0x008A)
#define WSA881X_OTP_REG_11 (WSA881X_DIGITAL_BASE+0x008B)
#define WSA881X_OTP_REG_12 (WSA881X_DIGITAL_BASE+0x008C)
#define WSA881X_OTP_REG_13 (WSA881X_DIGITAL_BASE+0x008D)
#define WSA881X_OTP_REG_14 (WSA881X_DIGITAL_BASE+0x008E)
#define WSA881X_OTP_REG_15 (WSA881X_DIGITAL_BASE+0x008F)
#define WSA881X_OTP_REG_16 (WSA881X_DIGITAL_BASE+0x0090)
#define WSA881X_OTP_REG_17 (WSA881X_DIGITAL_BASE+0x0091)
#define WSA881X_OTP_REG_18 (WSA881X_DIGITAL_BASE+0x0092)
#define WSA881X_OTP_REG_19 (WSA881X_DIGITAL_BASE+0x0093)
#define WSA881X_OTP_REG_20 (WSA881X_DIGITAL_BASE+0x0094)
#define WSA881X_OTP_REG_21 (WSA881X_DIGITAL_BASE+0x0095)
#define WSA881X_OTP_REG_22 (WSA881X_DIGITAL_BASE+0x0096)
#define WSA881X_OTP_REG_23 (WSA881X_DIGITAL_BASE+0x0097)
#define WSA881X_OTP_REG_24 (WSA881X_DIGITAL_BASE+0x0098)
#define WSA881X_OTP_REG_25 (WSA881X_DIGITAL_BASE+0x0099)
#define WSA881X_OTP_REG_26 (WSA881X_DIGITAL_BASE+0x009A)
#define WSA881X_OTP_REG_27 (WSA881X_DIGITAL_BASE+0x009B)
#define WSA881X_OTP_REG_28 (WSA881X_DIGITAL_BASE+0x009C)
#define WSA881X_OTP_REG_29 (WSA881X_DIGITAL_BASE+0x009D)
#define WSA881X_OTP_REG_30 (WSA881X_DIGITAL_BASE+0x009E)
#define WSA881X_OTP_REG_31 (WSA881X_DIGITAL_BASE+0x009F)
#define WSA881X_OTP_REG_63 (WSA881X_DIGITAL_BASE+0x00BF)
/* Analog Register address space */
#define WSA881X_BIAS_REF_CTRL (WSA881X_ANALOG_BASE+0x0000)
#define WSA881X_BIAS_TEST (WSA881X_ANALOG_BASE+0x0001)
#define WSA881X_BIAS_BIAS (WSA881X_ANALOG_BASE+0x0002)
#define WSA881X_TEMP_OP (WSA881X_ANALOG_BASE+0x0003)
#define WSA881X_TEMP_IREF_CTRL (WSA881X_ANALOG_BASE+0x0004)
#define WSA881X_TEMP_ISENS_CTRL (WSA881X_ANALOG_BASE+0x0005)
#define WSA881X_TEMP_CLK_CTRL (WSA881X_ANALOG_BASE+0x0006)
#define WSA881X_TEMP_TEST (WSA881X_ANALOG_BASE+0x0007)
#define WSA881X_TEMP_BIAS (WSA881X_ANALOG_BASE+0x0008)
#define WSA881X_TEMP_ADC_CTRL (WSA881X_ANALOG_BASE+0x0009)
#define WSA881X_TEMP_DOUT_MSB (WSA881X_ANALOG_BASE+0x000A)
#define WSA881X_TEMP_DOUT_LSB (WSA881X_ANALOG_BASE+0x000B)
#define WSA881X_ADC_EN_MODU_V (WSA881X_ANALOG_BASE+0x0010)
#define WSA881X_ADC_EN_MODU_I (WSA881X_ANALOG_BASE+0x0011)
#define WSA881X_ADC_EN_DET_TEST_V (WSA881X_ANALOG_BASE+0x0012)
#define WSA881X_ADC_EN_DET_TEST_I (WSA881X_ANALOG_BASE+0x0013)
#define WSA881X_ADC_SEL_IBIAS (WSA881X_ANALOG_BASE+0x0014)
#define WSA881X_ADC_EN_SEL_IBAIS (WSA881X_ANALOG_BASE+0x0015)
#define WSA881X_SPKR_DRV_EN (WSA881X_ANALOG_BASE+0x001A)
#define WSA881X_SPKR_DRV_GAIN (WSA881X_ANALOG_BASE+0x001B)
#define WSA881X_SPKR_DAC_CTL (WSA881X_ANALOG_BASE+0x001C)
#define WSA881X_SPKR_DRV_DBG (WSA881X_ANALOG_BASE+0x001D)
#define WSA881X_SPKR_PWRSTG_DBG (WSA881X_ANALOG_BASE+0x001E)
#define WSA881X_SPKR_OCP_CTL (WSA881X_ANALOG_BASE+0x001F)
#define WSA881X_SPKR_CLIP_CTL (WSA881X_ANALOG_BASE+0x0020)
#define WSA881X_SPKR_BBM_CTL (WSA881X_ANALOG_BASE+0x0021)
#define WSA881X_SPKR_MISC_CTL1 (WSA881X_ANALOG_BASE+0x0022)
#define WSA881X_SPKR_MISC_CTL2 (WSA881X_ANALOG_BASE+0x0023)
#define WSA881X_SPKR_BIAS_INT (WSA881X_ANALOG_BASE+0x0024)
#define WSA881X_SPKR_PA_INT (WSA881X_ANALOG_BASE+0x0025)
#define WSA881X_SPKR_BIAS_CAL (WSA881X_ANALOG_BASE+0x0026)
#define WSA881X_SPKR_BIAS_PSRR (WSA881X_ANALOG_BASE+0x0027)
#define WSA881X_SPKR_STATUS1 (WSA881X_ANALOG_BASE+0x0028)
#define WSA881X_SPKR_STATUS2 (WSA881X_ANALOG_BASE+0x0029)
#define WSA881X_BOOST_EN_CTL (WSA881X_ANALOG_BASE+0x002A)
#define WSA881X_BOOST_CURRENT_LIMIT (WSA881X_ANALOG_BASE+0x002B)
#define WSA881X_BOOST_PS_CTL (WSA881X_ANALOG_BASE+0x002C)
#define WSA881X_BOOST_PRESET_OUT1 (WSA881X_ANALOG_BASE+0x002D)
#define WSA881X_BOOST_PRESET_OUT2 (WSA881X_ANALOG_BASE+0x002E)
#define WSA881X_BOOST_FORCE_OUT (WSA881X_ANALOG_BASE+0x002F)
#define WSA881X_BOOST_LDO_PROG (WSA881X_ANALOG_BASE+0x0030)
#define WSA881X_BOOST_SLOPE_COMP_ISENSE_FB (WSA881X_ANALOG_BASE+0x0031)
#define WSA881X_BOOST_RON_CTL (WSA881X_ANALOG_BASE+0x0032)
#define WSA881X_BOOST_LOOP_STABILITY (WSA881X_ANALOG_BASE+0x0033)
#define WSA881X_BOOST_ZX_CTL (WSA881X_ANALOG_BASE+0x0034)
#define WSA881X_BOOST_START_CTL (WSA881X_ANALOG_BASE+0x0035)
#define WSA881X_BOOST_MISC1_CTL (WSA881X_ANALOG_BASE+0x0036)
#define WSA881X_BOOST_MISC2_CTL (WSA881X_ANALOG_BASE+0x0037)
#define WSA881X_BOOST_MISC3_CTL (WSA881X_ANALOG_BASE+0x0038)
#define WSA881X_BOOST_ATEST_CTL (WSA881X_ANALOG_BASE+0x0039)
#define WSA881X_SPKR_PROT_FE_GAIN (WSA881X_ANALOG_BASE+0x003A)
#define WSA881X_SPKR_PROT_FE_CM_LDO_SET (WSA881X_ANALOG_BASE+0x003B)
#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x003C)
#define WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2 (WSA881X_ANALOG_BASE+0x003D)
#define WSA881X_SPKR_PROT_ATEST1 (WSA881X_ANALOG_BASE+0x003E)
#define WSA881X_SPKR_PROT_ATEST2 (WSA881X_ANALOG_BASE+0x003F)
#define WSA881X_SPKR_PROT_FE_VSENSE_VCM (WSA881X_ANALOG_BASE+0x0040)
#define WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1 (WSA881X_ANALOG_BASE+0x0041)
#define WSA881X_BONGO_RESRV_REG1 (WSA881X_ANALOG_BASE+0x0042)
#define WSA881X_BONGO_RESRV_REG2 (WSA881X_ANALOG_BASE+0x0043)
#define WSA881X_SPKR_PROT_SAR (WSA881X_ANALOG_BASE+0x0044)
#define WSA881X_SPKR_STATUS3 (WSA881X_ANALOG_BASE+0x0045)
#define WSA881X_NUM_REGISTERS (WSA881X_SPKR_STATUS3+1)
#define WSA881X_MAX_REGISTER (WSA881X_NUM_REGISTERS-1)
#define WSA881X_CACHE_SIZE WSA881X_NUM_REGISTERS
#endif /* WSA881X_REGISTERS_H */

View File

@@ -0,0 +1,258 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
#include <linux/device.h>
#include "wsa881x-registers.h"
#include "wsa881x.h"
/*
* Default register reset values that are common across different versions
* are defined here. If a register reset value is changed based on version
* then remove it from this structure and add it in version specific
* structures.
*/
static struct reg_default wsa881x_defaults[] = {
{WSA881X_CHIP_ID0, 0x00},
{WSA881X_CHIP_ID1, 0x00},
{WSA881X_CHIP_ID2, 0x00},
{WSA881X_CHIP_ID3, 0x02},
{WSA881X_BUS_ID, 0x00},
{WSA881X_CDC_RST_CTL, 0x00},
{WSA881X_CDC_TOP_CLK_CTL, 0x03},
{WSA881X_CDC_ANA_CLK_CTL, 0x00},
{WSA881X_CDC_DIG_CLK_CTL, 0x00},
{WSA881X_CLOCK_CONFIG, 0x00},
{WSA881X_ANA_CTL, 0x08},
{WSA881X_SWR_RESET_EN, 0x00},
{WSA881X_TEMP_DETECT_CTL, 0x01},
{WSA881X_TEMP_MSB, 0x00},
{WSA881X_TEMP_LSB, 0x00},
{WSA881X_TEMP_CONFIG0, 0x00},
{WSA881X_TEMP_CONFIG1, 0x00},
{WSA881X_CDC_CLIP_CTL, 0x03},
{WSA881X_SDM_PDM9_LSB, 0x00},
{WSA881X_SDM_PDM9_MSB, 0x00},
{WSA881X_CDC_RX_CTL, 0x7E},
{WSA881X_DEM_BYPASS_DATA0, 0x00},
{WSA881X_DEM_BYPASS_DATA1, 0x00},
{WSA881X_DEM_BYPASS_DATA2, 0x00},
{WSA881X_DEM_BYPASS_DATA3, 0x00},
{WSA881X_OTP_CTRL0, 0x00},
{WSA881X_OTP_CTRL1, 0x00},
{WSA881X_HDRIVE_CTL_GROUP1, 0x00},
{WSA881X_INTR_MODE, 0x00},
{WSA881X_INTR_STATUS, 0x00},
{WSA881X_INTR_CLEAR, 0x00},
{WSA881X_INTR_LEVEL, 0x00},
{WSA881X_INTR_SET, 0x00},
{WSA881X_INTR_TEST, 0x00},
{WSA881X_PDM_TEST_MODE, 0x00},
{WSA881X_ATE_TEST_MODE, 0x00},
{WSA881X_PIN_CTL_MODE, 0x00},
{WSA881X_PIN_CTL_OE, 0x00},
{WSA881X_PIN_WDATA_IOPAD, 0x00},
{WSA881X_PIN_STATUS, 0x00},
{WSA881X_DIG_DEBUG_MODE, 0x00},
{WSA881X_DIG_DEBUG_SEL, 0x00},
{WSA881X_DIG_DEBUG_EN, 0x00},
{WSA881X_SWR_HM_TEST1, 0x08},
{WSA881X_SWR_HM_TEST2, 0x00},
{WSA881X_TEMP_DETECT_DBG_CTL, 0x00},
{WSA881X_TEMP_DEBUG_MSB, 0x00},
{WSA881X_TEMP_DEBUG_LSB, 0x00},
{WSA881X_SAMPLE_EDGE_SEL, 0x0C},
{WSA881X_SPARE_0, 0x00},
{WSA881X_SPARE_1, 0x00},
{WSA881X_SPARE_2, 0x00},
{WSA881X_OTP_REG_0, 0x01},
{WSA881X_OTP_REG_1, 0xFF},
{WSA881X_OTP_REG_2, 0xC0},
{WSA881X_OTP_REG_3, 0xFF},
{WSA881X_OTP_REG_4, 0xC0},
{WSA881X_OTP_REG_5, 0xFF},
{WSA881X_OTP_REG_6, 0xFF},
{WSA881X_OTP_REG_7, 0xFF},
{WSA881X_OTP_REG_8, 0xFF},
{WSA881X_OTP_REG_9, 0xFF},
{WSA881X_OTP_REG_10, 0xFF},
{WSA881X_OTP_REG_11, 0xFF},
{WSA881X_OTP_REG_12, 0xFF},
{WSA881X_OTP_REG_13, 0xFF},
{WSA881X_OTP_REG_14, 0xFF},
{WSA881X_OTP_REG_15, 0xFF},
{WSA881X_OTP_REG_16, 0xFF},
{WSA881X_OTP_REG_17, 0xFF},
{WSA881X_OTP_REG_18, 0xFF},
{WSA881X_OTP_REG_19, 0xFF},
{WSA881X_OTP_REG_20, 0xFF},
{WSA881X_OTP_REG_21, 0xFF},
{WSA881X_OTP_REG_22, 0xFF},
{WSA881X_OTP_REG_23, 0xFF},
{WSA881X_OTP_REG_24, 0x03},
{WSA881X_OTP_REG_25, 0x01},
{WSA881X_OTP_REG_26, 0x03},
{WSA881X_OTP_REG_27, 0x11},
{WSA881X_OTP_REG_63, 0x40},
/* WSA881x Analog registers */
{WSA881X_BIAS_REF_CTRL, 0x6C},
{WSA881X_BIAS_TEST, 0x16},
{WSA881X_BIAS_BIAS, 0xF0},
{WSA881X_TEMP_OP, 0x00},
{WSA881X_TEMP_IREF_CTRL, 0x56},
{WSA881X_TEMP_ISENS_CTRL, 0x47},
{WSA881X_TEMP_CLK_CTRL, 0x87},
{WSA881X_TEMP_TEST, 0x00},
{WSA881X_TEMP_BIAS, 0x51},
{WSA881X_TEMP_DOUT_MSB, 0x00},
{WSA881X_TEMP_DOUT_LSB, 0x00},
{WSA881X_ADC_EN_MODU_V, 0x00},
{WSA881X_ADC_EN_MODU_I, 0x00},
{WSA881X_ADC_EN_DET_TEST_V, 0x00},
{WSA881X_ADC_EN_DET_TEST_I, 0x00},
{WSA881X_ADC_EN_SEL_IBAIS, 0x10},
{WSA881X_SPKR_DRV_EN, 0x74},
{WSA881X_SPKR_DRV_DBG, 0x15},
{WSA881X_SPKR_PWRSTG_DBG, 0x00},
{WSA881X_SPKR_OCP_CTL, 0xD4},
{WSA881X_SPKR_CLIP_CTL, 0x90},
{WSA881X_SPKR_PA_INT, 0x54},
{WSA881X_SPKR_BIAS_CAL, 0xAC},
{WSA881X_SPKR_STATUS1, 0x00},
{WSA881X_SPKR_STATUS2, 0x00},
{WSA881X_BOOST_EN_CTL, 0x18},
{WSA881X_BOOST_CURRENT_LIMIT, 0x7A},
{WSA881X_BOOST_PRESET_OUT2, 0x70},
{WSA881X_BOOST_FORCE_OUT, 0x0E},
{WSA881X_BOOST_LDO_PROG, 0x16},
{WSA881X_BOOST_SLOPE_COMP_ISENSE_FB, 0x71},
{WSA881X_BOOST_RON_CTL, 0x0F},
{WSA881X_BOOST_ZX_CTL, 0x34},
{WSA881X_BOOST_START_CTL, 0x23},
{WSA881X_BOOST_MISC1_CTL, 0x80},
{WSA881X_BOOST_MISC2_CTL, 0x00},
{WSA881X_BOOST_MISC3_CTL, 0x00},
{WSA881X_BOOST_ATEST_CTL, 0x00},
{WSA881X_SPKR_PROT_FE_GAIN, 0x46},
{WSA881X_SPKR_PROT_FE_CM_LDO_SET, 0x3B},
{WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1, 0x8D},
{WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2, 0x8D},
{WSA881X_SPKR_PROT_ATEST1, 0x01},
{WSA881X_SPKR_PROT_FE_VSENSE_VCM, 0x8D},
{WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1, 0x4D},
{WSA881X_SPKR_PROT_SAR, 0x00},
{WSA881X_SPKR_STATUS3, 0x00},
};
/* Default register reset values for WSA881x rev 2.0 */
static struct reg_sequence wsa881x_rev_2_0[] = {
{WSA881X_RESET_CTL, 0x00, 0x00},
{WSA881X_TADC_VALUE_CTL, 0x01, 0x00},
{WSA881X_INTR_MASK, 0x1B, 0x00},
{WSA881X_IOPAD_CTL, 0x00, 0x00},
{WSA881X_OTP_REG_28, 0x3F, 0x00},
{WSA881X_OTP_REG_29, 0x3F, 0x00},
{WSA881X_OTP_REG_30, 0x01, 0x00},
{WSA881X_OTP_REG_31, 0x01, 0x00},
{WSA881X_TEMP_ADC_CTRL, 0x03, 0x00},
{WSA881X_ADC_SEL_IBIAS, 0x45, 0x00},
{WSA881X_SPKR_DRV_GAIN, 0xC1, 0x00},
{WSA881X_SPKR_DAC_CTL, 0x42, 0x00},
{WSA881X_SPKR_BBM_CTL, 0x02, 0x00},
{WSA881X_SPKR_MISC_CTL1, 0x40, 0x00},
{WSA881X_SPKR_MISC_CTL2, 0x07, 0x00},
{WSA881X_SPKR_BIAS_INT, 0x5F, 0x00},
{WSA881X_SPKR_BIAS_PSRR, 0x44, 0x00},
{WSA881X_BOOST_PS_CTL, 0xA0, 0x00},
{WSA881X_BOOST_PRESET_OUT1, 0xB7, 0x00},
{WSA881X_BOOST_LOOP_STABILITY, 0x8D, 0x00},
{WSA881X_SPKR_PROT_ATEST2, 0x02, 0x00},
{WSA881X_BONGO_RESRV_REG1, 0x5E, 0x00},
{WSA881X_BONGO_RESRV_REG2, 0x07, 0x00},
};
/*
* wsa881x_regmap_defaults - update regmap default register values
* @regmap: pointer to regmap structure
* @version: wsa881x version id
*
* Update regmap default register values based on version id
*
*/
void wsa881x_regmap_defaults(struct regmap *regmap, u8 version)
{
u16 ret = 0;
if (!regmap) {
pr_debug("%s: regmap structure is NULL\n", __func__);
return;
}
regcache_cache_only(regmap, true);
ret = regmap_multi_reg_write(regmap, wsa881x_rev_2_0,
ARRAY_SIZE(wsa881x_rev_2_0));
regcache_cache_only(regmap, false);
if (ret)
pr_debug("%s: Failed to update regmap defaults ret= %d\n",
__func__, ret);
}
EXPORT_SYMBOL(wsa881x_regmap_defaults);
static bool wsa881x_readable_register(struct device *dev, unsigned int reg)
{
return wsa881x_reg_readable[reg];
}
static bool wsa881x_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case WSA881X_CHIP_ID0:
case WSA881X_CHIP_ID1:
case WSA881X_CHIP_ID2:
case WSA881X_CHIP_ID3:
case WSA881X_BUS_ID:
case WSA881X_TEMP_MSB:
case WSA881X_TEMP_LSB:
case WSA881X_SDM_PDM9_LSB:
case WSA881X_SDM_PDM9_MSB:
case WSA881X_OTP_CTRL1:
case WSA881X_INTR_STATUS:
case WSA881X_ATE_TEST_MODE:
case WSA881X_PIN_STATUS:
case WSA881X_SWR_HM_TEST2:
case WSA881X_SPKR_STATUS1:
case WSA881X_SPKR_STATUS2:
case WSA881X_SPKR_STATUS3:
case WSA881X_OTP_REG_0:
case WSA881X_OTP_REG_1:
case WSA881X_OTP_REG_2:
case WSA881X_OTP_REG_3:
case WSA881X_OTP_REG_4:
case WSA881X_OTP_REG_5:
case WSA881X_OTP_REG_31:
case WSA881X_TEMP_DOUT_MSB:
case WSA881X_TEMP_DOUT_LSB:
case WSA881X_TEMP_OP:
case WSA881X_SPKR_PROT_SAR:
return true;
default:
return false;
}
}
struct regmap_config wsa881x_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.reg_defaults = wsa881x_defaults,
.num_reg_defaults = ARRAY_SIZE(wsa881x_defaults),
.max_register = WSA881X_MAX_REGISTER,
.volatile_reg = wsa881x_volatile_register,
.readable_reg = wsa881x_readable_register,
.reg_format_endian = REGMAP_ENDIAN_NATIVE,
.val_format_endian = REGMAP_ENDIAN_NATIVE,
.can_multi_write = true,
};

View File

@@ -0,0 +1,163 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015, The Linux Foundation. All rights reserved.
*/
#include <linux/regmap.h>
#include <linux/device.h>
#include "wsa881x-registers.h"
const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE] = {
[WSA881X_CHIP_ID0] = 1,
[WSA881X_CHIP_ID1] = 1,
[WSA881X_CHIP_ID2] = 1,
[WSA881X_CHIP_ID3] = 1,
[WSA881X_BUS_ID] = 1,
[WSA881X_CDC_RST_CTL] = 1,
[WSA881X_CDC_TOP_CLK_CTL] = 1,
[WSA881X_CDC_ANA_CLK_CTL] = 1,
[WSA881X_CDC_DIG_CLK_CTL] = 1,
[WSA881X_CLOCK_CONFIG] = 1,
[WSA881X_ANA_CTL] = 1,
[WSA881X_SWR_RESET_EN] = 1,
[WSA881X_RESET_CTL] = 1,
[WSA881X_TADC_VALUE_CTL] = 1,
[WSA881X_TEMP_DETECT_CTL] = 1,
[WSA881X_TEMP_MSB] = 1,
[WSA881X_TEMP_LSB] = 1,
[WSA881X_TEMP_CONFIG0] = 1,
[WSA881X_TEMP_CONFIG1] = 1,
[WSA881X_CDC_CLIP_CTL] = 1,
[WSA881X_SDM_PDM9_LSB] = 1,
[WSA881X_SDM_PDM9_MSB] = 1,
[WSA881X_CDC_RX_CTL] = 1,
[WSA881X_DEM_BYPASS_DATA0] = 1,
[WSA881X_DEM_BYPASS_DATA1] = 1,
[WSA881X_DEM_BYPASS_DATA2] = 1,
[WSA881X_DEM_BYPASS_DATA3] = 1,
[WSA881X_OTP_CTRL0] = 1,
[WSA881X_OTP_CTRL1] = 1,
[WSA881X_HDRIVE_CTL_GROUP1] = 1,
[WSA881X_INTR_MODE] = 1,
[WSA881X_INTR_MASK] = 1,
[WSA881X_INTR_STATUS] = 1,
[WSA881X_INTR_CLEAR] = 1,
[WSA881X_INTR_LEVEL] = 1,
[WSA881X_INTR_SET] = 1,
[WSA881X_INTR_TEST] = 1,
[WSA881X_PDM_TEST_MODE] = 1,
[WSA881X_ATE_TEST_MODE] = 1,
[WSA881X_PIN_CTL_MODE] = 1,
[WSA881X_PIN_CTL_OE] = 1,
[WSA881X_PIN_WDATA_IOPAD] = 1,
[WSA881X_PIN_STATUS] = 1,
[WSA881X_DIG_DEBUG_MODE] = 1,
[WSA881X_DIG_DEBUG_SEL] = 1,
[WSA881X_DIG_DEBUG_EN] = 1,
[WSA881X_SWR_HM_TEST1] = 1,
[WSA881X_SWR_HM_TEST2] = 1,
[WSA881X_TEMP_DETECT_DBG_CTL] = 1,
[WSA881X_TEMP_DEBUG_MSB] = 1,
[WSA881X_TEMP_DEBUG_LSB] = 1,
[WSA881X_SAMPLE_EDGE_SEL] = 1,
[WSA881X_IOPAD_CTL] = 1,
[WSA881X_SPARE_0] = 1,
[WSA881X_SPARE_1] = 1,
[WSA881X_SPARE_2] = 1,
[WSA881X_OTP_REG_0] = 1,
[WSA881X_OTP_REG_1] = 1,
[WSA881X_OTP_REG_2] = 1,
[WSA881X_OTP_REG_3] = 1,
[WSA881X_OTP_REG_4] = 1,
[WSA881X_OTP_REG_5] = 1,
[WSA881X_OTP_REG_6] = 1,
[WSA881X_OTP_REG_7] = 1,
[WSA881X_OTP_REG_8] = 1,
[WSA881X_OTP_REG_9] = 1,
[WSA881X_OTP_REG_10] = 1,
[WSA881X_OTP_REG_11] = 1,
[WSA881X_OTP_REG_12] = 1,
[WSA881X_OTP_REG_13] = 1,
[WSA881X_OTP_REG_14] = 1,
[WSA881X_OTP_REG_15] = 1,
[WSA881X_OTP_REG_16] = 1,
[WSA881X_OTP_REG_17] = 1,
[WSA881X_OTP_REG_18] = 1,
[WSA881X_OTP_REG_19] = 1,
[WSA881X_OTP_REG_20] = 1,
[WSA881X_OTP_REG_21] = 1,
[WSA881X_OTP_REG_22] = 1,
[WSA881X_OTP_REG_23] = 1,
[WSA881X_OTP_REG_24] = 1,
[WSA881X_OTP_REG_25] = 1,
[WSA881X_OTP_REG_26] = 1,
[WSA881X_OTP_REG_27] = 1,
[WSA881X_OTP_REG_28] = 1,
[WSA881X_OTP_REG_29] = 1,
[WSA881X_OTP_REG_30] = 1,
[WSA881X_OTP_REG_31] = 1,
[WSA881X_OTP_REG_63] = 1,
/* Analog Registers */
[WSA881X_BIAS_REF_CTRL] = 1,
[WSA881X_BIAS_TEST] = 1,
[WSA881X_BIAS_BIAS] = 1,
[WSA881X_TEMP_OP] = 1,
[WSA881X_TEMP_IREF_CTRL] = 1,
[WSA881X_TEMP_ISENS_CTRL] = 1,
[WSA881X_TEMP_CLK_CTRL] = 1,
[WSA881X_TEMP_TEST] = 1,
[WSA881X_TEMP_BIAS] = 1,
[WSA881X_TEMP_ADC_CTRL] = 1,
[WSA881X_TEMP_DOUT_MSB] = 1,
[WSA881X_TEMP_DOUT_LSB] = 1,
[WSA881X_ADC_EN_MODU_V] = 1,
[WSA881X_ADC_EN_MODU_I] = 1,
[WSA881X_ADC_EN_DET_TEST_V] = 1,
[WSA881X_ADC_EN_DET_TEST_I] = 1,
[WSA881X_ADC_SEL_IBIAS] = 1,
[WSA881X_ADC_EN_SEL_IBAIS] = 1,
[WSA881X_SPKR_DRV_EN] = 1,
[WSA881X_SPKR_DRV_GAIN] = 1,
[WSA881X_SPKR_DAC_CTL] = 1,
[WSA881X_SPKR_DRV_DBG] = 1,
[WSA881X_SPKR_PWRSTG_DBG] = 1,
[WSA881X_SPKR_OCP_CTL] = 1,
[WSA881X_SPKR_CLIP_CTL] = 1,
[WSA881X_SPKR_BBM_CTL] = 1,
[WSA881X_SPKR_MISC_CTL1] = 1,
[WSA881X_SPKR_MISC_CTL2] = 1,
[WSA881X_SPKR_BIAS_INT] = 1,
[WSA881X_SPKR_PA_INT] = 1,
[WSA881X_SPKR_BIAS_CAL] = 1,
[WSA881X_SPKR_BIAS_PSRR] = 1,
[WSA881X_SPKR_STATUS1] = 1,
[WSA881X_SPKR_STATUS2] = 1,
[WSA881X_BOOST_EN_CTL] = 1,
[WSA881X_BOOST_CURRENT_LIMIT] = 1,
[WSA881X_BOOST_PS_CTL] = 1,
[WSA881X_BOOST_PRESET_OUT1] = 1,
[WSA881X_BOOST_PRESET_OUT2] = 1,
[WSA881X_BOOST_FORCE_OUT] = 1,
[WSA881X_BOOST_LDO_PROG] = 1,
[WSA881X_BOOST_SLOPE_COMP_ISENSE_FB] = 1,
[WSA881X_BOOST_RON_CTL] = 1,
[WSA881X_BOOST_LOOP_STABILITY] = 1,
[WSA881X_BOOST_ZX_CTL] = 1,
[WSA881X_BOOST_START_CTL] = 1,
[WSA881X_BOOST_MISC1_CTL] = 1,
[WSA881X_BOOST_MISC2_CTL] = 1,
[WSA881X_BOOST_MISC3_CTL] = 1,
[WSA881X_BOOST_ATEST_CTL] = 1,
[WSA881X_SPKR_PROT_FE_GAIN] = 1,
[WSA881X_SPKR_PROT_FE_CM_LDO_SET] = 1,
[WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET1] = 1,
[WSA881X_SPKR_PROT_FE_ISENSE_BIAS_SET2] = 1,
[WSA881X_SPKR_PROT_ATEST1] = 1,
[WSA881X_SPKR_PROT_ATEST2] = 1,
[WSA881X_SPKR_PROT_FE_VSENSE_VCM] = 1,
[WSA881X_SPKR_PROT_FE_VSENSE_BIAS_SET1] = 1,
[WSA881X_BONGO_RESRV_REG1] = 1,
[WSA881X_BONGO_RESRV_REG2] = 1,
[WSA881X_SPKR_PROT_SAR] = 1,
[WSA881X_SPKR_STATUS3] = 1,
};

View File

@@ -0,0 +1,187 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015, 2017-2019 The Linux Foundation. All rights reserved.
*/
#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/suspend.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/thermal.h>
#include <sound/soc.h>
#include "wsa881x-temp-sensor.h"
#define T1_TEMP -10
#define T2_TEMP 150
#define LOW_TEMP_THRESHOLD 5
#define HIGH_TEMP_THRESHOLD 45
#define TEMP_INVALID 0xFFFF
#define WSA881X_TEMP_RETRY 3
/*
* wsa881x_get_temp - get wsa temperature
* @thermal: thermal zone device
* @temp: temperature value
*
* Get the temperature of wsa881x.
*
* Return: 0 on success or negative error code on failure.
*/
int wsa881x_get_temp(struct thermal_zone_device *thermal,
int *temp)
{
struct wsa881x_tz_priv *pdata;
struct snd_soc_codec *codec;
struct wsa_temp_register reg;
int dmeas, d1, d2;
int ret = 0;
int temp_val;
int t1 = T1_TEMP;
int t2 = T2_TEMP;
u8 retry = WSA881X_TEMP_RETRY;
if (!thermal)
return -EINVAL;
if (thermal->devdata) {
pdata = thermal->devdata;
if (pdata->codec) {
codec = pdata->codec;
} else {
pr_err("%s: codec is NULL\n", __func__);
return -EINVAL;
}
} else {
pr_err("%s: pdata is NULL\n", __func__);
return -EINVAL;
}
if (atomic_cmpxchg(&pdata->is_suspend_spk, 1, 0)) {
/*
* get_temp query happens as part of POST_PM_SUSPEND
* from thermal core. To avoid calls to slimbus
* as part of this thermal query, return default temp
* and reset the suspend flag.
*/
if (!pdata->t0_init) {
if (temp)
*temp = pdata->curr_temp;
return 0;
}
}
temp_retry:
if (pdata->wsa_temp_reg_read) {
ret = pdata->wsa_temp_reg_read(codec, &reg);
if (ret) {
pr_err("%s: temp read failed: %d, current temp: %d\n",
__func__, ret, pdata->curr_temp);
if (temp)
*temp = pdata->curr_temp;
return 0;
}
} else {
pr_err("%s: wsa_temp_reg_read is NULL\n", __func__);
return -EINVAL;
}
/*
* Temperature register values are expected to be in the
* following range.
* d1_msb = 68 - 92 and d1_lsb = 0, 64, 128, 192
* d2_msb = 185 -218 and d2_lsb = 0, 64, 128, 192
*/
if ((reg.d1_msb < 68 || reg.d1_msb > 92) ||
(!(reg.d1_lsb == 0 || reg.d1_lsb == 64 || reg.d1_lsb == 128 ||
reg.d1_lsb == 192)) ||
(reg.d2_msb < 185 || reg.d2_msb > 218) ||
(!(reg.d2_lsb == 0 || reg.d2_lsb == 64 || reg.d2_lsb == 128 ||
reg.d2_lsb == 192))) {
printk_ratelimited("%s: Temperature registers[%d %d %d %d] are out of range\n",
__func__, reg.d1_msb, reg.d1_lsb, reg.d2_msb,
reg.d2_lsb);
}
dmeas = ((reg.dmeas_msb << 0x8) | reg.dmeas_lsb) >> 0x6;
d1 = ((reg.d1_msb << 0x8) | reg.d1_lsb) >> 0x6;
d2 = ((reg.d2_msb << 0x8) | reg.d2_lsb) >> 0x6;
if (d1 == d2)
temp_val = TEMP_INVALID;
else
temp_val = t1 + (((dmeas - d1) * (t2 - t1))/(d2 - d1));
if (temp_val <= LOW_TEMP_THRESHOLD ||
temp_val >= HIGH_TEMP_THRESHOLD) {
pr_debug("%s: T0: %d is out of range[%d, %d]\n", __func__,
temp_val, LOW_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD);
if (retry--) {
msleep(20);
goto temp_retry;
}
}
pdata->curr_temp = temp_val;
if (temp)
*temp = temp_val;
pr_debug("%s: t0 measured: %d dmeas = %d, d1 = %d, d2 = %d\n",
__func__, temp_val, dmeas, d1, d2);
return ret;
}
EXPORT_SYMBOL(wsa881x_get_temp);
static struct thermal_zone_device_ops wsa881x_thermal_ops = {
.get_temp = wsa881x_get_temp,
};
static int wsa881x_pm_notify(struct notifier_block *nb,
unsigned long mode, void *_unused)
{
struct wsa881x_tz_priv *pdata =
container_of(nb, struct wsa881x_tz_priv, pm_nb);
switch (mode) {
case PM_SUSPEND_PREPARE:
atomic_set(&pdata->is_suspend_spk, 1);
break;
default:
break;
}
return 0;
}
int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata)
{
struct thermal_zone_device *tz_dev;
if (tz_pdata == NULL) {
pr_err("%s: thermal pdata is NULL\n", __func__);
return -EINVAL;
}
/* Register with the thermal zone */
tz_dev = thermal_zone_device_register(tz_pdata->name,
0, 0, tz_pdata,
&wsa881x_thermal_ops, NULL, 0, 0);
if (IS_ERR(tz_dev)) {
pr_err("%s: thermal device register failed.\n", __func__);
return -EINVAL;
}
tz_pdata->tz_dev = tz_dev;
tz_pdata->pm_nb.notifier_call = wsa881x_pm_notify;
register_pm_notifier(&tz_pdata->pm_nb);
atomic_set(&tz_pdata->is_suspend_spk, 0);
return 0;
}
EXPORT_SYMBOL(wsa881x_init_thermal);
void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev)
{
struct wsa881x_tz_priv *pdata;
if (tz_dev && tz_dev->devdata) {
pdata = tz_dev->devdata;
if (pdata)
unregister_pm_notifier(&pdata->pm_nb);
}
if (tz_dev)
thermal_zone_device_unregister(tz_dev);
}
EXPORT_SYMBOL(wsa881x_deinit_thermal);

View File

@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
*/
#ifndef WSA881X_TEMP_SENSOR_H
#define WSA881X_TEMP_SENSOR_H
#include <linux/thermal.h>
#include <sound/soc.h>
struct wsa_temp_register {
u8 d1_msb;
u8 d1_lsb;
u8 d2_msb;
u8 d2_lsb;
u8 dmeas_msb;
u8 dmeas_lsb;
};
typedef int32_t (*wsa_temp_register_read)(struct snd_soc_codec *codec,
struct wsa_temp_register *wsa_temp_reg);
struct wsa881x_tz_priv {
struct thermal_zone_device *tz_dev;
struct snd_soc_codec *codec;
struct wsa_temp_register *wsa_temp_reg;
char name[80];
wsa_temp_register_read wsa_temp_reg_read;
struct notifier_block pm_nb;
atomic_t is_suspend_spk;
int t0_init;
int curr_temp;
};
int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp);
int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata);
void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,48 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
*/
#ifndef _WSA881X_H
#define _WSA881X_H
#include <linux/regmap.h>
#include <sound/soc.h>
#include <sound/info.h>
#include "wsa881x-registers.h"
#define WSA881X_MAX_SWR_PORTS 4
#if IS_ENABLED(CONFIG_SND_SOC_WSA881X)
extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port,
u8 num_port, unsigned int *ch_mask,
unsigned int *ch_rate, u8 *port_type);
extern const u8 wsa881x_reg_readable[WSA881X_CACHE_SIZE];
extern struct regmap_config wsa881x_regmap_config;
extern int wsa881x_codec_info_create_codec_entry(
struct snd_info_entry *codec_root,
struct snd_soc_codec *codec);
void wsa881x_regmap_defaults(struct regmap *regmap, u8 version);
#else
extern int wsa881x_set_channel_map(struct snd_soc_codec *codec, u8 *port,
u8 num_port, unsigned int *ch_mask,
unsigned int *ch_rate, u8 *port_type);
{
return 0;
}
extern int wsa881x_codec_info_create_codec_entry(
struct snd_info_entry *codec_root,
struct snd_soc_codec *codec)
{
return 0;
}
void wsa881x_regmap_defaults(struct regmap *regmap, u8 version)
{
}
#endif
#endif /* _WSA881X_H */

View File

@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
*/
#ifndef __DEVICE_EVENT_H
#define __DEVICE_EVENT_H
#define QC_AUDIO_EXTERNAL_SPK_1_EVENT "qc_ext_spk_1"
#define QC_AUDIO_EXTERNAL_SPK_2_EVENT "qc_ext_spk_2"
#define QC_AUDIO_EXTERNAL_MIC_EVENT "qc_ext_mic"
#endif /* __DEVICE_EVENT_H */

View File

@@ -0,0 +1,76 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#ifndef _KONA_PORT_CONFIG
#define _KONA_PORT_CONFIG
#include <soc/swr-common.h>
#define WSA_MSTR_PORT_MASK 0xFF
/*
* Add port configuration in the format
*{ si, off1, off2, hstart, hstop, wd_len, bp_mode, bgp_ctrl, lane_ctrl}
*/
static struct port_params wsa_frame_params_default[SWR_MSTR_PORT_LEN] = {
{7, 1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{31, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{63, 12, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF},
{7, 6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{31, 18, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{63, 13, 31, 0xFF, 0xFF, 0xFF, 0x1, 0xFF, 0xFF},
{15, 7, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
{15, 10, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
};
static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0},
{7, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0},
{0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0},
};
static struct port_params rx_frame_params_dsd[SWR_MSTR_PORT_LEN] = {
{3, 0, 0, 0xFF, 0xFF, 1, 0xFF, 0xFF, 1},
{31, 0, 0, 3, 6, 7, 0, 0xFF, 0},
{31, 11, 11, 0xFF, 0xFF, 4, 1, 0xFF, 0},
{7, 9, 0, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0},
{3, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 3, 0},
};
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */
{1, 1, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX1 */
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX2 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX4 */
};
/* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
static struct port_params tx_frame_params_v2[SWR_MSTR_PORT_LEN] = {
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},/* PCM OUT */
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1}, /* TX1 */
{1, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX2 */
{3, 2, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0}, /* TX3 */
{3, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 2}, /* TX4 */
};
static struct swr_mstr_port_map sm_port_map[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_default},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
};
static struct swr_mstr_port_map sm_port_map_v2[] = {
{TX_MACRO, SWR_UC0, tx_frame_params_v2},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
};
#endif /* _KONA_PORT_CONFIG */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,692 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <dsp/apr_audio-v2.h>
#include <dsp/q6afe-v2.h>
#include "msm-dai-q6-v2.h"
#define HDMI_RX_CA_MAX 0x32
enum {
DP_CONTROLLER0 = 0,
DP_CONTROLLER1,
DP_CONTROLLER_MAX,
};
enum {
DP_STREAM0 = 0,
DP_STREAM1,
DP_STREAM_MAX,
};
enum {
STATUS_PORT_STARTED, /* track if AFE port has started */
STATUS_MAX
};
struct msm_ext_disp_ca {
bool set_ca;
u32 ca;
};
struct msm_dai_q6_hdmi_dai_data {
DECLARE_BITMAP(status_mask, STATUS_MAX);
u32 rate;
u32 channels;
u32 stream_idx;
u32 ctl_idx;
struct msm_ext_disp_ca ca;
union afe_port_config port_config;
};
static int get_port_id(int dai_id)
{
/* Currently, display devices share a common AFE port */
if (dai_id != HDMI_RX)
return DISPLAY_PORT_RX;
return dai_id;
}
static int msm_dai_q6_ext_disp_format_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data;
int value = ucontrol->value.integer.value[0];
if (!dai_data) {
pr_err("%s: dai_data is NULL\n", __func__);
return -EINVAL;
}
dai_data->port_config.hdmi_multi_ch.datatype = value;
pr_debug("%s: value = %d\n", __func__, value);
return 0;
}
static int msm_dai_q6_ext_disp_format_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data;
if (!dai_data) {
pr_err("%s: dai_data is NULL\n", __func__);
return -EINVAL;
}
ucontrol->value.integer.value[0] =
dai_data->port_config.hdmi_multi_ch.datatype;
pr_debug("%s: value = %ld\n",
__func__, ucontrol->value.integer.value[0]);
return 0;
}
static int msm_dai_q6_ext_disp_device_idx_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data;
if (!dai_data) {
pr_err("%s: dai_data is NULL\n", __func__);
return -EINVAL;
}
if ((ucontrol->value.integer.value[0] > (DP_CONTROLLER_MAX - 1)) ||
(ucontrol->value.integer.value[1] > (DP_STREAM_MAX - 1)) ||
(ucontrol->value.integer.value[0] < 0) ||
(ucontrol->value.integer.value[1] < 0)) {
pr_err("%s: DP control index invalid\n", __func__);
return -EINVAL;
}
dai_data->ctl_idx = ucontrol->value.integer.value[0];
dai_data->stream_idx = ucontrol->value.integer.value[1];
pr_debug("%s: DP ctl id %d stream id %d\n", __func__,
dai_data->ctl_idx, dai_data->stream_idx);
return 0;
}
static int msm_dai_q6_ext_disp_device_idx_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data;
if (!dai_data) {
pr_err("%s: dai_data is NULL\n", __func__);
return -EINVAL;
}
ucontrol->value.integer.value[0] = dai_data->ctl_idx;
ucontrol->value.integer.value[1] = dai_data->stream_idx;
pr_debug("%s: DP ctl id %d stream id %d\n", __func__,
dai_data->ctl_idx, dai_data->stream_idx);
return 0;
}
static int msm_dai_q6_ext_disp_ca_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data;
if (!dai_data) {
pr_err("%s: dai_data is NULL\n", __func__);
return -EINVAL;
}
dai_data->ca.ca = ucontrol->value.integer.value[0];
dai_data->ca.set_ca = true;
pr_debug("%s: ca = %d\n", __func__, dai_data->ca.ca);
return 0;
}
static int msm_dai_q6_ext_disp_ca_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = kcontrol->private_data;
if (!dai_data) {
pr_err("%s: dai_data is NULL\n", __func__);
return -EINVAL;
}
ucontrol->value.integer.value[0] = dai_data->ca.ca;
pr_debug("%s: ca = %d\n", __func__, dai_data->ca.ca);
return 0;
}
/* HDMI format field for AFE_PORT_MULTI_CHAN_HDMI_AUDIO_IF_CONFIG command
* 0: linear PCM
* 1: non-linear PCM
*/
static const char * const hdmi_format[] = {
"LPCM",
"Compr"
};
static const struct soc_enum hdmi_config_enum[] = {
SOC_ENUM_SINGLE_EXT(2, hdmi_format),
};
static int msm_dai_q6_ext_disp_drift_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
uinfo->count = sizeof(struct afe_param_id_dev_timing_stats);
return 0;
}
static int msm_dai_q6_ext_disp_drift_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int ret = -EINVAL;
struct afe_param_id_dev_timing_stats timing_stats;
struct snd_soc_dai *dai = kcontrol->private_data;
struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev);
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
pr_debug("%s: afe port not started. status_mask = %ld\n",
__func__, *dai_data->status_mask);
goto done;
}
memset(&timing_stats, 0, sizeof(struct afe_param_id_dev_timing_stats));
ret = afe_get_av_dev_drift(&timing_stats, get_port_id(dai->id));
if (ret) {
pr_err("%s: Error getting AFE Drift for port %d, err=%d\n",
__func__, get_port_id(dai->id), ret);
ret = -EINVAL;
goto done;
}
memcpy(ucontrol->value.bytes.data, (void *)&timing_stats,
sizeof(struct afe_param_id_dev_timing_stats));
done:
return ret;
}
static const struct snd_kcontrol_new hdmi_config_controls[] = {
SOC_ENUM_EXT("HDMI RX Format", hdmi_config_enum[0],
msm_dai_q6_ext_disp_format_get,
msm_dai_q6_ext_disp_format_put),
SOC_SINGLE_MULTI_EXT("HDMI RX CA", SND_SOC_NOPM, 0,
HDMI_RX_CA_MAX, 0, 1,
msm_dai_q6_ext_disp_ca_get,
msm_dai_q6_ext_disp_ca_put),
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "HDMI DRIFT",
.info = msm_dai_q6_ext_disp_drift_info,
.get = msm_dai_q6_ext_disp_drift_get,
},
};
static const struct snd_kcontrol_new display_port_config_controls[] = {
SOC_ENUM_EXT("Display Port RX Format", hdmi_config_enum[0],
msm_dai_q6_ext_disp_format_get,
msm_dai_q6_ext_disp_format_put),
SOC_SINGLE_MULTI_EXT("Display Port RX CA", SND_SOC_NOPM, 0,
HDMI_RX_CA_MAX, 0, 1,
msm_dai_q6_ext_disp_ca_get,
msm_dai_q6_ext_disp_ca_put),
SOC_SINGLE_MULTI_EXT("Display Port RX DEVICE IDX", SND_SOC_NOPM, 0,
1, 0, 2,
msm_dai_q6_ext_disp_device_idx_get,
msm_dai_q6_ext_disp_device_idx_put),
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "DISPLAY_PORT DRIFT",
.info = msm_dai_q6_ext_disp_drift_info,
.get = msm_dai_q6_ext_disp_drift_get,
},
SOC_ENUM_EXT("Display Port1 RX Format", hdmi_config_enum[0],
msm_dai_q6_ext_disp_format_get,
msm_dai_q6_ext_disp_format_put),
SOC_SINGLE_MULTI_EXT("Display Port1 RX CA", SND_SOC_NOPM, 0,
HDMI_RX_CA_MAX, 0, 1,
msm_dai_q6_ext_disp_ca_get,
msm_dai_q6_ext_disp_ca_put),
SOC_SINGLE_MULTI_EXT("Display Port1 RX DEVICE IDX", SND_SOC_NOPM, 0,
1, 0, 2,
msm_dai_q6_ext_disp_device_idx_get,
msm_dai_q6_ext_disp_device_idx_put),
{
.access = SNDRV_CTL_ELEM_ACCESS_READ,
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "DISPLAY_PORT1 DRIFT",
.info = msm_dai_q6_ext_disp_drift_info,
.get = msm_dai_q6_ext_disp_drift_get,
},
};
/* Current implementation assumes hw_param is called once
* This may not be the case but what to do when ADM and AFE
* port are already opened and parameter changes
*/
static int msm_dai_q6_hdmi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev);
dai_data->channels = params_channels(params);
dai_data->rate = params_rate(params);
dai_data->port_config.hdmi_multi_ch.reserved = 0;
dai_data->port_config.hdmi_multi_ch.hdmi_cfg_minor_version = 1;
dai_data->port_config.hdmi_multi_ch.sample_rate = dai_data->rate;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
dai_data->port_config.hdmi_multi_ch.bit_width = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
case SNDRV_PCM_FORMAT_S24_3LE:
dai_data->port_config.hdmi_multi_ch.bit_width = 24;
break;
}
/*refer to HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4*/
switch (dai_data->channels) {
case 2:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0;
break;
case 3:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x02;
break;
case 4:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x06;
break;
case 5:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x0A;
break;
case 6:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x0B;
break;
case 7:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x12;
break;
case 8:
dai_data->port_config.hdmi_multi_ch.channel_allocation = 0x13;
break;
default:
dev_err(dai->dev, "invalid Channels = %u\n",
dai_data->channels);
return -EINVAL;
}
dev_dbg(dai->dev, "%s() minor version: %u samplerate: %u bitwidth: %u\n"
"num_ch = %u channel_allocation = %u datatype = %d\n", __func__,
dai_data->port_config.hdmi_multi_ch.hdmi_cfg_minor_version,
dai_data->port_config.hdmi_multi_ch.sample_rate,
dai_data->port_config.hdmi_multi_ch.bit_width,
dai_data->channels,
dai_data->port_config.hdmi_multi_ch.channel_allocation,
dai_data->port_config.hdmi_multi_ch.datatype);
return 0;
}
static void msm_dai_q6_hdmi_shutdown(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev);
int rc = 0;
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
pr_info("%s: afe port not started. dai_data->status_mask = %ld\n",
__func__, *dai_data->status_mask);
return;
}
rc = afe_close(get_port_id(dai->id)); /* can block */
if (rc < 0)
dev_err(dai->dev, "fail to close AFE port\n");
pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
*dai_data->status_mask);
clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
}
static int msm_dai_q6_hdmi_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct msm_dai_q6_hdmi_dai_data *dai_data = dev_get_drvdata(dai->dev);
int rc = 0;
if (dai_data->ca.set_ca)
dai_data->port_config.hdmi_multi_ch.channel_allocation =
dai_data->ca.ca;
if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
rc = afe_set_display_stream(get_port_id(dai->id), dai_data->stream_idx,
dai_data->ctl_idx);
if (rc < 0) {
dev_err(dai->dev, "fail to set AFE ctl, stream ID params %x\n",
dai->id);
if (rc != -EOPNOTSUPP) {
dev_err(dai->dev, "not starting AFE port\n");
goto err;
}
}
rc = afe_port_start(get_port_id(dai->id), &dai_data->port_config,
dai_data->rate);
if (rc < 0)
dev_err(dai->dev, "fail to open AFE port %x\n",
get_port_id(dai->id));
else
set_bit(STATUS_PORT_STARTED,
dai_data->status_mask);
}
err:
return rc;
}
static inline void msm_dai_q6_hdmi_set_dai_id(struct snd_soc_dai *dai)
{
if (!dai->driver->id) {
dev_warn(dai->dev, "DAI driver id is not set\n");
return;
}
dai->id = dai->driver->id;
}
static int msm_dai_q6_hdmi_dai_probe(struct snd_soc_dai *dai)
{
struct msm_dai_q6_hdmi_dai_data *dai_data;
const struct snd_kcontrol_new *kcontrol;
int rc = 0;
struct snd_soc_dapm_route intercon;
struct snd_soc_dapm_context *dapm;
if (!dai || !dai->driver) {
pr_err("%s: dai or dai->driver is NULL\n", __func__);
return -EINVAL;
}
dai_data = kzalloc(sizeof(struct msm_dai_q6_hdmi_dai_data),
GFP_KERNEL);
if (!dai_data) {
dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
dai->id);
rc = -ENOMEM;
} else
dev_set_drvdata(dai->dev, dai_data);
msm_dai_q6_hdmi_set_dai_id(dai);
if (dai->driver->id == HDMI_RX) {
kcontrol = &hdmi_config_controls[0];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &hdmi_config_controls[1];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &hdmi_config_controls[2];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai));
} else if (dai->driver->id == MSM_DISPLAY_PORT) {
kcontrol = &display_port_config_controls[0];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &display_port_config_controls[1];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &display_port_config_controls[2];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &display_port_config_controls[3];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai));
} else if (dai->driver->id == MSM_DISPLAY_PORT1) {
kcontrol = &display_port_config_controls[4];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &display_port_config_controls[5];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &display_port_config_controls[6];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai_data));
kcontrol = &display_port_config_controls[7];
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(kcontrol, dai));
} else {
dev_err(dai->dev, "%s: Invalid id:%d\n",
__func__, dai->driver->id);
kfree(dai_data);
dev_set_drvdata(dai->dev, NULL);
return -EINVAL;
}
dapm = snd_soc_component_get_dapm(dai->component);
memset(&intercon, 0, sizeof(intercon));
if (!rc) {
if (dai->driver->playback.stream_name &&
dai->driver->playback.aif_name) {
dev_dbg(dai->dev, "%s add route for widget %s",
__func__, dai->driver->playback.stream_name);
intercon.source = dai->driver->playback.aif_name;
intercon.sink = dai->driver->playback.stream_name;
dev_dbg(dai->dev, "%s src %s sink %s\n",
__func__, intercon.source, intercon.sink);
snd_soc_dapm_add_routes(dapm, &intercon, 1);
}
if (dai->driver->capture.stream_name &&
dai->driver->capture.aif_name) {
dev_dbg(dai->dev, "%s add route for widget %s",
__func__, dai->driver->capture.stream_name);
intercon.sink = dai->driver->capture.aif_name;
intercon.source = dai->driver->capture.stream_name;
dev_dbg(dai->dev, "%s src %s sink %s\n",
__func__, intercon.source, intercon.sink);
snd_soc_dapm_add_routes(dapm, &intercon, 1);
}
}
return rc;
}
static int msm_dai_q6_hdmi_dai_remove(struct snd_soc_dai *dai)
{
struct msm_dai_q6_hdmi_dai_data *dai_data;
int rc;
dai_data = dev_get_drvdata(dai->dev);
/* If AFE port is still up, close it */
if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
rc = afe_close(get_port_id(dai->id)); /* can block */
if (rc < 0)
dev_err(dai->dev, "fail to close AFE port\n");
clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
}
kfree(dai_data);
return 0;
}
static struct snd_soc_dai_ops msm_dai_q6_hdmi_ops = {
.prepare = msm_dai_q6_hdmi_prepare,
.hw_params = msm_dai_q6_hdmi_hw_params,
.shutdown = msm_dai_q6_hdmi_shutdown,
};
static struct snd_soc_dai_driver msm_dai_q6_hdmi_hdmi_rx_dai = {
.playback = {
.stream_name = "HDMI Playback",
.aif_name = "HDMI",
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE,
.channels_min = 2,
.channels_max = 8,
.rate_max = 192000,
.rate_min = 48000,
},
.ops = &msm_dai_q6_hdmi_ops,
.id = HDMI_RX,
.probe = msm_dai_q6_hdmi_dai_probe,
.remove = msm_dai_q6_hdmi_dai_remove,
};
static struct snd_soc_dai_driver msm_dai_q6_display_port_rx_dai[] = {
{
.playback = {
.stream_name = "Display Port Playback",
.aif_name = "DISPLAY_PORT",
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE,
.channels_min = 2,
.channels_max = 8,
.rate_max = 192000,
.rate_min = 48000,
},
.ops = &msm_dai_q6_hdmi_ops,
.id = MSM_DISPLAY_PORT,
.probe = msm_dai_q6_hdmi_dai_probe,
.remove = msm_dai_q6_hdmi_dai_remove,
},
{
.playback = {
.stream_name = "Display Port1 Playback",
.aif_name = "DISPLAY_PORT1",
.rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |
SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_S16_LE |
SNDRV_PCM_FMTBIT_S24_LE |
SNDRV_PCM_FMTBIT_S24_3LE,
.channels_min = 2,
.channels_max = 8,
.rate_max = 192000,
.rate_min = 48000,
},
.ops = &msm_dai_q6_hdmi_ops,
.id = MSM_DISPLAY_PORT1,
.probe = msm_dai_q6_hdmi_dai_probe,
.remove = msm_dai_q6_hdmi_dai_remove,
},
};
static const struct snd_soc_component_driver msm_dai_hdmi_q6_component = {
.name = "msm-dai-q6-hdmi",
};
/* To do: change to register DAIs as batch */
static int msm_dai_q6_hdmi_dev_probe(struct platform_device *pdev)
{
int rc, id;
const char *q6_dev_id = "qcom,msm-dai-q6-dev-id";
rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id);
if (rc) {
dev_err(&pdev->dev,
"%s: missing %s in dt node\n", __func__, q6_dev_id);
return rc;
}
pdev->id = id;
pr_debug("%s: dev name %s, id:%d\n", __func__,
dev_name(&pdev->dev), pdev->id);
switch (pdev->id) {
case HDMI_RX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_hdmi_q6_component,
&msm_dai_q6_hdmi_hdmi_rx_dai, 1);
break;
case MSM_DISPLAY_PORT:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_hdmi_q6_component,
&msm_dai_q6_display_port_rx_dai[0], 1);
break;
case MSM_DISPLAY_PORT1:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_hdmi_q6_component,
&msm_dai_q6_display_port_rx_dai[1], 1);
break;
default:
dev_err(&pdev->dev, "invalid device ID %d\n", pdev->id);
rc = -ENODEV;
break;
}
return rc;
}
static int msm_dai_q6_hdmi_dev_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
return 0;
}
static const struct of_device_id msm_dai_q6_hdmi_dt_match[] = {
{.compatible = "qcom,msm-dai-q6-hdmi"},
{}
};
MODULE_DEVICE_TABLE(of, msm_dai_q6_hdmi_dt_match);
static struct platform_driver msm_dai_q6_hdmi_driver = {
.probe = msm_dai_q6_hdmi_dev_probe,
.remove = msm_dai_q6_hdmi_dev_remove,
.driver = {
.name = "msm-dai-q6-hdmi",
.owner = THIS_MODULE,
.of_match_table = msm_dai_q6_hdmi_dt_match,
.suppress_bind_attrs = true,
},
};
int __init msm_dai_q6_hdmi_init(void)
{
return platform_driver_register(&msm_dai_q6_hdmi_driver);
}
void msm_dai_q6_hdmi_exit(void)
{
platform_driver_unregister(&msm_dai_q6_hdmi_driver);
}
/* Module information */
MODULE_DESCRIPTION("MSM DSP HDMI DAI driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,104 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved.
*/
#ifndef __MSM_DAI_Q6_PDATA_H__
#define __MSM_DAI_Q6_PDATA_H__
#define MSM_MI2S_SD0 (1 << 0)
#define MSM_MI2S_SD1 (1 << 1)
#define MSM_MI2S_SD2 (1 << 2)
#define MSM_MI2S_SD3 (1 << 3)
#define MSM_MI2S_SD4 (1 << 4)
#define MSM_MI2S_SD5 (1 << 5)
#define MSM_MI2S_SD6 (1 << 6)
#define MSM_MI2S_SD7 (1 << 7)
#define MSM_MI2S_CAP_RX 0
#define MSM_MI2S_CAP_TX 1
#define MSM_PRIM_MI2S 0
#define MSM_SEC_MI2S 1
#define MSM_TERT_MI2S 2
#define MSM_QUAT_MI2S 3
#define MSM_QUIN_MI2S 4
#define MSM_SENARY_MI2S 5
#define MSM_SEC_MI2S_SD1 6
#define MSM_INT0_MI2S 7
#define MSM_INT1_MI2S 8
#define MSM_INT2_MI2S 9
#define MSM_INT3_MI2S 10
#define MSM_INT4_MI2S 11
#define MSM_INT5_MI2S 12
#define MSM_INT6_MI2S 13
#define MSM_MI2S_MIN MSM_PRIM_MI2S
#define MSM_MI2S_MAX MSM_INT6_MI2S
#define MSM_DISPLAY_PORT 0
#define MSM_DISPLAY_PORT1 1
#define MSM_PRIM_META_MI2S 0
#define MSM_SEC_META_MI2S 1
#define MSM_META_MI2S_MIN MSM_PRIM_META_MI2S
#define MSM_META_MI2S_MAX MSM_SEC_META_MI2S
struct msm_dai_auxpcm_config {
u16 mode;
u16 sync;
u16 frame;
u16 quant;
u16 num_slots;
u16 *slot_mapping;
u16 data;
u32 pcm_clk_rate;
};
struct msm_dai_auxpcm_pdata {
struct msm_dai_auxpcm_config mode_8k;
struct msm_dai_auxpcm_config mode_16k;
};
struct msm_mi2s_pdata {
u16 rx_sd_lines;
u16 tx_sd_lines;
u16 intf_id;
};
struct msm_meta_mi2s_pdata {
u32 num_member_ports;
u32 member_port[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
u32 sd_lines[MAX_NUM_I2S_META_PORT_MEMBER_PORTS];
u16 intf_id;
};
struct msm_i2s_data {
u32 capability; /* RX or TX */
u16 sd_lines;
};
struct msm_dai_tdm_group_config {
u16 group_id;
u16 num_ports;
u16 *port_id;
u32 clk_rate;
};
struct msm_dai_tdm_config {
u16 sync_mode;
u16 sync_src;
u16 data_out;
u16 invert_sync;
u16 data_delay;
u32 data_align;
u16 header_start_offset;
u16 header_width;
u16 header_num_frame_repeat;
};
struct msm_dai_tdm_pdata {
struct msm_dai_tdm_group_config group_config;
struct msm_dai_tdm_config config;
};
#endif

View File

@@ -0,0 +1,655 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/bitops.h>
#include <linux/slimbus/slimbus.h>
#include <sound/soc.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "msm-slim-dma.h"
#define SLIM_DEV_NAME "msm-dai-slim"
#define SLIM_DAI_RATES (SNDRV_PCM_RATE_48000 | \
SNDRV_PCM_RATE_8000 | \
SNDRV_PCM_RATE_16000 | \
SNDRV_PCM_RATE_96000 | \
SNDRV_PCM_RATE_192000 | \
SNDRV_PCM_RATE_384000)
#define SLIM_DAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
#define DAI_STATE_INITIALIZED (0x01 << 0)
#define DAI_STATE_PREPARED (0x01 << 1)
#define DAI_STATE_RUNNING (0x01 << 2)
#define SET_DAI_STATE(status, state) \
(status |= state)
#define CLR_DAI_STATE(status, state) \
(status = status & (~state))
enum {
MSM_DAI_SLIM0 = 0,
NUM_SLIM_DAIS,
};
struct msm_slim_dai_data {
unsigned int dai_id;
u16 *chan_h;
u16 *sh_ch;
u16 grph;
u32 rate;
u16 bits;
u16 ch_cnt;
u8 status;
struct snd_soc_dai_driver *dai_drv;
struct msm_slim_dma_data dma_data;
struct slim_port_cfg port_cfg;
};
struct msm_dai_slim_drv_data {
struct slim_device *sdev;
u16 num_dais;
struct msm_slim_dai_data slim_dai_data[NUM_SLIM_DAIS];
};
struct msm_slim_dai_data *msm_slim_get_dai_data(
struct msm_dai_slim_drv_data *drv_data,
struct snd_soc_dai *dai)
{
struct msm_slim_dai_data *dai_data_t;
int i;
for (i = 0; i < drv_data->num_dais; i++) {
dai_data_t = &drv_data->slim_dai_data[i];
if (dai_data_t->dai_id == dai->id)
return dai_data_t;
}
dev_err(dai->dev,
"%s: no dai data found for dai_id %d\n",
__func__, dai->id);
return NULL;
}
static int msm_dai_slim_ch_ctl(struct msm_slim_dma_data *dma_data,
struct snd_soc_dai *dai, bool enable)
{
struct slim_device *sdev;
struct msm_dai_slim_drv_data *drv_data;
struct msm_slim_dai_data *dai_data;
int rc, rc1, i;
if (!dma_data || !dma_data->sdev) {
pr_err("%s: Invalid %s\n", __func__,
(!dma_data) ? "dma_data" : "slim_device");
return -EINVAL;
}
sdev = dma_data->sdev;
drv_data = dev_get_drvdata(&sdev->dev);
dai_data = msm_slim_get_dai_data(drv_data, dai);
if (!dai_data) {
dev_err(dai->dev,
"%s: Invalid dai_data for dai_id %d\n",
__func__, dai->id);
return -EINVAL;
}
dev_dbg(&sdev->dev,
"%s: enable = %s, rate = %u\n", __func__,
enable ? "true" : "false",
dai_data->rate);
if (enable) {
if (!(dai_data->status & DAI_STATE_PREPARED)) {
dev_err(&sdev->dev,
"%s: dai id (%d) has invalid state 0x%x\n",
__func__, dai->id, dai_data->status);
return -EINVAL;
}
rc = slim_alloc_mgrports(sdev,
SLIM_REQ_DEFAULT, dai_data->ch_cnt,
&(dma_data->ph),
sizeof(dma_data->ph));
if (rc < 0) {
dev_err(&sdev->dev,
"%s:alloc mgrport failed rc %d\n",
__func__, rc);
goto done;
}
rc = slim_config_mgrports(sdev, &(dma_data->ph),
dai_data->ch_cnt,
&(dai_data->port_cfg));
if (rc < 0) {
dev_err(&sdev->dev,
"%s: config mgrport failed rc %d\n",
__func__, rc);
goto err_done;
}
for (i = 0; i < dai_data->ch_cnt; i++) {
rc = slim_connect_sink(sdev,
&dma_data->ph, 1,
dai_data->chan_h[i]);
if (rc < 0) {
dev_err(&sdev->dev,
"%s: slim_connect_sink failed, ch = %d, err = %d\n",
__func__, i, rc);
goto err_done;
}
}
rc = slim_control_ch(sdev,
dai_data->grph,
SLIM_CH_ACTIVATE, true);
if (rc < 0) {
dev_err(&sdev->dev,
"%s: slim activate ch failed, err = %d\n",
__func__, rc);
goto err_done;
}
/* Mark dai status as running */
SET_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
} else {
if (!(dai_data->status & DAI_STATE_RUNNING)) {
dev_err(&sdev->dev,
"%s: dai id (%d) has invalid state 0x%x\n",
__func__, dai->id, dai_data->status);
return -EINVAL;
}
rc = slim_control_ch(sdev,
dai_data->grph,
SLIM_CH_REMOVE, true);
if (rc < 0) {
dev_err(&sdev->dev,
"%s: slim activate ch failed, err = %d\n",
__func__, rc);
goto done;
}
rc = slim_dealloc_mgrports(sdev,
&dma_data->ph, 1);
if (rc < 0) {
dev_err(&sdev->dev,
"%s: dealloc mgrport failed, err = %d\n",
__func__, rc);
goto done;
}
/* clear running state for dai*/
CLR_DAI_STATE(dai_data->status, DAI_STATE_RUNNING);
}
return rc;
err_done:
rc1 = slim_dealloc_mgrports(sdev,
&dma_data->ph, 1);
if (rc1 < 0)
dev_err(&sdev->dev,
"%s: dealloc mgrport failed, err = %d\n",
__func__, rc1);
done:
return rc;
}
static int msm_dai_slim_hw_params(
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
struct msm_slim_dai_data *dai_data;
int rc = 0;
dai_data = msm_slim_get_dai_data(drv_data, dai);
if (!dai_data) {
dev_err(dai->dev,
"%s: Invalid dai_data for dai_id %d\n",
__func__, dai->id);
rc = -EINVAL;
goto done;
}
if (!dai_data->ch_cnt || dai_data->ch_cnt != params_channels(params)) {
dev_err(dai->dev, "%s: invalid ch_cnt %d %d\n",
__func__, dai_data->ch_cnt, params_channels(params));
rc = -EINVAL;
goto done;
}
dai_data->rate = params_rate(params);
dai_data->port_cfg.port_opts = SLIM_OPT_NONE;
if (dai_data->rate >= SNDRV_PCM_RATE_48000)
dai_data->port_cfg.watermark = 16;
else
dai_data->port_cfg.watermark = 8;
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
dai_data->bits = 16;
break;
case SNDRV_PCM_FORMAT_S24_LE:
dai_data->bits = 24;
break;
case SNDRV_PCM_FORMAT_S32_LE:
dai_data->bits = 32;
break;
default:
dev_err(dai->dev, "%s: invalid format %d\n", __func__,
params_format(params));
rc = -EINVAL;
goto done;
}
dev_dbg(dai->dev, "%s: ch_cnt=%u rate=%u, bit_width = %u\n",
__func__, dai_data->ch_cnt, dai_data->rate,
dai_data->bits);
done:
return rc;
}
static int msm_dai_slim_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 msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
struct msm_slim_dai_data *dai_data;
struct snd_soc_dai_driver *dai_drv;
u8 i = 0;
dev_dbg(dai->dev,
"%s: tx_num=%u, rx_num=%u\n",
__func__, tx_num, rx_num);
dai_data = msm_slim_get_dai_data(drv_data, dai);
if (!dai_data) {
dev_err(dai->dev,
"%s: Invalid dai_data for dai_id %d\n",
__func__, dai->id);
return -EINVAL;
}
dai_drv = dai_data->dai_drv;
if (tx_num > dai_drv->capture.channels_max) {
dev_err(dai->dev, "%s: tx_num %u max out master port cnt\n",
__func__, tx_num);
return -EINVAL;
}
for (i = 0; i < tx_num; i++)
dai_data->sh_ch[i] = tx_slot[i];
dai_data->ch_cnt = tx_num;
return 0;
}
static int msm_dai_slim_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
struct msm_slim_dma_data *dma_data;
struct msm_slim_dai_data *dai_data = NULL;
struct slim_ch prop;
int rc;
u8 i, j;
dai_data = msm_slim_get_dai_data(drv_data, dai);
if (!dai_data) {
dev_err(dai->dev,
"%s: Invalid dai_data for dai %d\n",
__func__, dai->id);
return -EINVAL;
}
if (!(dai_data->status & DAI_STATE_INITIALIZED)) {
dev_err(dai->dev,
"%s: dai id (%d) has invalid state 0x%x\n",
__func__, dai->id, dai_data->status);
return -EINVAL;
}
if (dai_data->status & DAI_STATE_PREPARED) {
dev_dbg(dai->dev,
"%s: dai id (%d) has already prepared.\n",
__func__, dai->id);
return 0;
}
dma_data = &dai_data->dma_data;
snd_soc_dai_set_dma_data(dai, substream, dma_data);
for (i = 0; i < dai_data->ch_cnt; i++) {
rc = slim_query_ch(drv_data->sdev, dai_data->sh_ch[i],
&dai_data->chan_h[i]);
if (rc) {
dev_err(dai->dev, "%s:query chan handle failed rc %d\n",
__func__, rc);
goto error_chan_query;
}
}
prop.prot = SLIM_AUTO_ISO;
prop.baser = SLIM_RATE_4000HZ;
prop.dataf = SLIM_CH_DATAF_NOT_DEFINED;
prop.auxf = SLIM_CH_AUXF_NOT_APPLICABLE;
prop.ratem = (dai_data->rate/4000);
prop.sampleszbits = dai_data->bits;
rc = slim_define_ch(drv_data->sdev, &prop, dai_data->chan_h,
dai_data->ch_cnt, true, &dai_data->grph);
if (rc) {
dev_err(dai->dev, "%s:define chan failed rc %d\n",
__func__, rc);
goto error_define_chan;
}
/* Mark stream status as prepared */
SET_DAI_STATE(dai_data->status, DAI_STATE_PREPARED);
return rc;
error_define_chan:
error_chan_query:
for (j = 0; j < i; j++)
slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[j]);
return rc;
}
static void msm_dai_slim_shutdown(struct snd_pcm_substream *stream,
struct snd_soc_dai *dai)
{
struct msm_dai_slim_drv_data *drv_data = dev_get_drvdata(dai->dev);
struct msm_slim_dma_data *dma_data = NULL;
struct msm_slim_dai_data *dai_data;
int i, rc = 0;
dai_data = msm_slim_get_dai_data(drv_data, dai);
dma_data = snd_soc_dai_get_dma_data(dai, stream);
if (!dma_data || !dai_data) {
dev_err(dai->dev,
"%s: Invalid %s\n", __func__,
(!dma_data) ? "dma_data" : "dai_data");
return;
}
if ((!(dai_data->status & DAI_STATE_PREPARED)) ||
dai_data->status & DAI_STATE_RUNNING) {
dev_err(dai->dev,
"%s: dai id (%d) has invalid state 0x%x\n",
__func__, dai->id, dai_data->status);
return;
}
for (i = 0; i < dai_data->ch_cnt; i++) {
rc = slim_dealloc_ch(drv_data->sdev, dai_data->chan_h[i]);
if (rc) {
dev_err(dai->dev,
"%s: dealloc_ch failed, err = %d\n",
__func__, rc);
}
}
snd_soc_dai_set_dma_data(dai, stream, NULL);
/* clear prepared state for the dai */
CLR_DAI_STATE(dai_data->status, DAI_STATE_PREPARED);
}
static const struct snd_soc_component_driver msm_dai_slim_component = {
.name = "msm-dai-slim-cmpnt",
};
static struct snd_soc_dai_ops msm_dai_slim_ops = {
.prepare = msm_dai_slim_prepare,
.hw_params = msm_dai_slim_hw_params,
.shutdown = msm_dai_slim_shutdown,
.set_channel_map = msm_dai_slim_set_channel_map,
};
static struct snd_soc_dai_driver msm_slim_dais[] = {
{
/*
* The first dai name should be same as device name
* to support registering single and multile dais.
*/
.name = SLIM_DEV_NAME,
.id = MSM_DAI_SLIM0,
.capture = {
.rates = SLIM_DAI_RATES,
.formats = SLIM_DAI_FORMATS,
.channels_min = 1,
/*
* max channels allowed is
* dependent on platform and
* will be updated before this
* dai driver is registered.
*/
.channels_max = 1,
.rate_min = 8000,
.rate_max = 384000,
.stream_name = "SLIM_DAI0 Capture",
},
.ops = &msm_dai_slim_ops,
},
/*
* If multiple dais are needed,
* add dais here and update the
* dai_id enum.
*/
};
static void msm_dai_slim_remove_dai_data(
struct device *dev,
struct msm_dai_slim_drv_data *drv_data)
{
int i;
struct msm_slim_dai_data *dai_data_t;
for (i = 0; i < drv_data->num_dais; i++) {
dai_data_t = &drv_data->slim_dai_data[i];
kfree(dai_data_t->chan_h);
dai_data_t->chan_h = NULL;
kfree(dai_data_t->sh_ch);
dai_data_t->sh_ch = NULL;
}
}
static int msm_dai_slim_populate_dai_data(struct device *dev,
struct msm_dai_slim_drv_data *drv_data)
{
struct snd_soc_dai_driver *dai_drv;
struct msm_slim_dai_data *dai_data_t;
u8 num_ch;
int i, j, rc;
for (i = 0; i < drv_data->num_dais; i++) {
num_ch = 0;
dai_drv = &msm_slim_dais[i];
num_ch += dai_drv->capture.channels_max;
num_ch += dai_drv->playback.channels_max;
dai_data_t = &drv_data->slim_dai_data[i];
dai_data_t->dai_drv = dai_drv;
dai_data_t->dai_id = dai_drv->id;
dai_data_t->dma_data.sdev = drv_data->sdev;
dai_data_t->dma_data.dai_channel_ctl =
msm_dai_slim_ch_ctl;
SET_DAI_STATE(dai_data_t->status,
DAI_STATE_INITIALIZED);
dai_data_t->chan_h = devm_kzalloc(dev,
sizeof(u16) * num_ch,
GFP_KERNEL);
if (!dai_data_t->chan_h) {
dev_err(dev,
"%s: DAI ID %d, Failed to alloc channel handles\n",
__func__, i);
rc = -ENOMEM;
goto err_mem_alloc;
}
dai_data_t->sh_ch = devm_kzalloc(dev,
sizeof(u16) * num_ch,
GFP_KERNEL);
if (!dai_data_t->sh_ch) {
dev_err(dev,
"%s: DAI ID %d, Failed to alloc sh_ch\n",
__func__, i);
rc = -ENOMEM;
goto err_mem_alloc;
}
}
return 0;
err_mem_alloc:
for (j = 0; j < i; j++) {
dai_data_t = &drv_data->slim_dai_data[i];
devm_kfree(dev, dai_data_t->chan_h);
dai_data_t->chan_h = NULL;
devm_kfree(dev, dai_data_t->sh_ch);
dai_data_t->sh_ch = NULL;
}
return rc;
}
static int msm_dai_slim_dev_probe(struct slim_device *sdev)
{
int rc, i;
u8 max_channels;
u32 apps_ch_pipes;
struct msm_dai_slim_drv_data *drv_data;
struct device *dev = &sdev->dev;
struct snd_soc_dai_driver *dai_drv;
if (!dev->of_node ||
!dev->of_node->parent) {
dev_err(dev,
"%s: Invalid %s\n", __func__,
(!dev->of_node) ? "of_node" : "parent_of_node");
return -EINVAL;
}
rc = of_property_read_u32(dev->of_node->parent,
"qcom,apps-ch-pipes",
&apps_ch_pipes);
if (rc) {
dev_err(dev,
"%s: Failed to lookup property %s in node %s, err = %d\n",
__func__, "qcom,apps-ch-pipes",
dev->of_node->parent->full_name, rc);
goto err_ret;
}
max_channels = hweight_long(apps_ch_pipes);
if (max_channels <= 0) {
dev_err(dev,
"%s: Invalid apps owned ports %d\n",
__func__, max_channels);
goto err_ret;
}
dev_dbg(dev, "%s: max channels = %u\n",
__func__, max_channels);
for (i = 0; i < ARRAY_SIZE(msm_slim_dais); i++) {
dai_drv = &msm_slim_dais[i];
dai_drv->capture.channels_max = max_channels;
dai_drv->playback.channels_max = max_channels;
}
drv_data = devm_kzalloc(dev, sizeof(*drv_data),
GFP_KERNEL);
if (!drv_data) {
rc = -ENOMEM;
goto err_ret;
}
drv_data->sdev = sdev;
drv_data->num_dais = NUM_SLIM_DAIS;
rc = msm_dai_slim_populate_dai_data(dev, drv_data);
if (rc) {
dev_err(dev,
"%s: failed to setup dai_data, err = %d\n",
__func__, rc);
goto err_populate_dai;
}
rc = snd_soc_register_component(&sdev->dev, &msm_dai_slim_component,
msm_slim_dais, NUM_SLIM_DAIS);
if (rc < 0) {
dev_err(dev, "%s: failed to register DAI, err = %d\n",
__func__, rc);
goto err_reg_comp;
}
dev_set_drvdata(dev, drv_data);
return rc;
err_reg_comp:
msm_dai_slim_remove_dai_data(dev, drv_data);
err_populate_dai:
devm_kfree(dev, drv_data);
err_ret:
return rc;
}
static int msm_dai_slim_dev_remove(struct slim_device *sdev)
{
snd_soc_unregister_component(&sdev->dev);
return 0;
}
static const struct slim_device_id msm_dai_slim_dt_match[] = {
{SLIM_DEV_NAME, 0 },
{}
};
static struct slim_driver msm_dai_slim_driver = {
.driver = {
.name = SLIM_DEV_NAME,
.owner = THIS_MODULE,
},
.probe = msm_dai_slim_dev_probe,
.remove = msm_dai_slim_dev_remove,
.id_table = msm_dai_slim_dt_match,
};
int __init msm_dai_slim_init(void)
{
int rc;
rc = slim_driver_register(&msm_dai_slim_driver);
if (rc)
pr_err("%s: failed to register with slimbus driver rc = %d",
__func__, rc);
return rc;
}
void msm_dai_slim_exit(void)
{
slim_driver_unregister(&msm_dai_slim_driver);
}
/* Module information */
MODULE_DESCRIPTION("Slimbus apps-owned channel handling driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,386 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2013-2014, 2017, 2019 The Linux Foundation. All rights reserved.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/soc.h>
enum {
STUB_RX,
STUB_TX,
STUB_1_RX,
STUB_1_TX,
STUB_DTMF_TX,
STUB_HOST_RX_CAPTURE_TX,
STUB_HOST_RX_PLAYBACK_RX,
STUB_HOST_TX_CAPTURE_TX,
STUB_HOST_TX_PLAYBACK_RX,
};
static int msm_dai_stub_set_channel_map(struct snd_soc_dai *dai,
unsigned int tx_num, unsigned int *tx_slot,
unsigned int rx_num, unsigned int *rx_slot)
{
pr_debug("%s:\n", __func__);
return 0;
}
static struct snd_soc_dai_ops msm_dai_stub_ops = {
.set_channel_map = msm_dai_stub_set_channel_map,
};
static int msm_dai_stub_add_route(struct snd_soc_dai *dai)
{
struct snd_soc_dapm_route intercon;
struct snd_soc_dapm_context *dapm;
if (!dai || !dai->driver) {
pr_err("%s Invalid params\n", __func__);
return -EINVAL;
}
dapm = snd_soc_component_get_dapm(dai->component);
memset(&intercon, 0, sizeof(intercon));
if (dai->driver->playback.stream_name &&
dai->driver->playback.aif_name) {
dev_dbg(dai->dev, "%s add route for widget %s",
__func__, dai->driver->playback.stream_name);
intercon.source = dai->driver->playback.aif_name;
intercon.sink = dai->driver->playback.stream_name;
dev_dbg(dai->dev, "%s src %s sink %s\n",
__func__, intercon.source, intercon.sink);
snd_soc_dapm_add_routes(dapm, &intercon, 1);
}
if (dai->driver->capture.stream_name &&
dai->driver->capture.aif_name) {
dev_dbg(dai->dev, "%s add route for widget %s",
__func__, dai->driver->capture.stream_name);
intercon.sink = dai->driver->capture.aif_name;
intercon.source = dai->driver->capture.stream_name;
dev_dbg(dai->dev, "%s src %s sink %s\n",
__func__, intercon.source, intercon.sink);
snd_soc_dapm_add_routes(dapm, &intercon, 1);
}
return 0;
}
static int msm_dai_stub_dai_probe(struct snd_soc_dai *dai)
{
return msm_dai_stub_add_route(dai);
}
static int msm_dai_stub_dai_remove(struct snd_soc_dai *dai)
{
pr_debug("%s:\n", __func__);
return 0;
}
static struct snd_soc_dai_driver msm_dai_stub_dai_rx = {
.playback = {
.stream_name = "Stub Playback",
.aif_name = "STUB_RX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
};
static struct snd_soc_dai_driver msm_dai_stub_dai_tx[] = {
{
.capture = {
.stream_name = "Stub Capture",
.aif_name = "STUB_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
},
{
.capture = {
.stream_name = "Stub1 Capture",
.aif_name = "STUB_1_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
}
};
static struct snd_soc_dai_driver msm_dai_stub_dtmf_tx_dai = {
.capture = {
.stream_name = "DTMF TX",
.aif_name = "STUB_DTMF_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
};
static struct snd_soc_dai_driver msm_dai_stub_host_capture_tx_dai[] = {
{
.capture = {
.stream_name = "CS-VOICE HOST RX CAPTURE",
.aif_name = "STUB_HOST_RX_CAPTURE_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
},
{
.capture = {
.stream_name = "CS-VOICE HOST TX CAPTURE",
.aif_name = "STUB_HOST_TX_CAPTURE_TX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
},
};
static struct snd_soc_dai_driver msm_dai_stub_host_playback_rx_dai[] = {
{
.playback = {
.stream_name = "CS-VOICE HOST RX PLAYBACK",
.aif_name = "STUB_HOST_RX_PLAYBACK_RX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
},
{
.playback = {
.stream_name = "CS-VOICE HOST TX PLAYBACK",
.aif_name = "STUB_HOST_TX_PLAYBACK_RX",
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
SNDRV_PCM_RATE_16000,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
.channels_min = 1,
.channels_max = 2,
.rate_min = 8000,
.rate_max = 48000,
},
.ops = &msm_dai_stub_ops,
.probe = &msm_dai_stub_dai_probe,
.remove = &msm_dai_stub_dai_remove,
},
};
static const struct snd_soc_component_driver msm_dai_stub_component = {
.name = "msm-dai-stub-dev",
};
static int msm_dai_stub_dev_probe(struct platform_device *pdev)
{
int rc, id = -1;
const char *stub_dev_id = "qcom,msm-dai-stub-dev-id";
rc = of_property_read_u32(pdev->dev.of_node, stub_dev_id, &id);
if (rc) {
dev_err(&pdev->dev,
"%s: missing %s in dt node\n", __func__, stub_dev_id);
return rc;
}
pdev->id = id;
pr_debug("%s: dev name %s, id:%d\n", __func__,
dev_name(&pdev->dev), pdev->id);
switch (id) {
case STUB_RX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component, &msm_dai_stub_dai_rx, 1);
break;
case STUB_TX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component, &msm_dai_stub_dai_tx[0], 1);
break;
case STUB_1_TX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component, &msm_dai_stub_dai_tx[1], 1);
break;
case STUB_DTMF_TX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component,
&msm_dai_stub_dtmf_tx_dai, 1);
break;
case STUB_HOST_RX_CAPTURE_TX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component,
&msm_dai_stub_host_capture_tx_dai[0], 1);
break;
case STUB_HOST_TX_CAPTURE_TX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component,
&msm_dai_stub_host_capture_tx_dai[1], 1);
break;
case STUB_HOST_RX_PLAYBACK_RX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component,
&msm_dai_stub_host_playback_rx_dai[0], 1);
break;
case STUB_HOST_TX_PLAYBACK_RX:
rc = snd_soc_register_component(&pdev->dev,
&msm_dai_stub_component,
&msm_dai_stub_host_playback_rx_dai[1], 1);
break;
}
return rc;
}
static int msm_dai_stub_dev_remove(struct platform_device *pdev)
{
snd_soc_unregister_component(&pdev->dev);
return 0;
}
static const struct of_device_id msm_dai_stub_dev_dt_match[] = {
{ .compatible = "qcom,msm-dai-stub-dev", },
{ }
};
MODULE_DEVICE_TABLE(of, msm_dai_stub_dev_dt_match);
static struct platform_driver msm_dai_stub_dev = {
.probe = msm_dai_stub_dev_probe,
.remove = msm_dai_stub_dev_remove,
.driver = {
.name = "msm-dai-stub-dev",
.owner = THIS_MODULE,
.of_match_table = msm_dai_stub_dev_dt_match,
.suppress_bind_attrs = true,
},
};
static int msm_dai_stub_probe(struct platform_device *pdev)
{
int rc = 0;
dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
rc = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
if (rc) {
dev_err(&pdev->dev, "%s: failed to add child nodes, rc=%d\n",
__func__, rc);
} else
dev_dbg(&pdev->dev, "%s: added child node\n", __func__);
return rc;
}
static int msm_dai_stub_remove(struct platform_device *pdev)
{
pr_debug("%s:\n", __func__);
return 0;
}
static const struct of_device_id msm_dai_stub_dt_match[] = {
{.compatible = "qcom,msm-dai-stub"},
{}
};
MODULE_DEVICE_TABLE(of, msm_dai_stub_dt_match);
static struct platform_driver msm_dai_stub_driver = {
.probe = msm_dai_stub_probe,
.remove = msm_dai_stub_remove,
.driver = {
.name = "msm-dai-stub",
.owner = THIS_MODULE,
.of_match_table = msm_dai_stub_dt_match,
.suppress_bind_attrs = true,
},
};
int __init msm_dai_stub_init(void)
{
int rc = 0;
pr_debug("%s:\n", __func__);
rc = platform_driver_register(&msm_dai_stub_driver);
if (rc) {
pr_err("%s: fail to register dai q6 driver", __func__);
goto fail;
}
rc = platform_driver_register(&msm_dai_stub_dev);
if (rc) {
pr_err("%s: fail to register dai q6 dev driver", __func__);
goto dai_stub_dev_fail;
}
return rc;
dai_stub_dev_fail:
platform_driver_unregister(&msm_dai_stub_driver);
fail:
return rc;
}
void msm_dai_stub_exit(void)
{
pr_debug("%s:\n", __func__);
platform_driver_unregister(&msm_dai_stub_dev);
platform_driver_unregister(&msm_dai_stub_driver);
}
/* Module information */
MODULE_DESCRIPTION("MSM Stub DSP DAI driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,259 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2013-2014, 2016, The Linux Foundation. All rights reserved.
*/
#ifndef _MSM_DOLBY_COMMON_H_
#define _MSM_DOLBY_COMMON_H_
#include <sound/soc.h>
#define DOLBY_BUNDLE_MODULE_ID 0x00010723
#define DOLBY_VISUALIZER_MODULE_ID 0x0001072B
#define DOLBY_PARAM_ID_VDHE 0x0001074D
#define DOLBY_PARAM_ID_VSPE 0x00010750
#define DOLBY_PARAM_ID_DSSF 0x00010753
#define DOLBY_PARAM_ID_DVLI 0x0001073E
#define DOLBY_PARAM_ID_DVLO 0x0001073F
#define DOLBY_PARAM_ID_DVLE 0x0001073C
#define DOLBY_PARAM_ID_DVMC 0x00010741
#define DOLBY_PARAM_ID_DVME 0x00010740
#define DOLBY_PARAM_ID_IENB 0x00010744
#define DOLBY_PARAM_ID_IEBF 0x00010745
#define DOLBY_PARAM_ID_IEON 0x00010743
#define DOLBY_PARAM_ID_DEON 0x00010738
#define DOLBY_PARAM_ID_NGON 0x00010736
#define DOLBY_PARAM_ID_GEON 0x00010748
#define DOLBY_PARAM_ID_GENB 0x00010749
#define DOLBY_PARAM_ID_GEBF 0x0001074A
#define DOLBY_PARAM_ID_AONB 0x0001075B
#define DOLBY_PARAM_ID_AOBF 0x0001075C
#define DOLBY_PARAM_ID_AOBG 0x0001075D
#define DOLBY_PARAM_ID_AOON 0x00010759
#define DOLBY_PARAM_ID_ARNB 0x0001075F
#define DOLBY_PARAM_ID_ARBF 0x00010760
#define DOLBY_PARAM_ID_PLB 0x00010768
#define DOLBY_PARAM_ID_PLMD 0x00010767
#define DOLBY_PARAM_ID_DHSB 0x0001074E
#define DOLBY_PARAM_ID_DHRG 0x0001074F
#define DOLBY_PARAM_ID_DSSB 0x00010751
#define DOLBY_PARAM_ID_DSSA 0x00010752
#define DOLBY_PARAM_ID_DVLA 0x0001073D
#define DOLBY_PARAM_ID_IEBT 0x00010746
#define DOLBY_PARAM_ID_IEA 0x0001076A
#define DOLBY_PARAM_ID_DEA 0x00010739
#define DOLBY_PARAM_ID_DED 0x0001073A
#define DOLBY_PARAM_ID_GEBG 0x0001074B
#define DOLBY_PARAM_ID_AOCC 0x0001075A
#define DOLBY_PARAM_ID_ARBI 0x00010761
#define DOLBY_PARAM_ID_ARBL 0x00010762
#define DOLBY_PARAM_ID_ARBH 0x00010763
#define DOLBY_PARAM_ID_AROD 0x00010764
#define DOLBY_PARAM_ID_ARTP 0x00010765
#define DOLBY_PARAM_ID_VMON 0x00010756
#define DOLBY_PARAM_ID_VMB 0x00010757
#define DOLBY_PARAM_ID_VCNB 0x00010733
#define DOLBY_PARAM_ID_VCBF 0x00010734
#define DOLBY_PARAM_ID_PREG 0x00010728
#define DOLBY_PARAM_ID_VEN 0x00010732
#define DOLBY_PARAM_ID_PSTG 0x00010729
#define DOLBY_PARAM_ID_INIT_ENDP 0x00010727
/* Not Used with Set Param kcontrol, only to query using Get Param */
#define DOLBY_PARAM_ID_VER 0x00010726
#define DOLBY_PARAM_ID_VCBG 0x00010730
#define DOLBY_PARAM_ID_VCBE 0x00010731
/* DOLBY DAP control params */
#define DOLBY_COMMIT_ALL_TO_DSP 0x70000001
#define DOLBY_COMMIT_TO_DSP 0x70000002
#define DOLBY_USE_CACHE 0x70000003
#define DOLBY_AUTO_ENDP 0x70000004
#define DOLBY_AUTO_ENDDEP_PARAMS 0x70000005
#define DOLBY_DAP_BYPASS 0x70000006
#define DOLBY_ENABLE_CUSTOM_STEREO 0x000108c7
/* DOLBY DAP offsets start */
#define DOLBY_PARAM_VDHE_LENGTH 1
#define DOLBY_PARAM_VDHE_OFFSET 0
#define DOLBY_PARAM_VSPE_LENGTH 1
#define DOLBY_PARAM_VSPE_OFFSET (DOLBY_PARAM_VDHE_OFFSET + \
DOLBY_PARAM_VDHE_LENGTH)
#define DOLBY_PARAM_DSSF_LENGTH 1
#define DOLBY_PARAM_DSSF_OFFSET (DOLBY_PARAM_VSPE_OFFSET + \
DOLBY_PARAM_VSPE_LENGTH)
#define DOLBY_PARAM_DVLI_LENGTH 1
#define DOLBY_PARAM_DVLI_OFFSET (DOLBY_PARAM_DSSF_OFFSET + \
DOLBY_PARAM_DSSF_LENGTH)
#define DOLBY_PARAM_DVLO_LENGTH 1
#define DOLBY_PARAM_DVLO_OFFSET (DOLBY_PARAM_DVLI_OFFSET + \
DOLBY_PARAM_DVLI_LENGTH)
#define DOLBY_PARAM_DVLE_LENGTH 1
#define DOLBY_PARAM_DVLE_OFFSET (DOLBY_PARAM_DVLO_OFFSET + \
DOLBY_PARAM_DVLO_LENGTH)
#define DOLBY_PARAM_DVMC_LENGTH 1
#define DOLBY_PARAM_DVMC_OFFSET (DOLBY_PARAM_DVLE_OFFSET + \
DOLBY_PARAM_DVLE_LENGTH)
#define DOLBY_PARAM_DVME_LENGTH 1
#define DOLBY_PARAM_DVME_OFFSET (DOLBY_PARAM_DVMC_OFFSET + \
DOLBY_PARAM_DVMC_LENGTH)
#define DOLBY_PARAM_IENB_LENGTH 1
#define DOLBY_PARAM_IENB_OFFSET (DOLBY_PARAM_DVME_OFFSET + \
DOLBY_PARAM_DVME_LENGTH)
#define DOLBY_PARAM_IEBF_LENGTH 40
#define DOLBY_PARAM_IEBF_OFFSET (DOLBY_PARAM_IENB_OFFSET + \
DOLBY_PARAM_IENB_LENGTH)
#define DOLBY_PARAM_IEON_LENGTH 1
#define DOLBY_PARAM_IEON_OFFSET (DOLBY_PARAM_IEBF_OFFSET + \
DOLBY_PARAM_IEBF_LENGTH)
#define DOLBY_PARAM_DEON_LENGTH 1
#define DOLBY_PARAM_DEON_OFFSET (DOLBY_PARAM_IEON_OFFSET + \
DOLBY_PARAM_IEON_LENGTH)
#define DOLBY_PARAM_NGON_LENGTH 1
#define DOLBY_PARAM_NGON_OFFSET (DOLBY_PARAM_DEON_OFFSET + \
DOLBY_PARAM_DEON_LENGTH)
#define DOLBY_PARAM_GEON_LENGTH 1
#define DOLBY_PARAM_GEON_OFFSET (DOLBY_PARAM_NGON_OFFSET + \
DOLBY_PARAM_NGON_LENGTH)
#define DOLBY_PARAM_GENB_LENGTH 1
#define DOLBY_PARAM_GENB_OFFSET (DOLBY_PARAM_GEON_OFFSET + \
DOLBY_PARAM_GEON_LENGTH)
#define DOLBY_PARAM_GEBF_LENGTH 40
#define DOLBY_PARAM_GEBF_OFFSET (DOLBY_PARAM_GENB_OFFSET + \
DOLBY_PARAM_GENB_LENGTH)
#define DOLBY_PARAM_AONB_LENGTH 1
#define DOLBY_PARAM_AONB_OFFSET (DOLBY_PARAM_GEBF_OFFSET + \
DOLBY_PARAM_GEBF_LENGTH)
#define DOLBY_PARAM_AOBF_LENGTH 40
#define DOLBY_PARAM_AOBF_OFFSET (DOLBY_PARAM_AONB_OFFSET + \
DOLBY_PARAM_AONB_LENGTH)
#define DOLBY_PARAM_AOBG_LENGTH 329
#define DOLBY_PARAM_AOBG_OFFSET (DOLBY_PARAM_AOBF_OFFSET + \
DOLBY_PARAM_AOBF_LENGTH)
#define DOLBY_PARAM_AOON_LENGTH 1
#define DOLBY_PARAM_AOON_OFFSET (DOLBY_PARAM_AOBG_OFFSET + \
DOLBY_PARAM_AOBG_LENGTH)
#define DOLBY_PARAM_ARNB_LENGTH 1
#define DOLBY_PARAM_ARNB_OFFSET (DOLBY_PARAM_AOON_OFFSET + \
DOLBY_PARAM_AOON_LENGTH)
#define DOLBY_PARAM_ARBF_LENGTH 40
#define DOLBY_PARAM_ARBF_OFFSET (DOLBY_PARAM_ARNB_OFFSET + \
DOLBY_PARAM_ARNB_LENGTH)
#define DOLBY_PARAM_PLB_LENGTH 1
#define DOLBY_PARAM_PLB_OFFSET (DOLBY_PARAM_ARBF_OFFSET + \
DOLBY_PARAM_ARBF_LENGTH)
#define DOLBY_PARAM_PLMD_LENGTH 1
#define DOLBY_PARAM_PLMD_OFFSET (DOLBY_PARAM_PLB_OFFSET + \
DOLBY_PARAM_PLB_LENGTH)
#define DOLBY_PARAM_DHSB_LENGTH 1
#define DOLBY_PARAM_DHSB_OFFSET (DOLBY_PARAM_PLMD_OFFSET + \
DOLBY_PARAM_PLMD_LENGTH)
#define DOLBY_PARAM_DHRG_LENGTH 1
#define DOLBY_PARAM_DHRG_OFFSET (DOLBY_PARAM_DHSB_OFFSET + \
DOLBY_PARAM_DHSB_LENGTH)
#define DOLBY_PARAM_DSSB_LENGTH 1
#define DOLBY_PARAM_DSSB_OFFSET (DOLBY_PARAM_DHRG_OFFSET + \
DOLBY_PARAM_DHRG_LENGTH)
#define DOLBY_PARAM_DSSA_LENGTH 1
#define DOLBY_PARAM_DSSA_OFFSET (DOLBY_PARAM_DSSB_OFFSET + \
DOLBY_PARAM_DSSB_LENGTH)
#define DOLBY_PARAM_DVLA_LENGTH 1
#define DOLBY_PARAM_DVLA_OFFSET (DOLBY_PARAM_DSSA_OFFSET + \
DOLBY_PARAM_DSSA_LENGTH)
#define DOLBY_PARAM_IEBT_LENGTH 40
#define DOLBY_PARAM_IEBT_OFFSET (DOLBY_PARAM_DVLA_OFFSET + \
DOLBY_PARAM_DVLA_LENGTH)
#define DOLBY_PARAM_IEA_LENGTH 1
#define DOLBY_PARAM_IEA_OFFSET (DOLBY_PARAM_IEBT_OFFSET + \
DOLBY_PARAM_IEBT_LENGTH)
#define DOLBY_PARAM_DEA_LENGTH 1
#define DOLBY_PARAM_DEA_OFFSET (DOLBY_PARAM_IEA_OFFSET + \
DOLBY_PARAM_IEA_LENGTH)
#define DOLBY_PARAM_DED_LENGTH 1
#define DOLBY_PARAM_DED_OFFSET (DOLBY_PARAM_DEA_OFFSET + \
DOLBY_PARAM_DEA_LENGTH)
#define DOLBY_PARAM_GEBG_LENGTH 40
#define DOLBY_PARAM_GEBG_OFFSET (DOLBY_PARAM_DED_OFFSET + \
DOLBY_PARAM_DED_LENGTH)
#define DOLBY_PARAM_AOCC_LENGTH 1
#define DOLBY_PARAM_AOCC_OFFSET (DOLBY_PARAM_GEBG_OFFSET + \
DOLBY_PARAM_GEBG_LENGTH)
#define DOLBY_PARAM_ARBI_LENGTH 40
#define DOLBY_PARAM_ARBI_OFFSET (DOLBY_PARAM_AOCC_OFFSET + \
DOLBY_PARAM_AOCC_LENGTH)
#define DOLBY_PARAM_ARBL_LENGTH 40
#define DOLBY_PARAM_ARBL_OFFSET (DOLBY_PARAM_ARBI_OFFSET + \
DOLBY_PARAM_ARBI_LENGTH)
#define DOLBY_PARAM_ARBH_LENGTH 40
#define DOLBY_PARAM_ARBH_OFFSET (DOLBY_PARAM_ARBL_OFFSET + \
DOLBY_PARAM_ARBL_LENGTH)
#define DOLBY_PARAM_AROD_LENGTH 1
#define DOLBY_PARAM_AROD_OFFSET (DOLBY_PARAM_ARBH_OFFSET + \
DOLBY_PARAM_ARBH_LENGTH)
#define DOLBY_PARAM_ARTP_LENGTH 1
#define DOLBY_PARAM_ARTP_OFFSET (DOLBY_PARAM_AROD_OFFSET + \
DOLBY_PARAM_AROD_LENGTH)
#define DOLBY_PARAM_VMON_LENGTH 1
#define DOLBY_PARAM_VMON_OFFSET (DOLBY_PARAM_ARTP_OFFSET + \
DOLBY_PARAM_ARTP_LENGTH)
#define DOLBY_PARAM_VMB_LENGTH 1
#define DOLBY_PARAM_VMB_OFFSET (DOLBY_PARAM_VMON_OFFSET + \
DOLBY_PARAM_VMON_LENGTH)
#define DOLBY_PARAM_VCNB_LENGTH 1
#define DOLBY_PARAM_VCNB_OFFSET (DOLBY_PARAM_VMB_OFFSET + \
DOLBY_PARAM_VMB_LENGTH)
#define DOLBY_PARAM_VCBF_LENGTH 20
#define DOLBY_PARAM_VCBF_OFFSET (DOLBY_PARAM_VCNB_OFFSET + \
DOLBY_PARAM_VCNB_LENGTH)
#define DOLBY_PARAM_PREG_LENGTH 1
#define DOLBY_PARAM_PREG_OFFSET (DOLBY_PARAM_VCBF_OFFSET + \
DOLBY_PARAM_VCBF_LENGTH)
#define DOLBY_PARAM_VEN_LENGTH 1
#define DOLBY_PARAM_VEN_OFFSET (DOLBY_PARAM_PREG_OFFSET + \
DOLBY_PARAM_PREG_LENGTH)
#define DOLBY_PARAM_PSTG_LENGTH 1
#define DOLBY_PARAM_PSTG_OFFSET (DOLBY_PARAM_VEN_OFFSET + \
DOLBY_PARAM_VEN_LENGTH)
#define DOLBY_PARAM_INT_ENDP_LENGTH 1
#define DOLBY_PARAM_PAYLOAD_SIZE 3
#define DOLBY_MAX_LENGTH_INDIVIDUAL_PARAM 329
#define TOTAL_LENGTH_DOLBY_PARAM 745
#define DOLBY_VIS_PARAM_HEADER_SIZE 25
#define DOLBY_PARAM_VCNB_MAX_LENGTH 40
#define DOLBY_INVALID_PORT_ID -1
enum {
DEVICE_NONE = 0x0,
/* output devices */
EARPIECE = 0x1,
SPEAKER = 0x2,
WIRED_HEADSET = 0x4,
WIRED_HEADPHONE = 0x8,
BLUETOOTH_SCO = 0x10,
BLUETOOTH_SCO_HEADSET = 0x20,
BLUETOOTH_SCO_CARKIT = 0x40,
BLUETOOTH_A2DP = 0x80,
BLUETOOTH_A2DP_HEADPHONES = 0x100,
BLUETOOTH_A2DP_SPEAKER = 0x200,
AUX_DIGITAL = 0x400,
ANLG_DOCK_HEADSET = 0x800,
DGTL_DOCK_HEADSET = 0x1000,
USB_ACCESSORY = 0x2000,
USB_DEVICE = 0x4000,
REMOTE_SUBMIX = 0x8000,
ANC_HEADSET = 0x10000,
ANC_HEADPHONE = 0x20000,
PROXY = 0x2000000,
FM = 0x100000,
FM_TX = 0x1000000,
DEVICE_OUT_DEFAULT = 0x40000000,
DEVICE_OUT_ALL = 0x403FFFFF,
};
#endif

Some files were not shown because too many files have changed in this diff Show More