summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Wei <lucaswei@google.com>2021-07-26 21:22:01 +0800
committerLucas Wei <lucaswei@google.com>2021-07-26 21:22:01 +0800
commitb91d7d909e4e0724235ae5a549aabc59ced1c263 (patch)
tree06a1db673415392eb52dc0d3a44ad57b033b493f
parent7c6cfed3e7ea8bb6371872aa8700d8d1f01456f4 (diff)
parent45edbf733479053bb97caf86cbf982df96173351 (diff)
downloadmsm-extra-b91d7d909e4e0724235ae5a549aabc59ced1c263.tar.gz
Merge 'android-msm-barbet-4.19' into android-msm-pixel-4.19
Bug: 194667419 Signed-off-by: Lucas Wei <lucaswei@google.com> Change-Id: I6ce5a4180292b85b304d1efe6440e4f52c37e93f
-rw-r--r--asoc/codecs/Kbuild1
-rw-r--r--asoc/codecs/tas256x/Kbuild144
-rw-r--r--asoc/codecs/tas256x/Makefile23
-rw-r--r--asoc/codecs/tas256x/algo/inc/tas25xx-calib.h29
-rw-r--r--asoc/codecs/tas256x/algo/inc/tas_smart_amp_v2.h157
-rw-r--r--asoc/codecs/tas256x/algo/platform/qcom/tas25xx-algo-qdsp-intf.c114
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.c286
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.h67
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-algo-common.c278
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.c80
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.h36
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-algo-kbin-intf.c1015
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.c1061
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.h85
-rw-r--r--asoc/codecs/tas256x/algo/src/tas25xx-calib.c196
-rw-r--r--asoc/codecs/tas256x/logical_layer/inc/smartpa-debug-common.h7
-rw-r--r--asoc/codecs/tas256x/logical_layer/inc/tas256x-logic.h29
-rw-r--r--asoc/codecs/tas256x/logical_layer/src/smartpa-debug-common.c214
-rw-r--r--asoc/codecs/tas256x/logical_layer/src/tas256x-logic.c1428
-rw-r--r--asoc/codecs/tas256x/misc/tas256x-misc.c240
-rw-r--r--asoc/codecs/tas256x/misc/tas256x-misc.h38
-rw-r--r--asoc/codecs/tas256x/os_layer/inc/tas256x-codec.h30
-rw-r--r--asoc/codecs/tas256x/os_layer/inc/tas256x-regmap.h22
-rw-r--r--asoc/codecs/tas256x/os_layer/src/tas256x-codec.c1880
-rw-r--r--asoc/codecs/tas256x/os_layer/src/tas256x-regmap.c1676
-rw-r--r--asoc/codecs/tas256x/physical_layer/inc/tas2562.h743
-rw-r--r--asoc/codecs/tas256x/physical_layer/inc/tas2564.h735
-rw-r--r--asoc/codecs/tas256x/physical_layer/inc/tas256x-device.h203
-rw-r--r--asoc/codecs/tas256x/physical_layer/inc/tas256x.h693
-rw-r--r--asoc/codecs/tas256x/physical_layer/src/tas256x.c1588
-rw-r--r--asoc/kona.c52
-rw-r--r--asoc/msm-dai-fe.c2
-rw-r--r--config/litoauto.conf5
-rw-r--r--config/litoautoconf.h9
-rw-r--r--dsp/q6afe.c437
-rw-r--r--include/dsp/tas_qualcomm.h69
36 files changed, 13670 insertions, 2 deletions
diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild
index 6dc44429..91149d22 100644
--- a/asoc/codecs/Kbuild
+++ b/asoc/codecs/Kbuild
@@ -233,6 +233,7 @@ ifeq ($(KERNEL_BUILD), 1)
obj-y += bolero/
obj-y += rouleur/
obj-y += wsa883x/
+ obj-y += tas256x/
obj-y += sdm660_cdc/
endif
# Module information used by KBuild framework
diff --git a/asoc/codecs/tas256x/Kbuild b/asoc/codecs/tas256x/Kbuild
new file mode 100644
index 00000000..fb320607
--- /dev/null
+++ b/asoc/codecs/tas256x/Kbuild
@@ -0,0 +1,144 @@
+# 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
+
+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)
+
+############ TAS256X ############
+
+ifdef CONFIG_SND_SOC_TAS256X
+ TAS256X_OBJS += os_layer/src/tas256x-codec.o
+ TAS256X_OBJS += os_layer/src/tas256x-regmap.o
+ TAS256X_OBJS += physical_layer/src/tas256x.o
+ TAS256X_OBJS += logical_layer/src/tas256x-logic.o
+endif
+
+ifdef CONFIG_TAS25XX_ALGO
+ TAS256X_OBJS += algo/src/tas25xx-algo-intf.o
+ TAS256X_OBJS += algo/src/tas25xx-algo-common.o
+ TAS256X_OBJS += algo/src/tas25xx-calib.o
+endif
+
+ifdef CONFIG_PLATFORM_QCOM
+ TAS256X_OBJS += algo/platform/qcom/tas25xx-algo-qdsp-intf.o
+endif
+
+ifdef CONFIG_TAS25XX_CALIB_VAL_BIG
+ TAS256X_OBJS += algo/src/tas25xx-calib-validation.o
+endif
+
+ifdef CONFIG_TAS256X_MISC
+ TAS256X_OBJS += misc/tas256x-misc.o
+endif
+
+ifdef CONFIG_TISA_DEBUGFS_INTF
+ TAS256X_OBJS += algo/src/tas25xx-algo-debugfs.o
+ TAS256X_OBJS += logical_layer/smartpa-debug-common.o
+endif
+
+ifdef CONFIG_TISA_BIN_INTF
+ TAS256X_OBJS += algo/src/tas25xx-algo-bin-intf.o
+endif
+
+ifdef CONFIG_PLATFORM_MTK
+ TAS256X_OBJS += algo/src/tas256x-mtk-wrapper.o
+endif
+
+ifdef CONFIG_TISA_KBIN_INTF
+ TAS256X_OBJS += algo/src/tas25xx-algo-kbin-intf.o
+ TAS256X_OBJS += algo/src/tas25xx-algo-bin-utils.o
+endif
+
+LINUX_INC += -Iinclude/linux
+
+INCS += $(COMMON_INC) \
+ $(UAPI_INC)
+
+EXTRA_CFLAGS += $(INCS)
+
+
+CDEFINES += -DANI_LITTLE_BYTE_ENDIAN \
+ -DANI_LITTLE_BIT_ENDIAN \
+ -DDOT11F_LITTLE_ENDIAN_HOST \
+ -DANI_COMPILER_TYPE_GCC \
+ -DANI_OS_TYPE_ANDROID=6 \
+ -DPTT_SOCK_SVC_ENABLE \
+ -Wall\
+ -Werror\
+ -D__linux__
+
+KBUILD_CPPFLAGS += $(CDEFINES)
+
+# Currently, for versions of gcc which support it, the kernel Makefile
+# is disabling the maybe-uninitialized warning. Re-enable it for the
+# AUDIO driver. Note that we must use EXTRA_CFLAGS here so that it
+# will override the kernel settings.
+ifeq ($(call cc-option-yn, -Wmaybe-uninitialized),y)
+EXTRA_CFLAGS += -Wmaybe-uninitialized
+endif
+#EXTRA_CFLAGS += -Wmissing-prototypes
+
+ifeq ($(call cc-option-yn, -Wheader-guard),y)
+EXTRA_CFLAGS += -Wheader-guard
+endif
+
+ifeq ($(KERNEL_BUILD), 0)
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/ipc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/dsp/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers
+KBUILD_EXTRA_SYMBOLS +=$(OUT)/obj/vendor/qcom/opensource/audio-kernel/soc/Module.symvers
+endif
+
+# Module information used by KBuild framework
+obj-$(CONFIG_SND_SOC_TAS256X) += tas256x_dlkm.o
+tas256x_dlkm-y := $(TAS256X_OBJS)
+
+# inject some build related information
+DEFINES += -DBUILD_TIMESTAMP=\"$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')\"
diff --git a/asoc/codecs/tas256x/Makefile b/asoc/codecs/tas256x/Makefile
new file mode 100644
index 00000000..ed75ee05
--- /dev/null
+++ b/asoc/codecs/tas256x/Makefile
@@ -0,0 +1,23 @@
+EXTRA_CFLAGS= -I$(shell pwd)
+obj-y += snd-soc-tas256x.o
+
+snd-soc-tas256x-y := os_layer/src/tas256x-codec.o \
+ os_layer/src/tas256x-regmap.o \
+ physical_layer/src/tas256x.o \
+ logical_layer/src/tas256x-logic.o
+
+snd-soc-tas256x-$(CONFIG_TAS256X_MISC) += misc/tas256x-misc.o
+snd-soc-tas256x-$(CONFIG_TAS25XX_ALGO) += algo/src/tas25xx-algo-intf.o \
+ algo/src/tas25xx-calib.o \
+ algo/src/tas25xx-algo-common.o
+
+snd-soc-tas256x-$(CONFIG_PLATFORM_QCOM) += algo/platform/qcom/tas25xx-algo-qdsp-intf.o
+snd-soc-tas256x-$(CONFIG_TISA_KBIN_INTF) += algo/src/tas25xx-algo-kbin-intf.o \
+ algo/src/tas25xx-algo-bin-utils.o
+
+
+snd-soc-tas256x-$(CONFIG_TAS25XX_CALIB_VAL_BIG) += algo/src/tas25xx-calib-validation.o
+snd-soc-tas256x-$(CONFIG_TISA_DEBUGFS_INTF) += algo/src/tas25xx-algo-debugfs.o \
+ logical_layer/src/smartpa-debug-common.o
+snd-soc-tas256x-$(CONFIG_TISA_BIN_INTF) += algo/src/tas25xx-algo-bin-intf.o
+snd-soc-tas256x-$(CONFIG_PLATFORM_MTK) += algo/platform/mtk/tas256x-mtk-wrapper.o11
diff --git a/asoc/codecs/tas256x/algo/inc/tas25xx-calib.h b/asoc/codecs/tas256x/algo/inc/tas25xx-calib.h
new file mode 100644
index 00000000..1a264a3a
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/inc/tas25xx-calib.h
@@ -0,0 +1,29 @@
+/*
+ ** ===========================================================================
+ ** Copyright (c) 2016 Texas Instruments Inc.
+ **
+ ** This program is free software; you can redistribute it and/or modify it
+ ** under the terms of the GNU General Public License as published by the Free
+ ** Software Foundation; version 2.
+ **
+ ** This program is distributed in the hope that it will be useful, but
+ ** WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ ** or FITNESSFOR A PARTICULAR PURPOSE. See the GNU General Public License
+ ** for more details.
+ **
+ ** File:
+ ** tas25xx-calib.h
+ **
+ ** Description:
+ ** header file for tas25xx-calib.c
+ **
+ ** ===========================================================================
+ */
+
+#ifndef _TAS25XX_CALIB_H_
+#define _TAS25XX_CALIB_H_
+
+int tas_calib_init(void);
+void tas_calib_exit(void);
+
+#endif /* _TAS25XX_CALIB_H */
diff --git a/asoc/codecs/tas256x/algo/inc/tas_smart_amp_v2.h b/asoc/codecs/tas256x/algo/inc/tas_smart_amp_v2.h
new file mode 100644
index 00000000..b85f1c1b
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/inc/tas_smart_amp_v2.h
@@ -0,0 +1,157 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas25xx-algo-bin-utils.c
+**
+** Description:
+** Common algo related header.
+**
+** =============================================================================
+*/
+#ifndef __TAS_SMART_AMP__
+#define __TAS_SMART_AMP__
+
+#include <linux/types.h>
+#include <sound/soc.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+struct snd_soc_component;
+#else
+struct snd_soc_codec;
+#endif
+
+typedef enum {
+ TISA_MOD_RX = 0,
+ TISA_MOD_TX = 1,
+ TISA_MOD_END = 2
+} module_id_t;
+
+#define CAPI_V2_TAS_TX_ENABLE 0x10012D14
+#define CAPI_V2_TAS_TX_CFG 0x10012D16
+#define CAPI_V2_TAS_RX_ENABLE 0x10012D13
+#define CAPI_V2_TAS_RX_CFG 0x10012D15
+
+#define TI_SMARTPA_VENDOR_ID 1234
+
+/* FIXME */
+/* update this value at OEM/ODM */
+/* #pragma message("########### FIXME ################") */
+/* #define SMARTAMP_SPEAKER_CALIBDATA_FILE "/mnt/vendor/persist/audio/tas25xx_calib.bin" */
+#define SMARTAMP_SPEAKER_CALIBDATA_FILE "/persist/audio/smartamp_calib.bin"
+
+#define MAX_DSP_PARAM_INDEX 2048
+#define MAX_CHANNELS 2
+
+#define TAS_SET_PARAM 0
+#define TAS_GET_PARAM 1
+
+#define CHANNEL0 1
+#define CHANNEL1 2
+
+#define TRUE 1
+#define FALSE 0
+
+#define TAS_DSP_SWAP_IDX 3
+
+#define TAS_SA_GET_F0 3810
+#define TAS_SA_GET_Q 3811
+#define TAS_SA_GET_TV 3812
+#define TAS_SA_GET_RE 3813
+#define TAS_SA_CALIB_INIT 3814
+#define TAS_SA_CALIB_DEINIT 3815
+#define TAS_SA_SET_RE 3816
+#define TAS_SA_F0_TEST_INIT 3817
+#define TAS_SA_F0_TEST_DEINIT 3818
+#define TAS_SA_SET_PROFILE 3819
+#define TAS_SA_GET_STATUS 3821
+#define TAS_SA_SET_SPKID 3822
+#define TAS_SA_SET_TCAL 3823
+#define TAS_SA_EXC_TEMP_STAT 3824
+
+#define TAS_SA_IV_VBAT_FMT 3825
+
+#define TAS_SA_VALID_INIT 3831
+#define TAS_SA_VALID_DEINIT 3832
+#define TAS_SA_GET_VALID_STATUS 3833
+#define TAS_SA_SET_BYPASS_MODE 3834
+#define TAS_SA_GET_OP_MODE 3835
+#define TAS_SA_SET_INTERFACE_MODE 3836
+#define TAS_PCM_CHANNEL_MAPPING 3837
+#define TAS_SA_GET_RE_RANGE 3838
+
+/*Added for DC Detection*/
+#define CAPI_V2_TAS_SA_DC_DETECT 0x40404040
+
+#define CALIB_START 1
+#define CALIB_STOP 2
+#define TEST_START 3
+#define TEST_STOP 4
+
+#define SLAVE1 0x98
+#define SLAVE2 0x9A
+#define SLAVE3 0x9C
+#define SLAVE4 0x9E
+
+#define TAS_SA_IS_SPL_IDX(X) ((((X) >= 3810) && ((X) < 3899)) ? 1 : 0)
+#define TAS_CALC_PARAM_IDX(I, LEN, CH) ((I) | ((LEN) << 16) | ((CH) << 28))
+#define AFE_SA_IS_SPL_IDX(X) TAS_SA_IS_SPL_IDX(X)
+
+
+typedef enum {
+ IV_SENSE_FORMAT_NO_VBAT = 0,
+ IV_SENSE_FORMAT_12_BIT_WITH_8BIT_VBAT = 1,
+ IV_SENSE_FORMAT_8_BIT_WITH_8BIT_VBAT = 2,
+ IV_SENSE_FORMAT_16_BIT_WITH_8BIT_VBAT = 3,
+} ti_smartamp_iv_vbat_format_t;
+
+/*
+ * List all the other profiles other than none and calibration.
+ */
+#define TAS_ALGO_PROFILE_LIST "MUSIC", "VOICE", "VOIP", "RINGTONE"
+
+void tas25xx_parse_algo_dt(struct device_node *np);
+typedef int (*dsp_set_get_f)(u8 *user_data, uint32_t param_id,
+ uint8_t get_set, uint32_t length, module_id_t module_id);
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+void tas_smartamp_add_algo_controls(struct snd_soc_component *codec,
+ struct device *dev, int number_of_channels);
+void tas_smartamp_remove_algo_controls(struct snd_soc_component *codec);
+void tas_smartamp_add_codec_mixer_controls(struct snd_soc_component *codec);
+#else
+void tas_smartamp_add_algo_controls(struct snd_soc_codec *codec,
+ struct device *dev, int number_of_channels);
+void tas_smartamp_remove_algo_controls(struct snd_soc_codec *codec);
+void tas_smartamp_add_codec_mixer_controls(struct snd_soc_codec *codec);
+#endif
+bool tas25xx_set_iv_bit_fomat(int iv_data_with, int vbat, int update_now);
+
+int get_iv_vbat_format(void);
+
+void tas25xx_send_channel_mapping(void);
+
+#if IS_ENABLED(CONFIG_TISA_KBIN_INTF)
+void tas25xx_algo_set_active (void);
+void tas25xx_algo_set_inactive (void);
+void tas_smartamp_kbin_deinitalize (void);
+#endif /* CONFIG_TISA_KBIN_INTF */
+
+#if IS_ENABLED(CONFIG_TAS25XX_CALIB_VAL_BIG)
+void tas25xx_send_algo_calibration(void);
+void tas25xx_update_big_data(void);
+#endif
+
+#endif /*__TAS_SMART_AMP__*/
diff --git a/asoc/codecs/tas256x/algo/platform/qcom/tas25xx-algo-qdsp-intf.c b/asoc/codecs/tas256x/algo/platform/qcom/tas25xx-algo-qdsp-intf.c
new file mode 100644
index 00000000..37388cb7
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/platform/qcom/tas25xx-algo-qdsp-intf.c
@@ -0,0 +1,114 @@
+/*
+** =============================================================================
+** Copyright (c) 2017 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+**
+** File:
+** tas25xx-algo-qdsp-intf.c
+**
+** Description:
+** Qcom interface wrapper.
+**
+** =============================================================================
+*/
+#include <linux/types.h>
+#include <linux/of.h>
+#include <dsp/tas_qualcomm.h>
+#include "../../inc/tas_smart_amp_v2.h"
+
+#define AFE_SMARTAMP_MODULE_RX 0x11111112
+#define AFE_SMARTAMP_MODULE_TX 0x11111111
+#define AFE_SMARTAMP_DFAULT_PORT 0x9000
+
+static uint16_t g_afe_port_id_rx = 0xFFFF;
+static int g_afe_initalized;
+static uint32_t s_tisa_module_id[] = {
+ AFE_SMARTAMP_MODULE_RX,
+ AFE_SMARTAMP_MODULE_TX
+};
+
+static void set_port_id_rx(uint16_t port_id)
+{
+ g_afe_port_id_rx = port_id;
+}
+
+static inline uint16_t get_rx_port_id(void)
+{
+ return g_afe_port_id_rx;
+}
+
+static void tas25xx_afe_init(void)
+{
+ if (g_afe_initalized)
+ return;
+
+ afe_tas_smartamp_init(s_tisa_module_id[0], s_tisa_module_id[1]);
+ g_afe_initalized = 1;
+}
+
+void tas25xx_parse_algo_dt_qdsp_intf(struct device_node *np)
+{
+ uint32_t port_id = 0;
+ uint32_t module_id = 0;
+ int32_t ret = 0;
+
+ ret = of_property_read_u32(np, "ti,port_id", &port_id);
+ if (!ret) {
+ set_port_id_rx ((uint16_t)port_id);
+ pr_info("[TI-SmartPA:%s] ti,port_id=0x%x", __func__, port_id);
+ }
+
+ ret = of_property_read_u32(np, "ti,module_id_rx", &module_id);
+ if (!ret) {
+ pr_info("[TI-SmartPA:%s] ti,module_id_rx=0x%x", __func__, module_id);
+ s_tisa_module_id[TISA_MOD_RX] = module_id;
+ }
+
+ ret = of_property_read_u32(np, "ti,module_id_tx", &module_id);
+ if (!ret) {
+ pr_info("[TI-SmartPA:%s] ti,module_id_tx=0x%x", __func__, module_id);
+ s_tisa_module_id[TISA_MOD_TX] = module_id;
+ }
+
+ return;
+}
+EXPORT_SYMBOL(tas25xx_parse_algo_dt_qdsp_intf);
+
+int tas25xx_smartamp_get_set(u8 *user_data, uint32_t param_id,
+ uint8_t get_set, uint32_t length, module_id_t mod_id_i)
+{
+ int ret = 0;
+ uint32_t module_id;
+
+ if (mod_id_i > 2)
+ return -EINVAL;
+
+ module_id = s_tisa_module_id[mod_id_i];
+
+ tas25xx_afe_init();
+
+ switch (get_set) {
+ case TAS_SET_PARAM:
+ ret = afe_tas_smartamp_set_calib_data(module_id, param_id,
+ length, user_data, get_rx_port_id());
+ break;
+
+ case TAS_GET_PARAM:
+ memset(user_data, 0, length);
+ ret = afe_tas_smartamp_get_calib_data(module_id,
+ param_id, length, user_data, get_rx_port_id());
+ break;
+
+ default:
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(tas25xx_smartamp_get_set);
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.c b/asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.c
new file mode 100644
index 00000000..36cba8cd
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.c
@@ -0,0 +1,286 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas25xx-algo-bin-utils.c
+**
+** Description:
+** Algorithm parameter's binary file utility wrapper.
+**
+** =============================================================================
+*/
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/slab.h>
+
+#include "tas25xx-algo-bin-utils.h"
+
+const char *binfilenames[NUM_SPK_TYPES] = {
+ "tas25xx_TI_0.bin",
+ "tas25xx_TI_1.bin",
+ "tas25xx_TI_2.bin",
+ "tas25xx_TI_3.bin"
+};
+
+static struct bin_file_data_t s_bin = {
+ .uses_bin_file = 0,
+ .parse_done = 0,
+ .profile_id = 0,
+ .spk_id = 0,
+ .bytes_per_prof_per_channel = 0,
+ .number_of_profiles = 0,
+ .no_of_channels = 0,
+ .single_profile_size = 0,
+ .profile_data = NULL,
+};
+
+static struct device *s_dev;
+
+void bin_file_set_device(struct device *dev)
+{
+ s_dev = dev;
+}
+
+static inline struct device *bin_file_get_device(void)
+{
+ return s_dev;
+}
+
+/*
+ * returns 0 on success, -ve errorcode otherwise
+ */
+int bin_file_parse_init(void)
+{
+ int ret = 0;
+ char metadata[SA_BIN_MDATA_SZ] = { 0 };
+ char header[SA_BIN_HDR_SIZE] = { 0 };
+ uint32_t *header_ptr = (uint32_t *)header;
+ const struct firmware *fw_entry = NULL;
+ struct device *dev;
+ int32_t i = 0;
+ int bin_data_size;
+
+ int32_t *data;
+ int32_t version;
+ int32_t time;
+ char *ddc;
+ char ddcl[64] = { 0 };
+
+ s_bin.uses_bin_file = 1;
+
+ if (s_bin.profile_data)
+ return 0;
+
+ dev = bin_file_get_device();
+ if (!dev) {
+ pr_err("TI-SmartPA BIN: struct device is null\n");
+ return -EINVAL;
+ }
+
+ if ((s_bin.spk_id >= 0) && (s_bin.spk_id < NUM_SPK_TYPES)) {
+ printk(KERN_INFO "TI-SmartPA BIN : Speaker ID:%d,Bin file : %s\n", s_bin.spk_id, binfilenames[s_bin.spk_id]);
+ ret = request_firmware(&fw_entry, binfilenames[s_bin.spk_id], dev);
+ if (ret || !fw_entry || !fw_entry->data || (fw_entry->size < (SA_BIN_MDATA_SZ+SA_BIN_HDR_SIZE))) {
+ printk(KERN_ERR "TI-SmartPA BIN : request_firmware failed with error=%d, fw_entry=%p, size=%d\n", ret, fw_entry,
+ fw_entry ? (int)fw_entry->size : 0);
+ return ret;
+ }
+
+ memcpy(metadata, fw_entry->data, SA_BIN_MDATA_SZ);
+
+ data = (int32_t *)metadata;
+ version = data[0];
+ time = data[1];
+
+ ddc = (char *)data;
+ while (((71 - i) > 8) && ddc[71 - i]) {
+ ddcl[i] = ddc[71 - i];
+ i++;
+ }
+
+ printk(KERN_INFO "TI-SmartPA BIN: Version = 0x%x\n", version);
+ printk(KERN_INFO "TI-SmartPA BIN: Time = %d seconds from epoch time\n", time);
+ printk(KERN_INFO "TI-SmartPA BIN: DDC Name = %s\n", ddcl);
+ printk(KERN_INFO "TI-SmartPA BIN: metadata read !!\n");
+
+ memcpy(header, (char *)(fw_entry->data) + SA_BIN_MDATA_SZ, SA_BIN_HDR_SIZE);
+ s_bin.number_of_profiles = header_ptr[0];
+ s_bin.no_of_channels = (header_ptr[1] >> 24) & 0xFF;
+ s_bin.single_profile_size = header_ptr[1] & 0xFFFF;
+ s_bin.bytes_per_prof_per_channel = s_bin.single_profile_size / s_bin.no_of_channels;
+
+ printk(KERN_INFO"TI-SmartPA BIN: [BIN]: num of prof=%d, num of ch=%d, single profile sz=%d\n",
+ s_bin.number_of_profiles,
+ s_bin.no_of_channels,
+ s_bin.single_profile_size);
+
+ bin_data_size = s_bin.number_of_profiles * s_bin.single_profile_size;
+ if (bin_data_size == (fw_entry->size - SA_BIN_MDATA_SZ - SA_BIN_HDR_SIZE)) {
+ s_bin.profile_data = kmalloc(bin_data_size, GFP_KERNEL);
+ } else {
+ printk(KERN_ERR "TI-SmartPA BIN : size mismatch bin vs firmware\n");
+ s_bin.profile_data = NULL;
+ }
+
+ if (!s_bin.profile_data) {
+ printk(KERN_ERR "TI-SmartPA BIN : kmalloc failed\n");
+ bin_file_parse_deinit();
+ ret = -ENOMEM;
+ } else {
+ char *data_start = ((char *)(fw_entry->data)) + SA_BIN_MDATA_SZ + SA_BIN_HDR_SIZE;
+ memcpy (s_bin.profile_data, data_start, bin_data_size);
+ s_bin.parse_done = 1;
+ printk(KERN_INFO "TI-SmartPA BIN: [BIN]: Read %d bytes successfully !!!\n", bin_data_size);
+ }
+
+ release_firmware(fw_entry);
+ } else {
+ printk(KERN_ERR "TI-SmartPA BIN : Invalid speaker ID : %d\n", s_bin.spk_id);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+/*
+ * 1 is success, 0 is false
+ */
+bool bin_file_parse_status(void)
+{
+ if (s_bin.uses_bin_file && s_bin.parse_done)
+ return true;
+
+ return false;
+}
+
+/* parse profile apr */
+bool bin_file_get_profile_data(char **buf, int *size)
+{
+ bool success = false;
+ int profile_id;
+
+ if (s_bin.profile_id < 0) {
+ s_bin.profile_id = 0;
+ }
+
+ profile_id = s_bin.profile_id;
+
+ printk(KERN_INFO "TI-SmartPA BIN: [BIN] load_profile %d", s_bin.profile_id);
+
+ /*
+ * profile_id [0- g_number_of_profiles)
+ */
+ if (!bin_file_parse_init() && (profile_id < s_bin.number_of_profiles) && buf && size) {
+
+ int sz = s_bin.bytes_per_prof_per_channel;
+ uint8_t *ptr = (uint8_t *)s_bin.profile_data;
+ ptr += (profile_id * s_bin.single_profile_size);
+ *buf = ptr;
+
+ if (s_bin.no_of_channels == 2) {
+ sz += s_bin.bytes_per_prof_per_channel;
+ }
+
+ *size = sz;
+ success = true;
+ } else {
+ printk(KERN_INFO "TI-SmartPA BIN:[BIN] error parsing bin file!!!");
+ }
+
+ return success;
+}
+
+void bin_file_parse_deinit(void)
+{
+
+ bool temp = s_bin.uses_bin_file;
+ int old_spk_id = s_bin.spk_id;
+ int old_profile_id = s_bin.profile_id;
+ if (s_bin.profile_data)
+ kfree(s_bin.profile_data);
+
+ memset(&s_bin, 0, sizeof(s_bin));
+
+ s_bin.profile_id = old_profile_id;
+ s_bin.spk_id = old_spk_id;
+ s_bin.uses_bin_file = temp;
+}
+
+void bin_file_set_profile_id(int profile_id)
+{
+ s_bin.profile_id = profile_id;
+}
+
+void bin_file_set_spk_id(int spk_id)
+{
+
+ bin_file_parse_deinit();
+ s_bin.spk_id = spk_id;
+}
+
+/*read only functions*/
+int bin_file_get_profile_id(void)
+{
+ return s_bin.profile_id;
+}
+
+int bin_file_get_spk_id(void)
+{
+ return s_bin.spk_id;
+}
+
+int bin_file_get_number_of_channels(void)
+{
+ return s_bin.no_of_channels;
+}
+
+bool uses_bin_file(void)
+{
+ return s_bin.uses_bin_file;
+}
+
+int bin_file_get_per_profile_per_channel_param_count(void)
+{
+ return s_bin.bytes_per_prof_per_channel / sizeof(int);
+}
+
+int32_t *bin_file_get_profile_0_data_pointer(void)
+{
+ if (s_bin.uses_bin_file && s_bin.parse_done)
+ return (int32_t *)s_bin.profile_data;
+
+ return NULL;
+}
+
+/**
+ * custom value start - size
+ * custom value 1
+ * custom value 2
+ */
+int32_t bin_file_get_custom_value_by_idx(int index_request, int *value)
+{
+ int custom_index_start;
+ int ret = -EINVAL;
+
+ int32_t *data = bin_file_get_profile_0_data_pointer();
+ if (data && value) {
+ custom_index_start = data[CUSTOM_VALUE_INDEX_PTR];
+ if (custom_index_start && (index_request < data[custom_index_start])) {
+ custom_index_start += 1; /* points to data - index 0 */
+ *value = data[custom_index_start + index_request];
+ ret = 0;
+ }
+ }
+
+ return ret;
+}
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.h b/asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.h
new file mode 100644
index 00000000..d04a3e0a
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-algo-bin-utils.h
@@ -0,0 +1,67 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas25xx-algo-bin-utils.c
+**
+** Description:
+** Algorithm parameter's binary file utility header file.
+**
+** =============================================================================
+*/
+#ifndef __BIN_IN_KERNEL_H__
+#define __BIN_IN_KERNEL_H__
+
+#include <linux/types.h>
+
+#define SA_BIN_HDR_SIZE 16 /*Bin file header size*/
+#define SA_BIN_MDATA_SZ 72
+#define DEFAULT_SMARTAMP_PROFILE 0
+#define NUM_SPK_TYPES 4
+#define CUSTOM_VALUE_INDEX_PTR 19
+
+struct bin_file_data_t {
+ int uses_bin_file;
+ int parse_done;
+ int profile_id;
+ int spk_id;
+ int bytes_per_prof_per_channel;
+ int number_of_profiles;
+ int no_of_channels;
+ int single_profile_size;
+ int *profile_data;
+};
+
+int bin_file_parse_init(void);
+bool bin_file_parse_status(void);
+bool bin_file_get_profile_data(char **buf, int *size);
+void bin_file_parse_deinit(void);
+
+void bin_file_set_profile_id(int profile_id);
+
+void bin_file_set_spk_id(int spk_id);
+
+int bin_file_get_profile_id(void);
+int bin_file_get_spk_id(void);
+bool uses_bin_file(void);
+int bin_file_get_per_profile_per_channel_param_count(void);
+int *bin_file_get_profile_0_data_pointer(void);
+
+int bin_file_get_number_of_channels(void);
+
+void bin_file_set_device(struct device *dev);
+
+/* Custom index access*/
+/* index starts from 0 */
+int32_t bin_file_get_custom_value_by_idx(int index_request, int *value);
+
+#endif /*__BIN_IN_KERNEL_H__*/
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-algo-common.c b/asoc/codecs/tas256x/algo/src/tas25xx-algo-common.c
new file mode 100644
index 00000000..dc479478
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-algo-common.c
@@ -0,0 +1,278 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas25xx-algo-common.c
+**
+** Description:
+** Basic common interface required for the algorithm.
+**
+** =============================================================================
+*/
+#include <sound/soc.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include "algo/inc/tas25xx-calib.h"
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "tas25xx-algo-bin-utils.h"
+#include "tas25xx-algo-intf.h"
+
+#define TDM_MAX_CHANNELS 4
+
+#if IS_ENABLED(CONFIG_PLATFORM_QCOM)
+#include <dsp/tas_qualcomm.h>
+void tas25xx_parse_algo_dt_qdsp_intf(struct device_node *np);
+#endif /*CONFIG_PLATFORM_XXX*/
+
+#if IS_ENABLED(CONFIG_TISA_DEBUGFS_INTF)
+void tas25xx_parse_algo_dt_debugfs(struct device_node *np);
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+int tas_smartamp_add_algo_controls_debugfs(struct snd_soc_component *codec,
+ int number_of_channels);
+void tas_smartamp_remove_algo_controls_debugfs(struct snd_soc_component *codec);
+#else
+int tas_smartamp_add_algo_controls_debugfs(struct snd_soc_codec *codec,
+ int number_of_channels);
+void tas_smartamp_remove_algo_controls_debugfs(struct snd_soc_codec *codec);
+#endif
+#endif
+
+#if IS_ENABLED(CONFIG_TAS25XX_CALIB_VAL_BIG)
+#include "tas25xx-calib-validation.h"
+#endif
+
+static int32_t g_fmt;
+static struct device *s_device;
+static char s_channel_map[TDM_MAX_CHANNELS] = {0, 1, 2, 3};
+
+struct soc_multi_control_ch_map {
+ int min, max, platform_max, count;
+ unsigned int reg, rreg, shift, rshift, invert;
+};
+
+int get_iv_vbat_format(void)
+{
+ return g_fmt;
+}
+
+void tas25xx_algo_set_device (struct device *dev)
+{
+ s_device = dev;
+}
+
+struct device *tas25xx_algo_get_device(void)
+{
+ return s_device;
+}
+
+bool tas25xx_set_iv_bit_fomat(int iv_data_with, int vbat, int update_now)
+{
+ int32_t param_id;
+ int32_t ret;
+ bool success;
+
+ if ((vbat == 1) && (iv_data_with == 12))
+ g_fmt = IV_SENSE_FORMAT_12_BIT_WITH_8BIT_VBAT;
+ else if ((vbat == 1) && (iv_data_with == 8))
+ g_fmt = IV_SENSE_FORMAT_8_BIT_WITH_8BIT_VBAT;
+ else if ((vbat == 1) && (iv_data_with == 16))
+ g_fmt = IV_SENSE_FORMAT_16_BIT_WITH_8BIT_VBAT;
+ else
+ g_fmt = IV_SENSE_FORMAT_NO_VBAT;
+
+ success = true;
+
+ if (update_now) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_IV_VBAT_FMT, 1, CHANNEL0);
+ pr_info("TI-SmartPA: %s: Sending IV,Vbat format %d\n",
+ __func__, g_fmt);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&g_fmt, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("TI-SmartPA: %s: Failed to set config\n",
+ __func__);
+ success = false;
+ }
+
+ }
+
+ return success;
+}
+EXPORT_SYMBOL(tas25xx_set_iv_bit_fomat);
+
+void tas25xx_send_channel_mapping(void)
+{
+ int ret;
+ int32_t param_id;
+
+ param_id = TAS_CALC_PARAM_IDX(TAS_PCM_CHANNEL_MAPPING,
+ TDM_MAX_CHANNELS/sizeof(int32_t), CHANNEL0);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)s_channel_map, param_id,
+ TAS_SET_PARAM, TDM_MAX_CHANNELS, TISA_MOD_RX);
+ if (ret)
+ pr_err("TI-SmartPA: %s, Error sending, ret=%d\n", __func__, ret);
+}
+
+/**
+ Common Mixer Controls required for all interfaces
+**/
+/* get api shall return the cached values from set api. Default mapping if not set*/
+static int tas25xx_algo_get_channel_map(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i;
+ for (i = 0; i < TDM_MAX_CHANNELS; i++) {
+ pr_debug("TI-SmartPA: %s idx=%d, value=%d\n", __func__, i, (int)s_channel_map[i]);
+ ucontrol->value.integer.value[i] = (unsigned int) s_channel_map[i];
+ }
+
+ return 0;
+}
+
+static int tas25xx_algo_put_channel_map(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i;
+ char channel_map[TDM_MAX_CHANNELS];
+
+ for (i = 0; i < TDM_MAX_CHANNELS; i++) {
+ channel_map[i] = (char)(ucontrol->value.integer.value[i]);
+ pr_debug("TI-SmartPA: %s mapping - index %d = channel %d\n",
+ __func__, i, channel_map[i]);
+ }
+
+ memcpy(s_channel_map, channel_map, sizeof(channel_map));
+ return 0;
+}
+
+int tas25xx_algo_channel_map_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct soc_multi_control_ch_map *mc =
+ (struct soc_multi_control_ch_map *)kcontrol->private_value;
+
+ pr_debug("TI-SmartPA: %s count=%d, platform_max=%d\n", __func__, mc->count,
+ mc->platform_max);
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = mc->count;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mc->platform_max;
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new tas25xx_algo_common_controls[] = {
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "TAS25XX_ALGO_RX_CH_MAP",
+ .info = tas25xx_algo_channel_map_info,
+ .get = tas25xx_algo_get_channel_map,
+ .put = tas25xx_algo_put_channel_map,
+ .private_value = (unsigned long) &(struct soc_multi_control_ch_map) {
+ .reg = SND_SOC_NOPM,
+ .shift = 0,
+ .rshift = 0,
+ .max = TDM_MAX_CHANNELS,
+ .count = TDM_MAX_CHANNELS,
+ .platform_max = 16,
+ .invert = 0,
+ }
+ }
+};
+
+void tas25xx_parse_algo_dt(struct device_node *np)
+{
+#if IS_ENABLED(CONFIG_PLATFORM_QCOM)
+ tas25xx_parse_algo_dt_qdsp_intf (np);
+#endif
+
+#if IS_ENABLED(CONFIG_TISA_DEBUGFS_INTF)
+ tas25xx_parse_algo_dt_debugfs(np);
+#endif
+}
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+void tas_smartamp_add_algo_controls(struct snd_soc_component *codec,
+ struct device *dev, int number_of_channels)
+#else
+void tas_smartamp_add_algo_controls(struct snd_soc_codec *codec,
+ struct device *dev, int number_of_channels)
+#endif
+{
+ pr_info("TI-SmartPA: %s: Adding smartamp controls\n", __func__);
+
+ g_fmt = 0;
+
+ tas25xx_smartamp_alg_intf_init();
+
+#if IS_ENABLED(CONFIG_TISA_DEBUGFS_INTF)
+ pr_err("TI-SmartPA: %s: Adding debugfs controls\n", __func__);
+ tas_smartamp_add_algo_controls_debugfs(codec, number_of_channels);
+#endif
+
+#if IS_ENABLED(CONFIG_TAS25XX_CALIB_VAL_BIG)
+ tas25xx_algo_add_calib_valid_bigdata(number_of_channels);
+#endif
+
+ /* Some common interfaces used*/
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ snd_soc_add_component_controls(codec, tas25xx_algo_common_controls,
+ ARRAY_SIZE(tas25xx_algo_common_controls));
+#else
+ snd_soc_add_codec_controls(codec, tas25xx_algo_common_controls,
+ ARRAY_SIZE(tas25xx_algo_common_controls));
+#endif
+
+#if IS_ENABLED(CONFIG_TISA_BIN_INTF)
+ pr_err("TI-SmartPA: %s: Adding bin intf controls\n", __func__);
+ tas_smartamp_add_codec_mixer_controls(codec);
+#endif
+
+#if IS_ENABLED(CONFIG_TISA_KBIN_INTF)
+ tas_smartamp_add_codec_mixer_controls (codec);
+ tas25xx_algo_set_device (dev);
+ bin_file_set_device (dev);
+ bin_file_parse_init();
+
+ pr_info("TI-SmartPA: %s: Initialising kbin file done\n", __func__);
+#endif
+
+ tas_calib_init();
+}
+EXPORT_SYMBOL(tas_smartamp_add_algo_controls);
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+void tas_smartamp_remove_algo_controls(struct snd_soc_component *codec)
+#else
+void tas_smartamp_remove_algo_controls(struct snd_soc_codec *codec)
+#endif
+{
+#if IS_ENABLED(CONFIG_TISA_DEBUGFS_INTF)
+ tas_smartamp_remove_algo_controls_debugfs(codec);
+#endif
+
+#if IS_ENABLED(CONFIG_TAS25XX_CALIB_VAL_BIG)
+ tas25xx_algo_remove_calib_valid_bigdata();
+#endif
+
+#if IS_ENABLED(CONFIG_TISA_KBIN_INTF)
+ tas_smartamp_kbin_deinitalize ();
+ tas25xx_algo_set_device(NULL);
+ bin_file_set_device(NULL);
+ bin_file_parse_deinit();
+#endif
+
+ tas25xx_smartamp_alg_intf_deinit();
+ tas_calib_exit();
+}
+EXPORT_SYMBOL(tas_smartamp_remove_algo_controls);
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.c b/asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.c
new file mode 100644
index 00000000..c583d570
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.c
@@ -0,0 +1,80 @@
+/*
+ * =============================================================================
+ * Copyright (c) 2016 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * File:
+ * tas25xx-algo-intf.c
+ *
+ * Description:
+ * Wrapper on Interface to algorithm.
+ *
+ * =============================================================================
+ */
+#include <sound/soc.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include "algo/inc/tas25xx-calib.h"
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "tas25xx-algo-bin-utils.h"
+#include "tas25xx-algo-intf.h"
+
+static int s_tas_smartamp_bypass;
+static int init_once;
+static struct mutex smartpa_algo_lock;
+
+void tas25xx_set_algo_bypass(int bypass)
+{
+ s_tas_smartamp_bypass = bypass;
+}
+
+int tas25xx_get_algo_bypass(void)
+{
+ return s_tas_smartamp_bypass;
+}
+
+void tas25xx_smartamp_alg_intf_init(void)
+{
+ if (!init_once) {
+ mutex_init(&smartpa_algo_lock);
+ pr_info("tas mutex init");
+ init_once = 1;
+ }
+}
+
+void tas25xx_smartamp_alg_intf_deinit(void)
+{
+ if (init_once) {
+ mutex_destroy(&smartpa_algo_lock);
+ pr_info("tas mutex destroy");
+ init_once = 0;
+ }
+}
+
+/*Wrapper arround set/get parameter,
+ *all set/get commands pass through this wrapper
+ */
+int tas25xx_smartamp_algo_ctrl(u8 *user_data, uint32_t param_id,
+ uint8_t get_set, uint32_t length, module_id_t module_id)
+{
+ int ret = 0;
+
+ if (!s_tas_smartamp_bypass) {
+ mutex_lock(&smartpa_algo_lock);
+ ret = tas25xx_smartamp_get_set(user_data, param_id, get_set,
+ length, module_id);
+ mutex_unlock(&smartpa_algo_lock);
+ } else {
+ pr_info("TI-SmartPA: %s: algo set/get is bypassed\n", __func__);
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL(tas25xx_smartamp_algo_ctrl);
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.h b/asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.h
new file mode 100644
index 00000000..1b4ba055
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-algo-intf.h
@@ -0,0 +1,36 @@
+/*
+ * =============================================================================
+ * Copyright (c) 2016 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * File:
+ * tas25xx-algo-intf.h
+ *
+ * Description:
+ * Header file for Wrapper on interface to algorithm.
+ *
+ * =============================================================================
+ */
+#ifndef __TAS25XX_ALGO_INTF__
+#define __TAS25XX_ALGO_INTF__
+
+void tas25xx_smartamp_alg_intf_init(void);
+void tas25xx_smartamp_alg_intf_deinit(void);
+int tas25xx_smartamp_algo_ctrl(u8 *user_data, uint32_t param_id,
+ uint8_t get_set, uint32_t length, module_id_t module_id);
+
+/* bypass set and get */
+int tas25xx_get_algo_bypass(void);
+void tas25xx_set_algo_bypass(int bypass);
+
+int tas25xx_smartamp_get_set(u8 *user_data, uint32_t param_id,
+ uint8_t get_set, uint32_t length, module_id_t mod_id_i);
+
+#endif /* __TAS25XX_ALGO_INTF__ */
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-algo-kbin-intf.c b/asoc/codecs/tas256x/algo/src/tas25xx-algo-kbin-intf.c
new file mode 100644
index 00000000..171dee93
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-algo-kbin-intf.c
@@ -0,0 +1,1015 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas25xx-algo-kbin-intf.c
+**
+** Description:
+** Algorithm interface wrapper to open the parameter bin file in kernel
+** using "request_firmware" API
+**
+** =============================================================================
+*/
+#include <sound/soc.h>
+#include <linux/delay.h> /* usleep_range */
+#include <linux/kernel.h>
+#include <linux/types.h> /* atomic_t */
+#include <linux/workqueue.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "algo/inc/tas25xx-calib.h"
+#include "tas25xx-algo-bin-utils.h"
+#include "tas25xx-algo-intf.h"
+
+#if IS_ENABLED(CONFIG_SND_SOC_CODEC_DETECT)
+#include <linux/codec-misc.h>
+#endif
+
+#define POISON_VAL 0xDEADDEAD
+#define MAX_STRING (300)
+#define QFORMAT19 19
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+
+static struct delayed_work query_tisa_algo_wrk;
+static atomic_t algo_active = ATOMIC_INIT(0);
+
+/*Master Control to Bypass the Smartamp TI CAPIv2 module*/
+static int s_tas_smartamp_enable;
+static int s_allow_dsp_query;
+static int s_calib_test_flag;
+
+/* fwd declaration */
+static int tas25xx_get_re_common(int channel);
+struct device *tas25xx_algo_get_device(void);
+
+/*Max value supported is 2^8*/
+static int trans_val_to_user_m(int val, int qformat, int scale)
+{
+ int ret = (int)(((long long)val * scale) >> qformat) % scale;
+ return ret;
+}
+
+/*Max value supported is 2^8*/
+static int trans_val_to_user_i(int val, int qformat)
+{
+ return ((val * 100) >> qformat) / 100;
+}
+
+#if IS_ENABLED(CONFIG_SND_SOC_CODEC_DETECT)
+static int trans_val_to_int(int val, int scale, int qformat)
+{
+ return trans_val_to_user_i(val, qformat) * scale +
+ trans_val_to_user_m(val, qformat, scale);
+}
+#endif
+
+#ifdef CONFIG_SET_RE_IN_KERNEL
+static int get_calibrated_re_tcalib(uint32_t *rdc_fix, uint32_t *tv_fix, int channel_count)
+{
+ int ret = 0;
+ int calib_re_sz;
+ uint32_t *calib_data;
+ struct device *dev;
+ const struct firmware *fw_entry;
+
+ static uint32_t s_rdc_fix[2] = { POISON_VAL, POISON_VAL };
+ static uint32_t s_tv_fix = POISON_VAL;
+
+ if ((s_rdc_fix[0] == POISON_VAL) &&
+ (s_rdc_fix[1] == POISON_VAL)) {
+ ret = -EINVAL;
+ dev = tas25xx_algo_get_device();
+ if (dev)
+ ret = request_firmware(&fw_entry, "smartamp_calib.bin", dev);
+
+ if (ret) {
+ pr_err("[TI-SmartPA: %s] request_firmware failed, err=%d!\n", __func__, ret);
+ return ret;
+ }
+
+ calib_re_sz = (channel_count * sizeof(uint32_t));
+ calib_data = (int32_t *) fw_entry->data;
+ /*calib re + temp*/
+ if (fw_entry->size < (calib_re_sz + 1)) {
+ memcpy(s_rdc_fix, calib_data, calib_re_sz);
+ memcpy(&s_tv_fix, calib_data + calib_re_sz, sizeof(uint32_t));
+ }
+
+ release_firmware(fw_entry);
+ }
+
+ if (ret == 0) {
+ if (rdc_fix) {
+ rdc_fix[0] = (uint32_t)s_rdc_fix[0];
+ if (channel_count == 2)
+ rdc_fix[1] = (uint32_t)s_rdc_fix[1];
+ }
+ if (tv_fix)
+ *tv_fix = (uint32_t)s_tv_fix;
+ }
+ return ret;
+}
+#endif /*CONFIG_SET_RE_IN_KERNEL*/
+
+void tas25xx_algo_set_inactive(void)
+{
+ atomic_set(&algo_active, 0);
+ s_tas_smartamp_enable = 0;
+
+ pr_info("[TI-SmartPA:%s] algo disabled..", __func__);
+
+ bin_file_set_profile_id(0);
+ s_calib_test_flag = 0;
+}
+
+void tas25xx_algo_set_active(void)
+{
+ atomic_set(&algo_active, 1);
+ schedule_delayed_work(&query_tisa_algo_wrk, msecs_to_jiffies(1000));
+}
+
+static void query_tisa_algo(struct work_struct *wrk)
+{
+ int sleep_ms;
+ int sleep_us;
+ int sleep_us_max;
+ int ret;
+ int temp;
+ int re_l = 0, re_r = 0;
+#if IS_ENABLED(CONFIG_SND_SOC_CODEC_DETECT)
+ int scale = 100000;
+#endif
+
+ ret = bin_file_get_custom_value_by_idx(0, &sleep_ms);
+ if (ret) {
+ sleep_ms = 1000;
+ }
+
+ sleep_us = sleep_ms * 1000;
+ sleep_us_max = sleep_us + 1000;
+
+ pr_info("TI-SmartPA: Re query interval is set to %d(ms)\n", sleep_ms);
+
+ while (atomic_read(&algo_active)) {
+
+ temp = s_allow_dsp_query;
+ s_allow_dsp_query = 1;
+ re_l = tas25xx_get_re_common(CHANNEL0);
+ re_r = tas25xx_get_re_common(CHANNEL1);
+ s_allow_dsp_query = temp;
+
+#if IS_ENABLED(CONFIG_SND_SOC_CODEC_DETECT)
+ codec_misc_amp_put(0, (long)trans_val_to_int(re_l, scale, QFORMAT19));
+ codec_misc_amp_put(1, (long)trans_val_to_int(re_r, scale, QFORMAT19));
+#endif
+ pr_debug("[TI-SmartPA:%s] Re value is %02d.%02d (%d), %02d.%02d (%d) \n",
+ __func__,
+ (int32_t)trans_val_to_user_i(re_l, QFORMAT19),
+ (int32_t)trans_val_to_user_m(re_l, QFORMAT19, 100),
+ re_l,
+ (int32_t)trans_val_to_user_i(re_r, QFORMAT19),
+ (int32_t)trans_val_to_user_m(re_r, QFORMAT19, 100),
+ re_r);
+
+ usleep_range(sleep_us, sleep_us_max);
+ }
+}
+
+static int tas25xx_send_kbin_params(void)
+{
+ int ret = -EINVAL;
+ int profile_size_bytes = 0;
+ int param_id = 0;
+ int sent = 0;
+ int ch = CHANNEL0;
+ int param_sz_rem;
+ int current_idx = 0;
+ u16 size;
+ int i;
+
+ char *profile_data = NULL;
+ int *data;
+
+ int per_ch_param_sz = bin_file_get_per_profile_per_channel_param_count();
+ int number_of_ch = bin_file_get_number_of_channels();
+ bool success = bin_file_get_profile_data(&profile_data, &profile_size_bytes);
+
+ if (success && profile_data && profile_size_bytes) {
+ data = (int *)profile_data;
+ ret = 0;
+
+ for (i = 0; i < number_of_ch; i++) {
+ ch = i + 1;
+ sent = 0;
+ param_sz_rem = per_ch_param_sz;
+ for (current_idx = 0; current_idx < per_ch_param_sz; ) {
+ /*size = MIN(1000, param_sz_rem);*/
+ size = MIN(100, param_sz_rem);
+ param_id = TAS_CALC_PARAM_IDX(current_idx, size, ch);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)data, param_id,
+ TAS_SET_PARAM, size * sizeof(int), TISA_MOD_RX);
+ if (ret) {
+ pr_err("TI-SmartPA: %s data send error = %d\n", __func__, ret);
+ }
+ data += size;
+ sent += size;
+ param_sz_rem -= size;
+ current_idx += size;
+
+ pr_debug("TI-SmartPA: %s send=%d, param_sz_rem=%d(total=%d), last sent sz=%d\n",
+ __func__, sent, param_sz_rem, per_ch_param_sz, size);
+ }
+ }
+ }
+
+ /*send swap index*/
+ if (ret == 0) {
+ int user_data = 1;
+ param_id = TAS_CALC_PARAM_IDX(TAS_DSP_SWAP_IDX, 1, CHANNEL0);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+
+ if (ch == CHANNEL1) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_DSP_SWAP_IDX, 1, CHANNEL1);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ }
+ }
+
+ return ret;
+
+}
+
+/*Control-1: Set Profile*/
+static const char *profile_index_text[] = {
+ "NONE", TAS_ALGO_PROFILE_LIST, "CALIB" };
+static const struct soc_enum profile_index_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(profile_index_text),
+ profile_index_text),
+};
+
+static int tas25xx_set_profile_kbin(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int profile_id = pUcontrol->value.integer.value[0];
+ int max_number_of_profiles =
+ sizeof(profile_index_text) / sizeof(profile_index_text[0]);
+
+ if ((profile_id >= max_number_of_profiles) || (profile_id < 0))
+ return -EINVAL;
+
+ pr_info("TI-SmartPA: %s: Setting profile %s \n",
+ __func__, profile_index_text[profile_id]);
+ if (profile_id)
+ profile_id -= 1;
+ else
+ return 0;
+
+ bin_file_set_profile_id(profile_id);
+
+ /*playback started*/
+ if (s_tas_smartamp_enable) {
+ tas25xx_send_kbin_params ();
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_profile_kbin(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int profile_id = bin_file_get_profile_id();
+ int max_number_of_profiles =
+ sizeof(profile_index_text) / sizeof(profile_index_text[0]);
+
+ pUcontrol->value.integer.value[0] = profile_id;
+ if ((profile_id < max_number_of_profiles) && (profile_id > -1))
+ pr_info("TI-SmartPA: %s: getting profile %s\n",
+ __func__, profile_index_text[profile_id]);
+
+ return 0;
+}
+
+/*Control-2: Set Calibrated Rdc*/
+static int tas25xx_set_Re_common(int re_value_in, int channel)
+{
+ int ret;
+ int param_id = 0;
+ int re_value = re_value_in;
+
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, channel);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&re_value, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+
+ return ret;
+}
+
+static int tas25xx_set_Re_left(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int re_value = pUcontrol->value.integer.value[0];
+
+ pr_info("TI-SmartPA: %s: Setting Re %d", __func__, re_value);
+ return tas25xx_set_Re_common(re_value, CHANNEL0);
+}
+
+static int tas25xx_dummy_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+
+ pUcontrol->value.integer.value[0] = 0;
+ return ret;
+}
+
+static int tas25xx_dummy_set(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ return 0;
+}
+
+/*Control-3: Calibration and Test(F0,Q,Tv) Controls*/
+static const char *tas25xx_calib_test_text[] = {
+ "NONE",
+ "CALIB_START",
+ "CALIB_STOP",
+ "TEST_START",
+ "TEST_STOP"
+};
+
+static const struct soc_enum tas25xx_calib_test_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_calib_test_text),
+ tas25xx_calib_test_text),
+};
+
+static int tas25xx_calib_test_set_common(int calib_command, int channel)
+{
+ int ret = 0;
+ int param_id = 0;
+ int data = 1;
+
+ switch (calib_command) {
+ case CALIB_START:
+ pr_info("TI-SmartPA: %s: CALIB_START", __func__);
+ s_calib_test_flag = 1;
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_CALIB_INIT, 1, channel);
+ break;
+
+ case CALIB_STOP:
+ pr_info("TI-SmartPA: %s: CALIB_STOP", __func__);
+ s_calib_test_flag = 0;
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_CALIB_DEINIT, 1, channel);
+ break;
+
+ case TEST_START:
+ s_calib_test_flag = 1;
+ break;
+
+ case TEST_STOP:
+ s_calib_test_flag = 0;
+ break;
+
+ default:
+ pr_info("TI-SmartPA: %s: no impl calib_command %d\n",
+ __func__, calib_command);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (param_id) {
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0) {
+ s_calib_test_flag = 0;
+ pr_err("TI-SmartPA: %s: Failed to set calib/test, ret=%d\n",
+ __func__, ret);
+ }
+ }
+
+ return ret;
+}
+
+static int tas25xx_calib_test_set(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int user_data = pUcontrol->value.integer.value[0];
+
+ ret = tas25xx_calib_test_set_common(user_data, CHANNEL0);
+
+ if (ret == 0) {
+#ifdef CONFIG_TAS25XX_ALGO_STEREO
+ ret = tas25xx_calib_test_set_common(user_data, CHANNEL1);
+#endif
+ }
+
+ return ret;
+}
+
+/*Control-4: Get Re*/
+/*returns -ve error or +ve re value, 0 if not called*/
+static int tas25xx_get_re_common(int channel)
+{
+ int ret = 0;
+ int re_value = 0;
+ int param_id = 0;
+
+ pr_debug("TI-SmartPA: %s, channel=%d\n", __func__, channel);
+
+ if (s_tas_smartamp_enable && (s_calib_test_flag || s_allow_dsp_query)) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_RE, 1, channel);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&re_value, param_id,
+ TAS_GET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0)
+ pr_err("TI-SmartPA: %s: Failed to get Re\n", __func__);
+ else
+ ret = re_value;
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_re_left(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = tas25xx_get_re_common(CHANNEL0);
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ ret = 0;
+ pr_info("TI-SmartPA: %s: Getting Re %d\n", __func__, ret);
+ }
+
+ return ret;
+}
+
+/*Control-5: Get F0*/
+static int tas25xx_get_f0_common(int channel)
+{
+ int f0_value = 0;
+ int param_id = 0;
+ int ret = 0;
+
+ pr_info("TI-SmartPA: %s, channel=%d\n", __func__, channel);
+
+ if (s_tas_smartamp_enable && (s_calib_test_flag || s_allow_dsp_query)) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_F0, 1, channel);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&f0_value, param_id,
+ TAS_GET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0)
+ pr_err("TI-SmartPA: %s: Failed to get F0\n", __func__);
+ else
+ ret = f0_value;
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_f0_left(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = tas25xx_get_f0_common(CHANNEL0);
+
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ pr_info("TI-SmartPA: %s: Getting F0 val=%d\n", __func__, ret);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*Control-6: Get Q*/
+static int tas25xx_get_q_common(int channel)
+{
+ int ret = 0;
+ int q_value = 0;
+ int param_id = 0;
+
+ pr_info("TI-SmartPA: %s, channel=%d", __func__, channel);
+
+ if (s_tas_smartamp_enable && (s_calib_test_flag || s_allow_dsp_query)) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_Q, 1, channel);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&q_value, param_id,
+ TAS_GET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0)
+ pr_err("TI-SmartPA: %s: Failed to get F0\n", __func__);
+ else
+ ret = q_value;
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_q_left(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = tas25xx_get_q_common(CHANNEL0);
+
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ pr_info("TI-SmartPA: %s: Getting Q %d\n", __func__, ret);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*Control-7: Get Tv*/
+static int tas25xx_get_tv_common(int channel)
+{
+ int ret = 0;
+ int tv_value = 0;
+ int param_id = 0;
+
+ pr_info("TI-SmartPA: %s, channel=%d", __func__, channel);
+
+ if (s_tas_smartamp_enable && (s_calib_test_flag || s_allow_dsp_query)) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_TV, 1, channel);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&tv_value, param_id,
+ TAS_GET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0)
+ pr_err("TI-SmartPA: %s: Failed to get Tv\n", __func__);
+ else
+ ret = tv_value;
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_tv_left(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+
+ int ret = tas25xx_get_tv_common(CHANNEL0);
+
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ pr_info("TI-SmartPA: %s: Getting Tv %d\n", __func__, ret);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+/*Control-8: Smartamp Enable*/
+static const char *tas25xx_smartamp_enable_text[] = {
+ "DISABLE",
+ "ENABLE"
+};
+
+static const struct soc_enum tas25xx_smartamp_enable_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_enable_text),
+ tas25xx_smartamp_enable_text),
+};
+
+static int tas25xx_smartamp_enable_set_kbin(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int param_id = 0;
+ int user_data = pUcontrol->value.integer.value[0];
+#ifdef CONFIG_SET_RE_IN_KERNEL
+ uint32_t calibration_data[3];
+#endif
+
+#ifdef CONFIG_TAS25XX_ALGO_STEREO
+ int number_of_ch = 2;
+#else
+ int number_of_ch = 1;
+#endif
+
+ if (tas25xx_get_algo_bypass()) {
+ pr_info("TI-SmartPA: bypass enabled, not enabling\n");
+ return 0;
+ }
+
+ pr_info("TI-SmartPA: %s: case %d, number_of_ch=%d\n",
+ __func__, user_data, number_of_ch);
+
+ s_tas_smartamp_enable = user_data;
+ if (s_tas_smartamp_enable == 0) {
+ pr_info("TI-SmartPA: %s: Disable called\n", __func__);
+ return 0;
+ }
+
+ pr_info("TI-SmartPA: %s: Sending TX Enable\n", __func__);
+ param_id = CAPI_V2_TAS_TX_ENABLE;
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_TX);
+ if (ret) {
+ pr_err("TI-SmartPA: %s: TX Enable Failed ret = 0x%x\n",
+ __func__, ret);
+ goto fail_cmd;
+ }
+
+ user_data = 1;
+ pr_info("TI-SmartPA: %s: Sending RX Enable\n", __func__);
+ param_id = CAPI_V2_TAS_RX_ENABLE;
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret) {
+ pr_err("TI-SmartPA: %s: RX Enable Failed ret = 0x%x\n",
+ __func__, ret);
+ goto fail_cmd;
+ }
+
+ tas25xx_send_kbin_params();
+
+ user_data = 0xCCCCB1B1;
+ pr_info("TI-SmartPA: %s: Sending TX Config\n", __func__);
+ param_id = CAPI_V2_TAS_TX_CFG;
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_TX);
+ if (ret < 0) {
+ pr_err("TI-SmartPA: %s: Failed to set config\n", __func__);
+ goto fail_cmd;
+ }
+
+ user_data = 0xCCCCB1B1;
+ pr_info("TI-SmartPA: %s: Sending RX Config\n", __func__);
+ param_id = CAPI_V2_TAS_RX_CFG;
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("TI-SmartPA: %s: Failed to set config\n", __func__);
+ goto fail_cmd;
+ }
+
+ tas25xx_send_channel_mapping();
+
+ user_data = get_iv_vbat_format();
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_IV_VBAT_FMT, 1, CHANNEL0);
+ pr_info("TI-SmartPA: %s: Sending IV,Vbat format %d\n",
+ __func__, user_data);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&user_data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("TI-SmartPA: %s: Failed to set config\n", __func__);
+ goto fail_cmd;
+ }
+
+ s_tas_smartamp_enable = true;
+
+#ifdef CONFIG_SET_RE_IN_KERNEL
+ if (number_of_ch == 2)
+ ret = get_calibrated_re_tcalib(calibration_data,
+ &calibration_data[2], number_of_ch);
+ else
+ ret = get_calibrated_re_tcalib(calibration_data,
+ &calibration_data[1], number_of_ch);
+
+ if (ret) {
+ pr_err("[Smartamp:%s] unable to get the calibration data = 0x%x\n",
+ __func__, ret);
+ /* TODO: Ignore the calibration read error */
+ ret = 0;
+ } else {
+ int32_t t_cal;
+ if (number_of_ch == 2) {
+ t_cal = calibration_data[2];
+ pr_info("[Smartamp:%s] setting re %d,%d and tcal %d\n",
+ __func__, calibration_data[0],
+ calibration_data[1],
+ calibration_data[2]);
+ } else {
+ t_cal = calibration_data[1];
+ pr_info("[Smartamp:%s] setting re %d and tcal %d\n",
+ __func__, calibration_data[0],
+ calibration_data[1]);
+ }
+
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, CHANNEL0);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&t_cal,
+ param_id, TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("[Smartamp:%s] Failed to set Tcal\n", __func__);
+ goto fail_cmd;
+ }
+
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, CHANNEL0);
+ ret = tas25xx_smartamp_algo_ctrl(
+ (u8 *)(&(calibration_data[0])),
+ param_id, TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("TI-SmartPA: %s: Failed to set Re\n", __func__);
+ goto fail_cmd;
+ }
+
+ if (number_of_ch == 2) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, CHANNEL1);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&(calibration_data[1]),
+ param_id, TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("TI-SmartPA: %s: Failed to set Re\n",
+ __func__);
+ goto fail_cmd;
+ }
+ }
+ }
+#endif /* CONFIG_SET_RE_IN_KERNEL */
+
+ tas25xx_algo_set_active();
+
+fail_cmd:
+ return ret;
+}
+
+static int tas25xx_smartamp_enable_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int user_data = s_tas_smartamp_enable;
+
+ pUcontrol->value.integer.value[0] = user_data;
+ pr_info("TI-SmartPA: %s: case %d(0=DISABLE, 1=ENABLE)\n",
+ __func__, user_data);
+ return ret;
+}
+
+/*Control-9: Smartamp Bypass */
+static const char *tas25xx_smartamp_bypass_text[] = {
+ "FALSE",
+ "TRUE"
+};
+
+static const struct soc_enum tas25xx_smartamp_bypass_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_bypass_text), tas25xx_smartamp_bypass_text),
+};
+
+static int tas25xx_smartamp_bypass_set(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int user_data = pUcontrol->value.integer.value[0];
+
+ if (s_tas_smartamp_enable) {
+ pr_debug("TI-SmartPA: %s: cannot update while smartamp enabled\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ tas25xx_set_algo_bypass (user_data);
+ pr_info("TI-SmartPA: %s: case %d(FALSE=0,TRUE=1)\n",
+ __func__, user_data);
+ return ret;
+}
+
+static int tas25xx_smartamp_bypass_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+
+ pUcontrol->value.integer.value[0] = tas25xx_get_algo_bypass();
+ pr_info("TI-SmartPA: %s: case %d\n", __func__, (int)pUcontrol->value.integer.value[0]);
+ return ret;
+}
+
+/*Control-9: Smartamp Bypass */
+static const char *tas25xx_smartamp_debug_enable_text[] = {
+ "FALSE",
+ "TRUE"
+};
+
+static const struct soc_enum tas25xx_smartamp_debug_enable_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas25xx_smartamp_debug_enable_text),
+ tas25xx_smartamp_debug_enable_text),
+};
+
+static int tas25xx_smartamp_debug_enable_set(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int user_data = pUcontrol->value.integer.value[0];
+
+ s_allow_dsp_query = user_data;
+ pr_info("TI-SmartPA: %s: case %d(FALSE=0,TRUE=1)\n",
+ __func__, user_data);
+ return ret;
+}
+
+static int tas25xx_smartamp_debug_enable_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+
+ pUcontrol->value.integer.value[0] = s_allow_dsp_query;
+ pr_info("TI-SmartPA: %s: case %d\n", __func__, s_allow_dsp_query);
+ return ret;
+}
+
+static int tas25xx_set_spk_id_kbin(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int spk_id = pUcontrol->value.integer.value[0];
+ bin_file_set_spk_id(spk_id);
+ pr_info("TI-SmartPA: %s: spk-id set %d\n", __func__, spk_id);
+ return ret;
+}
+
+static int tas25xx_set_t_calib(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = 0;
+ int calib_temp = pUcontrol->value.integer.value[0];
+ int param_id = 0;
+
+ pr_info("TI-SmartPA: %s: tcalib set %d\n", __func__, calib_temp);
+ if (s_tas_smartamp_enable) {
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, CHANNEL0);
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&calib_temp, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t),
+ TISA_MOD_RX);
+ if (ret < 0)
+ pr_err("TI-SmartPA: %s: Failed to set spk id\n",
+ __func__);
+ }
+
+ return ret;
+}
+
+#ifdef CONFIG_TAS25XX_ALGO_STEREO
+static int tas25xx_set_Re_right(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int re_value = pUcontrol->value.integer.value[0];
+
+ pr_info("TI-SmartPA: %s: Setting Re %d\n", __func__, re_value);
+ return tas25xx_set_Re_common(re_value, CHANNEL1);
+}
+
+static int tas25xx_get_re_right(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret;
+
+ ret = tas25xx_get_re_common(CHANNEL1);
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ ret = 0;
+ pr_info("TI-SmartPA: %s: Getting Re value=%d\n",
+ __func__, ret);
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_f0_right(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = tas25xx_get_f0_common(CHANNEL1);
+
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ pr_info("TI-SmartPA: %s: Getting F0 valu=%d\n", __func__, ret);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_q_right(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = tas25xx_get_q_common(CHANNEL1);
+
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ pr_info("TI-SmartPA: %s: Getting Q val=%d\n", __func__, ret);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int tas25xx_get_tv_right(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int ret = tas25xx_get_tv_common(CHANNEL1);
+
+ if (ret >= 0) {
+ pUcontrol->value.integer.value[0] = ret;
+ pr_info("TI-SmartPA: %s: Getting Tv %d\n", __func__, ret);
+ ret = 0;
+ }
+
+ return ret;
+}
+#endif
+
+static int tas25xx_smartamp_set_bin_updated(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pUcontrol)
+{
+ int update = pUcontrol->value.integer.value[0];
+ if (update) {
+ bin_file_parse_deinit();
+ bin_file_parse_init();
+ }
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new smartamp_tas25xx_mixer_controls[] = {
+ SOC_ENUM_EXT("TAS25XX_DEBUG_ENABLE", tas25xx_smartamp_debug_enable_enum[0],
+ tas25xx_smartamp_debug_enable_get,
+ tas25xx_smartamp_debug_enable_set),
+ SOC_ENUM_EXT("TAS25XX_ALGO_PROFILE", profile_index_enum[0],
+ tas25xx_get_profile_kbin, tas25xx_set_profile_kbin),
+ SOC_ENUM_EXT("TAS25XX_ALGO_CALIB_TEST", tas25xx_calib_test_enum[0],
+ tas25xx_dummy_get, tas25xx_calib_test_set),
+ SOC_SINGLE_EXT("TAS25XX_SET_SPK_ID", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_dummy_get, tas25xx_set_spk_id_kbin),
+ SOC_SINGLE_EXT("TAS25XX_SET_T_CALIB", SND_SOC_NOPM, 0, 100, 0,
+ tas25xx_dummy_get, tas25xx_set_t_calib),
+
+ /*left*/
+ SOC_SINGLE_EXT("TAS25XX_SET_RE_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_dummy_get, tas25xx_set_Re_left),
+ SOC_SINGLE_EXT("TAS25XX_GET_RE_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_re_left, tas25xx_dummy_set),
+ SOC_SINGLE_EXT("TAS25XX_GET_F0_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_f0_left, tas25xx_dummy_set),
+ SOC_SINGLE_EXT("TAS25XX_GET_Q_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_q_left, tas25xx_dummy_set),
+ SOC_SINGLE_EXT("TAS25XX_GET_TV_LEFT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_tv_left, tas25xx_dummy_set),
+
+ SOC_SINGLE_EXT("TAS25XX_PARAMS_UPDATED", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_dummy_get, tas25xx_smartamp_set_bin_updated),
+
+ /*Right*/
+#ifdef CONFIG_TAS25XX_ALGO_STEREO
+ SOC_SINGLE_EXT("TAS25XX_SET_RE_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_dummy_get, tas25xx_set_Re_right),
+ SOC_SINGLE_EXT("TAS25XX_GET_RE_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_re_right, tas25xx_dummy_set),
+ SOC_SINGLE_EXT("TAS25XX_GET_F0_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_f0_right, tas25xx_dummy_set),
+ SOC_SINGLE_EXT("TAS25XX_GET_Q_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_q_right, tas25xx_dummy_set),
+ SOC_SINGLE_EXT("TAS25XX_GET_TV_RIGHT", SND_SOC_NOPM, 0, 0x7fffffff, 0,
+ tas25xx_get_tv_right, tas25xx_dummy_set),
+#endif
+ SOC_ENUM_EXT("TAS25XX_SMARTPA_ENABLE", tas25xx_smartamp_enable_enum[0],
+ tas25xx_smartamp_enable_get,
+ tas25xx_smartamp_enable_set_kbin),
+
+ SOC_ENUM_EXT("TAS25XX_ALGO_BYPASS", tas25xx_smartamp_bypass_enum[0],
+ tas25xx_smartamp_bypass_get,
+ tas25xx_smartamp_bypass_set),
+};
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+void tas_smartamp_add_codec_mixer_controls(struct snd_soc_component *codec)
+#else
+void tas_smartamp_add_codec_mixer_controls(struct snd_soc_codec *codec)
+#endif
+{
+ pr_debug("TI-SmartPA: %s: Adding smartamp controls\n", __func__);
+
+ /*Initialize all to global variables to 0s*/
+ s_tas_smartamp_enable = 0;
+ s_allow_dsp_query = 0;
+ s_calib_test_flag = 0;
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+
+ snd_soc_add_component_controls(codec, smartamp_tas25xx_mixer_controls,
+ ARRAY_SIZE(smartamp_tas25xx_mixer_controls));
+
+#else
+ snd_soc_add_codec_controls(codec, smartamp_tas25xx_mixer_controls,
+ ARRAY_SIZE(smartamp_tas25xx_mixer_controls));
+#endif
+ INIT_DELAYED_WORK(&query_tisa_algo_wrk, query_tisa_algo);
+
+}
+EXPORT_SYMBOL(tas_smartamp_add_codec_mixer_controls);
+
+void tas_smartamp_kbin_deinitalize (void)
+{
+ tas25xx_algo_set_inactive();
+ cancel_delayed_work_sync(&query_tisa_algo_wrk);
+}
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.c b/asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.c
new file mode 100644
index 00000000..b9749ead
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.c
@@ -0,0 +1,1061 @@
+#ifdef CONFIG_TAS25XX_ALGO
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/slab.h>
+#include <linux/debugfs.h>
+#include <linux/kthread.h>
+#include <linux/uaccess.h>
+#include <linux/wait.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/power_supply.h>
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "tas25xx-calib-validation.h"
+
+static uint8_t calibration_result[MAX_CHANNELS] = {STATUS_NONE};
+static uint8_t validation_result[MAX_CHANNELS] = {STATUS_NONE};
+static bool calibration_status;
+static bool validation_running_status;
+static uint32_t calib_re_hold[MAX_CHANNELS] = {0};
+static uint32_t amb_temp_hold[MAX_CHANNELS] = {0};
+static int32_t re_low[MAX_CHANNELS] = {0};
+static int32_t re_high[MAX_CHANNELS] = {0};
+
+static struct tas25xx_algo *p_tas25xx_algo;
+
+struct tas25xx_algo *smartamp_get_sysfs_ptr(void)
+{
+ if (!p_tas25xx_algo)
+ p_tas25xx_algo = kzalloc(sizeof(struct tas25xx_algo), GFP_KERNEL);
+
+ if (!p_tas25xx_algo)
+ return ERR_PTR(-ENOMEM);
+
+ return p_tas25xx_algo;
+}
+
+/*Max value supported is 2^8*/
+static uint8_t trans_val_to_user_m(uint32_t val, uint8_t qformat)
+{
+ uint32_t ret = (uint32_t)(((long long)val * 1000) >> qformat) % 1000;
+ return (uint8_t)(ret / 10);
+}
+
+/*Max value supported is 2^8*/
+static uint8_t trans_val_to_user_i(uint32_t val, uint8_t qformat)
+{
+ return ((val * 100) >> qformat) / 100;
+}
+
+static uint8_t tas25xx_get_amb_temp(void)
+{
+ struct power_supply *psy;
+ union power_supply_propval value = {0};
+
+ psy = power_supply_get_by_name("battery");
+ if (!psy || !psy->desc || !psy->desc->get_property) {
+ pr_err("[TI-SmartPA:%s] getting ambient temp failed, using default value %d\n",
+ __func__, DEFAULT_AMBIENT_TEMP);
+ return DEFAULT_AMBIENT_TEMP;
+ }
+ psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &value);
+
+ return DIV_ROUND_CLOSEST(value.intval, 10);
+}
+
+static int tas25xx_get_efs_data(uint32_t *data, uint8_t rdc_temp_l_r)
+{
+ struct file *pf = NULL;
+ char fname[MAX_STRING] = {0};
+ loff_t pos = 0;
+ char calib_data[MAX_STRING] = {0};
+ uint32_t data_flt[2];
+ mm_segment_t fs;
+ int ret = 0;
+
+ fs = get_fs();
+ set_fs(get_ds());
+
+ if (rdc_temp_l_r == TEMP_L)
+ memcpy(fname, TAS25XX_EFS_TEMP_DATA_L, sizeof(TAS25XX_EFS_TEMP_DATA_L));
+ else if (rdc_temp_l_r == RDC_L)
+ memcpy(fname, TAS25XX_EFS_CALIB_DATA_L, sizeof(TAS25XX_EFS_CALIB_DATA_L));
+ else if (rdc_temp_l_r == TEMP_R)
+ memcpy(fname, TAS25XX_EFS_TEMP_DATA_R, sizeof(TAS25XX_EFS_TEMP_DATA_R));
+ else if (rdc_temp_l_r == RDC_R)
+ memcpy(fname, TAS25XX_EFS_CALIB_DATA_R, sizeof(TAS25XX_EFS_CALIB_DATA_R));
+
+ pf = filp_open(fname, O_RDONLY, 0666);
+
+ if (!IS_ERR(pf)) {
+ vfs_read(pf, calib_data, MAX_STRING-1, &pos);
+ if ((rdc_temp_l_r == TEMP_L) || (rdc_temp_l_r == TEMP_R)) {
+ ret = sscanf(calib_data, "%d", data);
+ if (ret != 1) {
+ pr_err("[TI-SmartPA:%s] file %s read error\n", __func__, fname);
+ ret = -1;
+ }
+ } else {
+ ret = sscanf(calib_data, "%d.%d", &(data_flt[0]), &(data_flt[1]));
+ if (ret != 2) {
+ pr_err("[TI-SmartPA:%s] file %s read error\n", __func__, fname);
+ ret = -1;
+ }
+ *data = TRANSF_USER_TO_IMPED(data_flt[0], data_flt[1]);
+ }
+ filp_close(pf, NULL);
+ } else {
+ pr_err("[TI-SmartPA:%s] file %s open failed\n", __func__, fname);
+ ret = -1;
+ }
+ set_fs(fs);
+ return ret;
+}
+
+void tas25xx_update_big_data(void)
+{
+ uint8_t iter = 0;
+ uint32_t data[8] = {0};
+ uint32_t param_id = 0;
+ int32_t ret = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] BigData update skipping memory not allocated yet!!\n", __func__);
+ return;
+ }
+
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ /*Reset data*/
+ memset(data, 0, 8*sizeof(uint32_t));
+ //param_id = (TAS_SA_EXC_TEMP_STAT)|((uint32_t)(iter+1)<<24)|((uint32_t)(sizeof(data)/sizeof(uint32_t))<<16);
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_EXC_TEMP_STAT, sizeof(data) / sizeof(data[0]), (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)(&(data[0])), param_id
+ , TAS_GET_PARAM, sizeof(data), TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("[TI-SmartPA:%s] Failed to get Excursion and Temperature Stats\n", __func__);
+ } else {
+ pr_info("[TI-SmartPA:%s] Emax[%d] %d(%02d.%02d), Tmax[%d] %d, EOcount[%d] %d, TOcount[%d] %d \n",
+ __func__, iter, data[0], (int32_t)trans_val_to_user_i(data[0], QFORMAT31),
+ (int32_t)trans_val_to_user_m(data[0], QFORMAT31),
+ iter, data[1], iter, data[2], iter, data[3]);
+
+ /*Update Excursion Data*/
+ algo->b_data[iter].exc_max =
+ (data[0] > algo->b_data[iter].exc_max) ? data[0] : algo->b_data[iter].exc_max;
+ algo->b_data[iter].exc_max_persist =
+ (data[0] > algo->b_data[iter].exc_max_persist) ? data[0] : algo->b_data[iter].exc_max_persist;
+ algo->b_data[iter].exc_over_count += data[2];
+
+ /*Update Temperature Data*/
+ algo->b_data[iter].temp_max =
+ (data[1] > algo->b_data[iter].temp_max) ? data[1] : algo->b_data[iter].temp_max;
+ algo->b_data[iter].temp_max_persist =
+ (data[1] > algo->b_data[iter].temp_max_persist) ? data[1] : algo->b_data[iter].temp_max_persist;
+ algo->b_data[iter].temp_over_count += data[3];
+ }
+ }
+}
+
+int tas25xx_update_calibration_limits(void)
+{
+ uint8_t iter = 0;
+ uint32_t param_id = 0;
+ int32_t ret = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ ret = PTR_ERR(algo);
+ return ret;
+ }
+
+ /*Reset Calibration Result*/
+ memset(calibration_result, STATUS_NONE, sizeof(uint8_t)*MAX_CHANNELS);
+
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ int32_t re_range[2] = {0};
+
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_RE_RANGE, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)re_range, param_id,
+ TAS_GET_PARAM, sizeof(re_range), TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("[TI-SmartPA:%s]get re low fail channel no %d Exiting ..\n", __func__, iter);
+ return ret;
+ }
+
+ re_low[iter] = re_range[0] >> 8; /* Qformat 27 -> 19*/
+ re_high[iter] = re_range[1] >> 8; /* Qformat 27 -> 19*/
+
+ pr_info("[TI-SmartPA:%s] Channel No:%d, Rdc Limits(%02d.%02d ~ %02d.%02d) \n", __func__, iter,
+ (int32_t)trans_val_to_user_i(re_low[iter], QFORMAT19), (int32_t)trans_val_to_user_m(re_low[iter], QFORMAT19),
+ (int32_t)trans_val_to_user_i(re_high[iter], QFORMAT19), (int32_t)trans_val_to_user_m(re_high[iter], QFORMAT19));
+ }
+ return 0;
+}
+
+int tas25xx_check_limits(uint8_t channel, int32_t rdc)
+{
+ if ((rdc >= re_low[channel]) && (rdc <= re_high[channel])) {
+ calibration_result[channel] = STATUS_SUCCESS;
+ return 1;
+ }
+ calibration_result[channel] = STATUS_FAIL;
+ return 0;
+}
+
+void tas25xx_send_algo_calibration(void)
+{
+ uint32_t calib_re = 0;
+ uint32_t amb_temp = 0;
+ uint32_t data = 0;
+ uint32_t param_id = 0;
+ uint8_t iter;
+ int32_t ret = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ return;
+ }
+
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ if (!(algo->calib_update[iter])) {
+ algo->calib_update[iter] = true;
+
+ ret = tas25xx_get_efs_data(&calib_re, RDC_L + iter*2);
+ if (ret < 0) {
+ algo->calib_update[iter] = false;
+ }
+
+ ret = tas25xx_get_efs_data(&amb_temp, TEMP_L + iter*2);
+ if (ret < 0) {
+ algo->calib_update[iter] = false;
+ }
+
+ if (algo->calib_update[iter]) {
+ algo->calib_re[iter] = calib_re;
+ algo->amb_temp[iter] = amb_temp;
+ }
+ }
+
+ if (algo->calib_update[iter]) {
+ /*Set ambient temperature*/
+ data = algo->amb_temp[iter];
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_TCAL, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+
+ /*Set Re*/
+ data = algo->calib_re[iter];
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_SET_RE, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ }
+ }
+}
+
+static int tas25xx_save_calib_data(uint32_t *calib_rdc)
+{
+ uint8_t iter = 0;
+ int ret = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ ret = PTR_ERR(algo);
+ return ret;
+ }
+
+ if (!calib_rdc) {
+ pr_err("[TI-SmartPA:%s] argument is Null\n", __func__);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ calib_re_hold[iter] = calib_rdc[iter];
+ amb_temp_hold[iter] = tas25xx_get_amb_temp();
+ }
+ return 0;
+}
+
+/*******************************Calibration Related Codes Start*************************************/
+/* Forward declerations */
+static ssize_t tas25xx_calib_calibration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size);
+
+static ssize_t tas25xx_calib_calibration_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_calib_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_calib_rdc_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_amb_temp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static void calib_work_routine(struct work_struct *work)
+{
+ uint8_t iter = 0, iter2 = 0;
+ uint32_t data = 0;
+ uint32_t param_id = 0;
+ uint32_t calib_re[MAX_CHANNELS] = {0};
+ int32_t ret = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ return;
+ }
+
+ if (tas25xx_update_calibration_limits())
+ return;
+
+ /*Get Re*/
+ for (iter2 = 0; iter2 < CALIB_RETRY_COUNT; iter2++) {
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ if (calibration_result[iter] == STATUS_SUCCESS)
+ continue;
+
+ /*Calinration Init*/
+ data = 1;/*Value is ignored*/
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_CALIB_INIT, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("[TI-SmartPA:%s] Init error. Exiting ..\n", __func__);
+ return;
+ }
+
+ msleep(CALIB_TIME*1000);
+
+ data = 0;//Reset data to 0
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_RE, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_GET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ if (ret < 0) {
+ calibration_result[iter] = STATUS_FAIL;
+ pr_info("[TI-SmartPA:%s]get re fail. Exiting ..\n", __func__);
+ } else {
+ calib_re[iter] = data;
+ pr_info("[TI-SmartPA:%s]calib_re is %02d.%02d (%d) \n", __func__,
+ (int32_t)trans_val_to_user_i(calib_re[iter], QFORMAT19), (int32_t)trans_val_to_user_m(calib_re[iter], QFORMAT19),
+ (int32_t)calib_re[iter]);
+ if (tas25xx_check_limits(iter, calib_re[iter]))
+ pr_info("[TI-SmartPA:%s] Calibration Pass Channel No:%d\n", __func__, iter);
+ }
+
+ /*Calibration De-Init*/
+ data = 1;//Value is ignored
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_CALIB_DEINIT, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id
+ , TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ /*Wait some time*/
+ msleep(200);
+ }
+ }
+ tas25xx_save_calib_data(calib_re);
+
+ calibration_status = 0;
+ return;
+}
+
+static DEVICE_ATTR(calibration, 0664, tas25xx_calib_calibration_show,
+ tas25xx_calib_calibration_store);
+
+static DEVICE_ATTR(cstatus, 0664, tas25xx_calib_status_show,
+ NULL);
+
+static DEVICE_ATTR(rdc, 0664, tas25xx_calib_rdc_show,
+ NULL);
+
+static DEVICE_ATTR(temp, 0664, tas25xx_amb_temp_show,
+ NULL);
+
+static DEVICE_ATTR(cstatus_r, 0664, tas25xx_calib_status_show,
+ NULL);
+
+static DEVICE_ATTR(rdc_r, 0664, tas25xx_calib_rdc_show,
+ NULL);
+
+static DEVICE_ATTR(temp_r, 0664, tas25xx_amb_temp_show,
+ NULL);
+
+static ssize_t tas25xx_calib_calibration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int32_t ret = 0;
+ int32_t start;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ ret = PTR_ERR(algo);
+ goto end;
+ }
+
+ ret = kstrtos32(buf, 10, &start);
+ if (ret) {
+ pr_err("[TI-SmartPA:%s] Invalid input\n", __func__);
+ goto end;
+ }
+
+ if (start) {
+ calibration_status = 1;
+ /*Give time for algorithm to converge rdc*/
+ schedule_delayed_work(&algo->calib_work,
+ msecs_to_jiffies(200));
+ }
+end:
+ return size;
+}
+
+static ssize_t tas25xx_calib_calibration_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ /*Enough to check for only one channel*/
+ return snprintf(buf, MAX_STRING, "%s\n",
+ (calibration_status) ? "Enabled" : "Disabled");
+}
+
+static ssize_t tas25xx_calib_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret = 0;
+
+ if (attr == &dev_attr_cstatus_r)
+ ret = snprintf(buf, MAX_STRING, "%d", calibration_result[1]);
+ else
+ ret = snprintf(buf, MAX_STRING, "%d", calibration_result[0]);
+
+ return ret;
+}
+
+static ssize_t tas25xx_calib_rdc_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ uint32_t calib_re = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ ret = PTR_ERR(algo);
+ return ret;
+ }
+
+ if (attr == &dev_attr_rdc_r) {
+ if (calibration_result[1] == STATUS_NONE) {
+ if (algo->calib_update[1])
+ calib_re = algo->calib_re[1];
+ else
+ tas25xx_get_efs_data(&calib_re, RDC_R);
+ } else
+ calib_re = calib_re_hold[1];
+
+ ret = snprintf(buf, MAX_STRING, "%02d.%02d",
+ (int32_t)trans_val_to_user_i(calib_re, QFORMAT19), (int32_t)trans_val_to_user_m(calib_re, QFORMAT19));
+ } else {
+ if (calibration_result[0] == STATUS_NONE) {
+ if (algo->calib_update[0])
+ calib_re = algo->calib_re[0];
+ else
+ tas25xx_get_efs_data(&calib_re, RDC_L);
+ } else
+ calib_re = calib_re_hold[0];
+
+ ret = snprintf(buf, MAX_STRING, "%02d.%02d",
+ (int32_t)trans_val_to_user_i(calib_re, QFORMAT19), (int32_t)trans_val_to_user_m(calib_re, QFORMAT19));
+ }
+
+ return ret;
+}
+
+static ssize_t tas25xx_amb_temp_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ uint32_t amb_temp = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ ret = PTR_ERR(algo);
+ return ret;
+ }
+
+ if (attr == &dev_attr_temp_r) {
+ if (calibration_result[1] == STATUS_NONE) {
+ if (algo->calib_update[1])
+ amb_temp = algo->amb_temp[1];
+ else
+ tas25xx_get_efs_data(&amb_temp, TEMP_R);
+ } else
+ amb_temp = amb_temp_hold[1];
+
+ ret = snprintf(buf, MAX_STRING, "%d", amb_temp);
+ } else {
+ if (calibration_result[0] == STATUS_NONE) {
+ if (algo->calib_update[0])
+ amb_temp = algo->amb_temp[0];
+ else
+ tas25xx_get_efs_data(&amb_temp, TEMP_L);
+ } else
+ amb_temp = amb_temp_hold[0];
+
+ ret = snprintf(buf, MAX_STRING, "%d", amb_temp);
+ }
+
+ return ret;
+}
+
+static struct attribute *tas25xx_calib_attr[] = {
+ &dev_attr_calibration.attr,
+ &dev_attr_cstatus.attr,
+ &dev_attr_rdc.attr,
+ &dev_attr_temp.attr,
+};
+
+static struct attribute *tas25xx_calib_attr_r[] = {
+ &dev_attr_cstatus_r.attr,
+ &dev_attr_rdc_r.attr,
+ &dev_attr_temp_r.attr,
+};
+
+static struct attribute *tas25xx_calib_attr_m[
+ ARRAY_SIZE(tas25xx_calib_attr) +
+ ARRAY_SIZE(tas25xx_calib_attr_r) + 1] = {NULL};
+
+static struct attribute_group tas25xx_calib_attr_grp = {
+ .attrs = tas25xx_calib_attr_m,
+};
+
+/*******************************Calibration Related Codes End*************************************/
+/*******************************Validation Related Codes Start*************************************/
+/* Forward Declarations */
+static ssize_t tas25xx_valid_validation_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size);
+
+static ssize_t tas25xx_valid_validation_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_valid_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static void valid_work_routine(struct work_struct *work)
+{
+ uint8_t iter = 0;
+ uint32_t data = 0;
+ uint32_t param_id = 0;
+ int32_t ret = 0;
+
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! memory not allocated yet!!\n", __func__);
+ return;
+ }
+
+ //Get Validation Status
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ data = 0;//Reset data to 0
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_GET_VALID_STATUS, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_GET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ if (ret < 0) {
+ validation_result[iter] = STATUS_FAIL;
+ pr_info("[TI-SmartPA:%s]status read failed \n", __func__);
+ } else {
+ if (data == VALIDATION_SUCCESS) {
+ validation_result[iter] = STATUS_SUCCESS;
+ } else {
+ validation_result[iter] = STATUS_FAIL;
+ }
+ }
+ pr_info("[TI-SmartPA:%s] Channel-%d\n", __func__, iter);
+ pr_info("[TI-SmartPA:%s] validation_result %s(0x%x)\n", __func__,
+ validation_result[iter] == STATUS_SUCCESS ? "Success" : "Fail\n", (int32_t)data);
+
+ /*De-Init the validation process*/
+ data = 0; //Value is ignored
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_VALID_DEINIT, 1, (iter+1));
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id,
+ TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ }
+ validation_running_status = 0;
+}
+
+static DEVICE_ATTR(validation, 0644, tas25xx_valid_validation_show,
+ tas25xx_valid_validation_store);
+
+static DEVICE_ATTR(status, 0644, tas25xx_valid_status_show,
+ NULL);
+
+static DEVICE_ATTR(status_r, 0644, tas25xx_valid_status_show,
+ NULL);
+
+static ssize_t tas25xx_valid_validation_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ uint8_t iter = 0;
+ uint32_t data = 0;
+ uint32_t param_id = 0;
+ int32_t start = 0;
+ int32_t ret = 0;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! Error memory allocation\n", __func__);
+ ret = PTR_ERR(algo);
+ goto end;
+ }
+
+ ret = kstrtos32(buf, 10, &start);
+ if (ret) {
+ pr_err("[TI-SmartPA:%s] Invalid input\n", __func__);
+ goto end;
+ }
+
+ if (start) {
+ //Init
+ for (iter = 0; iter < algo->spk_count; iter++) {
+ data = 1;/*Value is ignored*/
+ param_id = TAS_CALC_PARAM_IDX(TAS_SA_VALID_INIT, 1, (iter+1));
+
+ ret = tas25xx_smartamp_algo_ctrl((u8 *)&data, param_id
+ , TAS_SET_PARAM, sizeof(uint32_t), TISA_MOD_RX);
+ if (ret < 0) {
+ pr_err("[TI-SmartPA:%s] Init error. Exiting ..", __func__);
+ goto end;
+ }
+ }
+
+ //Give time for algorithm to converge V-sns level
+ validation_running_status = 1;
+ schedule_delayed_work(&algo->valid_work,
+ msecs_to_jiffies(VALIDATION_TIME * 1000));
+ }
+end:
+ return size;
+}
+
+static ssize_t tas25xx_valid_validation_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return snprintf(buf, MAX_STRING, "%s\n",
+ (validation_running_status) ? "Enabled" : "Disabled");
+}
+
+static ssize_t tas25xx_valid_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+
+ if (attr == &dev_attr_status_r) {
+ ret = snprintf(buf, MAX_STRING, "%d", validation_result[1]);
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%d", validation_result[0]);
+ }
+ return ret;
+}
+
+static struct attribute *tas25xx_valid_attr[] = {
+ &dev_attr_validation.attr,
+ &dev_attr_status.attr,
+};
+
+static struct attribute *tas25xx_valid_attr_r[] = {
+ &dev_attr_status_r.attr,
+};
+
+static struct attribute *tas25xx_valid_attr_m[
+ ARRAY_SIZE(tas25xx_valid_attr) +
+ ARRAY_SIZE(tas25xx_valid_attr_r) + 1] = {NULL};
+
+static struct attribute_group tas25xx_valid_attr_grp = {
+ .attrs = tas25xx_valid_attr_m,
+};
+/*******************************Validation Related Codes End*************************************/
+/*******************************BigData Related Codes Start*************************************/
+/* Forward Declarations */
+static ssize_t tas25xx_bd_exc_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_bd_exc_max_persist_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_bd_exc_over_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_bd_temp_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_bd_temp_max_persist_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static ssize_t tas25xx_bd_temp_over_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf);
+
+static DEVICE_ATTR(exc_max, 0664, tas25xx_bd_exc_max_show,
+ NULL);
+
+static DEVICE_ATTR(exc_max_persist, 0664, tas25xx_bd_exc_max_persist_show,
+ NULL);
+
+static DEVICE_ATTR(exc_over_count, 0664, tas25xx_bd_exc_over_count_show,
+ NULL);
+
+static DEVICE_ATTR(temp_max, 0664, tas25xx_bd_temp_max_show,
+ NULL);
+
+static DEVICE_ATTR(temp_max_persist, 0664, tas25xx_bd_temp_max_persist_show,
+ NULL);
+
+static DEVICE_ATTR(temp_over_count, 0664, tas25xx_bd_temp_over_count_show,
+ NULL);
+
+static DEVICE_ATTR(exc_max_r, 0664, tas25xx_bd_exc_max_show,
+ NULL);
+
+static DEVICE_ATTR(exc_max_persist_r, 0664, tas25xx_bd_exc_max_persist_show,
+ NULL);
+
+static DEVICE_ATTR(exc_over_count_r, 0664, tas25xx_bd_exc_over_count_show,
+ NULL);
+
+static DEVICE_ATTR(temp_max_r, 0664, tas25xx_bd_temp_max_show,
+ NULL);
+
+static DEVICE_ATTR(temp_max_persist_r, 0664, tas25xx_bd_temp_max_persist_show,
+ NULL);
+
+static DEVICE_ATTR(temp_over_count_r, 0664, tas25xx_bd_temp_over_count_show,
+ NULL);
+
+static ssize_t tas25xx_bd_exc_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] failed !! Error memory allocation\n", __func__);
+ return PTR_ERR(algo);
+ }
+
+ if (attr == &dev_attr_exc_max_r) {
+ ret = snprintf(buf, MAX_STRING, "%02d.%02d",
+ (int32_t)trans_val_to_user_i(algo->b_data[1].exc_max, QFORMAT31),
+ (int32_t)trans_val_to_user_m(algo->b_data[1].exc_max, QFORMAT31));
+ algo->b_data[1].exc_max = 0;
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%02d.%02d",
+ (int32_t)trans_val_to_user_i(algo->b_data[0].exc_max, QFORMAT31),
+ (int32_t)trans_val_to_user_m(algo->b_data[0].exc_max, QFORMAT31));
+ algo->b_data[0].exc_max = 0;
+ }
+
+ return ret;
+}
+
+static ssize_t tas25xx_bd_exc_max_persist_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ return PTR_ERR(algo);
+ }
+
+ if (attr == &dev_attr_exc_max_persist_r) {
+ ret = snprintf(buf, MAX_STRING, "%02d.%02d",
+ (int32_t)trans_val_to_user_i(algo->b_data[1].exc_max_persist, QFORMAT31),
+ (int32_t)trans_val_to_user_m(algo->b_data[1].exc_max_persist, QFORMAT31));
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%02d.%02d",
+ (int32_t)trans_val_to_user_i(algo->b_data[0].exc_max_persist, QFORMAT31),
+ (int32_t)trans_val_to_user_m(algo->b_data[0].exc_max_persist, QFORMAT31));
+ }
+
+ return ret;
+}
+
+static ssize_t tas25xx_bd_exc_over_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ return PTR_ERR(algo);
+ }
+
+ if (attr == &dev_attr_exc_over_count_r) {
+ ret = snprintf(buf, MAX_STRING, "%d",
+ algo->b_data[1].exc_over_count);
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%d",
+ algo->b_data[0].exc_over_count);
+ }
+
+ return ret;
+}
+
+static ssize_t tas25xx_bd_temp_max_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ return PTR_ERR(algo);
+ }
+
+ if (attr == &dev_attr_temp_max_r) {
+ ret = snprintf(buf, MAX_STRING, "%d", algo->b_data[1].temp_max);
+ algo->b_data[1].temp_max = 0;
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%d", algo->b_data[0].temp_max);
+ algo->b_data[0].temp_max = 0;
+ }
+
+ return ret;
+}
+
+static ssize_t tas25xx_bd_temp_max_persist_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ return PTR_ERR(algo);
+ }
+
+ if (attr == &dev_attr_temp_max_persist_r) {
+ ret = snprintf(buf, MAX_STRING, "%d", algo->b_data[1].temp_max_persist);
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%d", algo->b_data[0].temp_max_persist);
+ }
+
+ return ret;
+}
+
+static ssize_t tas25xx_bd_temp_over_count_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ ssize_t ret;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ return PTR_ERR(algo);
+ }
+
+ if (attr == &dev_attr_temp_over_count_r) {
+ ret = snprintf(buf, MAX_STRING, "%d", algo->b_data[1].temp_over_count);
+ } else {
+ ret = snprintf(buf, MAX_STRING, "%d", algo->b_data[0].temp_over_count);
+ }
+
+ return ret;
+}
+
+static struct attribute *tas25xx_bd_attr[] = {
+ &dev_attr_exc_max.attr,
+ &dev_attr_exc_max_persist.attr,
+ &dev_attr_exc_over_count.attr,
+ &dev_attr_temp_max.attr,
+ &dev_attr_temp_max_persist.attr,
+ &dev_attr_temp_over_count.attr,
+};
+
+static struct attribute *tas25xx_bd_attr_r[] = {
+ &dev_attr_exc_max_r.attr,
+ &dev_attr_exc_max_persist_r.attr,
+ &dev_attr_exc_over_count_r.attr,
+ &dev_attr_temp_max_r.attr,
+ &dev_attr_temp_max_persist_r.attr,
+ &dev_attr_temp_over_count_r.attr,
+};
+
+static struct attribute *tas25xx_bd_attr_m[
+ ARRAY_SIZE(tas25xx_bd_attr) +
+ ARRAY_SIZE(tas25xx_bd_attr_r) + 1] = {NULL};
+
+static struct attribute_group tas25xx_bd_attr_grp = {
+ .attrs = tas25xx_bd_attr_m,
+};
+
+/*******************************BigData Related Codes End*************************************/
+
+static void clean_up_tas_sysfs (void)
+{
+ if (p_tas25xx_algo) {
+ struct tas25xx_algo *algo = p_tas25xx_algo;
+ if (algo->calib_dev) {
+ sysfs_remove_group (&algo->calib_dev->kobj, &tas25xx_calib_attr_grp);
+ device_destroy (algo->algo_class, 1);
+ }
+
+ if (algo->valid_dev) {
+ sysfs_remove_group (&algo->valid_dev->kobj, &tas25xx_valid_attr_grp);
+ device_destroy (algo->algo_class, 1);
+ }
+
+ if (algo->bd_dev) {
+ sysfs_remove_group (&algo->bd_dev->kobj, &tas25xx_bd_attr_grp);
+ device_destroy (algo->algo_class, 1);
+ }
+
+ if (algo->algo_class) {
+ class_destroy (algo->algo_class);
+ }
+
+ kfree (p_tas25xx_algo);
+ p_tas25xx_algo = NULL;
+ }
+}
+
+void tas25xx_algo_add_calib_valid_bigdata(uint8_t channels)
+{
+ int32_t ret = 0;
+ struct tas25xx_algo *algo = smartamp_get_sysfs_ptr();
+
+ if (IS_ERR(algo)) {
+ pr_err("[TI-SmartPA:%s] Error memory allocation\n", __func__);
+ ret = PTR_ERR(algo);
+ goto err_dev;
+ }
+
+ pr_info("[TI-SmartPA:%s] Adding Smartamp algo functions, spk_count=%d\n",
+ __func__, channels);
+ algo->spk_count = channels;
+
+ memcpy(tas25xx_calib_attr_m, tas25xx_calib_attr, sizeof(tas25xx_calib_attr));
+ memcpy(tas25xx_valid_attr_m, tas25xx_valid_attr, sizeof(tas25xx_valid_attr));
+ memcpy(tas25xx_bd_attr_m, tas25xx_bd_attr, sizeof(tas25xx_bd_attr));
+ if (channels == 2) {
+ memcpy(tas25xx_calib_attr_m + ARRAY_SIZE(tas25xx_calib_attr),
+ tas25xx_calib_attr_r, sizeof(tas25xx_calib_attr_r));
+ memcpy(tas25xx_valid_attr_m + ARRAY_SIZE(tas25xx_valid_attr),
+ tas25xx_valid_attr_r, sizeof(tas25xx_valid_attr_r));
+ memcpy(tas25xx_bd_attr_m + ARRAY_SIZE(tas25xx_bd_attr),
+ tas25xx_bd_attr_r, sizeof(tas25xx_bd_attr_r));
+ }
+
+ algo->algo_class = class_create(THIS_MODULE, TAS25XX_SYSFS_CLASS_NAME);
+ if (IS_ERR(algo->algo_class)) {
+ ret = PTR_ERR(algo->algo_class);
+ pr_err("[TI-SmartPA:%s] err class create\n", __func__);
+ algo->algo_class = NULL;
+ goto err_dev;
+ }
+
+ algo->calib_dev = device_create(algo->algo_class, NULL, 1, NULL, TAS25XX_CALIB_DIR_NAME);
+ if (IS_ERR(algo->calib_dev)) {
+ pr_err("[TI-SmartPA:%s]Failed to create calib_dev\n", __func__);
+ ret = PTR_ERR(algo->calib_dev);
+ algo->calib_dev = NULL;
+ goto err_dev;
+ }
+
+ ret = sysfs_create_group(&algo->calib_dev->kobj, &tas25xx_calib_attr_grp);
+ if (ret) {
+ pr_err("[TI-SmartPA:%s]Failed to create sysfs group\n", __func__);
+ goto err_dev;
+ }
+
+ INIT_DELAYED_WORK(&algo->calib_work, calib_work_routine);
+
+ algo->valid_dev = device_create(algo->algo_class, NULL, 1, NULL,
+ TAS25XX_VALID_DIR_NAME);
+ if (IS_ERR(algo->valid_dev)) {
+ pr_err("[TI-SmartPA:%s]Failed to create valid_dev\n", __func__);
+ ret = PTR_ERR(algo->valid_dev);
+ algo->valid_dev = NULL;
+ goto err_dev;
+ }
+
+ ret = sysfs_create_group(&algo->valid_dev->kobj, &tas25xx_valid_attr_grp);
+ if (ret) {
+ pr_err("[TI-SmartPA:%s]Failed to create sysfs group\n", __func__);
+ algo->valid_dev = NULL;
+ goto err_dev;
+ }
+
+ INIT_DELAYED_WORK(&algo->valid_work, valid_work_routine);
+
+ algo->bd_dev = device_create(algo->algo_class, NULL, 1, NULL,
+ TAS25XX_BD_DIR_NAME);
+ if (IS_ERR(algo->bd_dev)) {
+ pr_err("[TI-SmartPA:%s]Failed to create bd_dev\n", __func__);
+ ret = PTR_ERR(algo->bd_dev);
+ algo->bd_dev = NULL;
+ goto err_dev;
+ }
+
+ ret = sysfs_create_group(&algo->bd_dev->kobj, &tas25xx_bd_attr_grp);
+ if (ret) {
+ pr_err("[TI-SmartPA:%s]Failed to create sysfs group\n", __func__);
+ algo->bd_dev = NULL;
+ goto err_dev;
+ }
+
+ pr_info ("[TI-SmartPA:%s] ret=%d\n", __func__, ret);
+ return;
+
+err_dev:
+ clean_up_tas_sysfs();
+ pr_err("[TI-SmartPA:%s] Error %d\n", __func__, ret);
+}
+
+void tas25xx_algo_remove_calib_valid_bigdata(void)
+{
+ pr_info("[TI-SmartPA:%s] Removing Smartamp Algorithm functions\n", __func__);
+ clean_up_tas_sysfs();
+}
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS25XX Algorithm");
+MODULE_LICENSE("GPL v2");
+
+#endif /*CONFIG_TAS25XX_ALGO*/
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.h b/asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.h
new file mode 100644
index 00000000..d7534e1f
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-calib-validation.h
@@ -0,0 +1,85 @@
+/*
+** =============================================================================
+** Copyright (c) 2016 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+**
+** File:
+** tas25xx-calib-validataion.h
+**
+** Description:
+** header file for calibration and validataion interface to SmartPA
+**
+** =============================================================================
+*/
+
+#ifndef _TAS25XX_ALGO_H
+#define _TAS25XX_ALGO_H
+
+#define MAX_STRING 200
+#define CALIB_RETRY_COUNT 5
+#define RDC_L 0
+#define TEMP_L 1
+#define RDC_R 2
+#define TEMP_R 3
+#define DEFAULT_AMBIENT_TEMP 25
+#define CALIB_TIME 2
+#define VALIDATION_TIME 3
+#define STATUS_NONE 0x00
+#define STATUS_SUCCESS 0x01
+#define STATUS_FAIL 0xcc
+
+#define TAS_SA_GET_RE_LOW 398
+#define TAS_SA_GET_RE_HIGH 399
+#define VALIDATION_SUCCESS 0xC00DC00D
+
+#define TRANSF_USER_TO_IMPED(X, Y) \
+ ((X << 19) + ((Y << 19) / 100))
+#define QFORMAT19 19
+#define QFORMAT31 31
+
+#define TAS25XX_SYSFS_CLASS_NAME "tas25xx"
+#define TAS25XX_CALIB_DIR_NAME "calib"
+#define TAS25XX_VALID_DIR_NAME "valid"
+#define TAS25XX_BD_DIR_NAME "bigdata"
+
+#define TAS25XX_EFS_CALIB_DATA_L "/efs/tas25xx/calib_re"
+#define TAS25XX_EFS_TEMP_DATA_L "/efs/tas25xx/amb_temp"
+#define TAS25XX_EFS_CALIB_DATA_R "/efs/tas25xx/calib_re_r"
+#define TAS25XX_EFS_TEMP_DATA_R "/efs/tas25xx/amb_temp_r"
+
+struct big_data {
+ uint32_t exc_max;
+ uint32_t exc_max_persist;
+ uint32_t exc_over_count;
+ uint32_t temp_max;
+ uint32_t temp_max_persist;
+ uint32_t temp_over_count;
+};
+
+struct tas25xx_algo {
+ struct class *algo_class;
+ struct device *calib_dev;
+ struct device *valid_dev;
+ struct device *bd_dev;
+ struct big_data b_data[MAX_CHANNELS];
+ struct delayed_work calib_work;
+ struct delayed_work valid_work;
+ uint8_t spk_count;
+ uint32_t port;
+ uint32_t calib_re[MAX_CHANNELS];
+ uint32_t amb_temp[MAX_CHANNELS];
+ bool calib_update[MAX_CHANNELS];
+};
+
+void tas25xx_algo_add_calib_valid_bigdata(uint8_t channels);
+void tas25xx_algo_remove_calib_valid_bigdata(void);
+struct tas25xx_algo *smartamp_get_sysfs_ptr(void);
+
+#endif /* _TAS25XX_ALGO_H */ \ No newline at end of file
diff --git a/asoc/codecs/tas256x/algo/src/tas25xx-calib.c b/asoc/codecs/tas256x/algo/src/tas25xx-calib.c
new file mode 100644
index 00000000..3af138d3
--- /dev/null
+++ b/asoc/codecs/tas256x/algo/src/tas25xx-calib.c
@@ -0,0 +1,196 @@
+/*
+** =============================================================================
+** Copyright (c) 2017 Texas Instruments Inc.
+**
+** This program is free software; you can redistribute it and/or modify it under
+** the terms of the GNU General Public License as published by the Free Software
+** Foundation; version 2.
+**
+** This program is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
+**
+** File:
+** tas25xx-calib.c
+**
+** Description:
+** misc driver for interfacing for Texas Instruments TAS25xx algorithm
+**
+** =============================================================================
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/semaphore.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "tas25xx-algo-intf.h"
+
+#define TAS_PAYLOAD_SIZE 14
+
+/* Holds the Packet data required for processing */
+struct tas_dsp_pkt {
+ u8 slave_id;
+ u8 book;
+ u8 page;
+ u8 offset;
+ u8 data[TAS_PAYLOAD_SIZE * 4];
+};
+
+static int smartamp_params_ctrl(uint8_t *input, u8 dir, u8 count)
+{
+ u32 length = count / 4;
+ u32 paramid = 0;
+ u32 index;
+ int ret = 0;
+ int special_index = 0;
+ struct tas_dsp_pkt *ppacket;
+
+ if (length >= TAS_PAYLOAD_SIZE) {
+ pr_err("TI-SmartPA: %s: Unsupported length!", __func__);
+ return -EINVAL;
+ }
+
+ ppacket = (struct tas_dsp_pkt *)kmalloc(sizeof(struct tas_dsp_pkt),
+ GFP_KERNEL);
+ if (!ppacket) {
+ pr_err("TI-SmartPA: %s: kmalloc failed!", __func__);
+ return -ENOMEM;
+ }
+
+ memset(ppacket, 0, sizeof(struct tas_dsp_pkt));
+ ret = copy_from_user(ppacket, input, sizeof(struct tas_dsp_pkt));
+ if (ret) {
+ pr_err("TI-SmartPA: %s: Error copying from user\n", __func__);
+ kfree(ppacket);
+ return -EFAULT;
+ }
+
+ index = (ppacket->page - 1) * 30 + (ppacket->offset - 8) / 4;
+ special_index = TAS_SA_IS_SPL_IDX(index);
+ pr_info("TI-SmartPA: %s: index = %d", __func__, index);
+ if (special_index == 0) {
+ if ((index < 0 || index > MAX_DSP_PARAM_INDEX)) {
+ pr_err("TI-SmartPA: %s: invalid index !\n", __func__);
+ kfree(ppacket);
+ return -EINVAL;
+ }
+ }
+ pr_info("TI-SmartPA: %s: Valid Index. special = %s\n",
+ __func__, special_index ? "Yes" : "No");
+
+ /* speakers are differentiated by slave ids */
+ if (ppacket->slave_id == SLAVE1) {
+ paramid = TAS_CALC_PARAM_IDX(index, length, CHANNEL0);
+ pr_err("TI-SmartPA: %s: Rcvd Slave id for slave 1, %x\n", __func__, ppacket->slave_id);
+ } else if (ppacket->slave_id == SLAVE2) {
+ paramid = TAS_CALC_PARAM_IDX(index, length, CHANNEL1);
+ pr_err("TI-SmartPA: %s: Rcvd Slave id for slave 2, %x\n", __func__, ppacket->slave_id);
+ } else {
+ pr_err("TI-SmartPA: %s: Wrong slaveid = %x\n",
+ __func__, ppacket->slave_id);
+ }
+
+ ret = tas25xx_smartamp_algo_ctrl(ppacket->data, paramid,
+ dir, length * 4, 0/*Default to Rx*/);
+ if (ret)
+ pr_err("TI-SmartPA: %s: %s Slave 0x%x params failed from afe, ret=%x\n",
+ __func__,
+ dir == TAS_GET_PARAM ? "get" : "set",
+ ppacket->slave_id, ret);
+ else
+ pr_info("TI-SmartPA: %s: Algo control returned %d\n",
+ __func__, ret);
+
+ if (dir == TAS_GET_PARAM) {
+ ret = copy_to_user(input, ppacket, sizeof(struct tas_dsp_pkt));
+ if (ret) {
+ pr_err("TI-SmartPA: %s: Error copying to user after DSP",
+ __func__);
+ ret = -EFAULT;
+ }
+ }
+
+ kfree(ppacket);
+ return ret;
+}
+
+static int tas_calib_open(struct inode *inode, struct file *fd)
+{
+ return 0;
+}
+
+static ssize_t tas_calib_write(struct file *file,
+ const char __user *buffer, size_t count, loff_t *offp)
+{
+ int rc = 0;
+
+ rc = smartamp_params_ctrl((uint8_t *)buffer, TAS_SET_PARAM, count);
+ return rc;
+}
+
+static ssize_t tas_calib_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ptr)
+{
+ int rc;
+
+ rc = smartamp_params_ctrl((uint8_t *)buffer, TAS_GET_PARAM, count);
+ if (rc < 0)
+ count = rc;
+ return count;
+}
+
+static long tas_calib_ioctl(struct file *filp, uint cmd, ulong arg)
+{
+ return 0;
+}
+
+static int tas_calib_release(struct inode *inode, struct file *fd)
+{
+ return 0;
+}
+
+const struct file_operations tas_calib_fops = {
+ .owner = THIS_MODULE,
+ .open = tas_calib_open,
+ .write = tas_calib_write,
+ .read = tas_calib_read,
+ .release = tas_calib_release,
+ .unlocked_ioctl = tas_calib_ioctl,
+};
+
+static struct miscdevice tas_calib_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "tas_calib",
+ .fops = &tas_calib_fops,
+};
+
+int tas_calib_init(void)
+{
+ int rc;
+
+ pr_info("TI-SmartPA: %s", __func__);
+ rc = misc_register(&tas_calib_misc);
+ if (rc)
+ pr_err("TI-SmartPA: %s: register calib misc failed\n",
+ __func__);
+ return rc;
+}
+
+void tas_calib_exit(void)
+{
+ misc_deregister(&tas_calib_misc);
+}
+
+/*
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("tas2560 Misc driver");
+MODULE_LICENSE("GPL v2");
+*/
diff --git a/asoc/codecs/tas256x/logical_layer/inc/smartpa-debug-common.h b/asoc/codecs/tas256x/logical_layer/inc/smartpa-debug-common.h
new file mode 100644
index 00000000..14bde3d2
--- /dev/null
+++ b/asoc/codecs/tas256x/logical_layer/inc/smartpa-debug-common.h
@@ -0,0 +1,7 @@
+#ifndef __SMARTPA_DEGUG_COMMON_H__
+#define __SMARTPA_DEGUG_COMMON_H__
+#include <linux/i2c.h>
+
+int smartpa_debug_probe(struct i2c_client *client);
+
+#endif
diff --git a/asoc/codecs/tas256x/logical_layer/inc/tas256x-logic.h b/asoc/codecs/tas256x/logical_layer/inc/tas256x-logic.h
new file mode 100644
index 00000000..695e088d
--- /dev/null
+++ b/asoc/codecs/tas256x/logical_layer/inc/tas256x-logic.h
@@ -0,0 +1,29 @@
+#ifndef __TAS256X_LOGIC_
+#define __TAS256X_LOGIC_
+
+#include "physical_layer/inc/tas256x.h"
+
+#define TAS256X_STREAM_PLAYBACK 0
+#define TAS256X_STREAM_CAPTURE 1
+
+int tas256x_register_device(struct tas256x_priv *p_tas256x);
+int tas256x_probe(struct tas256x_priv *p_tas256x);
+void tas256x_remove(struct tas256x_priv *p_tas256x);
+int tas256x_load_init(struct tas256x_priv *p_tas256x);
+int tas256x_irq_work_func(struct tas256x_priv *p_tas256x);
+void tas256x_load_config(struct tas256x_priv *p_tas256x);
+int tas256x_init_work_func(struct tas256x_priv *p_tas256x);
+int tas256x_dc_work_func(struct tas256x_priv *p_tas256x, int ch);
+void tas_reload(struct tas256x_priv *p_tas256x, int chn);
+int tas256x_set_power_state(struct tas256x_priv *p_tas256x,
+ int state);
+int tas256x_iv_vbat_slot_config(struct tas256x_priv *p_tas256x,
+ int mn_slot_width);
+int tas256x_set_bitwidth(struct tas256x_priv *p_tas256x,
+ int bitwidth, int stream);
+int tas256x_set_tdm_rx_slot(struct tas256x_priv *p_tas256x,
+ int slots, int slot_width);
+int tas256x_set_tdm_tx_slot(struct tas256x_priv *p_tas256x,
+ int slots, int slot_width);
+
+#endif /*__TAS256X_LOGIC_*/ \ No newline at end of file
diff --git a/asoc/codecs/tas256x/logical_layer/src/smartpa-debug-common.c b/asoc/codecs/tas256x/logical_layer/src/smartpa-debug-common.c
new file mode 100644
index 00000000..753318a9
--- /dev/null
+++ b/asoc/codecs/tas256x/logical_layer/src/smartpa-debug-common.c
@@ -0,0 +1,214 @@
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/serial_core.h>
+#include <linux/dma-mapping.h>
+#include <linux/device.h>
+#include <linux/miscdevice.h>
+
+#include "logical_layer/inc/smartpa-debug-common.h"
+
+#define AM_DEV_NAME "smartpa"
+#define MSGS_SIZE 256
+#define RESERVED_SIZE 252
+
+struct smartpa_msg {
+ char msgs[MSGS_SIZE];
+ char reserved[RESERVED_SIZE];
+ int msg_result;
+};
+
+struct smartpa_prars {
+ int fRes_max;
+ int fRes_min;
+ int Qt;
+ int impedance_max;
+ int impedance_min;
+};
+
+#define TFA_CTL_IOC_MAGIC 'T'
+#define TFA_IOCTL_SPK_REST _IOW(TFA_CTL_IOC_MAGIC, 0x01, int)
+#define TFA_IOCTL_SPK_INTS _IOR(TFA_CTL_IOC_MAGIC, 0x02, struct smartpa_msg)
+#define TFA_IOCTL_SPK_INTT _IOW(TFA_CTL_IOC_MAGIC, 0x03, int)
+#define TFA_IOCTL_SPK_RFDES _IOR(TFA_CTL_IOC_MAGIC, 0x04, struct smartpa_msg)
+#define TFA_IOCTL_SPK_CHCK _IOR(TFA_CTL_IOC_MAGIC, 0x05, int)
+#define TFA_IOCTL_SPK_PRARS _IOR(TFA_CTL_IOC_MAGIC, 0x06, struct smartpa_prars)
+#define TFA_IOCTL_SPK_ADDR _IOW(TFA_CTL_IOC_MAGIC, 0x07, unsigned char)
+#define TFA_IOCTL_SPK_MTP_BACKUP _IOR(TFA_CTL_IOC_MAGIC, 0x08, int)
+
+extern int smartpa_check_calib_dbg(void);
+extern int smartpa_init_dbg(char *buffer, int size);
+extern int smartpa_read_freq_dbg(char *buffer, int size);
+extern void smartpa_read_prars_dbg(int temp[5], unsigned char addr);
+extern void smartpa_get_client(struct i2c_client **client, unsigned char addr);
+
+static struct i2c_client *smartpa_debug_client;
+static unsigned char last_addr;
+
+static ssize_t smartpa_debug_read(struct file *file,
+ char __user *buf, size_t count, loff_t *offset)
+{
+ char *tmp;
+ int ret;
+
+ smartpa_get_client(&smartpa_debug_client, last_addr);
+ tmp = kmalloc(count, GFP_KERNEL);
+ if (tmp == NULL)
+ return -ENOMEM;
+
+ ret = i2c_master_recv(smartpa_debug_client, tmp, count);
+ if (ret >= 0)
+ ret = copy_to_user(buf, tmp, count) ? -EFAULT : ret;
+ else
+ printk("[SmartPA]%s: transfer error %d\n", __func__, ret);
+ kfree(tmp);
+ return ret;
+}
+
+static ssize_t smartpa_debug_write(struct file *file,
+ const char __user *buf, size_t count, loff_t *offset)
+{
+ char *tmp;
+ int ret;
+
+ smartpa_get_client(&smartpa_debug_client, last_addr);
+ tmp = memdup_user(buf, count);
+ if (IS_ERR(tmp))
+ return PTR_ERR(tmp);
+ ret = i2c_master_send(smartpa_debug_client, tmp, count);
+ if (ret < 0)
+ printk("[SmartPA]%s: transfer error %d\n", __func__, ret);
+ kfree(tmp);
+ return ret;
+}
+
+static long smartpa_debug_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int ret = 0, check = 0;
+ int temp[5] = {0};
+ struct smartpa_msg msg = {0};
+ struct smartpa_prars prars = {0};
+
+ memset(&prars, 0, sizeof(struct smartpa_prars));
+ memset(&msg, 0, sizeof(struct smartpa_msg));
+ switch (cmd) {
+ /* Reset MTP */
+ case TFA_IOCTL_SPK_REST:
+ printk("smartpa_ioctl SPK_REST\n");
+ break;
+ /* calibrate */
+ case TFA_IOCTL_SPK_INTS:
+ printk("smartpa_ioctl SPK_INTS\n");
+ check = smartpa_init_dbg(msg.msgs, MSGS_SIZE);
+ msg.msg_result = check;
+ ret = copy_to_user((void *)arg, &msg,
+ sizeof(struct smartpa_msg));
+ break;
+ case TFA_IOCTL_SPK_INTT:
+
+ printk("smartpa_ioctl SPK_INT\n");
+ break;
+ case TFA_IOCTL_SPK_RFDES:
+ usleep_range(10*1000, 10*1000);
+ printk("smartpa_ioctl SPK_ReadFDes\n");
+ ret = smartpa_read_freq_dbg(msg.msgs, MSGS_SIZE);
+ ret = copy_to_user((void *)arg, &msg,
+ sizeof(struct smartpa_msg));
+ break;
+ /* checkmtp */
+ case TFA_IOCTL_SPK_CHCK:
+ printk("smartpa_ioctl SPK Check MtpEx\n");
+ check = smartpa_check_calib_dbg();
+ pr_info("%s check %d.\n", __func__, check);
+ ret = copy_to_user((__user int *)arg, &check, sizeof(int));
+ break;
+ case TFA_IOCTL_SPK_PRARS:
+ printk("smartpa_ioctl SPK Read f0 and Qt\n");
+ smartpa_read_prars_dbg(temp, last_addr);
+ prars.fRes_max = temp[0];
+ prars.fRes_min = temp[1];
+ prars.Qt = temp[2];
+ prars.impedance_max = temp[3];
+ prars.impedance_min = temp[4];
+ ret = copy_to_user((void *)arg, &prars,
+ sizeof(struct smartpa_prars));
+ pr_info("smartpa_ioctl %d %d %d\n", temp[0], temp[1], temp[2]);
+ break;
+ case TFA_IOCTL_SPK_ADDR:
+ ret = copy_from_user(&last_addr, (void __user *)arg,
+ sizeof(unsigned char));
+ printk("smartpa_ioctl addr %x\n", last_addr);
+ break;
+ case TFA_IOCTL_SPK_MTP_BACKUP:
+ pr_info("%s mtp backup %d.\n", __func__, check);
+ default:
+ printk("smartpa Fail IOCTL command no such ioctl cmd = %x\n",
+ cmd);
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+static int smartpa_debug_open(
+ struct inode *inode, struct file *file)
+{
+ printk("[SmartPA]%s\n", __func__);
+ return 0;
+}
+
+int smartpa_debug_release(
+ struct inode *inode, struct file *file)
+{
+ printk("[SmartPA]%s\n", __func__);
+ return 0;
+}
+
+static const struct file_operations smartpa_debug_fileops = {
+ .owner = THIS_MODULE,
+ .open = smartpa_debug_open,
+ .read = smartpa_debug_read,
+ .write = smartpa_debug_write,
+ .unlocked_ioctl = smartpa_debug_ioctl,
+ .release = smartpa_debug_release,
+};
+
+static struct miscdevice smartpa_debug_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = AM_DEV_NAME,
+ .fops = &smartpa_debug_fileops,
+};
+
+int smartpa_debug_probe(struct i2c_client *client)
+{
+ int err = 0;
+
+ printk("%s\n", __func__);
+
+ if (smartpa_debug_client)
+ return 0;
+
+ err = misc_register(&smartpa_debug_device);
+ if (err) {
+ printk("%s: smartpa_device register failed\n", __func__);
+ return err;
+ }
+
+ smartpa_debug_client = client;
+
+ return 0;
+}
+
+MODULE_DESCRIPTION("smartpa debug driver");
+MODULE_AUTHOR("chenjinquan <chenjinquan@vivo.com>");
+MODULE_LICENSE("GPL");
diff --git a/asoc/codecs/tas256x/logical_layer/src/tas256x-logic.c b/asoc/codecs/tas256x/logical_layer/src/tas256x-logic.c
new file mode 100644
index 00000000..125d0a45
--- /dev/null
+++ b/asoc/codecs/tas256x/logical_layer/src/tas256x-logic.c
@@ -0,0 +1,1428 @@
+#include "logical_layer/inc/tas256x-logic.h"
+#include "physical_layer/inc/tas256x-device.h"
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "algo/inc/tas25xx-calib.h"
+#include "os_layer/inc/tas256x-regmap.h"
+#endif /*CONFIG_TAS25XX_ALGO*/
+
+static int tas256x_change_book_page(struct tas256x_priv *p_tas256x,
+ enum channel chn,
+ int book, int page)
+{
+ int n_result = 0, rc = 0;
+ int i = 0;
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (((chn&channel_left) && (i == 0))
+ || ((chn&channel_right) && (i == 1))) {
+ if (p_tas256x->devs[i]->mn_current_book != book) {
+ n_result = p_tas256x->plat_write(p_tas256x->platform_data,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_BOOKCTL_PAGE, 0);
+ if (n_result < 0) {
+ pr_err(
+ "%s, ERROR, L=%d, E=%d\n",
+ __func__, __LINE__, n_result);
+ rc |= n_result;
+ continue;
+ }
+ p_tas256x->devs[i]->mn_current_page = 0;
+ n_result = p_tas256x->plat_write(p_tas256x->platform_data,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_BOOKCTL_REG, book);
+ if (n_result < 0) {
+ pr_err(
+ "%s, ERROR, L=%d, E=%d\n",
+ __func__, __LINE__, n_result);
+ rc |= n_result;
+ continue;
+ }
+ p_tas256x->devs[i]->mn_current_book = book;
+ }
+
+ if (p_tas256x->devs[i]->mn_current_page != page) {
+ n_result = p_tas256x->plat_write(p_tas256x->platform_data,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_BOOKCTL_PAGE, page);
+ if (n_result < 0) {
+ pr_err(
+ "%s, ERROR, L=%d, E=%d\n",
+ __func__, __LINE__, n_result);
+ rc |= n_result;
+ continue;
+ }
+ p_tas256x->devs[i]->mn_current_page = page;
+ }
+ }
+ }
+
+ if (rc < 0) {
+ if (chn&channel_left)
+ p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM;
+ } else {
+ if (chn&channel_left)
+ p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM;
+ }
+ return rc;
+}
+
+static int tas256x_dev_read(struct tas256x_priv *p_tas256x,
+ enum channel chn,
+ unsigned int reg, unsigned int *pValue)
+{
+ int n_result = 0;
+ int i = 0, chnTemp = 0;
+
+ mutex_lock(&p_tas256x->dev_lock);
+
+ if (chn == channel_both) {
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+ }
+
+ n_result = tas256x_change_book_page(p_tas256x, chn,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg));
+ if (n_result < 0)
+ goto end;
+
+ /*Force left incase of mono*/
+ if ((chn == channel_right) && (p_tas256x->mn_channels == 1))
+ chn = channel_left;
+
+ n_result = p_tas256x->plat_read(p_tas256x->platform_data,
+ p_tas256x->devs[chn >> 1]->mn_addr,
+ TAS256X_PAGE_REG(reg), pValue);
+ if (n_result < 0) {
+ pr_err("%s, ERROR, L=%d, E=%d\n",
+ __func__, __LINE__, n_result);
+ if (chn&channel_left)
+ p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM;
+ } else {
+ pr_debug(
+ "%s: chn:%x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x,0x%02x\n",
+ __func__,
+ p_tas256x->devs[chn >> 1]->mn_addr, TAS256X_BOOK_ID(reg),
+ TAS256X_PAGE_ID(reg),
+ TAS256X_PAGE_REG(reg), *pValue);
+ if (chn&channel_left)
+ p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM;
+ }
+end:
+ mutex_unlock(&p_tas256x->dev_lock);
+ return n_result;
+}
+
+static int tas256x_dev_write(struct tas256x_priv *p_tas256x, enum channel chn,
+ unsigned int reg, unsigned int value)
+{
+ int n_result = 0, rc = 0;
+ int i = 0, chnTemp = 0;
+
+ mutex_lock(&p_tas256x->dev_lock);
+
+ if (chn == channel_both) {
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+ }
+
+ n_result = tas256x_change_book_page(p_tas256x, chn,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg));
+ if (n_result < 0)
+ goto end;
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (((chn&channel_left) && (i == 0))
+ || ((chn&channel_right) && (i == 1))) {
+ n_result = p_tas256x->plat_write(p_tas256x->platform_data,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_PAGE_REG(reg), value);
+ if (n_result < 0) {
+ pr_err(
+ "%s, ERROR, L=%u, chn=0x%02x, E=%d\n",
+ __func__, __LINE__,
+ p_tas256x->devs[i]->mn_addr, n_result);
+ rc |= n_result;
+ if (chn&channel_left)
+ p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM;
+ } else {
+ pr_debug(
+ "%s: %u: chn:0x%02x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x, VAL: 0x%02x\n",
+ __func__, __LINE__,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_BOOK_ID(reg),
+ TAS256X_PAGE_ID(reg),
+ TAS256X_PAGE_REG(reg), value);
+ if (chn&channel_left)
+ p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM;
+ }
+ }
+ }
+end:
+ mutex_unlock(&p_tas256x->dev_lock);
+ return rc;
+}
+
+static int tas256x_dev_bulk_write(struct tas256x_priv *p_tas256x,
+ enum channel chn,
+ unsigned int reg, unsigned char *p_data, unsigned int n_length)
+{
+ int n_result = 0, rc = 0;
+ int i = 0, chnTemp = 0;
+
+ mutex_lock(&p_tas256x->dev_lock);
+
+ if (chn == channel_both) {
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+ }
+
+ n_result = tas256x_change_book_page(p_tas256x, chn,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg));
+ if (n_result < 0)
+ goto end;
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (((chn&channel_left) && (i == 0))
+ || ((chn&channel_right) && (i == 1))) {
+ n_result = p_tas256x->plat_bulk_write(p_tas256x->platform_data,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_PAGE_REG(reg),
+ p_data, n_length);
+ if (n_result < 0) {
+ pr_err(
+ "%s, ERROR, L=%u, chn=0x%02x: E=%d\n",
+ __func__, __LINE__,
+ p_tas256x->devs[i]->mn_addr, n_result);
+ rc |= n_result;
+ if (chn&channel_left)
+ p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM;
+ } else {
+ pr_debug(
+ "%s: chn%x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x, len: %u\n",
+ __func__, p_tas256x->devs[i]->mn_addr,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg),
+ TAS256X_PAGE_REG(reg), n_length);
+ if (chn&channel_left)
+ p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM;
+ }
+ }
+ }
+
+end:
+ mutex_unlock(&p_tas256x->dev_lock);
+ return rc;
+}
+
+static int tas256x_dev_bulk_read(struct tas256x_priv *p_tas256x,
+ enum channel chn,
+ unsigned int reg, unsigned char *p_data, unsigned int n_length)
+{
+ int n_result = 0;
+ int i = 0, chnTemp = 0;
+
+ mutex_lock(&p_tas256x->dev_lock);
+
+ if (chn == channel_both) {
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+ }
+
+ n_result = tas256x_change_book_page(p_tas256x, chn,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg));
+ if (n_result < 0)
+ goto end;
+
+ n_result = p_tas256x->plat_bulk_read(p_tas256x->platform_data,
+ p_tas256x->devs[chn >> 1]->mn_addr, TAS256X_PAGE_REG(reg),
+ p_data, n_length);
+ if (n_result < 0) {
+ pr_err("%s, ERROR, L=%d, E=%d\n",
+ __func__, __LINE__, n_result);
+ if (chn&channel_left)
+ p_tas256x->mn_err_code |= ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code |= ERROR_DEVB_I2C_COMM;
+ } else {
+ pr_debug(
+ "%s: chn%x:BOOK:PAGE:REG %u:%u:%u, len: 0x%02x\n",
+ __func__, p_tas256x->devs[chn >> 1]->mn_addr,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg),
+ TAS256X_PAGE_REG(reg), n_length);
+ if (chn&channel_left)
+ p_tas256x->mn_err_code &= ~ERROR_DEVA_I2C_COMM;
+ if (chn&channel_right)
+ p_tas256x->mn_err_code &= ~ERROR_DEVB_I2C_COMM;
+ }
+end:
+ mutex_unlock(&p_tas256x->dev_lock);
+ return n_result;
+}
+
+static int tas256x_dev_update_bits(struct tas256x_priv *p_tas256x,
+ enum channel chn,
+ unsigned int reg, unsigned int mask, unsigned int value)
+{
+ int n_result = 0, rc = 0;
+ int i = 0, chnTemp = 0;
+
+ mutex_lock(&p_tas256x->dev_lock);
+
+ if (chn == channel_both) {
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+ }
+
+ n_result = tas256x_change_book_page(p_tas256x, chn,
+ TAS256X_BOOK_ID(reg), TAS256X_PAGE_ID(reg));
+ if (n_result < 0) {
+ rc = n_result;
+ goto end;
+ }
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (((chn&channel_left) && (i == 0))
+ || ((chn&channel_right) && (i == 1))) {
+ n_result = p_tas256x->plat_update_bits(p_tas256x->platform_data,
+ p_tas256x->devs[i]->mn_addr,
+ TAS256X_PAGE_REG(reg),
+ mask, value);
+ if (n_result < 0) {
+ pr_err(
+ "%s, ERROR, L=%u, chn=0x%02x: E=%d\n",
+ __func__, __LINE__,
+ p_tas256x->devs[i]->mn_addr, n_result);
+ rc |= n_result;
+ p_tas256x->mn_err_code |=
+ (chn == channel_left) ? ERROR_DEVA_I2C_COMM : ERROR_DEVB_I2C_COMM;
+ } else {
+ pr_debug(
+ "%s: chn%x:BOOK:PAGE:REG 0x%02x:0x%02x:0x%02x, mask: 0x%02x, val: 0x%02x\n",
+ __func__, p_tas256x->devs[i]->mn_addr,
+ TAS256X_BOOK_ID(reg),
+ TAS256X_PAGE_ID(reg),
+ TAS256X_PAGE_REG(reg), mask, value);
+ p_tas256x->mn_err_code &=
+ (chn == channel_left) ? ~ERROR_DEVA_I2C_COMM : ~ERROR_DEVB_I2C_COMM;
+ }
+ }
+ }
+
+end:
+ mutex_unlock(&p_tas256x->dev_lock);
+ return rc;
+}
+
+static void tas256x_hard_reset(struct tas256x_priv *p_tas256x)
+{
+ int i = 0;
+
+ p_tas256x->hw_reset(p_tas256x);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ p_tas256x->devs[i]->mn_current_book = -1;
+ p_tas256x->devs[i]->mn_current_page = -1;
+ }
+
+ if (p_tas256x->mn_err_code)
+ pr_err("%s: before reset, ErrCode=0x%x\n", __func__,
+ p_tas256x->mn_err_code);
+ p_tas256x->mn_err_code = 0;
+}
+
+void tas256x_failsafe(struct tas256x_priv *p_tas256x)
+{
+ int n_result;
+
+ pr_err("%s\n", __func__);
+ p_tas256x->mn_err_code |= ERROR_FAILSAFE;
+
+ if (p_tas256x->mn_restart < RESTART_MAX) {
+ p_tas256x->mn_restart++;
+ msleep(100);
+ pr_err("I2C COMM error, restart SmartAmp.\n");
+ tas256x_set_power_state(p_tas256x, p_tas256x->mn_power_state);
+ return;
+ }
+
+ n_result = tas256x_set_power_shutdown(p_tas256x, channel_both);
+ p_tas256x->mb_power_up = false;
+ p_tas256x->mn_power_state = TAS256X_POWER_SHUTDOWN;
+ msleep(20);
+ /*Mask interrupt for TDM*/
+ n_result = tas256x_interrupt_enable(p_tas256x, 0/*Disable*/,
+ channel_both);
+ p_tas256x->enable_irq(p_tas256x, false);
+ tas256x_hard_reset(p_tas256x);
+ p_tas256x->write(p_tas256x, channel_both, TAS256X_SOFTWARERESET,
+ TAS256X_SOFTWARERESET_SOFTWARERESET_RESET);
+ udelay(1000);
+ /*pTAS256x->write(pTAS256x, channel_both, TAS256X_SPK_CTRL_REG, 0x04);*/
+}
+
+int tas256x_load_i2s_tdm_interface_settings(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ /*Frame_Start Settings*/
+ n_result |= tas256x_rx_set_frame_start(p_tas256x,
+ p_tas256x->mn_frame_start, ch);
+ /*RX Edge Settings*/
+ n_result |= tas256x_rx_set_edge(p_tas256x,
+ p_tas256x->mn_rx_edge, ch);
+ /*RX Offset Settings*/
+ n_result |= tas256x_rx_set_start_slot(p_tas256x,
+ p_tas256x->mn_rx_offset, ch);
+ /*TX Edge Settings*/
+ n_result |= tas256x_tx_set_edge(p_tas256x,
+ p_tas256x->mn_tx_edge, ch);
+ /*TX Offset Settings*/
+ n_result |= tas256x_tx_set_start_slot(p_tas256x,
+ p_tas256x->mn_tx_offset, ch);
+
+ return n_result;
+}
+
+int tas256x_load_init(struct tas256x_priv *p_tas256x)
+{
+ int ret = 0, i;
+
+ pr_info("%s:\n", __func__);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->dev_ops.tas_init)
+ ret |= (p_tas256x->devs[i]->dev_ops.tas_init)(p_tas256x, i+1);
+ }
+
+ ret |= tas256x_set_misc_config(p_tas256x, 0/*Ignored*/, channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_tx_config(p_tas256x, 0/*Ignored*/, channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_load_i2s_tdm_interface_settings(p_tas256x, channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_clock_config(p_tas256x, 0/*Ignored*/, channel_both);
+ if (ret < 0)
+ goto end;
+
+ /*ICN Improve Performance*/
+ ret |= tas256x_icn_config(p_tas256x, 0/*Ignored*/, channel_both);
+ if (ret < 0)
+ goto end;
+#if IS_ENABLED(HPF_BYPASS)
+ /*Disable the HPF in Forward Path*/
+ ret |= tas256x_HPF_FF_Bypass(p_tas256x, 0/*Ignored*/, channel_both);
+ if (ret < 0)
+ goto end;
+ /*Disable the HPF in Reverse Path*/
+ ret |= tas256x_HPF_FB_Bypass(p_tas256x, 0/*Ignored*/, channel_both);
+ if (ret < 0)
+ goto end;
+#endif
+ ret |= tas256x_set_classH_config(p_tas256x, 0/*Ignored*/, channel_both);
+
+end:
+ if (ret < 0) {
+ if (p_tas256x->mn_err_code &
+ (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM))
+ tas256x_failsafe(p_tas256x);
+ }
+ return ret;
+}
+
+int tas256x_load_ctrl_values(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ n_result |= tas256x_update_playback_volume(p_tas256x,
+ p_tas256x->devs[ch-1]->dvc_pcm, ch);
+
+ n_result |= tas256x_update_lim_max_attenuation(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_max_attn, ch);
+
+ n_result |= tas256x_update_lim_max_thr(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_thr_max, ch);
+
+ n_result |= tas256x_update_lim_min_thr(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_thr_min, ch);
+
+ n_result |= tas256x_update_lim_inflection_point(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_infl_pt, ch);
+
+ n_result |= tas256x_update_lim_slope(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_trk_slp, ch);
+
+ n_result |= tas256x_update_bop_thr(p_tas256x,
+ p_tas256x->devs[ch-1]->bop_thd, ch);
+
+ n_result |= tas256x_update_bosd_thr(p_tas256x,
+ p_tas256x->devs[ch-1]->bosd_thd, ch);
+
+ n_result |= tas256x_update_boost_voltage(p_tas256x,
+ p_tas256x->devs[ch-1]->bst_vltg, ch);
+
+ n_result |= tas256x_update_current_limit(p_tas256x,
+ p_tas256x->devs[ch-1]->bst_ilm, ch);
+
+ n_result |= tas256x_update_ampoutput_level(p_tas256x,
+ p_tas256x->devs[ch-1]->ampoutput_lvl, ch);
+
+ n_result |= tas256x_update_limiter_enable(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_switch, ch);
+
+ n_result |= tas256x_update_limiter_attack_rate(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_att_rate, ch);
+
+ n_result |= tas256x_update_limiter_attack_step_size(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_att_stp_size, ch);
+
+ n_result |= tas256x_update_limiter_release_rate(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_rel_rate, ch);
+
+ n_result |= tas256x_update_limiter_release_step_size(p_tas256x,
+ p_tas256x->devs[ch-1]->lim_rel_stp_size, ch);
+
+ n_result |= tas256x_update_bop_enable(p_tas256x,
+ p_tas256x->devs[ch-1]->bop_enable, ch);
+
+ n_result |= tas256x_update_bop_mute(p_tas256x,
+ p_tas256x->devs[ch-1]->bop_mute, ch);
+
+ n_result |= tas256x_update_bop_shutdown_enable(p_tas256x,
+ p_tas256x->devs[ch-1]->bosd_enable, ch);
+
+ n_result |= tas256x_update_bop_attack_rate(p_tas256x,
+ p_tas256x->devs[ch-1]->bop_att_rate, ch);
+
+ n_result |= tas256x_update_bop_attack_step_size(p_tas256x,
+ p_tas256x->devs[ch-1]->bop_att_stp_size, ch);
+
+ n_result |= tas256x_update_bop_hold_time(p_tas256x,
+ p_tas256x->devs[ch-1]->bop_hld_time, ch);
+
+ n_result |= tas256x_update_vbat_lpf(p_tas256x,
+ p_tas256x->devs[ch-1]->vbat_lpf, ch);
+
+ n_result |= tas256x_update_rx_cfg(p_tas256x,
+ p_tas256x->devs[ch-1]->rx_cfg, ch);
+
+ n_result |= tas256x_update_classh_timer(p_tas256x,
+ p_tas256x->devs[ch-1]->classh_timer, ch);
+
+ n_result |= tas256x_enable_reciever_mode(p_tas256x,
+ p_tas256x->devs[ch-1]->reciever_enable, ch);
+
+ n_result |= tas256x_icn_disable(p_tas256x,
+ p_tas256x->icn_sw, ch);
+
+ n_result |= tas256x_rx_set_slot(p_tas256x,
+ p_tas256x->mn_rx_slot_map[ch-1], ch);
+
+ return n_result;
+}
+
+void tas256x_irq_reload(struct tas256x_priv *p_tas256x)
+{
+ int ret = 0;
+
+ pr_info("%s:\n", __func__);
+ ret |= tas256x_set_power_state(p_tas256x, p_tas256x->mn_power_state);
+ /* power up failed, restart later */
+ if (ret < 0) {
+ if (p_tas256x->mn_err_code &
+ (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM))
+ tas256x_failsafe(p_tas256x);
+ }
+
+}
+
+void tas256x_load_config(struct tas256x_priv *p_tas256x)
+{
+ int ret = 0;
+
+ pr_info("%s:\n", __func__);
+ tas256x_hard_reset(p_tas256x);
+ msleep(20);
+
+ ret |= tas56x_software_reset(p_tas256x, channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_load_ctrl_values(p_tas256x, channel_left);
+ if (ret < 0)
+ goto end;
+ if (p_tas256x->mn_channels == 2) {
+ ret |= tas256x_load_ctrl_values(p_tas256x, channel_right);
+ if (ret < 0)
+ goto end;
+ }
+ ret |= tas256x_load_init(p_tas256x);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_update_rx_cfg(p_tas256x, p_tas256x->devs[0]->rx_cfg,
+ channel_left);
+ if (ret < 0)
+ goto end;
+ if (p_tas256x->mn_channels == 2) {
+ ret |= tas256x_update_rx_cfg(p_tas256x, p_tas256x->devs[1]->rx_cfg,
+ channel_right);
+ if (ret < 0)
+ goto end;
+ }
+ ret |= tas256x_iv_sense_enable_set(p_tas256x, 1,
+ channel_both);
+ if (ret < 0)
+ goto end;
+ if (p_tas256x->mn_fmt_mode == 2) {
+ ret |= tas256x_set_tdm_rx_slot(p_tas256x, p_tas256x->mn_slots,
+ p_tas256x->mn_rx_slot_width);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_tdm_tx_slot(p_tas256x, p_tas256x->mn_slots,
+ p_tas256x->mn_tx_slot_width);
+ if (ret < 0)
+ goto end;
+ } else { /*I2S Mode*/
+ ret |= tas256x_set_bitwidth(p_tas256x,
+ p_tas256x->mn_rx_width, TAS256X_STREAM_PLAYBACK);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_bitwidth(p_tas256x,
+ p_tas256x->mn_rx_width, TAS256X_STREAM_CAPTURE);
+ if (ret < 0)
+ goto end;
+ }
+
+ ret |= tas256x_set_samplerate(p_tas256x, p_tas256x->mn_sampling_rate,
+ channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_power_state(p_tas256x, p_tas256x->mn_power_state);
+ if (ret < 0)
+ goto end;
+end:
+/* power up failed, restart later */
+ if (ret < 0) {
+ if (p_tas256x->mn_err_code &
+ (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM))
+ tas256x_failsafe(p_tas256x);
+ }
+}
+
+void tas256x_reload(struct tas256x_priv *p_tas256x, int chn)
+{
+ int ret = 0;
+ /*To be used later*/
+ (void)chn;
+
+ pr_info("%s: chn %d\n", __func__, chn);
+ p_tas256x->enable_irq(p_tas256x, false);
+
+ ret |= tas56x_software_reset(p_tas256x, channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_load_init(p_tas256x);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_load_ctrl_values(p_tas256x, channel_left);
+ if (ret < 0)
+ goto end;
+ if (p_tas256x->mn_channels == 2) {
+ ret |= tas256x_load_ctrl_values(p_tas256x, channel_right);
+ if (ret < 0)
+ goto end;
+ }
+ ret |= tas256x_iv_sense_enable_set(p_tas256x, 1,
+ channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_bitwidth(p_tas256x,
+ p_tas256x->mn_rx_width, TAS256X_STREAM_PLAYBACK);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_bitwidth(p_tas256x,
+ p_tas256x->mn_rx_width, TAS256X_STREAM_CAPTURE);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_samplerate(p_tas256x, p_tas256x->mn_sampling_rate,
+ channel_both);
+ if (ret < 0)
+ goto end;
+ ret |= tas256x_set_power_state(p_tas256x, p_tas256x->mn_power_state);
+ if (ret < 0)
+ goto end;
+end:
+ p_tas256x->enable_irq(p_tas256x, true);
+/* power up failed, restart later */
+ if (ret < 0) {
+ if (p_tas256x->mn_err_code &
+ (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM))
+ tas256x_failsafe(p_tas256x);
+ }
+}
+
+static int tas2558_specific(struct tas256x_priv *p_tas256x, int chn)
+{
+ int ret = 0;
+
+ pr_info("%s: chn %d\n", __func__, chn);
+ ret = tas256x_boost_volt_update(p_tas256x, DEVICE_TAS2558, chn);
+
+ return ret;
+}
+
+static int tas2564_specific(struct tas256x_priv *p_tas256x, int chn)
+{
+ int ret = 0;
+
+ pr_info("%s: chn %d\n", __func__, chn);
+ ret = tas256x_boost_volt_update(p_tas256x, DEVICE_TAS2564, chn);
+
+ return ret;
+}
+
+int tas256x_irq_work_func(struct tas256x_priv *p_tas256x)
+{
+ unsigned int nDevInt1Status = 0, nDevInt2Status = 0,
+ nDevInt3Status = 0, nDevInt4Status = 0;
+ int n_counter = 2;
+ int n_result = 0;
+ int irqreg, irqreg2, i, chnTemp = 0;
+ enum channel chn = channel_left;
+
+ pr_info("%s:\n", __func__);
+
+ p_tas256x->enable_irq(p_tas256x, false);
+
+ if (p_tas256x->mn_err_code & ERROR_FAILSAFE)
+ goto reload;
+
+ if (p_tas256x->mn_power_state == TAS256X_POWER_SHUTDOWN) {
+ pr_err("%s: device not powered\n", __func__);
+ goto end;
+ }
+
+ n_result = tas256x_interrupt_enable(p_tas256x, 0/*Disable*/,
+ channel_both);
+ if (n_result < 0)
+ goto reload;
+
+ /*Reset error codes*/
+ p_tas256x->mn_err_code = 0;
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+
+ if (chn & channel_left) {
+ n_result = tas256x_interrupt_read(p_tas256x,
+ &nDevInt1Status, &nDevInt2Status, channel_left);
+ if (n_result < 0)
+ goto reload;
+ p_tas256x->mn_err_code =
+ tas256x_interrupt_determine(p_tas256x, channel_left,
+ nDevInt1Status, nDevInt2Status);
+ }
+
+ if (chn & channel_right) {
+ n_result = tas256x_interrupt_read(p_tas256x,
+ &nDevInt3Status, &nDevInt4Status, channel_right);
+ if (n_result < 0)
+ goto reload;
+ p_tas256x->mn_err_code |=
+ tas256x_interrupt_determine(p_tas256x, channel_right,
+ nDevInt3Status, nDevInt4Status);
+ }
+
+ pr_err("%s: IRQ status : 0x%x, 0x%x, 0x%x, 0x%x mn_err_code %d\n",
+ __func__,
+ nDevInt1Status, nDevInt2Status,
+ nDevInt3Status, nDevInt4Status,
+ p_tas256x->mn_err_code);
+
+ if (p_tas256x->mn_err_code) {
+ tas256x_irq_reload(p_tas256x);
+ goto end;
+ } else {
+ pr_err("%s: Power Up\n", __func__);
+ n_counter = 2;
+ while (n_counter > 0) {
+ if (chn & channel_left)
+ n_result = tas256x_power_check(p_tas256x,
+ &nDevInt1Status,
+ channel_left);
+ if (n_result < 0)
+ goto reload;
+ if (chn & channel_right)
+ n_result = tas256x_power_check(p_tas256x,
+ &nDevInt3Status,
+ channel_right);
+ if (n_result < 0)
+ goto reload;
+
+ if (nDevInt1Status) {
+ /* If only left should be power on */
+ if (chn == channel_left)
+ break;
+ /* If both should be power on */
+ if (nDevInt3Status)
+ break;
+ } else if (chn == channel_right) {
+ /*If only right should be power on */
+ if (nDevInt3Status)
+ break;
+ }
+
+ tas256x_interrupt_read(p_tas256x,
+ &irqreg, &irqreg2, channel_both);
+ n_counter--;
+ if (n_counter > 0) {
+ /* in case check pow status
+ *just after power on TAS256x
+ */
+ if (chn & channel_left)
+ pr_err("%s: PowSts A: 0x%x, check again after 10ms\n",
+ __func__,
+ nDevInt1Status);
+
+ if (chn & channel_right)
+ pr_err("%s: PowSts B: 0x%x, check again after 10ms\n",
+ __func__,
+ nDevInt3Status);
+
+ msleep(20);
+ }
+ }
+
+ if (((!nDevInt1Status) && (chn & channel_left))
+ || ((!nDevInt3Status) && (chn & channel_right))) {
+ if (chn & channel_left)
+ pr_err("%s, Critical ERROR A REG[POWERCONTROL] = 0x%x\n",
+ __func__,
+ nDevInt1Status);
+
+ if (chn & channel_right)
+ pr_err("%s, Critical ERROR B REG[POWERCONTROL] = 0x%x\n",
+ __func__,
+ nDevInt3Status);
+ goto reload;
+ }
+ }
+
+ n_result = tas256x_interrupt_enable(p_tas256x, 1/*Enable*/,
+ channel_both);
+ if (n_result < 0)
+ goto reload;
+
+ goto end;
+
+reload:
+ /* hardware reset and reload */
+ tas256x_load_config(p_tas256x);
+
+end:
+ p_tas256x->enable_irq(p_tas256x, true);
+
+ return n_result;
+}
+
+int tas256x_init_work_func(struct tas256x_priv *p_tas256x)
+{
+ int n_result = 0;
+
+ pr_info("%s:\n", __func__);
+
+ /* Clear latched IRQ before power on */
+ n_result = tas256x_interrupt_clear(p_tas256x, channel_both);
+
+ /*Un-Mask interrupt for TDM*/
+ n_result = tas256x_interrupt_enable(p_tas256x, 1/*Enable*/,
+ channel_both);
+
+ p_tas256x->enable_irq(p_tas256x, true);
+
+ return n_result;
+}
+
+int tas256x_dc_work_func(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ pr_info("%s: ch %d\n", __func__, ch);
+ tas256x_reload(p_tas256x, ch);
+
+ return n_result;
+}
+
+int tas256x_register_device(struct tas256x_priv *p_tas256x)
+{
+ int n_result;
+ int i;
+
+ pr_info("%s:\n", __func__);
+ p_tas256x->read = tas256x_dev_read;
+ p_tas256x->write = tas256x_dev_write;
+ p_tas256x->bulk_read = tas256x_dev_bulk_read;
+ p_tas256x->bulk_write = tas256x_dev_bulk_write;
+ p_tas256x->update_bits = tas256x_dev_update_bits;
+
+ tas256x_hard_reset(p_tas256x);
+
+ pr_info("Before SW reset\n");
+ /* Reset the chip */
+ n_result = tas56x_software_reset(p_tas256x, channel_both);
+ if (n_result < 0) {
+ pr_err("I2c fail, %d\n", n_result);
+ goto err;
+ }
+
+ pr_info("After SW reset\n");
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ n_result = tas56x_get_chipid(p_tas256x,
+ &(p_tas256x->devs[i]->mn_chip_id),
+ (i == 0) ? channel_left : channel_right);
+ if (n_result < 0)
+ goto err;
+ switch (p_tas256x->devs[i]->mn_chip_id) {
+ case 0x10:
+ case 0x20:
+ p_tas256x->devs[i]->device_id = DEVICE_TAS2562;
+ p_tas256x->devs[i]->dev_ops.tas_init = NULL;
+ break;
+ case 0x00:
+ p_tas256x->devs[i]->device_id = DEVICE_TAS2564;
+ p_tas256x->devs[i]->dev_ops.tas_init =
+ tas2564_specific;
+ break;
+ default:
+ p_tas256x->devs[i]->device_id = DEVICE_TAS2558;
+ p_tas256x->devs[i]->dev_ops.tas_init =
+ tas2558_specific;
+ break;
+ }
+ pr_info("TAS%x chip, chip_id = 0x%x",
+ p_tas256x->devs[i]->device_id,
+ p_tas256x->devs[i]->mn_chip_id);
+ n_result |= tas256x_set_misc_config(p_tas256x, 0,
+ (i == 0) ? channel_left : channel_right);
+ }
+err:
+ return n_result;
+}
+
+int tas256x_probe(struct tas256x_priv *p_tas256x)
+{
+ int ret = 0;
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+#endif
+
+ pr_info("%s:\n", __func__);
+ ret = tas256x_load_init(p_tas256x);
+ if (ret < 0)
+ goto end;
+ ret = tas256x_iv_sense_enable_set(p_tas256x, 1, channel_both);
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+ if (plat_data) {
+ tas_smartamp_add_algo_controls(plat_data->codec, plat_data->dev,
+ p_tas256x->mn_channels);
+ /*Send IV Vbat format but don't update to algo yet*/
+ tas25xx_set_iv_bit_fomat(p_tas256x->mn_iv_width,
+ p_tas256x->mn_vbat, 0);
+ }
+#endif
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ ret = tas256x_load_container(p_tas256x);
+ pr_info("%s Bin file loading requested: %d\n", __func__, ret);
+#endif
+end:
+ return ret;
+}
+
+void tas256x_remove(struct tas256x_priv *p_tas256x)
+{
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ if (plat_data) {
+ tas_smartamp_remove_algo_controls(plat_data->codec);
+ }
+#else
+ /*Ignore argument*/
+ (void)p_tas256x;
+#endif
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ tas256x_config_info_remove(p_tas256x);
+#endif
+}
+
+int tas256x_set_power_state(struct tas256x_priv *p_tas256x,
+ int state)
+{
+ int n_result = 0, i = 0, chnTemp = 0;
+ enum channel chn = channel_left;
+
+ pr_info("%s: state %d\n", __func__, state);
+
+ if ((p_tas256x->mb_mute) && (state == TAS256X_POWER_ACTIVE))
+ state = TAS256X_POWER_MUTE;
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+
+ switch (state) {
+ case TAS256X_POWER_ACTIVE:
+ n_result = tas256x_iv_sense_enable_set(p_tas256x, 1, chn);
+#if IS_ENABLED(CONFIG_TAS25XX_CALIB_VAL_BIG)
+ tas25xx_send_channel_mapping();
+ tas25xx_send_algo_calibration();
+ tas25xx_set_iv_bit_fomat(p_tas256x->mn_iv_width,
+ p_tas256x->mn_vbat, 1);
+#endif
+ /* Clear latched IRQ before power on */
+ tas256x_interrupt_clear(p_tas256x, chn);
+
+ /*Mask interrupt for TDM*/
+ n_result = tas256x_interrupt_enable(p_tas256x, 0/*Disable*/,
+ channel_both);
+
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ /*set p_tas256x->profile_cfg_id by tinymix*/
+ tas256x_select_cfg_blk(p_tas256x,
+ p_tas256x->profile_cfg_id,
+ TAS256X_BIN_BLK_PRE_POWER_UP);
+#endif
+ n_result = tas256x_set_power_up(p_tas256x, chn);
+
+ pr_info("%s: set ICN to -80dB\n", __func__);
+ n_result = tas256x_icn_data(p_tas256x, chn);
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ /*set p_tas256x->profile_cfg_id by tinymix*/
+ tas256x_select_cfg_blk(p_tas256x,
+ p_tas256x->profile_cfg_id,
+ TAS256X_BIN_BLK_POST_POWER_UP);
+#endif
+ p_tas256x->mb_power_up = true;
+ p_tas256x->mn_power_state = TAS256X_POWER_ACTIVE;
+ p_tas256x->schedule_init_work(p_tas256x);
+ break;
+
+ case TAS256X_POWER_MUTE:
+ n_result = tas256x_set_power_mute(p_tas256x, chn);
+ p_tas256x->mb_power_up = true;
+ p_tas256x->mn_power_state = TAS256X_POWER_MUTE;
+
+ /*Mask interrupt for TDM*/
+ n_result = tas256x_interrupt_enable(p_tas256x, 0/*Disable*/,
+ chn);
+ break;
+
+ case TAS256X_POWER_SHUTDOWN:
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ /*set p_tas256x->profile_cfg_id by tinymix*/
+ tas256x_select_cfg_blk(p_tas256x, p_tas256x->profile_cfg_id,
+ TAS256X_BIN_BLK_PRE_SHUTDOWN);
+#endif
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->device_id == DEVICE_TAS2564) {
+ if (chn & (i+1)) {
+ /*Mask interrupt for TDM*/
+ n_result =
+ tas256x_interrupt_enable(p_tas256x,
+ 0/*Disable*/, i+1);
+ n_result =
+ tas256x_set_power_mute(p_tas256x,
+ i+1);
+ n_result =
+ tas256x_iv_sense_enable_set(p_tas256x,
+ 0, i+1);
+ p_tas256x->mb_power_up = false;
+ p_tas256x->mn_power_state =
+ TAS256X_POWER_SHUTDOWN;
+ }
+ } else {
+ if (chn & (i+1)) {
+ n_result =
+ tas256x_set_power_shutdown(p_tas256x, i+1);
+ n_result =
+ tas256x_iv_sense_enable_set(p_tas256x, 0,
+ i+1);
+ p_tas256x->mb_power_up = false;
+ p_tas256x->mn_power_state =
+ TAS256X_POWER_SHUTDOWN;
+ /*Mask interrupt for TDM*/
+ n_result = tas256x_interrupt_enable(p_tas256x,
+ 0/*Disable*/,
+ i+1);
+ }
+ }
+ }
+ p_tas256x->enable_irq(p_tas256x, false);
+ /*Device Shutdown need 16ms after shutdown writes are made*/
+ usleep_range(16000, 16100);
+
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ /*set p_tas256x->profile_cfg_id by tinymix*/
+ tas256x_select_cfg_blk(p_tas256x, p_tas256x->profile_cfg_id,
+ TAS256X_BIN_BLK_POST_SHUTDOWN);
+#endif
+#if IS_ENABLED(CONFIG_TAS25XX_CALIB_VAL_BIG)
+ tas25xx_update_big_data();
+#endif
+#if IS_ENABLED(CONFIG_TISA_KBIN_INTF)
+ tas25xx_algo_set_inactive();
+#endif
+ break;
+ default:
+ pr_err("wrong power state setting %d\n",
+ state);
+ }
+
+ return n_result;
+}
+
+int tas256x_iv_vbat_slot_config(struct tas256x_priv *p_tas256x,
+ int mn_slot_width)
+{
+ int n_result = 0;
+
+ pr_debug("%s: mn_slot_width %d\n", __func__, mn_slot_width);
+
+ if (p_tas256x->mn_fmt_mode == 2) { /*TDM Mode*/
+ if (p_tas256x->mn_channels == 2) {
+ if (mn_slot_width == 16) {
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT1,
+ TX_SLOT0);
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOT5,
+ TX_SLOT4);
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT3);
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_right,
+ TX_SLOT7);
+ } else {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT2,
+ TX_SLOT0);
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOT6,
+ TX_SLOT4);
+ }
+
+ } else if (mn_slot_width == 24) {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT3,
+ TX_SLOT0);
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOT9,
+ TX_SLOT6);
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT5);
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_right,
+ TX_SLOTa);
+ }
+ } else { /*Assumed 32bit*/
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT4,
+ TX_SLOT0);
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOTc,
+ TX_SLOT8);
+
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT6);
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_right,
+ TX_SLOTe);
+ }
+ }
+ } else { /*Assumed Mono Channels*/
+ if (mn_slot_width == 16) {
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT1,
+ TX_SLOT0);
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT3);
+ } else {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT2,
+ TX_SLOT0);
+ }
+ } else if (mn_slot_width == 24) {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT3,
+ TX_SLOT0);
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT5);
+ }
+ } else { /*Assumed 32bit*/
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT4,
+ TX_SLOT0);
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT6);
+ }
+ }
+ }
+ } else { /*I2S Mode*/
+ if (p_tas256x->mn_channels == 2) {
+ if (mn_slot_width == 16) {
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT1, TX_SLOT0);
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOT3, TX_SLOT2);
+ } else { /*16 or 32 bit*/
+ if (p_tas256x->mn_iv_width == 8) {
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT1,
+ TX_SLOT0);
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOT5,
+ TX_SLOT4);
+ if (p_tas256x->mn_vbat == 1) {
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT2);
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_right, TX_SLOT6);
+ }
+ } else { /*p_tas256x->mn_iv_width == 16 & VBat
+ *cannot exist in this combination
+ */
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT2,
+ TX_SLOT0);
+ n_result |=
+ tas256x_set_iv_slot(p_tas256x,
+ channel_right, TX_SLOT6,
+ TX_SLOT4);
+ }
+ }
+ } else if ((p_tas256x->mn_channels == 1)
+ && (mn_slot_width == 32)) {
+ if (p_tas256x->mn_iv_width == 16) {
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT4, TX_SLOT0);
+ } else if (p_tas256x->mn_iv_width == 12) {
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT1, TX_SLOT0);
+ if (p_tas256x->mn_vbat == 1)
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT4);
+ }
+ } else if ((p_tas256x->mn_channels == 1)
+ && (mn_slot_width == 16)) {
+ if (p_tas256x->mn_iv_width == 16) {
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT2, TX_SLOT0);
+ } else if (p_tas256x->mn_iv_width == 12) {
+ n_result |= tas256x_set_iv_slot(p_tas256x,
+ channel_left, TX_SLOT1, TX_SLOT0);
+ if (p_tas256x->mn_vbat == 1)
+ n_result |=
+ tas256x_set_vbat_slot(p_tas256x,
+ channel_left, TX_SLOT3);
+ }
+ } else {
+ n_result = -1;
+ }
+ }
+
+ if (n_result == 0)
+ p_tas256x->mn_tx_slot_width = mn_slot_width;
+
+ return n_result;
+}
+
+int tas256x_set_bitwidth(struct tas256x_priv *p_tas256x,
+ int bitwidth, int stream)
+{
+ int n_result = 0;
+ int slot_width_tmp = 16;
+
+ if (bitwidth == 24)
+ slot_width_tmp = 32;
+
+ pr_info("%s: bitwidth %d stream %d\n", __func__, bitwidth, stream);
+
+ if (stream == TAS256X_STREAM_PLAYBACK) {
+ n_result |= tas256x_rx_set_bitwidth(p_tas256x, bitwidth,
+ channel_both);
+ n_result |= tas256x_rx_set_slot_len(p_tas256x, slot_width_tmp,
+ channel_both);
+ } else { /*stream == TAS256X_STREAM_CAPTURE*/
+ n_result |= tas256x_iv_bitwidth_config(p_tas256x,
+ p_tas256x->mn_iv_width, channel_both);
+ n_result |= tas256x_iv_vbat_slot_config(p_tas256x,
+ slot_width_tmp);
+ }
+
+ if (n_result < 0) {
+ if (p_tas256x->mn_err_code &
+ (ERROR_DEVA_I2C_COMM | ERROR_DEVB_I2C_COMM))
+ tas256x_failsafe(p_tas256x);
+ }
+
+ return n_result;
+}
+
+int tas256x_set_tdm_rx_slot(struct tas256x_priv *p_tas256x,
+ int slots, int slot_width)
+{
+ int ret = -1;
+ int bitwidth = slot_width;
+
+ if (((p_tas256x->mn_channels == 1) && (slots < 1)) ||
+ ((p_tas256x->mn_channels == 2) && (slots < 2))) {
+ pr_err("Invalid Slots %d\n", slots);
+ return ret;
+ }
+ p_tas256x->mn_slots = slots;
+
+ if ((slot_width != 16) &&
+ (slot_width != 24) &&
+ (slot_width != 32)) {
+ pr_err("Unsupported slot width %d\n", slot_width);
+ return ret;
+ }
+
+ ret = tas256x_rx_set_slot_len(p_tas256x, slot_width, channel_both);
+
+ switch (bitwidth) {
+ case 16:
+ ret = tas256x_rx_set_bitwidth(p_tas256x,
+ 16, channel_both);
+ break;
+ case 24:
+ case 32:
+ ret = tas256x_rx_set_bitwidth(p_tas256x,
+ 24, channel_both);
+ break;
+ default:
+ pr_err("Not supported params format\n");
+ }
+
+ /*Enable Auto Detect of Sample Rate */
+ ret = tas256x_set_auto_detect_clock(p_tas256x,
+ 1, channel_both);
+
+ /*Enable Clock Config*/
+ ret = tas256x_set_clock_config(p_tas256x, 0/*Ignored*/,
+ channel_both);
+
+ return ret;
+}
+
+int tas256x_set_tdm_tx_slot(struct tas256x_priv *p_tas256x,
+ int slots, int slot_width)
+{
+ int ret = -1;
+
+ if ((slot_width != 16) &&
+ (slot_width != 24) &&
+ (slot_width != 32)) {
+ pr_err("Unsupported slot width %d\n", slot_width);
+ return ret;
+ }
+
+ if (((p_tas256x->mn_channels == 1) && (slots < 2)) ||
+ ((p_tas256x->mn_channels == 2) && (slots < 4))) {
+ pr_err("Invalid Slots %d\n", slots);
+ return ret;
+ }
+ p_tas256x->mn_slots = slots;
+
+ if (slot_width == 24)
+ slot_width = 32;
+
+ ret = tas256x_iv_vbat_slot_config(p_tas256x, slot_width);
+
+ if ((p_tas256x->mn_channels == 2) &&
+ (p_tas256x->mn_tx_slot_width == 16)) {
+ if (p_tas256x->mn_vbat == 1) {
+ ret |= tas256x_iv_bitwidth_config(p_tas256x, 12,
+ channel_both);
+ } else {
+ ret |= tas256x_iv_bitwidth_config(p_tas256x, 16,
+ channel_both);
+ }
+ } else {
+ ret |= tas256x_iv_bitwidth_config(p_tas256x, 16,
+ channel_both);
+ }
+
+ return ret;
+}
diff --git a/asoc/codecs/tas256x/misc/tas256x-misc.c b/asoc/codecs/tas256x/misc/tas256x-misc.c
new file mode 100644
index 00000000..2561efc4
--- /dev/null
+++ b/asoc/codecs/tas256x/misc/tas256x-misc.c
@@ -0,0 +1,240 @@
+/*
+ * =============================================================================
+ * Copyright (c) 2016 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ * File:
+ * tas256x-misc.c
+ *
+ * Description:
+ * misc driver for Texas Instruments
+ * TAS256X High Performance 4W Smart Amplifier
+ *
+ * =============================================================================
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/fcntl.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+
+#include "physical_layer/inc/tas256x.h"
+#include "tas256x-misc.h"
+#include <linux/dma-mapping.h>
+
+static struct tas256x_priv *g_tas256x;
+
+static int tas256x_file_open(struct inode *inode, struct file *file)
+{
+ struct tas256x_priv *p_tas256x = g_tas256x;
+
+ file->private_data = (void *)p_tas256x;
+
+ pr_info("TAS256X %s\n", __func__);
+ return 0;
+}
+
+static int tas256x_file_release(struct inode *inode, struct file *file)
+{
+ pr_info("TAS256X %s\n", __func__);
+
+ file->private_data = (void *)NULL;
+
+ return 0;
+}
+
+static ssize_t tas256x_file_read(struct file *file,
+ char *buf, size_t count, loff_t *ppos)
+{
+ struct tas256x_priv *p_tas256x =
+ (struct tas256x_priv *)file->private_data;
+ int ret = 0;
+ unsigned char *p_kbuf = NULL;
+ unsigned int reg = 0;
+ unsigned int len = 0;
+ unsigned int channel = channel_left;
+
+ mutex_lock(&p_tas256x->file_lock);
+
+ p_kbuf = kzalloc(count, GFP_KERNEL);
+ if (p_kbuf == NULL) {
+ pr_err("TAS256X write no mem\n");
+ goto err;
+ }
+
+ ret = copy_from_user(p_kbuf, buf, count);
+ if (ret != 0) {
+ pr_err("TAS256X copy_from_user failed.\n");
+ goto err;
+ }
+
+ if ((p_kbuf[1] >= 0) && ((p_kbuf[1] <= 1)))
+ channel = p_kbuf[1]+1;
+
+ switch (p_kbuf[0]) {
+ case TIAUDIO_CMD_REG_READ:
+ {
+ reg = ((unsigned int)p_kbuf[2] << 24) +
+ ((unsigned int)p_kbuf[3] << 16) +
+ ((unsigned int)p_kbuf[4] << 8) +
+ (unsigned int)p_kbuf[5];
+
+ pr_info("TAS256X TIAUDIO_CMD_REG_READ: current_reg = 0x%x, count=%d\n",
+ reg, (int)count-6);
+ len = count-6;
+ if (len == 1) {
+ unsigned int value = 0;
+ ret = p_tas256x->read(p_tas256x, channel,
+ reg, &value);
+ if (ret < 0) {
+ pr_err("TAS256X dev read fail %d\n", ret);
+ break;
+ }
+ p_kbuf[6] = value;
+ ret = copy_to_user(buf, p_kbuf, count);
+ /* Failed to copy all the data, exit */
+ if (ret != 0)
+ pr_err("TAS256X copy to user fail %d\n", ret);
+ } else if (len > 1) {
+ ret = p_tas256x->bulk_read(p_tas256x, channel,
+ reg, (unsigned char *)&p_kbuf[6], len);
+ if (ret < 0) {
+ pr_err("TAS256X dev bulk read fail %d\n", ret);
+ } else {
+ ret = copy_to_user(buf, p_kbuf, count);
+ /* Failed to copy all the data, exit */
+ if (ret != 0)
+ pr_err("TAS256X copy to user fail %d\n", ret);
+ }
+ }
+ }
+ break;
+ }
+err:
+ if (p_kbuf != NULL)
+ kfree(p_kbuf);
+ mutex_unlock(&p_tas256x->file_lock);
+ return count;
+}
+
+static ssize_t tas256x_file_write(struct file *file,
+ const char *buf, size_t count, loff_t *ppos)
+{
+ struct tas256x_priv *p_tas256x =
+ (struct tas256x_priv *)file->private_data;
+ int ret = 0;
+ unsigned char *p_kbuf = NULL;
+ unsigned int reg = 0;
+ unsigned int len = 0;
+ unsigned int channel = channel_left;
+
+ mutex_lock(&p_tas256x->file_lock);
+
+ p_kbuf = kzalloc(count, GFP_KERNEL);
+ if (p_kbuf == NULL) {
+ pr_err("TAS256X write no mem\n");
+ goto err;
+ }
+
+ ret = copy_from_user(p_kbuf, buf, count);
+ if (ret != 0) {
+ pr_err("TAS256X copy_from_user failed.\n");
+ goto err;
+ }
+
+ if ((p_kbuf[1] >= 0) && ((p_kbuf[1] <= 1)))
+ channel = p_kbuf[1]+1;
+ switch (p_kbuf[0]) {
+ case TIAUDIO_CMD_REG_WITE:
+ if (count > 5) {
+ reg = ((unsigned int)p_kbuf[2] << 24) +
+ ((unsigned int)p_kbuf[3] << 16) +
+ ((unsigned int)p_kbuf[4] << 8) +
+ (unsigned int)p_kbuf[5];
+ len = count - 6;
+ pr_info("TAS256X TIAUDIO_CMD_REG_WITE, Reg=0x%x, Val=0x%x\n",
+ reg, p_kbuf[6]);
+ if (len == 1) {
+ unsigned int value = 0;
+ value = p_kbuf[6];
+ ret = p_tas256x->write(p_tas256x, channel, reg, value);
+ } else if (len > 1) {
+ ret = p_tas256x->bulk_write(p_tas256x, channel,
+ reg, &p_kbuf[6], len);
+ }
+ } else {
+ pr_err("TAS256X %s, write len fail, count=%d.\n",
+ __func__, (int)count);
+ }
+ break;
+ }
+err:
+ if (p_kbuf != NULL)
+ kfree(p_kbuf);
+
+ mutex_unlock(&p_tas256x->file_lock);
+
+ return count;
+}
+
+static const struct file_operations fops = {
+ .owner = THIS_MODULE,
+ .read = tas256x_file_read,
+ .write = tas256x_file_write,
+ .unlocked_ioctl = NULL,
+ .open = tas256x_file_open,
+ .release = tas256x_file_release,
+};
+
+#define MODULE_NAME "tas256x"
+static struct miscdevice tas256x_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = MODULE_NAME,
+ .fops = &fops,
+};
+
+int tas256x_register_misc(struct tas256x_priv *p_tas256x)
+{
+ int ret = 0;
+
+ g_tas256x = p_tas256x;
+ ret = misc_register(&tas256x_misc);
+ if (ret)
+ pr_err("TAS256X TAS256X misc fail: %d\n", ret);
+
+ pr_info("TAS256X %s, leave\n", __func__);
+
+ return ret;
+}
+EXPORT_SYMBOL(tas256x_register_misc);
+
+int tas256x_deregister_misc(struct tas256x_priv *p_tas256x)
+{
+ misc_deregister(&tas256x_misc);
+ return 0;
+}
+EXPORT_SYMBOL(tas256x_deregister_misc);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS256X Misc Smart Amplifier driver");
+MODULE_LICENSE("GPL v2");
diff --git a/asoc/codecs/tas256x/misc/tas256x-misc.h b/asoc/codecs/tas256x/misc/tas256x-misc.h
new file mode 100644
index 00000000..03a29680
--- /dev/null
+++ b/asoc/codecs/tas256x/misc/tas256x-misc.h
@@ -0,0 +1,38 @@
+/*
+ * =============================================================================
+ * Copyright (c) 2016 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ *
+ * File:
+ * tas2562-misc.h
+ *
+ * Description:
+ * header file for tas2562-misc.c
+ *
+ * =============================================================================
+ */
+
+#ifndef _TAS256X_MISC_H
+#define _TAS256X_MISC_H
+
+#define TIAUDIO_CMD_REG_WITE 1
+#define TIAUDIO_CMD_REG_READ 2
+#define TIAUDIO_CMD_DEBUG_ON 3
+#define TIAUDIO_CMD_CALIBRATION 7
+#define TIAUDIO_CMD_SAMPLERATE 8
+#define TIAUDIO_CMD_BITRATE 9
+#define TIAUDIO_CMD_DACVOLUME 10
+#define TIAUDIO_CMD_SPEAKER 11
+
+int tas256x_register_misc(struct tas256x_priv *p_tas256x);
+int tas256x_deregister_misc(struct tas256x_priv *p_tas256x);
+
+#endif /* _TAS256X_MISC_H */
diff --git a/asoc/codecs/tas256x/os_layer/inc/tas256x-codec.h b/asoc/codecs/tas256x/os_layer/inc/tas256x-codec.h
new file mode 100644
index 00000000..e8116b96
--- /dev/null
+++ b/asoc/codecs/tas256x/os_layer/inc/tas256x-codec.h
@@ -0,0 +1,30 @@
+/*
+ * =============================================================================
+ * Copyright (c) 2016 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.
+ *
+ * File:
+ * tas256x-codec.h
+ *
+ * Description:
+ * header file for tas256x-codec.c
+ *
+ * =============================================================================
+ */
+
+#ifndef _TAS256X_CODEC_H
+#define _TAS256X_CODEC_H
+
+#include "physical_layer/inc/tas256x.h"
+
+int tas256x_register_codec(struct tas256x_priv *p_tas256x);
+int tas256x_deregister_codec(struct tas256x_priv *p_tas256x);
+
+#endif /* _TAS256X_CODEC_H */
diff --git a/asoc/codecs/tas256x/os_layer/inc/tas256x-regmap.h b/asoc/codecs/tas256x/os_layer/inc/tas256x-regmap.h
new file mode 100644
index 00000000..36779d67
--- /dev/null
+++ b/asoc/codecs/tas256x/os_layer/inc/tas256x-regmap.h
@@ -0,0 +1,22 @@
+#ifndef __TAS256X_REGMAP__
+#define __TAS256X_REGMAP__
+#include <linux/version.h>
+
+struct linux_platform {
+ struct device *dev;
+ struct i2c_client *client;
+ struct regmap *regmap;
+ struct hrtimer mtimer;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec;
+#else
+ struct snd_soc_codec *codec;
+#endif
+ /* device is working, but system is suspended */
+ int (*runtime_suspend)(struct tas256x_priv *p_tas256x);
+ int (*runtime_resume)(struct tas256x_priv *p_tas256x);
+ bool mb_runtime_suspend;
+ bool i2c_suspend;
+};
+
+#endif /*__TAS256X_REGMAP__*/ \ No newline at end of file
diff --git a/asoc/codecs/tas256x/os_layer/src/tas256x-codec.c b/asoc/codecs/tas256x/os_layer/src/tas256x-codec.c
new file mode 100644
index 00000000..b228ead4
--- /dev/null
+++ b/asoc/codecs/tas256x/os_layer/src/tas256x-codec.c
@@ -0,0 +1,1880 @@
+/*
+ * =============================================================================
+ * Copyright (c) 2016 Texas Instruments Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.
+ *
+ * File:
+ * tas256x-codec.c
+ *
+ * Description:
+ * ALSA SoC driver for Texas Instruments TAS256X High Performance 4W Smart
+ * Amplifier
+ *
+ * =============================================================================
+ */
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/initval.h>
+#include <sound/tlv.h>
+#include <linux/version.h>
+
+#include "physical_layer/inc/tas256x.h"
+#include "physical_layer/inc/tas256x-device.h"
+#include "logical_layer/inc/tas256x-logic.h"
+#include "os_layer/inc/tas256x-regmap.h"
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#include "algo/inc/tas_smart_amp_v2.h"
+#include "algo/inc/tas25xx-calib.h"
+#endif /*CONFIG_TAS25XX_ALGO*/
+
+#define TAS256X_MDELAY 0xFFFFFFFE
+#define TAS256X_MSLEEP 0xFFFFFFFD
+#define TAS256X_IVSENSER_ENABLE 1
+#define TAS256X_IVSENSER_DISABLE 0
+/* #define TAS2558_CODEC */
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static unsigned int tas256x_codec_read(struct snd_soc_component *codec,
+ unsigned int reg)
+{
+ unsigned int value = 0;
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+ int ret = 0;
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ switch (reg) {
+ case TAS256X_LEFT_SWITCH:
+ value = p_tas256x->devs[0]->spk_control;
+ break;
+ case TAS256X_RIGHT_SWITCH:
+ value = p_tas256x->devs[1]->spk_control;
+ break;
+ case RX_SCFG_LEFT:
+ value = p_tas256x->devs[0]->rx_cfg;
+ break;
+ case RX_SCFG_RIGHT:
+ value = p_tas256x->devs[1]->rx_cfg;
+ break;
+ default:
+ ret = p_tas256x->read(p_tas256x, channel_left, reg,
+ &value);
+ break;
+ }
+
+ dev_dbg(plat_data->dev, "%s, reg=%d, value=%d", __func__, reg, value);
+
+ if (ret == 0)
+ return value;
+ else
+ return ret;
+}
+#else
+static unsigned int tas256x_codec_read(struct snd_soc_codec *codec,
+ unsigned int reg)
+{
+ unsigned int value = 0;
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ switch (reg) {
+ case TAS256X_LEFT_SWITCH:
+ value = p_tas256x->devs[0]->spk_control;
+ break;
+ case TAS256X_RIGHT_SWITCH:
+ value = p_tas256x->devs[1]->spk_control;
+ break;
+ case RX_SCFG_LEFT:
+ value = p_tas256x->devs[0]->rx_cfg;
+ break;
+ case RX_SCFG_RIGHT:
+ value = p_tas256x->devs[1]->rx_cfg;
+ break;
+ default:
+ ret = p_tas256x->read(p_tas256x, channel_left, reg,
+ &value);
+ break;
+ }
+
+ dev_dbg(plat_data->dev, "%s, reg=%d, value=%d", __func__, reg, value);
+
+ if (ret == 0)
+ return value;
+ else
+ return ret;
+}
+#endif
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static int tas256x_codec_write(struct snd_soc_component *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ dev_dbg(plat_data->dev, "%s: %d, %d", __func__, reg, value);
+
+ switch (reg) {
+ case TAS256X_LEFT_SWITCH:
+ p_tas256x->devs[0]->spk_control = value;
+ break;
+ case TAS256X_RIGHT_SWITCH:
+ p_tas256x->devs[1]->spk_control = value;
+ break;
+ case RX_SCFG_LEFT:
+ ret = tas256x_update_rx_cfg(p_tas256x, value,
+ channel_left);
+ break;
+ case RX_SCFG_RIGHT:
+ ret = tas256x_update_rx_cfg(p_tas256x, value,
+ channel_right);
+ break;
+ default:
+ ret = p_tas256x->write(p_tas256x, channel_both,
+ reg, value);
+ break;
+ }
+
+ return ret;
+}
+#else
+static int tas256x_codec_write(struct snd_soc_codec *codec,
+ unsigned int reg, unsigned int value)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ dev_dbg(plat_data->dev, "%s: %d, %d", __func__, reg, value);
+
+ switch (reg) {
+ case TAS256X_LEFT_SWITCH:
+ p_tas256x->devs[0]->spk_control = value;
+ break;
+ case TAS256X_RIGHT_SWITCH:
+ p_tas256x->devs[1]->spk_control = value;
+ break;
+ case RX_SCFG_LEFT:
+ ret = tas256x_update_rx_cfg(p_tas256x, value,
+ channel_left);
+ break;
+ case RX_SCFG_RIGHT:
+ ret = tas256x_update_rx_cfg(p_tas256x, value,
+ channel_right);
+ break;
+ default:
+ ret = p_tas256x->write(p_tas256x, channel_both,
+ reg, value);
+ break;
+ }
+
+ return ret;
+}
+#endif
+
+#if IS_ENABLED(CODEC_PM)
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static int tas256x_codec_suspend(struct snd_soc_component *codec)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ mutex_lock(&p_tas256x->codec_lock);
+
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+ plat_data->runtime_suspend(p_tas256x);
+
+ mutex_unlock(&p_tas256x->codec_lock);
+ return ret;
+}
+
+static int tas256x_codec_resume(struct snd_soc_component *codec)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ mutex_lock(&p_tas256x->codec_lock);
+
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+ plat_data->runtime_resume(p_tas256x);
+
+ mutex_unlock(&p_tas256x->codec_lock);
+ return ret;
+}
+#else
+static int tas256x_codec_suspend(struct snd_soc_codec *codec)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ mutex_lock(&p_tas256x->codec_lock);
+
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+ plat_data->runtime_suspend(p_tas256x);
+
+ mutex_unlock(&p_tas256x->codec_lock);
+ return ret;
+}
+
+static int tas256x_codec_resume(struct snd_soc_codec *codec)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+
+ mutex_lock(&p_tas256x->codec_lock);
+
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+ plat_data->runtime_resume(p_tas256x);
+
+ mutex_unlock(&p_tas256x->codec_lock);
+ return ret;
+}
+#endif
+#endif
+
+static int tas256x_dac_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_dapm_to_component(w->dapm);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ dev_info(plat_data->dev, "SND_SOC_DAPM_POST_PMU\n");
+ if (p_tas256x->mb_power_up == false)
+ tas256x_set_power_state(p_tas256x,
+ TAS256X_POWER_ACTIVE);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ dev_info(plat_data->dev, "SND_SOC_DAPM_PRE_PMD\n");
+ if (p_tas256x->mb_power_up == true)
+ tas256x_set_power_state(p_tas256x,
+ TAS256X_POWER_SHUTDOWN);
+ break;
+ }
+
+ return 0;
+}
+
+static const char * const tas256x_ASI1_src[] = {
+ "I2C offset", "Left", "Right", "LeftRightDiv2",
+};
+
+static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_left_enum, RX_SCFG_LEFT, 0,
+ tas256x_ASI1_src);
+static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_right_enum, RX_SCFG_RIGHT, 0,
+ tas256x_ASI1_src);
+
+static const struct snd_kcontrol_new dapm_switch_left =
+ SOC_DAPM_SINGLE("Switch", TAS256X_LEFT_SWITCH, 0, 1, 0);
+static const struct snd_kcontrol_new dapm_switch_right =
+ SOC_DAPM_SINGLE("Switch", TAS256X_RIGHT_SWITCH, 0, 1, 0);
+static const struct snd_kcontrol_new tas256x_asi1_left_mux =
+ SOC_DAPM_ENUM("Mux", tas2562_ASI1_src_left_enum);
+static const struct snd_kcontrol_new tas256x_asi1_right_mux =
+ SOC_DAPM_ENUM("Mux", tas2562_ASI1_src_right_enum);
+
+static const struct snd_soc_dapm_widget tas256x_dapm_widgets_stereo[] = {
+ SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_SWITCH("TAS256X ASI Left", SND_SOC_NOPM, 0, 0,
+ &dapm_switch_left),
+ SND_SOC_DAPM_SWITCH("TAS256X ASI Right", SND_SOC_NOPM, 0, 0,
+ &dapm_switch_right),
+ SND_SOC_DAPM_MUX("TAS256X ASI1 SEL LEFT", SND_SOC_NOPM, 0, 0,
+ &tas256x_asi1_left_mux),
+ SND_SOC_DAPM_MUX("TAS256X ASI1 SEL RIGHT", SND_SOC_NOPM, 0, 0,
+ &tas256x_asi1_right_mux),
+ SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 1,
+ SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0,
+ SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC_E("DAC1", NULL, SND_SOC_NOPM, 0, 0, tas256x_dac_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_DAC_E("DAC2", NULL, SND_SOC_NOPM, 0, 0, tas256x_dac_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_OUTPUT("OUT1"),
+ SND_SOC_DAPM_OUTPUT("OUT2"),
+ SND_SOC_DAPM_SIGGEN("VMON"),
+ SND_SOC_DAPM_SIGGEN("IMON")
+};
+
+static const struct snd_soc_dapm_route tas256x_audio_map_stereo[] = {
+ {"TAS256X ASI1 SEL LEFT", "Left", "ASI1"},
+ {"TAS256X ASI1 SEL LEFT", "Right", "ASI1"},
+ {"TAS256X ASI1 SEL LEFT", "LeftRightDiv2", "ASI1"},
+ {"TAS256X ASI1 SEL LEFT", "I2C offset", "ASI1"},
+ {"TAS256X ASI1 SEL RIGHT", "Left", "ASI1"},
+ {"TAS256X ASI1 SEL RIGHT", "Right", "ASI1"},
+ {"TAS256X ASI1 SEL RIGHT", "LeftRightDiv2", "ASI1"},
+ {"TAS256X ASI1 SEL RIGHT", "I2C offset", "ASI1"},
+ {"DAC1", NULL, "TAS256X ASI1 SEL LEFT"},
+ {"DAC2", NULL, "TAS256X ASI1 SEL RIGHT"},
+ {"TAS256X ASI Left", "Switch", "DAC1"},
+ {"TAS256X ASI Right", "Switch", "DAC2"},
+ {"OUT1", NULL, "TAS256X ASI Left"},
+ {"OUT2", NULL, "TAS256X ASI Right"},
+ {"Voltage Sense", NULL, "VMON"},
+ {"Current Sense", NULL, "IMON"}
+};
+
+static const struct snd_soc_dapm_widget tas256x_dapm_widgets_mono[] = {
+ SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_SWITCH("TAS256X ASI", SND_SOC_NOPM, 0, 0,
+ &dapm_switch_left),
+ SND_SOC_DAPM_MUX("TAS256X ASI1 SEL", SND_SOC_NOPM, 0, 0,
+ &tas256x_asi1_left_mux),
+ SND_SOC_DAPM_AIF_OUT("Voltage Sense", "ASI1 Capture", 0,
+ SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("Current Sense", "ASI1 Capture", 0,
+ SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas256x_dac_event,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
+ SND_SOC_DAPM_OUTPUT("OUT"),
+ SND_SOC_DAPM_SIGGEN("VMON"),
+ SND_SOC_DAPM_SIGGEN("IMON")
+};
+
+static const struct snd_soc_dapm_route tas256x_audio_map_mono[] = {
+ {"TAS256X ASI1 SEL", "Left", "ASI1"},
+ {"TAS256X ASI1 SEL", "Right", "ASI1"},
+ {"TAS256X ASI1 SEL", "LeftRightDiv2", "ASI1"},
+ {"TAS256X ASI1 SEL", "I2C offset", "ASI1"},
+ {"DAC", NULL, "TAS256X ASI1 SEL"},
+ {"TAS256X ASI", "Switch", "DAC"},
+ {"OUT", NULL, "TAS256X ASI"},
+ {"Voltage Sense", NULL, "VMON"},
+ {"Current Sense", NULL, "IMON"}
+};
+
+static int tas256x_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = dai->component;
+ struct tas256x_priv *p_tas256x
+ = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ int bitwidth = 16;
+ int n_result = 0;
+ unsigned int channels = params_channels(params);
+
+ dev_dbg(plat_data->dev, "%s, stream %s format: %d\n", __func__,
+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : ("Capture"),
+ params_format(params));
+
+ mutex_lock(&p_tas256x->codec_lock);
+#ifndef TDM_MACHINE
+ /*Assumed TDM*/
+ if (channels > 2) {
+ p_tas256x->mn_fmt_mode = 2;
+
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ bitwidth = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bitwidth = 24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bitwidth = 32;
+ break;
+ }
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ n_result = tas256x_set_tdm_rx_slot(p_tas256x, channels, bitwidth);
+ else /*Assumed Capture*/
+ n_result = tas256x_set_tdm_tx_slot(p_tas256x, channels, bitwidth);
+ } else { /*Assumed I2S Mode*/
+ p_tas256x->mn_fmt_mode = 1;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ bitwidth = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bitwidth = 24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bitwidth = 32;
+ break;
+ }
+
+ n_result = tas256x_set_bitwidth(p_tas256x,
+ bitwidth, substream->stream);
+ if (n_result < 0) {
+ dev_err(plat_data->dev, "set bitwidth failed, %d\n",
+ n_result);
+ goto ret;
+ }
+ }
+#else
+ if (p_tas256x->mn_fmt_mode != 2) {
+ p_tas256x->mn_fmt_mode = 1;
+ switch (params_format(params)) {
+ case SNDRV_PCM_FORMAT_S16_LE:
+ bitwidth = 16;
+ break;
+ case SNDRV_PCM_FORMAT_S24_LE:
+ bitwidth = 24;
+ break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ bitwidth = 32;
+ break;
+ }
+
+ n_result = tas256x_set_bitwidth(p_tas256x,
+ bitwidth, substream->stream);
+ if (n_result < 0) {
+ dev_err(plat_data->dev, "set bitwidth failed, %d\n",
+ n_result);
+ goto ret;
+ }
+ }
+#endif
+
+ dev_info(plat_data->dev, "%s, stream %s sample rate: %d\n", __func__,
+ (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : ("Capture"),
+ params_rate(params));
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ n_result = tas256x_set_samplerate(p_tas256x,
+ params_rate(params), channel_both);
+
+ret:
+ mutex_unlock(&p_tas256x->codec_lock);
+ return n_result;
+}
+
+static int tas256x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = dai->component;
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ int ret = 0;
+ u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0, asi_cfg_2 = 0;
+
+ dev_dbg(plat_data->dev, "%s, format=0x%x\n", __func__, fmt);
+
+ p_tas256x->mn_fmt = 1;
+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBS_CFS:
+ asi_cfg_1 = 0x00;
+ asi_cfg_2 = 0x00;
+ break;
+ default:
+ dev_err(plat_data->dev, "ASI format master is not found\n");
+ ret = -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ dev_dbg(plat_data->dev, "INV format: NBNF\n");
+ asi_cfg_1 |= 0;
+ asi_cfg_2 |= 0;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ dev_dbg(plat_data->dev, "INV format: IBNF\n");
+ asi_cfg_1 |= 1;
+ asi_cfg_2 |= 0;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ dev_dbg(plat_data->dev, "INV format: NBIF\n");
+ asi_cfg_1 |= 0;
+ asi_cfg_2 |= 1;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ dev_dbg(plat_data->dev, "INV format: IBIF\n");
+ asi_cfg_1 |= 1;
+ asi_cfg_2 |= 1;
+ break;
+ default:
+ dev_err(plat_data->dev, "ASI format Inverse is not found\n");
+ ret = -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case (SND_SOC_DAIFMT_I2S):
+ tdm_rx_start_slot = 1;
+ dev_dbg(plat_data->dev, " SND_SOC_DAIFMT_I2S tdm_rx_start_slot = 1\n");
+ break;
+ case (SND_SOC_DAIFMT_DSP_A):
+ tdm_rx_start_slot = 1;
+ dev_dbg(plat_data->dev, "SND_SOC_DAIFMT_DSP_A tdm_rx_start_slot =1\n");
+ break;
+ case (SND_SOC_DAIFMT_DSP_B):
+ tdm_rx_start_slot = 0;
+ dev_dbg(plat_data->dev, "SND_SOC_DAIFMT_DSP_B tdm_rx_start_slot = 0\n");
+ break;
+ case (SND_SOC_DAIFMT_LEFT_J):
+ tdm_rx_start_slot = 0;
+ dev_dbg(plat_data->dev, "SND_SOC_DAIFMT_LEFT_J tdm_rx_start_slot = 0\n");
+ break;
+ default:
+ dev_err(plat_data->dev, "DAI Format is not found, fmt=0x%x\n", fmt);
+ ret = -EINVAL;
+ break;
+ }
+
+ ret = tas256x_rx_set_start_slot(p_tas256x,
+ tdm_rx_start_slot, channel_both);
+ if (ret)
+ goto end;
+
+ /*TX Offset is same as RX Offset*/
+ ret = tas256x_tx_set_start_slot(p_tas256x,
+ tdm_rx_start_slot, channel_both);
+ if (ret)
+ goto end;
+
+ ret = tas256x_rx_set_edge(p_tas256x,
+ asi_cfg_1, channel_both);
+ if (ret)
+ goto end;
+
+ /*TX Edge is reverse of RX Edge*/
+ ret = tas256x_tx_set_edge(p_tas256x,
+ !asi_cfg_1, channel_both);
+ if (ret)
+ goto end;
+
+ ret = tas256x_rx_set_frame_start(p_tas256x,
+ asi_cfg_2, channel_both);
+ if (ret)
+ goto end;
+
+end:
+ return ret;
+}
+
+static int tas256x_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ int ret = 0;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = dai->component;
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ dev_dbg(plat_data->dev, "%s, tx_mask:%d, rx_mask:%d",
+ __func__, tx_mask, rx_mask);
+ dev_dbg(plat_data->dev, "%s, slots:%d,slot_width:%d",
+ __func__, slots, slot_width);
+
+ if (rx_mask) {
+ p_tas256x->mn_fmt_mode = 2; /*TDM Mode*/
+ ret = tas256x_set_tdm_rx_slot(p_tas256x, slots, slot_width);
+ } else if (tx_mask) {
+ p_tas256x->mn_fmt_mode = 2;
+ ret = tas256x_set_tdm_tx_slot(p_tas256x, slots, slot_width);
+ } else {
+ dev_err(plat_data->dev, "%s, Invalid Mask",
+ __func__);
+ p_tas256x->mn_fmt_mode = 0;
+ }
+
+ return ret;
+}
+
+static int tas256x_mute_stream(struct snd_soc_dai *dai, int mute, int stream)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = dai->component;
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = dai->codec;
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ dev_dbg(plat_data->dev, "%s, stream %s mute %d\n", __func__,
+ (stream == SNDRV_PCM_STREAM_PLAYBACK) ? ("Playback") : ("Capture"),
+ mute);
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops tas256x_dai_ops = {
+ .hw_params = tas256x_hw_params,
+ .set_fmt = tas256x_set_dai_fmt,
+ .set_tdm_slot = tas256x_set_dai_tdm_slot,
+ .mute_stream = tas256x_mute_stream,
+};
+
+#define TAS256X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S20_3LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver tas256x_dai_driver[] = {
+ {
+ .name = "tas256x ASI1",
+ .id = 0,
+ .playback = {
+ .stream_name = "ASI1 Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = TAS256X_FORMATS,
+ },
+ .capture = {
+ .stream_name = "ASI1 Capture",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = SNDRV_PCM_RATE_8000_192000,
+ .formats = TAS256X_FORMATS,
+ },
+ .ops = &tas256x_dai_ops,
+ .symmetric_rates = 1,
+ },
+};
+
+/*Generic Control-1: IV Sense enable*/
+static char const *iv_enable_text[] = {"Off", "On"};
+static const struct soc_enum tas256x_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(iv_enable_text), iv_enable_text),
+};
+
+static int tas256xiv_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec
+ = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct tas256x_priv *p_tas256x = NULL;
+ int iv_enable = 0, n_result = 0;
+ struct linux_platform *plat_data = NULL;
+
+ if (codec == NULL) {
+ pr_err("%s:codec is NULL\n", __func__);
+ return 0;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return 0;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ iv_enable = ucontrol->value.integer.value[0];
+
+ n_result = tas256x_iv_sense_enable_set(p_tas256x, iv_enable,
+ channel_both);
+
+ pr_debug("%s: tas256x->iv_enable = %d\n", __func__,
+ p_tas256x->iv_enable);
+
+ return n_result;
+}
+
+static int tas256xiv_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct tas256x_priv *p_tas256x = NULL;
+ struct linux_platform *plat_data = NULL;
+
+ if (codec == NULL) {
+ pr_err("%s:codec is NULL\n", __func__);
+ return 0;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return 0;
+ }
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ ucontrol->value.integer.value[0] =
+ tas256x_iv_sense_enable_get(p_tas256x, channel_left);
+ p_tas256x->iv_enable = ucontrol->value.integer.value[0];
+
+ dev_info(plat_data->dev, "p_tas256x->iv_enable %d\n",
+ p_tas256x->iv_enable);
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new tas256x_controls[] = {
+SOC_ENUM_EXT("TAS256X IVSENSE ENABLE", tas256x_enum[0],
+ tas256xiv_get, tas256xiv_put),
+};
+
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+/* max. length of a alsa mixer control name */
+#define MAX_CONTROL_NAME 48
+
+static char *fw_name = "tas256x_reg.bin";
+
+const char *blocktype[5] = {
+ "COEFF",
+ "POST_POWER_UP",
+ "PRE_SHUTDOWN",
+ "PRE_POWER_UP",
+ "POST_SHUTDOWN"
+};
+
+static int tas256x_process_block(void *pContext, unsigned char *data,
+ unsigned char dev_idx, int sublocksize)
+{
+ struct tas256x_priv *pTAS256x = (struct tas256x_priv *)pContext;
+ unsigned char subblk_typ = data[1];
+ int subblk_offset = 2;
+ enum channel chn = (0 == dev_idx) ? channel_both : (enum channel)dev_idx;
+
+ switch (subblk_typ) {
+ case TAS256X_CMD_SING_W: {
+/*
+ dev_idx : one byte
+ subblk_type : one byte
+ payload_len : two bytes
+ {
+ book : one byte
+ page : one byte
+ reg : one byte
+ val : one byte
+ }[payload_len/4]
+*/
+ int i = 0;
+ unsigned short len = SMS_HTONS(data[2], data[3]);
+ subblk_offset += 2;
+ if (subblk_offset + 4 * len > sublocksize) {
+ pr_err("Out of memory %s: %u\n", __func__, __LINE__);
+ break;
+ }
+
+ for (i = 0; i < len; i++) {
+ pTAS256x->write(pTAS256x, chn,
+ TAS256X_REG(data[subblk_offset], data[subblk_offset + 1], data[subblk_offset + 2]),
+ data[subblk_offset + 3]);
+ subblk_offset += 4;
+ }
+ }
+ break;
+ case TAS256X_CMD_BURST: {
+/*
+ dev_idx : one byte
+ subblk_type : one byte
+ payload_len : two bytes
+ book : one byte
+ page : one byte
+ reg : one byte
+ reserve : one byte
+ payload : payload_len bytes
+*/
+ unsigned short len = SMS_HTONS(data[2], data[3]);
+ subblk_offset += 2;
+ if (subblk_offset + 4 + len > sublocksize) {
+ pr_err("Out of memory %s: %u\n", __func__, __LINE__);
+ break;
+ }
+ if (len % 4) {
+ pr_err("Burst len is wrong %s: %u\n", __func__, __LINE__);
+ break;
+ }
+
+ pTAS256x->bulk_write(pTAS256x, chn,
+ TAS256X_REG(data[subblk_offset], data[subblk_offset + 1],
+ data[subblk_offset + 2]), &(data[subblk_offset + 4]), len);
+ subblk_offset += (len + 4);
+ }
+ break;
+ case TAS256X_CMD_DELAY: {
+/*
+ dev_idx : one byte
+ subblk_type : one byte
+ delay_time : two bytes
+*/
+ unsigned short delay_time = 0;
+ if (subblk_offset + 2 > sublocksize) {
+ pr_err("Out of memory %s: %u\n", __func__, __LINE__);
+ break;
+ }
+ delay_time = SMS_HTONS(data[2], data[3]);
+ usleep_range(delay_time * 1000, delay_time * 1000);
+ subblk_offset += 2;
+ }
+ break;
+ case TAS256X_CMD_FIELD_W:
+/*
+ dev_idx : one byte
+ subblk_type : one byte
+ reserve : one byte
+ mask : one byte
+ book : one byte
+ page : one byte
+ reg : one byte
+ reserve : one byte
+ payload : payload_len bytes
+*/
+ if (subblk_offset + 6 > sublocksize) {
+ pr_err("Out of memory %s: %u\n", __func__, __LINE__);
+ break;
+ }
+ pTAS256x->update_bits(pTAS256x, chn,
+ TAS256X_REG(data[subblk_offset + 2], data[subblk_offset + 3], data[subblk_offset + 4]),
+ data[subblk_offset + 1], data[subblk_offset + 5]);
+ subblk_offset += 6;
+ break;
+ default:
+ break;
+ };
+
+ return subblk_offset;
+
+}
+
+void tas256x_select_cfg_blk(void *pContext, int conf_no, unsigned char block_type)
+{
+ struct tas256x_priv *pTAS256x = (struct tas256x_priv *) pContext;
+ struct tas256x_config_info **cfg_info = pTAS256x->cfg_info;
+ int i = 0, j = 0, k = 0;
+
+ if (conf_no > pTAS256x->ncfgs || conf_no < 0 || NULL == cfg_info) {
+ pr_err("conf_no shoud be in range from 0 to %u\n", pTAS256x->ncfgs - 1);
+ goto EXIT;
+ } else {
+ pr_info("%s:%u:profile_conf_id = %d\n", __func__, __LINE__, conf_no);
+ }
+ for (i = 0; i < pTAS256x->ncfgs; i++) {
+ if (conf_no == i) {
+ for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) {
+ unsigned int length = 0, rc = 0;
+ if (block_type > 5 || block_type < 2) {
+ pr_err("ERROR!!!block_type shoud be in range from 2 to 5\n");
+ goto EXIT;
+ }
+ if (block_type != cfg_info[i]->blk_data[j]->block_type)
+ continue;
+ pr_info("%s:%u:conf %d\n", __func__, __LINE__, i);
+ pr_info("%s:%u:block type:%s\t device idx = 0x%02x\n",
+ __func__, __LINE__, blocktype[cfg_info[i]->blk_data[j]->block_type - 1],
+ cfg_info[i]->blk_data[j]->dev_idx);
+ for (k = 0; k < (int)cfg_info[i]->blk_data[j]->nSublocks; k++) {
+ rc = tas256x_process_block(pTAS256x, cfg_info[i]->blk_data[j]->regdata + length,
+ cfg_info[i]->blk_data[j]->dev_idx, cfg_info[i]->blk_data[j]->block_size - length);
+ length += rc;
+ if (cfg_info[i]->blk_data[j]->block_size < length) {
+ pr_err("%s:%u:ERROR:%u %u out of memory\n", __func__, __LINE__,
+ length, cfg_info[i]->blk_data[j]->block_size);
+ break;
+ }
+ }
+ if (length != cfg_info[i]->blk_data[j]->block_size) {
+ pr_err("%s:%u:ERROR: %u %u size is not same\n", __func__,
+ __LINE__, length, cfg_info[i]->blk_data[j]->block_size);
+ }
+ }
+ } else {
+ continue;
+ }
+ }
+EXIT:
+ return;
+}
+
+static struct tas256x_config_info *tas256x_add_config(unsigned char *config_data, unsigned int config_size)
+{
+ struct tas256x_config_info *cfg_info = NULL;
+ int config_offset = 0, i = 0;
+ cfg_info = (struct tas256x_config_info *)kzalloc(sizeof(struct tas256x_config_info), GFP_KERNEL);
+ if (!cfg_info) {
+ pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__);
+ goto EXIT;
+ }
+ if (config_offset + 4 > (int)config_size) {
+ pr_err("%s:%u:Out of memory\n", __func__, __LINE__);
+ goto EXIT;
+ }
+ cfg_info->nblocks = SMS_HTONL(config_data[config_offset], config_data[config_offset + 1],
+ config_data[config_offset + 2], config_data[config_offset + 3]);
+ config_offset += 4;
+ pr_info("cfg_info->num_blocks = %u\n", cfg_info->nblocks);
+ cfg_info->blk_data = (struct tas256x_block_data **)kzalloc(
+ cfg_info->nblocks*sizeof(struct tas256x_block_data *),
+ GFP_KERNEL);
+ if (!cfg_info->blk_data) {
+ pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__);
+ goto EXIT;
+ }
+ cfg_info->real_nblocks = 0;
+ for (i = 0; i < (int)cfg_info->nblocks; i++) {
+ if (config_offset + 12 > config_size) {
+ pr_err("%s:%u:Out of memory: i = %d nblocks = %u!\n",
+ __func__, __LINE__, i, cfg_info->nblocks);
+ break;
+ }
+ cfg_info->blk_data[i] = (struct tas256x_block_data *)kzalloc(
+ sizeof(struct tas256x_block_data), GFP_KERNEL);
+ if (!cfg_info->blk_data[i]) {
+ pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__);
+ break;
+ }
+ cfg_info->blk_data[i]->dev_idx = config_data[config_offset];
+ config_offset++;
+ pr_info("blk_data(%d).dev_idx = 0x%02x\n", i,
+ cfg_info->blk_data[i]->dev_idx);
+ cfg_info->blk_data[i]->block_type = config_data[config_offset];
+ config_offset++;
+ pr_info("blk_data(%d).block_type = 0x%02x\n", i,
+ cfg_info->blk_data[i]->block_type);
+ cfg_info->blk_data[i]->yram_checksum = SMS_HTONS(config_data[config_offset],
+ config_data[config_offset + 1]);
+ config_offset += 2;
+ cfg_info->blk_data[i]->block_size = SMS_HTONL(config_data[config_offset],
+ config_data[config_offset + 1], config_data[config_offset + 2],
+ config_data[config_offset + 3]);
+ config_offset += 4;
+ pr_info("blk_data(%d).block_size = %u\n", i,
+ cfg_info->blk_data[i]->block_size);
+ cfg_info->blk_data[i]->nSublocks = SMS_HTONL(config_data[config_offset],
+ config_data[config_offset + 1], config_data[config_offset + 2],
+ config_data[config_offset + 3]);
+ pr_info("blk_data(%d).num_subblocks = %u\n", i,
+ cfg_info->blk_data[i]->nSublocks);
+ config_offset += 4;
+ pr_info("config_offset = %d\n", config_offset);
+ cfg_info->blk_data[i]->regdata = (unsigned char *)kzalloc(
+ cfg_info->blk_data[i]->block_size, GFP_KERNEL);
+ if (!cfg_info->blk_data[i]->regdata) {
+ pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__);
+ goto EXIT;
+ }
+ if (config_offset + cfg_info->blk_data[i]->block_size > config_size) {
+ pr_err("%s:%u:Out of memory: i = %d nblocks = %u!\n",
+ __func__, __LINE__, i, cfg_info->nblocks);
+ break;
+ }
+ memcpy(cfg_info->blk_data[i]->regdata, &config_data[config_offset],
+ cfg_info->blk_data[i]->block_size);
+ config_offset += cfg_info->blk_data[i]->block_size;
+ cfg_info->real_nblocks += 1;
+ }
+EXIT:
+ return cfg_info;
+}
+
+static int tas256x_info_profile(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec
+ = snd_soc_kcontrol_component(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&p_tas256x->codec_lock);
+#endif
+ uinfo->count = 1;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&p_tas256x->codec_lock);
+#endif
+ uinfo->value.integer.min = -1;
+ uinfo->value.integer.max = max(-1, p_tas256x->ncfgs - 1);
+ pr_info("%s: max profile = %d\n", __func__, (int)uinfo->value.integer.max);
+
+ return 0;
+}
+
+static int tas256x_get_profile_id(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec
+ = snd_soc_kcontrol_component(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&p_tas256x->codec_lock);
+#endif
+ ucontrol->value.integer.value[0] = p_tas256x->profile_cfg_id;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&p_tas256x->codec_lock);
+#endif
+ return 0;
+}
+
+static int tas256x_set_profile_id(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec
+ = snd_soc_kcontrol_component(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&p_tas256x->codec_lock);
+#endif
+ p_tas256x->profile_cfg_id = ucontrol->value.integer.value[0];
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&p_tas256x->codec_lock);
+#endif
+
+ return 0;
+}
+
+static int tas256x_create_controls(struct tas256x_priv *pTAS256x)
+{
+ int nr_controls = 1, ret = 0, mix_index = 0;
+ char *name = NULL;
+ struct linux_platform *platform_data =
+ (struct linux_platform *)pTAS256x->platform_data;
+
+ struct snd_kcontrol_new *tas256x_profile_controls = NULL;
+ tas256x_profile_controls = devm_kzalloc(platform_data->dev,
+ nr_controls * sizeof(tas256x_profile_controls[0]), GFP_KERNEL);
+ if (NULL == tas256x_profile_controls) {
+ ret = -ENOMEM;
+ goto EXIT;
+ }
+
+ /* Create a mixer item for selecting the active profile */
+ name = devm_kzalloc(platform_data->dev, MAX_CONTROL_NAME, GFP_KERNEL);
+ if (!name) {
+ ret = -ENOMEM;
+ goto EXIT;
+ }
+ scnprintf(name, MAX_CONTROL_NAME, "TAS256x Profile id");
+ tas256x_profile_controls[mix_index].name = name;
+ tas256x_profile_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+ tas256x_profile_controls[mix_index].info = tas256x_info_profile;
+ tas256x_profile_controls[mix_index].get = tas256x_get_profile_id;
+ tas256x_profile_controls[mix_index].put = tas256x_set_profile_id;
+ mix_index++;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ ret = snd_soc_add_component_controls(platform_data->codec,
+ tas256x_profile_controls, nr_controls < mix_index ? nr_controls : mix_index);
+#else
+ ret = snd_soc_add_codec_controls(platform_data->codec,
+ tas256x_profile_controls, nr_controls < mix_index ? nr_controls : mix_index);
+#endif
+EXIT:
+ return ret;
+}
+
+static void tas256x_fw_ready(const struct firmware *pFW, void *pContext)
+{
+ struct tas256x_priv *pTAS256x = (struct tas256x_priv *) pContext;
+ struct tas256x_fw_hdr *fw_hdr = &(pTAS256x->fw_hdr);
+ struct tas256x_config_info **cfg_info = NULL;
+ unsigned char *buf = NULL;
+ int offset = 0, i = 0;
+ unsigned int total_config_sz = 0;
+
+ pTAS256x->fw_state = TAS256X_DSP_FW_FAIL;
+
+ if (unlikely(!pFW) || unlikely(!pFW->data)) {
+ pr_err("Failed to read %s, no side-effect on driver running\n", fw_name);
+ return;
+ }
+ buf = (unsigned char *)pFW->data;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&pTAS256x->codec_lock);
+#endif
+#if IS_ENABLED(CONFIG_TAS256X_MISC)
+ mutex_lock(&pTAS256x->file_lock);
+#endif
+ pr_info("%s: start\n", __func__);
+ fw_hdr->img_sz = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ if (fw_hdr->img_sz != pFW->size) {
+ pr_err("File size not match, %d %u", (int)pFW->size, fw_hdr->img_sz);
+ goto EXIT;
+ }
+
+ fw_hdr->checksum = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ fw_hdr->binnary_version_num = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ fw_hdr->drv_fw_version = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ fw_hdr->timestamp = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ fw_hdr->plat_type = buf[offset];
+ offset += 1;
+ fw_hdr->dev_family = buf[offset];
+ offset += 1;
+ fw_hdr->reserve = buf[offset];
+ offset += 1;
+ fw_hdr->ndev = buf[offset];
+ offset += 1;
+
+ pr_info("ndev = %u\n", fw_hdr->ndev);
+
+ if (offset + TAS256X_DEVICE_SUM > fw_hdr->img_sz) {
+ pr_err("%s:%u:Out of Memory!\n", __func__, __LINE__);
+ goto EXIT;
+ }
+
+ for (i = 0; i < TAS256X_DEVICE_SUM; i++) {
+ fw_hdr->devs[i] = buf[offset];
+ offset += 1;
+ pr_info("devs[%d] = %u\n", i, fw_hdr->devs[i]);
+ }
+ fw_hdr->nconfig = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ pr_info("nconfig = %u\n", fw_hdr->nconfig);
+ for (i = 0; i < TAS256X_CONFIG_SIZE; i++) {
+ fw_hdr->config_size[i] = SMS_HTONL(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
+ offset += 4;
+ pr_info("config_size[%d] = %u\n", i, fw_hdr->config_size[i]);
+ total_config_sz += fw_hdr->config_size[i];
+ }
+ pr_info("img_sz = %u total_config_sz = %u offset = %d\n",
+ fw_hdr->img_sz, total_config_sz, offset);
+ if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
+ pr_err("Bin file error!\n");
+ goto EXIT;
+ }
+ cfg_info = (struct tas256x_config_info **)kzalloc(
+ fw_hdr->nconfig*sizeof(struct tas256x_config_info *),
+ GFP_KERNEL);
+ if (!cfg_info) {
+ pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__);
+ goto EXIT;
+ }
+ pTAS256x->cfg_info = cfg_info;
+ pTAS256x->ncfgs = 0;
+ for (i = 0; i < (int)fw_hdr->nconfig; i++) {
+ cfg_info[i] = tas256x_add_config(&buf[offset], fw_hdr->config_size[i]);
+ if (!cfg_info[i]) {
+ pr_err("%s:%u:Memory alloc failed!\n", __func__, __LINE__);
+ break;
+ }
+ offset += (int)fw_hdr->config_size[i];
+ pTAS256x->ncfgs += 1;
+ }
+
+ pTAS256x->fw_state = TAS256X_DSP_FW_OK;
+ tas256x_create_controls(pTAS256x);
+EXIT:
+#if IS_ENABLED(CONFIG_TAS256X_MISC)
+ mutex_unlock(&pTAS256x->file_lock);
+#endif
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&pTAS256x->codec_lock);
+#endif
+ release_firmware(pFW);
+ pr_info("%s: Firmware init complete\n", __func__);
+ return;
+}
+
+int tas256x_load_container(struct tas256x_priv *pTAS256x)
+{
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) pTAS256x->platform_data;
+ pTAS256x->fw_state = TAS256X_DSP_FW_PENDING;
+ return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+ fw_name, plat_data->dev, GFP_KERNEL, pTAS256x, tas256x_fw_ready);
+}
+
+void tas256x_config_info_remove(void *pContext)
+{
+ struct tas256x_priv *pTAS256x = (struct tas256x_priv *) pContext;
+ struct tas256x_config_info **cfg_info = pTAS256x->cfg_info;
+ int i = 0, j = 0;
+
+ if (cfg_info) {
+ for (i = 0; i < pTAS256x->ncfgs; i++) {
+ if (cfg_info[i]) {
+ for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) {
+ if (cfg_info[i]->blk_data[j]->regdata)
+ kfree(cfg_info[i]->blk_data[j]->regdata);
+ if (cfg_info[i]->blk_data[j])
+ kfree(cfg_info[i]->blk_data[j]);
+ }
+ if (cfg_info[i]->blk_data)
+ kfree(cfg_info[i]->blk_data);
+ kfree(cfg_info[i]);
+ }
+ }
+ kfree(cfg_info);
+ }
+}
+#endif
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static int tas256x_codec_probe(struct snd_soc_component *codec)
+{
+ int ret, i;
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_component_get_dapm(codec);
+
+ if (plat_data)
+ plat_data->codec = codec;
+
+ ret = snd_soc_add_component_controls(codec, tas256x_controls,
+ ARRAY_SIZE(tas256x_controls));
+ if (ret < 0) {
+ pr_err("%s: add_codec_controls failed, err %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ snd_soc_dapm_ignore_suspend(dapm, "ASI1 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "ASI1 Capture");
+ if (p_tas256x->mn_channels == 2) {
+ snd_soc_dapm_ignore_suspend(dapm, "OUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "OUT2");
+ snd_soc_dapm_ignore_suspend(dapm, "VMON");
+ snd_soc_dapm_ignore_suspend(dapm, "IMON");
+ } else {
+ snd_soc_dapm_ignore_suspend(dapm, "OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "VMON");
+ snd_soc_dapm_ignore_suspend(dapm, "IMON");
+ }
+
+ snd_soc_dapm_sync(dapm);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->dev_ops.tas_probe)
+ ret |= (p_tas256x->devs[i]->dev_ops.tas_probe)(p_tas256x, codec, i + 1);
+ }
+
+ /* Generic Probe */
+ ret = tas256x_probe(p_tas256x);
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+
+ return 0;
+}
+#else
+static int tas256x_codec_probe(struct snd_soc_codec *codec)
+{
+ int ret, i;
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ struct snd_soc_dapm_context *dapm =
+ snd_soc_codec_get_dapm(codec);
+
+ if (plat_data)
+ plat_data->codec = codec;
+
+ dev_info(plat_data->dev, "Driver Tag: %s\n", TAS256X_DRIVER_TAG);
+ ret = snd_soc_add_codec_controls(codec, tas256x_controls,
+ ARRAY_SIZE(tas256x_controls));
+ if (ret < 0) {
+ pr_err("%s: add_codec_controls failed, err %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ snd_soc_dapm_ignore_suspend(dapm, "ASI1 Playback");
+ snd_soc_dapm_ignore_suspend(dapm, "ASI1 Capture");
+ if (p_tas256x->mn_channels == 2) {
+ snd_soc_dapm_ignore_suspend(dapm, "OUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "OUT2");
+ snd_soc_dapm_ignore_suspend(dapm, "VMON");
+ snd_soc_dapm_ignore_suspend(dapm, "IMON");
+ } else {
+ snd_soc_dapm_ignore_suspend(dapm, "OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "VMON");
+ snd_soc_dapm_ignore_suspend(dapm, "IMON");
+ }
+
+ snd_soc_dapm_sync(dapm);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->dev_ops.tas_probe)
+ ret |= (p_tas256x->devs[i]->dev_ops.tas_probe)(p_tas256x, codec, i + 1);
+ }
+ /* Generic Probe */
+ ret = tas256x_probe(p_tas256x);
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+
+ return ret;
+}
+#endif
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static void tas256x_codec_remove(struct snd_soc_component *codec)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+
+ tas256x_remove(p_tas256x);
+}
+#else
+static int tas256x_codec_remove(struct snd_soc_codec *codec)
+{
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+
+ tas256x_remove(p_tas256x);
+ return 0;
+}
+#endif
+
+/*snd control-1: SmartPA System Mute(Master) Control*/
+static int tas256x_system_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec
+ = snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ pValue->value.integer.value[0] = p_tas256x->mb_mute;
+ dev_dbg(plat_data->dev, "%s = %d\n",
+ __func__, p_tas256x->mb_mute);
+
+ return 0;
+}
+
+static int tas256x_system_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int mb_mute = pValue->value.integer.value[0];
+
+ dev_dbg(plat_data->dev, "%s = %d\n", __func__, mb_mute);
+
+ p_tas256x->mb_mute = !!mb_mute;
+
+ return 0;
+}
+
+/*snd control-2: SmartPA Mute Control*/
+static int tas256x_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ pValue->value.integer.value[0] = p_tas256x->mb_mute;
+
+ if ((p_tas256x->mb_power_up == true) &&
+ (p_tas256x->mn_power_state == TAS256X_POWER_ACTIVE))
+ pValue->value.integer.value[0] = 0;
+ else
+ pValue->value.integer.value[0] = 1;
+
+ dev_dbg(plat_data->dev, "%s = %ld\n",
+ __func__, pValue->value.integer.value[0]);
+
+ return 0;
+}
+
+static int tas256x_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int mute = pValue->value.integer.value[0];
+
+ dev_dbg(plat_data->dev, "%s, %d\n", __func__, mute);
+ mutex_lock(&p_tas256x->codec_lock);
+
+ if (mute)
+ tas256x_set_power_state(p_tas256x, TAS256X_POWER_MUTE);
+ else
+ tas256x_set_power_state(p_tas256x, TAS256X_POWER_ACTIVE);
+
+ mutex_unlock(&p_tas256x->codec_lock);
+ return 0;
+}
+
+/*snd control-3: DAC Mute Control*/
+static int tas256x_dac_mute_ctrl_get(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ pValue->value.integer.value[0] = p_tas256x->dac_mute;
+
+ dev_dbg(plat_data->dev, "%s = %ld\n",
+ __func__, pValue->value.integer.value[0]);
+
+ return 0;
+}
+
+static int tas256x_dac_mute_ctrl_put(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+ int n_result = 0;
+ enum channel chn = channel_left;
+ int mute = pValue->value.integer.value[0];
+ int i = 0, chnTemp = 0;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ dev_dbg(plat_data->dev, "%s, %d\n", __func__, mute);
+ mutex_lock(&p_tas256x->codec_lock);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (p_tas256x->devs[i]->spk_control == 1)
+ chnTemp |= 1 << i;
+ }
+ chn = (chnTemp == 0) ? chn : (enum channel)chnTemp;
+
+ if (mute) {
+ n_result = tas256x_set_power_mute(p_tas256x, chn);
+ } else {
+ msleep(50);
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ /*set p_tas256x->profile_cfg_id by tinymix*/
+ tas256x_select_cfg_blk(p_tas256x, p_tas256x->profile_cfg_id,
+ TAS256X_BIN_BLK_PRE_POWER_UP);
+#endif
+ n_result = tas256x_set_power_up(p_tas256x, chn);
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ /*set p_tas256x->profile_cfg_id by tinymix*/
+ tas256x_select_cfg_blk(p_tas256x, p_tas256x->profile_cfg_id,
+ TAS256X_BIN_BLK_POST_POWER_UP);
+#endif
+ }
+
+ p_tas256x->dac_mute = mute;
+ mutex_unlock(&p_tas256x->codec_lock);
+
+ return n_result;
+}
+
+/*ICN Disable*/
+static const char * const icn_sw_text[] = {"Enable", "Disable"};
+static const struct soc_enum icn_sw_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(icn_sw_text),
+ icn_sw_text),
+};
+static int tas256x_get_icn_switch(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *p_u_control)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ dev_info(plat_data->dev, "%s, icn_sw = %ld\n",
+ __func__, p_u_control->value.integer.value[0]);
+ p_u_control->value.integer.value[0] = p_tas256x->icn_sw;
+ return 0;
+}
+static int tas256x_set_icn_switch(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *p_u_control)
+{
+ int ret = 0;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+
+ p_tas256x->icn_sw = p_u_control->value.integer.value[0];
+ ret = tas256x_icn_disable(p_tas256x, p_tas256x->icn_sw, channel_both);
+
+ return ret;
+}
+
+/*Rx Slot*/
+static int tas256x_set_rx_slot_map_single(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+ int ret = 0;
+ int value = 0;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ value = pValue->value.integer.value[0];
+
+ ret = tas256x_rx_set_slot(p_tas256x, value, channel_left);
+ dev_dbg(plat_data->dev, "%s = %ld\n",
+ __func__, pValue->value.integer.value[0]);
+
+ return ret;
+}
+
+static int tas256x_get_rx_slot_map_single(struct snd_kcontrol *pKcontrol,
+ struct snd_ctl_elem_value *pValue)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ pValue->value.integer.value[0] = p_tas256x->mn_rx_slot_map[0];
+ dev_dbg(plat_data->dev, "%s = %ld\n",
+ __func__, pValue->value.integer.value[0]);
+ return 0;
+}
+
+static const struct snd_kcontrol_new tas256x_snd_controls_mono[] = {
+ SOC_SINGLE_EXT("SmartPA System Mute", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas256x_system_mute_ctrl_get, tas256x_system_mute_ctrl_put),
+ SOC_SINGLE_EXT("SmartPA Mute", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas256x_mute_ctrl_get, tas256x_mute_ctrl_put),
+ SOC_SINGLE_EXT("TAS256X DAC Mute", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas256x_dac_mute_ctrl_get, tas256x_dac_mute_ctrl_put),
+ SOC_ENUM_EXT("TAS256X ICN Switch", icn_sw_enum[0],
+ tas256x_get_icn_switch,
+ tas256x_set_icn_switch),
+ SOC_SINGLE_EXT("TAS256X_RX_SLOT_MAP", SND_SOC_NOPM, 0, 7, 0,
+ tas256x_get_rx_slot_map_single,
+ tas256x_set_rx_slot_map_single),
+};
+
+struct soc_multi_control_ch_map {
+ int min, max, platform_max, count;
+ unsigned int reg, rreg, shift, rshift, invert;
+};
+
+int tas256x_rx_slot_map_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ struct soc_multi_control_ch_map *mc =
+ (struct soc_multi_control_ch_map *)kcontrol->private_value;
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = mc->count;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = mc->platform_max;
+
+ return 0;
+}
+
+static int tas256x_get_rx_slot_map_multi(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int i;
+ for (i = 0; i < 2; i++) {
+ dev_info(plat_data->dev, "%s idx=%d, value=%d\n",
+ __func__, i, (int)p_tas256x->mn_rx_slot_map[i]);
+ ucontrol->value.integer.value[i] =
+ (unsigned int) p_tas256x->mn_rx_slot_map[i];
+ }
+
+ return 0;
+}
+
+static int tas256x_set_rx_slot_map_multi(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec =
+ snd_soc_kcontrol_component(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+ struct tas256x_priv *p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+ int i, ret = 0;
+ char slot_map[2];
+
+ for (i = 0; i < 2; i++) {
+ slot_map[i] = (char)(ucontrol->value.integer.value[i]);
+ ret = tas256x_rx_set_slot(p_tas256x, slot_map[i], i+1);
+ dev_info(plat_data->dev, "%s mapping - index %d = channel %d\n",
+ __func__, i, slot_map[i]);
+ }
+
+ return ret;
+}
+
+static const struct snd_kcontrol_new tas256x_snd_controls_stereo[] = {
+ SOC_SINGLE_EXT("SmartPA System Mute", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas256x_system_mute_ctrl_get, tas256x_system_mute_ctrl_put),
+ SOC_SINGLE_EXT("SmartPA Mute", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas256x_mute_ctrl_get, tas256x_mute_ctrl_put),
+ SOC_SINGLE_EXT("TAS256X DAC Mute", SND_SOC_NOPM, 0, 0x0001, 0,
+ tas256x_dac_mute_ctrl_get, tas256x_dac_mute_ctrl_put),
+ SOC_ENUM_EXT("TAS256X ICN Switch", icn_sw_enum[0],
+ tas256x_get_icn_switch,
+ tas256x_set_icn_switch),
+ {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "TAS256X_RX_SLOT_MAP",
+ .info = tas256x_rx_slot_map_info,
+ .get = tas256x_get_rx_slot_map_multi,
+ .put = tas256x_set_rx_slot_map_multi,
+ .private_value = (unsigned long) &(struct soc_multi_control_ch_map) {
+ .reg = SND_SOC_NOPM,
+ .shift = 0,
+ .rshift = 0,
+ .max = 7,
+ .count = 2,
+ .platform_max = 7,
+ .invert = 0,
+ }
+ },
+};
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static struct snd_soc_component_driver soc_codec_driver_tas256x = {
+ .probe = tas256x_codec_probe,
+ .remove = tas256x_codec_remove,
+ .read = tas256x_codec_read,
+ .write = tas256x_codec_write,
+#if IS_ENABLED(CODEC_PM)
+ .suspend = tas256x_codec_suspend,
+ .resume = tas256x_codec_resume,
+#endif
+ .controls = tas256x_snd_controls_mono,
+ .num_controls = ARRAY_SIZE(tas256x_snd_controls_mono),
+ .dapm_widgets = tas256x_dapm_widgets_mono,
+ .num_dapm_widgets = ARRAY_SIZE(tas256x_dapm_widgets_mono),
+ .dapm_routes = tas256x_audio_map_mono,
+ .num_dapm_routes = ARRAY_SIZE(tas256x_audio_map_mono),
+};
+#else
+static struct snd_soc_codec_driver soc_codec_driver_tas256x = {
+ .probe = tas256x_codec_probe,
+ .remove = tas256x_codec_remove,
+ .read = tas256x_codec_read,
+ .write = tas256x_codec_write,
+#if IS_ENABLED(CODEC_PM)
+ .suspend = tas256x_codec_suspend,
+ .resume = tas256x_codec_resume,
+#endif
+ .component_driver = {
+ .controls = tas256x_snd_controls_mono,
+ .num_controls = ARRAY_SIZE(tas256x_snd_controls_mono),
+ .dapm_widgets = tas256x_dapm_widgets_mono,
+ .num_dapm_widgets = ARRAY_SIZE(tas256x_dapm_widgets_mono),
+ .dapm_routes = tas256x_audio_map_mono,
+ .num_dapm_routes = ARRAY_SIZE(tas256x_audio_map_mono),
+ },
+};
+#endif
+
+int tas256x_register_codec(struct tas256x_priv *p_tas256x)
+{
+ int n_result = 0;
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+
+ dev_info(plat_data->dev, "%s, enter\n", __func__);
+
+ if (p_tas256x->mn_channels == 2) {
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ soc_codec_driver_tas256x.controls =
+ tas256x_snd_controls_stereo;
+ soc_codec_driver_tas256x.num_controls =
+ ARRAY_SIZE(tas256x_snd_controls_stereo);
+ soc_codec_driver_tas256x.dapm_widgets =
+ tas256x_dapm_widgets_stereo;
+ soc_codec_driver_tas256x.num_dapm_widgets =
+ ARRAY_SIZE(tas256x_dapm_widgets_stereo);
+ soc_codec_driver_tas256x.dapm_routes =
+ tas256x_audio_map_stereo;
+ soc_codec_driver_tas256x.num_dapm_routes =
+ ARRAY_SIZE(tas256x_audio_map_stereo);
+ n_result = devm_snd_soc_register_component(plat_data->dev,
+ &soc_codec_driver_tas256x,
+ tas256x_dai_driver, ARRAY_SIZE(tas256x_dai_driver));
+#else
+ soc_codec_driver_tas256x.component_driver.controls =
+ tas256x_snd_controls_stereo;
+ soc_codec_driver_tas256x.component_driver.num_controls =
+ ARRAY_SIZE(tas256x_snd_controls_stereo);
+ soc_codec_driver_tas256x.component_driver.dapm_widgets =
+ tas256x_dapm_widgets_stereo;
+ soc_codec_driver_tas256x.component_driver.num_dapm_widgets =
+ ARRAY_SIZE(tas256x_dapm_widgets_stereo);
+ soc_codec_driver_tas256x.component_driver.dapm_routes =
+ tas256x_audio_map_stereo;
+ soc_codec_driver_tas256x.component_driver.num_dapm_routes =
+ ARRAY_SIZE(tas256x_audio_map_stereo);
+ n_result = snd_soc_register_codec(plat_data->dev,
+ &soc_codec_driver_tas256x,
+ tas256x_dai_driver, ARRAY_SIZE(tas256x_dai_driver));
+#endif
+ } else {
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ n_result = devm_snd_soc_register_component(plat_data->dev,
+ &soc_codec_driver_tas256x,
+ tas256x_dai_driver, ARRAY_SIZE(tas256x_dai_driver));
+#else
+ n_result = snd_soc_register_codec(plat_data->dev,
+ &soc_codec_driver_tas256x,
+ tas256x_dai_driver, ARRAY_SIZE(tas256x_dai_driver));
+#endif
+ }
+ return n_result;
+}
+
+int tas256x_deregister_codec(struct tas256x_priv *p_tas256x)
+{
+ struct linux_platform *plat_data =
+ (struct linux_platform *) p_tas256x->platform_data;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ snd_soc_unregister_component(plat_data->dev);
+#else
+ snd_soc_unregister_codec(plat_data->dev);
+#endif
+ return 0;
+}
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS256X ALSA SOC Smart Amplifier driver");
+MODULE_LICENSE("GPL v2");
+#endif /* CONFIG_TAS256X_CODEC */
diff --git a/asoc/codecs/tas256x/os_layer/src/tas256x-regmap.c b/asoc/codecs/tas256x/os_layer/src/tas256x-regmap.c
new file mode 100644
index 00000000..de5d3ee0
--- /dev/null
+++ b/asoc/codecs/tas256x/os_layer/src/tas256x-regmap.c
@@ -0,0 +1,1676 @@
+/*
+ * ALSA SoC Texas Instruments TAS256X High Performance 4W Smart Amplifier
+ *
+ * Copyright (C) 2016 Texas Instruments, Inc.
+ *
+ * Author: saiprasad
+ *
+ * This package is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#if IS_ENABLED(CONFIG_TAS256X_REGMAP)
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/firmware.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/pm.h>
+#include <linux/version.h>
+#include "physical_layer/inc/tas256x.h"
+#include "logical_layer/inc/tas256x-logic.h"
+#include "physical_layer/inc/tas256x-device.h"
+#include "os_layer/inc/tas256x-codec.h"
+#include "os_layer/inc/tas256x-regmap.h"
+#include "misc/tas256x-misc.h"
+
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#include "algo/inc/tas_smart_amp_v2.h"
+
+#if IS_ENABLED(CONFIG_PLATFORM_QCOM)
+#include <dsp/tas_qualcomm.h>
+static dc_detection_data_t s_dc_detect;
+#endif /*CONFIG_PLATFORM_QCOM*/
+#endif /*CONFIG_TAS25XX_ALGO*/
+/*For mixer_control implementation*/
+#define MAX_STRING 200
+
+static const char *dts_tag[][3] = {
+ {
+ "ti,left-channel",
+ "ti,reset-gpio",
+ "ti,irq-gpio"
+ },
+ {
+ "ti,right-channel",
+ "ti,reset-gpio2",
+ "ti,irq-gpio2"
+ }
+};
+
+static const char *reset_gpio_label[2] = {
+ "TAS256X_RESET", "TAS256X_RESET2"
+};
+
+static const char *irq_gpio_label[2] = {
+ "TAS256X-IRQ", "TAS256X-IRQ2"
+};
+
+static int tas256x_regmap_write(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned int value)
+{
+ int nResult = 0;
+ int retry_count = TAS256X_I2C_RETRY_COUNT;
+ struct linux_platform *platform_data =
+ (struct linux_platform *)plat_data;
+
+ if (platform_data->i2c_suspend)
+ return ERROR_I2C_SUSPEND;
+
+ platform_data->client->addr = i2c_addr;
+ while (retry_count--) {
+ nResult = regmap_write(platform_data->regmap, reg,
+ value);
+ if (nResult >= 0)
+ break;
+ msleep(20);
+ }
+ if (retry_count == -1)
+ return ERROR_I2C_FAILED;
+ else
+ return 0;
+}
+
+static int tas256x_regmap_bulk_write(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned char *pData,
+ unsigned int nLength)
+{
+ int nResult = 0;
+ int retry_count = TAS256X_I2C_RETRY_COUNT;
+ struct linux_platform *platform_data =
+ (struct linux_platform *)plat_data;
+
+ if (platform_data->i2c_suspend)
+ return ERROR_I2C_SUSPEND;
+
+ platform_data->client->addr = i2c_addr;
+ while (retry_count--) {
+ nResult = regmap_bulk_write(platform_data->regmap, reg,
+ pData, nLength);
+ if (nResult >= 0)
+ break;
+ msleep(20);
+ }
+ if (retry_count == -1)
+ return ERROR_I2C_FAILED;
+ else
+ return 0;
+}
+
+static int tas256x_regmap_read(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned int *value)
+{
+ int nResult = 0;
+ int retry_count = TAS256X_I2C_RETRY_COUNT;
+ struct linux_platform *platform_data =
+ (struct linux_platform *)plat_data;
+
+ if (platform_data->i2c_suspend)
+ return ERROR_I2C_SUSPEND;
+
+ platform_data->client->addr = i2c_addr;
+ while (retry_count--) {
+ nResult = regmap_read(platform_data->regmap, reg,
+ value);
+ if (nResult >= 0)
+ break;
+ msleep(20);
+ }
+ if (retry_count == -1)
+ return ERROR_I2C_FAILED;
+ else
+ return 0;
+}
+
+static int tas256x_regmap_bulk_read(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned char *pData,
+ unsigned int nLength)
+{
+ int nResult = 0;
+ int retry_count = TAS256X_I2C_RETRY_COUNT;
+ struct linux_platform *platform_data =
+ (struct linux_platform *)plat_data;
+
+ if (platform_data->i2c_suspend)
+ return ERROR_I2C_SUSPEND;
+
+ platform_data->client->addr = i2c_addr;
+ while (retry_count--) {
+ nResult = regmap_bulk_read(platform_data->regmap, reg,
+ pData, nLength);
+ if (nResult >= 0)
+ break;
+ msleep(20);
+ }
+ if (retry_count == -1)
+ return ERROR_I2C_FAILED;
+ else
+ return 0;
+}
+
+static int tas256x_regmap_update_bits(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned int mask,
+ unsigned int value)
+{
+ int nResult = 0;
+ int retry_count = TAS256X_I2C_RETRY_COUNT;
+ struct linux_platform *platform_data =
+ (struct linux_platform *)plat_data;
+
+ if (platform_data->i2c_suspend)
+ return ERROR_I2C_SUSPEND;
+
+ platform_data->client->addr = i2c_addr;
+ while (retry_count--) {
+ nResult = regmap_update_bits(platform_data->regmap, reg,
+ mask, value);
+ if (nResult >= 0)
+ break;
+ msleep(20);
+ }
+ if (retry_count == -1)
+ return ERROR_I2C_FAILED;
+ else
+ return 0;
+}
+
+static char const *tas2564_rx_mode_text[] = {"Speaker", "Receiver"};
+
+static const struct soc_enum tas2564_rx_mode_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas2564_rx_mode_text),
+ tas2564_rx_mode_text),
+};
+
+static int tas2564_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct tas256x_priv *p_tas256x = NULL;
+ struct linux_platform *plat_data = NULL;
+ int ret = -1;
+
+ if (codec == NULL) {
+ pr_err("%s:codec is NULL\n", __func__);
+ return ret;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING))
+ ret = tas2564_rx_mode_update(p_tas256x,
+ ucontrol->value.integer.value[0], channel_left);
+ else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING))
+ ret = tas2564_rx_mode_update(p_tas256x,
+ ucontrol->value.integer.value[0], channel_right);
+ else
+ dev_err(plat_data->dev, "Invalid Channel %s\n",
+ ucontrol->id.name);
+
+ return ret;
+}
+
+static int tas2564_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = -1;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct linux_platform *plat_data = NULL;
+ struct tas256x_priv *p_tas256x = NULL;
+
+ if (codec == NULL) {
+ pr_err("%s:codec is NULL\n", __func__);
+ return ret;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->rx_mode;
+ else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->rx_mode;
+ else
+ dev_err(plat_data->dev, "Invalid Channel %s\n",
+ ucontrol->id.name);
+
+ return 0;
+}
+
+static int tas256x_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct tas256x_priv *p_tas256x = NULL;
+ struct linux_platform *plat_data = NULL;
+ int ret = -1;
+
+ if ((codec == NULL) || (mc == NULL)) {
+ pr_err("%s:codec or control is NULL\n", __func__);
+ return ret;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ if (ucontrol->value.integer.value[0] > mc->max)
+ return ret;
+
+ switch (mc->reg) {
+ case DVC_PCM:
+ ret = tas256x_update_playback_volume(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIM_MAX_ATN:
+ ret = tas256x_update_lim_max_attenuation(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_INF_PT:
+ ret = tas256x_update_lim_inflection_point(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_SLOPE:
+ ret = tas256x_update_lim_slope(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_ATK_RT:
+ ret = tas256x_update_limiter_attack_rate(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_RLS_RT:
+ ret = tas256x_update_limiter_release_rate(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_RLS_ST:
+ ret = tas256x_update_limiter_release_step_size(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_ATK_ST:
+ ret = tas256x_update_limiter_attack_step_size(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BOP_ATK_RT:
+ ret = tas256x_update_bop_attack_rate(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BOP_ATK_ST:
+ ret = tas256x_update_bop_attack_step_size(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BOP_HLD_TM:
+ ret = tas256x_update_bop_hold_time(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BST_VREG:
+ ret = tas256x_update_boost_voltage(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BST_ILIM:
+ ret = tas256x_update_current_limit(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_TH_MAX:
+ ret = tas256x_update_lim_max_thr(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case LIMB_TH_MIN:
+ ret = tas256x_update_lim_min_thr(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BOP_TH:
+ ret = tas256x_update_bop_thr(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case BOSD_TH:
+ ret = tas256x_update_bosd_thr(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case CLASSH_TIMER:
+ ret = tas256x_update_classh_timer(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ case AMPOUTPUT_LVL:
+ ret = tas256x_update_ampoutput_level(p_tas256x,
+ ucontrol->value.integer.value[0], mc->shift);
+ break;
+ }
+ return ret;
+}
+
+static int tas256x_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct tas256x_priv *p_tas256x = NULL;
+ struct linux_platform *plat_data = NULL;
+ int ret = -1;
+
+ if ((codec == NULL) || (mc == NULL)) {
+ pr_err("%s:codec or control is NULL\n", __func__);
+ return ret;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ switch (mc->reg) {
+ case DVC_PCM:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->dvc_pcm;
+ break;
+ case LIM_MAX_ATN:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_max_attn;
+ break;
+ case LIMB_INF_PT:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_infl_pt;
+ break;
+ case LIMB_SLOPE:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_trk_slp;
+ break;
+ case LIMB_ATK_RT:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_att_rate;
+ break;
+ case LIMB_RLS_RT:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_rel_rate;
+ break;
+ case LIMB_RLS_ST:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_rel_stp_size;
+ break;
+ case LIMB_ATK_ST:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_att_stp_size;
+ break;
+ case BOP_ATK_RT:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bop_att_rate;
+ break;
+ case BOP_ATK_ST:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bop_att_stp_size;
+ break;
+ case BOP_HLD_TM:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bop_hld_time;
+ break;
+ case BST_VREG:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bst_vltg;
+ break;
+ case BST_ILIM:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bst_ilm;
+ break;
+ case LIMB_TH_MAX:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_thr_max;
+ break;
+ case LIMB_TH_MIN:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->lim_thr_min;
+ break;
+ case BOP_TH:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bop_thd;
+ break;
+ case BOSD_TH:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->bosd_thd;
+ break;
+ case CLASSH_TIMER:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->classh_timer;
+ break;
+ case AMPOUTPUT_LVL:
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[mc->shift-1]->ampoutput_lvl;
+ break;
+ }
+ return 0;
+}
+
+static int tas256x_enum_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int ret = -1;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct tas256x_priv *p_tas256x = NULL;
+ struct linux_platform *plat_data = NULL;
+
+ if (codec == NULL) {
+ pr_err("%s:codec is NULL\n", __func__);
+ return ret;
+ }
+
+ if (ucontrol == NULL) {
+ pr_err("%s:ucontrol is NULL\n", __func__);
+ return ret;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ if (strnstr(ucontrol->id.name, "Version", MAX_STRING)) {
+ ucontrol->value.integer.value[0] = 0;
+ } else if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING)) {
+ if (strnstr(ucontrol->id.name, "LIMITER SWITCH",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->lim_switch;
+ else if (strnstr(ucontrol->id.name, "BOP ENABLE",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->bop_enable;
+ else if (strnstr(ucontrol->id.name, "BOP MUTE",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->bop_mute;
+ else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->bosd_enable;
+ else if (strnstr(ucontrol->id.name, "VBAT LPF",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->vbat_lpf;
+ else if (strnstr(ucontrol->id.name, "RECIEVER ENABLE",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[0]->reciever_enable;
+ else
+ dev_err(plat_data->dev, "Invalid controll %s\n",
+ ucontrol->id.name);
+ } else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING)) {
+ if (strnstr(ucontrol->id.name, "LIMITER SWITCH",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->lim_switch;
+ else if (strnstr(ucontrol->id.name, "BOP ENABLE",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->bop_enable;
+ else if (strnstr(ucontrol->id.name, "BOP MUTE",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->bop_mute;
+ else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->bosd_enable;
+ else if (strnstr(ucontrol->id.name, "VBAT LPF",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->vbat_lpf;
+ else if (strnstr(ucontrol->id.name, "RECIEVER ENABLE",
+ MAX_STRING))
+ ucontrol->value.integer.value[0] =
+ p_tas256x->devs[1]->reciever_enable;
+ else
+ dev_err(plat_data->dev, "Invalid controll %s\n",
+ ucontrol->id.name);
+ } else {
+ dev_err(plat_data->dev, "Invalid Channel %s\n",
+ ucontrol->id.name);
+ }
+ return 0;
+}
+
+static int tas256x_enum_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol);
+#else
+ struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+ struct soc_mixer_control *mc =
+ (struct soc_mixer_control *)kcontrol->private_value;
+ struct tas256x_priv *p_tas256x = NULL;
+ struct linux_platform *plat_data = NULL;
+ int ret = -1;
+
+ if ((codec == NULL) || (mc == NULL)) {
+ pr_err("%s:codec or control is NULL\n", __func__);
+ return ret;
+ }
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ p_tas256x = snd_soc_component_get_drvdata(codec);
+#else
+ p_tas256x = snd_soc_codec_get_drvdata(codec);
+#endif
+ if (p_tas256x == NULL) {
+ pr_err("%s:p_tas256x is NULL\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ if (strnstr(ucontrol->id.name, "LEFT", MAX_STRING)) {
+ if (strnstr(ucontrol->id.name, "LIMITER SWITCH",
+ MAX_STRING))
+ ret = tas256x_update_limiter_enable(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_left);
+ else if (strnstr(ucontrol->id.name, "BOP ENABLE",
+ MAX_STRING))
+ ret = tas256x_update_bop_enable(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_left);
+ else if (strnstr(ucontrol->id.name, "BOP MUTE",
+ MAX_STRING))
+ ret = tas256x_update_bop_mute(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_left);
+ else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN",
+ MAX_STRING))
+ ret = tas256x_update_bop_shutdown_enable(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_left);
+ else if (strnstr(ucontrol->id.name, "VBAT LPF",
+ MAX_STRING))
+ ret = tas256x_update_vbat_lpf(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_left);
+ else if (strnstr(ucontrol->id.name, "RECIEVER ENABLE",
+ MAX_STRING))
+ ret = tas256x_enable_reciever_mode(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_left);
+ else
+ dev_err(plat_data->dev, "Invalid Control %s\n",
+ ucontrol->id.name);
+ } else if (strnstr(ucontrol->id.name, "RIGHT", MAX_STRING)) {
+ if (strnstr(ucontrol->id.name, "LIMITER SWITCH",
+ MAX_STRING))
+ ret = tas256x_update_limiter_enable(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_right);
+ else if (strnstr(ucontrol->id.name, "BOP ENABLE",
+ MAX_STRING))
+ ret = tas256x_update_bop_enable(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_right);
+ else if (strnstr(ucontrol->id.name, "BOP MUTE",
+ MAX_STRING))
+ ret = tas256x_update_bop_mute(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_right);
+ else if (strnstr(ucontrol->id.name, "BROWNOUT SHUTDOWN",
+ MAX_STRING))
+ ret = tas256x_update_bop_shutdown_enable(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_right);
+ else if (strnstr(ucontrol->id.name, "VBAT LPF",
+ MAX_STRING))
+ ret = tas256x_update_vbat_lpf(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_right);
+ else if (strnstr(ucontrol->id.name, "RECIEVER ENABLE",
+ MAX_STRING))
+ ret = tas256x_enable_reciever_mode(p_tas256x,
+ ucontrol->value.integer.value[0],
+ channel_right);
+ else
+ dev_err(plat_data->dev, "Invalid control %s\n",
+ ucontrol->id.name);
+ } else {
+ dev_err(plat_data->dev, "Invalid Channel %s\n",
+ ucontrol->id.name);
+ }
+ return ret;
+}
+
+static char const *tas256x_rx_switch_text[] = {"DISABLE", "ENABLE"};
+static const struct soc_enum tas256x_rx_switch_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas256x_rx_switch_text),
+ tas256x_rx_switch_text),
+};
+
+static char const *tas256x_version_text[] = {TAS256X_DRIVER_TAG};
+static const struct soc_enum tas256x_version_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas256x_version_text),
+ tas256x_version_text),
+};
+
+static const struct snd_kcontrol_new tas256x_left_controls[] = {
+ SOC_ENUM_EXT("TAS256X Version", tas256x_version_enum[0],
+ tas256x_enum_get, NULL),
+ SOC_SINGLE_EXT("TAS256X PLAYBACK VOLUME LEFT", DVC_PCM, 1, 56, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM MAX ATTN LEFT", LIM_MAX_ATN, 1, 15, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM THR MAX LEFT", LIMB_TH_MAX,
+ 1, 26, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM THR MIN LEFT", LIMB_TH_MIN,
+ 1, 26, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM INFLECTION POINT LEFT", LIMB_INF_PT,
+ 1, 40, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM SLOPE LEFT", LIMB_SLOPE, 1, 6, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP THR LEFT", BOP_TH,
+ 1, 15, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOSD THR LEFT", BOSD_TH,
+ 1, 15, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM ATTACT RATE LEFT", LIMB_ATK_RT, 1, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM RELEASE RATE LEFT", LIMB_RLS_RT, 1, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM ATTACK STEP LEFT", LIMB_ATK_ST, 1, 3, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM RELEASE STEP LEFT", LIMB_RLS_ST, 1, 3, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP ATTACK RATE LEFT", BOP_ATK_RT, 1, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP ATTACK STEP LEFT", BOP_ATK_ST, 1, 3, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP HOLD TIME LEFT", BOP_HLD_TM, 1, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_ENUM_EXT("TAS256X LIMITER SWITCH LEFT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_ENUM_EXT("TAS256X BOP ENABLE LEFT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_ENUM_EXT("TAS256X BOP MUTE LEFT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_ENUM_EXT("TAS256X BROWNOUT SHUTDOWN LEFT",
+ tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_SINGLE_EXT("TAS256X CLASSH TIMER LEFT", CLASSH_TIMER, 1, 22, 0,
+ tas256x_get, tas256x_put),
+ SOC_ENUM_EXT("TAS256X RECIEVER ENABLE LEFT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+};
+
+static const struct snd_kcontrol_new tas256x_right_controls[] = {
+ SOC_SINGLE_EXT("TAS256X PLAYBACK VOLUME RIGHT", DVC_PCM, 2, 56, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM MAX ATTN RIGHT", LIM_MAX_ATN, 2, 15, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM THR MAX RIGHT", LIMB_TH_MAX,
+ 2, 26, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM THR MIN RIGHT", LIMB_TH_MIN,
+ 2, 26, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM INFLECTION POINT RIGHT", LIMB_INF_PT,
+ 2, 40, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM SLOPE RIGHT", LIMB_SLOPE, 2, 6, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP THR RIGHT", BOP_TH,
+ 2, 15, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOSD THR RIGHT", BOSD_TH,
+ 2, 15, 0, tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM ATTACT RATE RIGHT", LIMB_ATK_RT, 2, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM RELEASE RATE RIGHT", LIMB_RLS_RT, 2, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM ATTACK STEP RIGHT", LIMB_ATK_ST, 2, 3, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X LIM RELEASE STEP RIGHT", LIMB_RLS_ST, 2, 3, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP ATTACK RATE RIGHT", BOP_ATK_RT, 2, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP ATTACK STEP RIGHT", BOP_ATK_ST, 2, 3, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOP HOLD TIME RIGHT", BOP_HLD_TM, 2, 7, 0,
+ tas256x_get, tas256x_put),
+ SOC_ENUM_EXT("TAS256X LIMITER SWITCH RIGHT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_ENUM_EXT("TAS256X BOP ENABLE RIGHT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_ENUM_EXT("TAS256X BOP MUTE RIGHT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_ENUM_EXT("TAS256X BROWNOUT SHUTDOWN RIGHT",
+ tas256x_rx_switch_enum[0], tas256x_enum_get, tas256x_enum_put),
+ SOC_SINGLE_EXT("TAS256X CLASSH TIMER RIGHT", CLASSH_TIMER, 2, 22, 0,
+ tas256x_get, tas256x_put),
+ SOC_ENUM_EXT("TAS256X RECIEVER ENABLE RIGHT", tas256x_rx_switch_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+};
+
+static char const *tas2564_vbat_lpf_text[] = {
+ "DISABLE", "HZ_10", "HZ_100", "KHZ_1"};
+static const struct soc_enum tas2564_vbat_lpf_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas2564_vbat_lpf_text),
+ tas2564_vbat_lpf_text),
+};
+
+static char const *tas2562_vbat_lpf_text[] = {
+ "DISABLE", "HZ_100", "KHZ_1", "KHZ_10"};
+static const struct soc_enum tas2562_vbat_lpf_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tas2562_vbat_lpf_text),
+ tas2562_vbat_lpf_text),
+};
+
+static const struct snd_kcontrol_new tas2564_left_controls[] = {
+ SOC_ENUM_EXT("TAS256X RX MODE LEFT", tas2564_rx_mode_enum[0],
+ tas2564_get, tas2564_put),
+ SOC_ENUM_EXT("TAS256X VBAT LPF LEFT", tas2564_vbat_lpf_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE LEFT", BST_VREG, 1, 15, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOOST CURRENT LEFT", BST_ILIM, 1, 63, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X AMP OUTPUT LVL LEFT", AMPOUTPUT_LVL, 1, 0x1C, 0,
+ tas256x_get, tas256x_put),
+};
+
+static const struct snd_kcontrol_new tas2564_right_controls[] = {
+ SOC_ENUM_EXT("TAS256X RX MODE RIGHT", tas2564_rx_mode_enum[0],
+ tas2564_get, tas2564_put),
+ SOC_ENUM_EXT("TAS256X VBAT LPF RIGHT", tas2564_vbat_lpf_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE RIGHT", BST_VREG, 2, 15, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOOST CURRENT RIGHT", BST_ILIM, 2, 63, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X AMP OUTPUT LVL RIGHT", AMPOUTPUT_LVL, 2, 0x1C, 0,
+ tas256x_get, tas256x_put),
+};
+
+static const struct snd_kcontrol_new tas2562_left_controls[] = {
+ SOC_ENUM_EXT("TAS256X VBAT LPF LEFT", tas2562_vbat_lpf_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE LEFT", BST_VREG, 1, 12, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOOST CURRENT LEFT", BST_ILIM, 1, 55, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X AMP OUTPUT LVL LEFT", AMPOUTPUT_LVL, 1, 0x1C, 0,
+ tas256x_get, tas256x_put),
+};
+
+static const struct snd_kcontrol_new tas2562_right_controls[] = {
+ SOC_ENUM_EXT("TAS256X VBAT LPF RIGHT", tas2562_vbat_lpf_enum[0],
+ tas256x_enum_get, tas256x_enum_put),
+ SOC_SINGLE_EXT("TAS256X BOOST VOLTAGE RIGHT", BST_VREG, 2, 12, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X BOOST CURRENT RIGHT", BST_ILIM, 2, 55, 0,
+ tas256x_get, tas256x_put),
+ SOC_SINGLE_EXT("TAS256X AMP OUTPUT LVL RIGHT", AMPOUTPUT_LVL, 2, 0x1C, 0,
+ tas256x_get, tas256x_put),
+};
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static int tas2564_probe(struct tas256x_priv *p_tas256x,
+ struct snd_soc_component *codec, int chn)
+{
+ int ret = -1;
+ struct linux_platform *plat_data = NULL;
+
+ if ((!p_tas256x) || (!codec)) {
+ pr_err("tas256x:%s p_tas256x or codec is Null\n", __func__);
+ return ret;
+ }
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_dbg(plat_data->dev, "%s channel %d", __func__, chn);
+
+ tas256x_update_default_params(p_tas256x, chn);
+ if (chn == channel_left) {
+ ret = snd_soc_add_component_controls(codec, tas256x_left_controls,
+ ARRAY_SIZE(tas256x_left_controls));
+ ret = snd_soc_add_component_controls(codec, tas2564_left_controls,
+ ARRAY_SIZE(tas2564_left_controls));
+ } else if (chn == channel_right) {
+ ret = snd_soc_add_component_controls(codec, tas256x_right_controls,
+ ARRAY_SIZE(tas256x_right_controls));
+ ret = snd_soc_add_component_controls(codec, tas2564_right_controls,
+ ARRAY_SIZE(tas2564_right_controls));
+ } else {
+ dev_err(plat_data->dev, "Invalid Channel %d\n", chn);
+ }
+
+ return ret;
+}
+#else
+static int tas2564_probe(struct tas256x_priv *p_tas256x,
+ struct snd_soc_codec *codec, int chn)
+{
+ int ret = -1;
+ struct linux_platform *plat_data = NULL;
+
+ if ((!p_tas256x) || (!codec)) {
+ pr_err("tas256x:%s p_tas256x or codec is Null\n", __func__);
+ return ret;
+ }
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_dbg(plat_data->dev, "%s channel %d", __func__, chn);
+
+ tas256x_update_default_params(p_tas256x, chn);
+ if (chn == channel_left) {
+ ret = snd_soc_add_codec_controls(codec, tas256x_left_controls,
+ ARRAY_SIZE(tas256x_left_controls));
+ ret = snd_soc_add_codec_controls(codec, tas2564_left_controls,
+ ARRAY_SIZE(tas2564_left_controls));
+ } else if (chn == channel_right) {
+ ret = snd_soc_add_codec_controls(codec, tas256x_right_controls,
+ ARRAY_SIZE(tas256x_right_controls));
+ ret = snd_soc_add_codec_controls(codec, tas2564_right_controls,
+ ARRAY_SIZE(tas2564_right_controls));
+ } else {
+ dev_err(plat_data->dev, "Invalid Channel %d\n", chn);
+ }
+
+ return ret;
+}
+#endif
+
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+static int tas2562_probe(struct tas256x_priv *p_tas256x,
+ struct snd_soc_component *codec, int chn)
+{
+ struct linux_platform *plat_data = NULL;
+ int ret = -1;
+
+ if ((!p_tas256x) || (!codec)) {
+ pr_err("tas256x:%s p_tas256x or codec is Null\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_dbg(plat_data->dev, "%s channel %d", __func__, chn);
+
+ tas256x_update_default_params(p_tas256x, chn);
+ if (chn == channel_left) {
+ ret = snd_soc_add_component_controls(codec, tas256x_left_controls,
+ ARRAY_SIZE(tas256x_left_controls));
+ ret = snd_soc_add_component_controls(codec, tas2562_left_controls,
+ ARRAY_SIZE(tas2562_left_controls));
+ } else if (chn == channel_right) {
+ ret = snd_soc_add_component_controls(codec, tas256x_right_controls,
+ ARRAY_SIZE(tas256x_right_controls));
+ ret = snd_soc_add_component_controls(codec, tas2562_right_controls,
+ ARRAY_SIZE(tas2562_right_controls));
+ } else {
+ dev_err(plat_data->dev, "Invalid Channel %d\n", chn);
+ }
+
+ return ret;
+}
+#else
+static int tas2562_probe(struct tas256x_priv *p_tas256x,
+ struct snd_soc_codec *codec, int chn)
+{
+ struct linux_platform *plat_data = NULL;
+ int ret = -1;
+
+ if ((!p_tas256x) || (!codec)) {
+ pr_err("tas256x:%s p_tas256x or codec is Null\n", __func__);
+ return ret;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_dbg(plat_data->dev, "%s channel %d", __func__, chn);
+
+ tas256x_update_default_params(p_tas256x, chn);
+ if (chn == channel_left) {
+ ret = snd_soc_add_codec_controls(codec, tas256x_left_controls,
+ ARRAY_SIZE(tas256x_left_controls));
+ ret = snd_soc_add_codec_controls(codec, tas2562_left_controls,
+ ARRAY_SIZE(tas2562_left_controls));
+ } else if (chn == channel_right) {
+ ret = snd_soc_add_codec_controls(codec, tas256x_right_controls,
+ ARRAY_SIZE(tas256x_right_controls));
+ ret = snd_soc_add_codec_controls(codec, tas2562_right_controls,
+ ARRAY_SIZE(tas2562_right_controls));
+ } else {
+ dev_err(plat_data->dev, "Invalid Channel %d\n", chn);
+ }
+
+ return ret;
+}
+#endif
+
+static bool tas256x_volatile(struct device *dev, unsigned int reg)
+{
+ return true;
+}
+
+static bool tas256x_writeable(struct device *dev, unsigned int reg)
+{
+ return true;
+}
+static const struct regmap_config tas256x_i2c_regmap = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .writeable_reg = tas256x_writeable,
+ .volatile_reg = tas256x_volatile,
+ .cache_type = REGCACHE_NONE,
+ .max_register = 1 * 128,
+};
+
+static void tas256x_hw_reset(struct tas256x_priv *p_tas256x)
+{
+ struct linux_platform *plat_data = NULL;
+ int i = 0;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) {
+ gpio_direction_output(
+ p_tas256x->devs[i]->mn_reset_gpio, 0);
+ }
+ }
+ msleep(20);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) {
+ gpio_direction_output(
+ p_tas256x->devs[i]->mn_reset_gpio, 1);
+ }
+ p_tas256x->devs[i]->mn_current_book = -1;
+ p_tas256x->devs[i]->mn_current_page = -1;
+ }
+ msleep(20);
+
+ dev_info(plat_data->dev, "reset gpio up !!\n");
+}
+
+void tas256x_enable_irq(struct tas256x_priv *p_tas256x, bool enable)
+{
+ static int irq_enabled[2] = {0};
+ struct irq_desc *desc = NULL;
+ struct linux_platform *plat_data = NULL;
+ int i = 0;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ if (enable) {
+ if (p_tas256x->mb_irq_eable)
+ return;
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio) &&
+ irq_enabled[i] == 0) {
+ if (i == 0) {
+ desc = irq_to_desc(
+ p_tas256x->devs[i]->mn_irq);
+ if (desc && desc->depth > 0)
+ enable_irq(
+ p_tas256x->devs[i]->mn_irq);
+ else
+ dev_info(plat_data->dev,
+ "### irq already enabled");
+ } else {
+ enable_irq(p_tas256x->devs[i]->mn_irq);
+ }
+ irq_enabled[i] = 1;
+ }
+ }
+ p_tas256x->mb_irq_eable = true;
+ } else {
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio)
+ && irq_enabled[i] == 1) {
+ disable_irq_nosync(p_tas256x->devs[i]->mn_irq);
+ irq_enabled[i] = 0;
+ }
+ }
+ p_tas256x->mb_irq_eable = false;
+ }
+}
+
+static void irq_work_routine(struct work_struct *work)
+{
+ struct tas256x_priv *p_tas256x =
+ container_of(work, struct tas256x_priv, irq_work.work);
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_info(plat_data->dev, "%s\n", __func__);
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&p_tas256x->codec_lock);
+#endif
+ if (plat_data->mb_runtime_suspend) {
+ pr_info("%s, Runtime Suspended\n", __func__);
+ goto end;
+ }
+ /*Logical Layer IRQ function, return is ignored*/
+ tas256x_irq_work_func(p_tas256x);
+
+end:
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&p_tas256x->codec_lock);
+#endif
+ return;
+}
+
+static void init_work_routine(struct work_struct *work)
+{
+ struct tas256x_priv *p_tas256x =
+ container_of(work, struct tas256x_priv, init_work.work);
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&p_tas256x->codec_lock);
+#endif
+ /*Init Work Function. return is ignored*/
+ tas256x_init_work_func(p_tas256x);
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&p_tas256x->codec_lock);
+#endif
+}
+
+static irqreturn_t tas256x_irq_handler(int irq, void *dev_id)
+{
+ struct tas256x_priv *p_tas256x = (struct tas256x_priv *)dev_id;
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ /* get IRQ status after 100 ms */
+ schedule_delayed_work(&p_tas256x->irq_work, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+}
+
+static int tas256x_runtime_suspend(struct tas256x_priv *p_tas256x)
+{
+ struct linux_platform *plat_data = NULL;
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+
+ plat_data->mb_runtime_suspend = true;
+
+ if (delayed_work_pending(&p_tas256x->irq_work)) {
+ dev_dbg(plat_data->dev, "cancel IRQ work\n");
+ cancel_delayed_work_sync(&p_tas256x->irq_work);
+ }
+
+ return 0;
+}
+
+static int tas256x_runtime_resume(struct tas256x_priv *p_tas256x)
+{
+ struct linux_platform *plat_data = NULL;
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_dbg(plat_data->dev, "%s\n", __func__);
+
+ plat_data->mb_runtime_suspend = false;
+
+ return 0;
+}
+
+static int tas256x_pm_suspend(struct device *dev)
+{
+ struct tas256x_priv *p_tas256x = dev_get_drvdata(dev);
+ struct linux_platform *plat_data = NULL;
+
+ if (!p_tas256x) {
+ dev_err(plat_data->dev, "drvdata is NULL\n");
+ return -EINVAL;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ mutex_lock(&p_tas256x->codec_lock);
+ tas256x_runtime_suspend(p_tas256x);
+ mutex_unlock(&p_tas256x->codec_lock);
+ return 0;
+}
+
+static int tas256x_pm_resume(struct device *dev)
+{
+ struct tas256x_priv *p_tas256x = dev_get_drvdata(dev);
+ struct linux_platform *plat_data = NULL;
+
+ if (!p_tas256x) {
+ dev_err(plat_data->dev, "drvdata is NULL\n");
+ return -EINVAL;
+ }
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+
+ mutex_lock(&p_tas256x->codec_lock);
+ tas256x_runtime_resume(p_tas256x);
+ mutex_unlock(&p_tas256x->codec_lock);
+ return 0;
+}
+
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#if IS_ENABLED(CONFIG_PLATFORM_QCOM)
+struct tas256x_priv *g_p_tas256x;
+
+void tas256x_software_reset(void *prv_data)
+{
+ pr_err("[TI-SmartPA:%s]\n", __func__);
+ schedule_delayed_work(&g_p_tas256x->dc_work, msecs_to_jiffies(10));
+}
+
+static void dc_work_routine(struct work_struct *work)
+{
+ struct tas256x_priv *p_tas256x =
+ container_of(work, struct tas256x_priv, dc_work.work);
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_lock(&p_tas256x->codec_lock);
+#endif
+ tas256x_dc_work_func(p_tas256x, s_dc_detect.channel);
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_unlock(&p_tas256x->codec_lock);
+#endif
+
+}
+#endif/*CONFIG_PLATFORM_QCOM*/
+#endif /*CONFIG_TAS25XX_ALGO*/
+
+void schedule_init_work(struct tas256x_priv *p_tas256x)
+{
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ schedule_delayed_work(&p_tas256x->init_work, msecs_to_jiffies(50));
+}
+
+static int tas256x_parse_dt(struct device *dev,
+ struct tas256x_priv *p_tas256x)
+{
+ struct device_node *np = dev->of_node;
+ int rc = 0, i = 0;
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ rc = of_property_read_u32(np, "ti,channels", &p_tas256x->mn_channels);
+ if (rc) {
+ dev_err(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,channels", np->full_name, rc);
+ goto EXIT;
+ } else {
+ dev_dbg(plat_data->dev, "ti,channels=%d",
+ p_tas256x->mn_channels);
+ }
+
+ /*the device structures array*/
+ p_tas256x->devs =
+ kmalloc(p_tas256x->mn_channels * sizeof(struct tas_device *),
+ GFP_KERNEL);
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ p_tas256x->devs[i] = kmalloc(sizeof(struct tas_device),
+ GFP_KERNEL);
+ if (p_tas256x->devs[i] == NULL) {
+ dev_err(plat_data->dev,
+ "%s:%u:kmalloc failed!\n", __func__, __LINE__);
+ rc = -1;
+ break;
+ }
+
+ rc = of_property_read_u32(np, dts_tag[i][0],
+ &p_tas256x->devs[i]->mn_addr);
+ if (rc) {
+ dev_err(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ dts_tag[i][0], np->full_name, rc);
+ break;
+ } else {
+ dev_dbg(plat_data->dev, "%s = 0x%02x",
+ dts_tag[i][0], p_tas256x->devs[i]->mn_addr);
+ }
+
+ p_tas256x->devs[i]->mn_reset_gpio =
+ of_get_named_gpio(np, dts_tag[i][1], 0);
+ if (!gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio))
+ dev_err(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ dts_tag[i][1], np->full_name,
+ p_tas256x->devs[i]->mn_reset_gpio);
+ else
+ dev_dbg(plat_data->dev, "%s = %d",
+ dts_tag[i][1],
+ p_tas256x->devs[i]->mn_reset_gpio);
+
+ p_tas256x->devs[i]->mn_irq_gpio =
+ of_get_named_gpio(np, dts_tag[i][2], 0);
+ if (!gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio)) {
+ dev_err(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ dts_tag[i][2], np->full_name,
+ p_tas256x->devs[i]->mn_irq_gpio);
+ } else {
+ dev_dbg(plat_data->dev, "%s = %d",
+ dts_tag[i][2],
+ p_tas256x->devs[i]->mn_irq_gpio);
+ }
+ p_tas256x->devs[i]->spk_control = 1;
+ }
+
+ if (rc)
+ goto EXIT;
+
+ rc = of_property_read_u32(np, "ti,frame-start", &p_tas256x->mn_frame_start);
+ if (rc) {
+ dev_info(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,frame-start", np->full_name, rc);
+ p_tas256x->mn_frame_start = 0;
+ } else {
+ dev_dbg(plat_data->dev, "ti,frame-start=0x%x",
+ p_tas256x->mn_frame_start);
+ }
+
+ rc = of_property_read_u32(np, "ti,rx-offset", &p_tas256x->mn_rx_offset);
+ if (rc) {
+ dev_info(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,rx-offset", np->full_name, rc);
+ p_tas256x->mn_rx_offset = 1;
+ } else {
+ dev_dbg(plat_data->dev, "ti,rx-offset=0x%x",
+ p_tas256x->mn_rx_offset);
+ }
+
+ rc = of_property_read_u32(np, "ti,rx-edge", &p_tas256x->mn_rx_edge);
+ if (rc) {
+ dev_info(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,rx-edge", np->full_name, rc);
+ p_tas256x->mn_rx_edge = 1;
+ } else {
+ dev_dbg(plat_data->dev, "ti,rx-edge=0x%x",
+ p_tas256x->mn_rx_edge);
+ }
+
+ rc = of_property_read_u32(np, "ti,tx-offset", &p_tas256x->mn_tx_offset);
+ if (rc) {
+ dev_info(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,tx-offset", np->full_name, rc);
+ p_tas256x->mn_tx_offset = 0;
+ } else {
+ dev_dbg(plat_data->dev, "ti,tx-offset=0x%x",
+ p_tas256x->mn_tx_offset);
+ }
+
+ rc = of_property_read_u32(np, "ti,tx-edge", &p_tas256x->mn_tx_edge);
+ if (rc) {
+ dev_info(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,tx-edge", np->full_name, rc);
+ p_tas256x->mn_tx_edge = 0;
+ } else {
+ dev_dbg(plat_data->dev, "ti,tx-edge=0x%x",
+ p_tas256x->mn_tx_edge);
+ }
+
+ rc = of_property_read_u32(np, "ti,iv-width", &p_tas256x->mn_iv_width);
+ if (rc) {
+ dev_err(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,iv-width", np->full_name, rc);
+ } else {
+ dev_dbg(plat_data->dev, "ti,iv-width=0x%x",
+ p_tas256x->mn_iv_width);
+ }
+
+ rc = of_property_read_u32(np, "ti,vbat-mon", &p_tas256x->mn_vbat);
+ if (rc) {
+ dev_err(plat_data->dev,
+ "Looking up %s property in node %s failed %d\n",
+ "ti,vbat-mon", np->full_name, rc);
+ } else {
+ dev_dbg(plat_data->dev, "ti,vbat-mon=0x%x",
+ p_tas256x->mn_vbat);
+ }
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+ /* Needs to be enabled always */
+ tas25xx_parse_algo_dt(np);
+#endif /*CONFIG_TAS25XX_ALGO*/
+EXIT:
+ return rc;
+}
+
+static int tas256x_i2c_probe(struct i2c_client *p_client,
+ const struct i2c_device_id *id)
+{
+ struct tas256x_priv *p_tas256x;
+ struct linux_platform *plat_data;
+ int n_result = 0;
+ int i = 0;
+
+ dev_info(&p_client->dev, "Driver Tag: %s\n", TAS256X_DRIVER_TAG);
+ dev_info(&p_client->dev, "%s enter\n", __func__);
+
+ p_tas256x = devm_kzalloc(&p_client->dev,
+ sizeof(struct tas256x_priv), GFP_KERNEL);
+ if (p_tas256x == NULL) {
+ dev_err(&p_client->dev, "failed to allocate memory\n");
+ n_result = -ENOMEM;
+ goto err;
+ }
+
+ plat_data = (struct linux_platform *)devm_kzalloc(&p_client->dev,
+ sizeof(struct linux_platform), GFP_KERNEL);
+ if (p_tas256x == NULL) {
+ dev_err(&p_client->dev, "failed to allocate memory\n");
+ n_result = -ENOMEM;
+ goto err;
+ }
+
+ p_tas256x->platform_data = plat_data;
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ p_tas256x->profile_cfg_id = -1;
+#endif
+ p_tas256x->plat_write = tas256x_regmap_write;
+ p_tas256x->plat_read = tas256x_regmap_read;
+ p_tas256x->plat_bulk_write = tas256x_regmap_bulk_write;
+ p_tas256x->plat_bulk_read = tas256x_regmap_bulk_read;
+ p_tas256x->plat_update_bits = tas256x_regmap_update_bits;
+
+ plat_data->client = p_client;
+ plat_data->dev = &p_client->dev;
+ i2c_set_clientdata(p_client, p_tas256x);
+ dev_set_drvdata(&p_client->dev, p_tas256x);
+ plat_data->regmap = devm_regmap_init_i2c(p_client,
+ &tas256x_i2c_regmap);
+ if (IS_ERR(plat_data->regmap)) {
+ n_result = PTR_ERR(plat_data->regmap);
+ dev_err(&p_client->dev,
+ "Failed to allocate register map: %d\n",
+ n_result);
+ goto err;
+ }
+
+ mutex_init(&p_tas256x->dev_lock);
+ p_tas256x->hw_reset = tas256x_hw_reset;
+ p_tas256x->enable_irq = tas256x_enable_irq;
+ p_tas256x->schedule_init_work = schedule_init_work;
+#if IS_ENABLED(CODEC_PM)
+ plat_data->runtime_suspend = tas256x_runtime_suspend;
+ plat_data->runtime_resume = tas256x_runtime_resume;
+ plat_data->mn_power_state = TAS256X_POWER_SHUTDOWN;
+#endif
+
+ if (p_client->dev.of_node)
+ tas256x_parse_dt(&p_client->dev, p_tas256x);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio)) {
+ n_result = gpio_request(
+ p_tas256x->devs[i]->mn_reset_gpio,
+ reset_gpio_label[i]);
+ if (n_result) {
+ dev_err(plat_data->dev,
+ "%s: Failed to request gpio %d\n",
+ __func__,
+ p_tas256x->devs[i]->mn_reset_gpio);
+ n_result = -EINVAL;
+ goto err;
+ }
+ }
+ }
+
+ n_result = tas256x_register_device(p_tas256x);
+ if (n_result < 0)
+ goto err;
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ switch (p_tas256x->devs[i]->device_id) {
+ case DEVICE_TAS2562:
+ p_tas256x->devs[i]->dev_ops.tas_probe = tas2562_probe;
+ break;
+ case DEVICE_TAS2564:
+ p_tas256x->devs[i]->dev_ops.tas_probe = tas2564_probe;
+ break;
+ default:
+ p_tas256x->devs[i]->dev_ops.tas_probe = NULL;
+ break;
+ }
+ }
+
+ INIT_DELAYED_WORK(&p_tas256x->irq_work, irq_work_routine);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio)) {
+ n_result =
+ gpio_request(
+ p_tas256x->devs[i]->mn_irq_gpio,
+ irq_gpio_label[i]);
+ if (n_result < 0) {
+ dev_err(plat_data->dev,
+ "%s:%u: ch 0x%02x: GPIO %d request error\n",
+ __func__, __LINE__,
+ p_tas256x->devs[i]->mn_addr,
+ p_tas256x->devs[i]->mn_irq_gpio);
+ goto err;
+ }
+ gpio_direction_input(p_tas256x->devs[i]->mn_irq_gpio);
+ /*tas256x_dev_write(p_tas256x,
+ * (i == 0) ? channel_left : channel_right,
+ * TAS256X_MISCCONFIGURATIONREG0, 0xce);
+ */
+
+ p_tas256x->devs[i]->mn_irq =
+ gpio_to_irq(p_tas256x->devs[i]->mn_irq_gpio);
+ dev_info(plat_data->dev, "irq = %d\n",
+ p_tas256x->devs[i]->mn_irq);
+
+ n_result = request_threaded_irq(
+ p_tas256x->devs[i]->mn_irq,
+ tas256x_irq_handler,
+ NULL,
+ IRQF_TRIGGER_FALLING|IRQF_ONESHOT,
+ p_client->name, p_tas256x);
+ if (n_result < 0) {
+ dev_err(plat_data->dev,
+ "request_irq failed, %d\n", n_result);
+ goto err;
+ }
+ disable_irq_nosync(p_tas256x->devs[i]->mn_irq);
+ }
+ }
+
+ tas256x_enable_irq(p_tas256x, true);
+ INIT_DELAYED_WORK(&p_tas256x->init_work, init_work_routine);
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ mutex_init(&p_tas256x->codec_lock);
+ n_result = tas256x_register_codec(p_tas256x);
+ if (n_result < 0) {
+ dev_err(plat_data->dev,
+ "register codec failed, %d\n", n_result);
+ goto err;
+ }
+#endif
+
+#if IS_ENABLED(CONFIG_TAS256X_MISC)
+ mutex_init(&p_tas256x->file_lock);
+ n_result = tas256x_register_misc(p_tas256x);
+ if (n_result < 0) {
+ dev_err(plat_data->dev, "register codec failed %d\n",
+ n_result);
+ goto err;
+ }
+#endif
+
+
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#if IS_ENABLED(CONFIG_PLATFORM_QCOM)
+ INIT_DELAYED_WORK(&p_tas256x->dc_work, dc_work_routine);
+ g_p_tas256x = p_tas256x;
+ register_tas256x_reset_func(tas256x_software_reset, &s_dc_detect);
+#endif /*CONFIG_PLATFORM_QCOM*/
+#endif /*CONFIG_TAS25XX_ALGO*/
+
+
+err:
+ return n_result;
+}
+
+static int tas256x_i2c_remove(struct i2c_client *p_client)
+{
+ int i = 0;
+ struct tas256x_priv *p_tas256x = i2c_get_clientdata(p_client);
+ struct linux_platform *plat_data = NULL;
+
+ plat_data = (struct linux_platform *) p_tas256x->platform_data;
+ dev_info(plat_data->dev, "%s\n", __func__);
+
+ /*Cancel all the work routine before exiting*/
+ cancel_delayed_work_sync(&p_tas256x->irq_work);
+ cancel_delayed_work_sync(&p_tas256x->init_work);
+ cancel_delayed_work_sync(&p_tas256x->dc_work);
+
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ tas256x_deregister_codec(p_tas256x);
+ mutex_destroy(&p_tas256x->codec_lock);
+#endif
+
+#if IS_ENABLED(CONFIG_TAS256X_MISC)
+ tas256x_deregister_misc(p_tas256x);
+ mutex_destroy(&p_tas256x->file_lock);
+#endif
+
+ mutex_destroy(&p_tas256x->dev_lock);
+
+ for (i = 0; i < p_tas256x->mn_channels; i++) {
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_reset_gpio))
+ gpio_free(p_tas256x->devs[i]->mn_reset_gpio);
+ if (gpio_is_valid(p_tas256x->devs[i]->mn_irq_gpio))
+ gpio_free(p_tas256x->devs[i]->mn_irq_gpio);
+ if (p_tas256x->devs[i])
+ kfree(p_tas256x->devs[i]);
+ }
+
+ if (p_tas256x->devs)
+ kfree(p_tas256x->devs);
+
+ return 0;
+}
+
+
+static const struct i2c_device_id tas256x_i2c_id[] = {
+ { "tas256x", 0},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tas256x_i2c_id);
+
+#if defined(CONFIG_OF)
+static const struct of_device_id tas256x_of_match[] = {
+ { .compatible = "ti, tas256x" },
+ { .compatible = "ti, tas2562" },
+ { .compatible = "ti, tas2564" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, tas256x_of_match);
+#endif
+
+static const struct dev_pm_ops tas256x_pm_ops = {
+ .suspend = tas256x_pm_suspend,
+ .resume = tas256x_pm_resume
+};
+
+static struct i2c_driver tas256x_i2c_driver = {
+ .driver = {
+ .name = "tas256x",
+ .owner = THIS_MODULE,
+#if defined(CONFIG_OF)
+ .of_match_table = of_match_ptr(tas256x_of_match),
+#endif
+ .pm = &tas256x_pm_ops,
+ },
+ .probe = tas256x_i2c_probe,
+ .remove = tas256x_i2c_remove,
+ .id_table = tas256x_i2c_id,
+};
+
+module_i2c_driver(tas256x_i2c_driver);
+
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_DESCRIPTION("TAS256X I2C Smart Amplifier driver");
+MODULE_LICENSE("GPL v2");
+#endif
diff --git a/asoc/codecs/tas256x/physical_layer/inc/tas2562.h b/asoc/codecs/tas256x/physical_layer/inc/tas2562.h
new file mode 100644
index 00000000..c163986d
--- /dev/null
+++ b/asoc/codecs/tas256x/physical_layer/inc/tas2562.h
@@ -0,0 +1,743 @@
+#ifndef __TAS2562_
+#define __TAS2562_
+/* Software Reset */
+#define TAS2562_SOFTWARERESET (TAS256X_SOFTWARERESET)
+#define TAS2562_SOFTWARERESET_SOFTWARERESET_MASK \
+ (TAS256X_SOFTWARERESET_SOFTWARERESET_MASK)
+#define TAS2562_SOFTWARERESET_SOFTWARERESET_DONTRESET \
+ (TAS256X_SOFTWARERESET_SOFTWARERESET_DONTRESET)
+#define TAS2562_SOFTWARERESET_SOFTWARERESET_RESET \
+ (TAS256X_SOFTWARERESET_SOFTWARERESET_RESET)
+
+/* Power Control */
+#define TAS2562_POWERCONTROL (TAS256X_POWERCONTROL)
+#define TAS2562_POWERCONTROL_ISNSPOWER_MASK \
+ (TAS256X_POWERCONTROL_ISNSPOWER_MASK)
+#define TAS2562_POWERCONTROL_ISNSPOWER_ACTIVE \
+ (TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE)
+#define TAS2562_POWERCONTROL_ISNSPOWER_POWEREDDOWN \
+ (TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN)
+#define TAS2562_POWERCONTROL_VSNSPOWER_MASK \
+ (TAS256X_POWERCONTROL_VSNSPOWER_MASK)
+#define TAS2562_POWERCONTROL_VSNSPOWER_ACTIVE \
+ (TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE)
+#define TAS2562_POWERCONTROL_VSNSPOWER_POWEREDDOWN \
+ (TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN)
+#define TAS2562_POWERCONTROL_OPERATIONALMODE10_MASK \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK)
+#define TAS2562_POWERCONTROL_OPERATIONALMODE10_ACTIVE \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE)
+#define TAS2562_POWERCONTROL_OPERATIONALMODE10_MUTE \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE)
+#define TAS2562_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN)
+
+
+/* Playback Configuration Reg0 */
+#define TAS2562_PLAYBACKCONFIGURATIONREG0 \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0)
+#define TAS2562_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK)
+#define TAS2562_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED)
+#define TAS2562_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED)
+#define TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK (0x1f << 1)
+#define TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_SHIFT (1)
+
+/* Misc Configuration Reg0 */
+#define TAS2562_MISCCONFIGURATIONREG0 (TAS256X_MISCCONFIGURATIONREG0)
+#define TAS2562_MISCCONFIGURATIONREG0_CPPGRETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_MASK)
+#define TAS2562_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK)
+#define TAS2562_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_OCERETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_MASK)
+#define TAS2562_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_OCERETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_RETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_OTERETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_MASK)
+#define TAS2562_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_OTERETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_RETRY)
+#define TAS2562_MISCCONFIGURATIONREG0_IRQZPULL_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_MASK)
+#define TAS2562_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED)
+#define TAS2562_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED)
+#define TAS2562_MISCCONFIGURATIONREG0_AMPSS_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_AMPSS_MASK)
+#define TAS2562_MISCCONFIGURATIONREG0_AMPSS_DISABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_AMPSS_DISABLED)
+#define TAS2562_MISCCONFIGURATIONREG0_AMPSS_ENABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_AMPSS_ENABLED)
+
+/* TDM Configuration Reg0 */
+#define TAS2562_TDMCONFIGURATIONREG0 (TAS256X_TDMCONFIGURATIONREG0)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ)
+#define TAS2562_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK)
+#define TAS2562_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED \
+ (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED)
+#define TAS2562_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED \
+ (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ)
+#define TAS2562_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ)
+#define TAS2562_TDMCONFIGURATIONREG0_FRAMESTART_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK)
+#define TAS2562_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH \
+ (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH)
+#define TAS2562_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW \
+ (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW)
+
+/* TDM Configuration Reg1 */
+#define TAS2562_TDMCONFIGURATIONREG1 (TAS256X_TDMCONFIGURATIONREG1)
+#define TAS2562_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK \
+ (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK)
+#define TAS2562_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT \
+ (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT)
+#define TAS2562_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT \
+ (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT)
+#define TAS2562_TDMCONFIGURATIONREG1_RXOFFSET51_MASK \
+ (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK)
+#define TAS2562_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT \
+ (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT)
+#define TAS2562_TDMCONFIGURATIONREG1_RXEDGE_MASK \
+ (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK)
+#define TAS2562_TDMCONFIGURATIONREG1_RXEDGE_RISING \
+ (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING)
+#define TAS2562_TDMCONFIGURATIONREG1_RXEDGE_FALLING \
+ (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING)
+
+/* TDM Configuration Reg2 */
+#define TAS2562_TDMCONFIGURATIONREG2 (TAS256X_TDMCONFIGURATIONREG2)
+#define TAS2562_TDMCONFIGURATIONREG2_IVLEN76_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK)
+#define TAS2562_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK)
+#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX)
+#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK)
+#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_20BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_20BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_24BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXWLEN32_32BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_24BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS)
+#define TAS2562_TDMCONFIGURATIONREG2_RXSLEN10_32BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS)
+
+/* TDM Configuration Reg3 */
+#define TAS2562_TDMCONFIGURATIONREG3 (TAS256X_TDMCONFIGURATIONREG3)
+#define TAS2562_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK \
+ (TAS256X_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK)
+#define TAS2562_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask \
+ (TAS256X_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask)
+
+/* TDM Configuration Reg4 */
+#define TAS2562_TDMConfigurationReg4 (TAS256X_TDMConfigurationReg4)
+#define TAS2562_TDMCONFIGURATIONREG4_TXKEEPER_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_MASK)
+#define TAS2562_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE)
+#define TAS2562_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE)
+#define TAS2562_TDMCONFIGURATIONREG4_TXFILL_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXFILL_MASK)
+#define TAS2562_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0 \
+ (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0)
+#define TAS2562_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ \
+ (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ)
+#define TAS2562_TDMCONFIGURATIONREG4_TXOFFSET31_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK)
+#define TAS2562_TDMCONFIGURATIONREG4_TXEDGE_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK)
+#define TAS2562_TDMCONFIGURATIONREG4_TXEDGE_RISING \
+ (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_RISING)
+#define TAS2562_TDMCONFIGURATIONREG4_TXEDGE_FALLING \
+ (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_FALLING)
+
+/* TDM Configuration Reg5 */
+#define TAS2562_TDMCONFIGURATIONREG5 (TAS256X_TDMCONFIGURATIONREG5)
+#define TAS2562_TDMCONFIGURATIONREG5_VSNSTX_MASK \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_MASK)
+#define TAS2562_TDMCONFIGURATIONREG5_VSNSTX_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_DISABLE)
+#define TAS2562_TDMCONFIGURATIONREG5_VSNSTX_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE)
+#define TAS2562_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK)
+
+/* TDM Configuration Reg6 */
+#define TAS2562_TDMCONFIGURATIONREG6 (TAS256X_TDMCONFIGURATIONREG6)
+#define TAS2562_TDMCONFIGURATIONREG6_ISNSTX_MASK \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_MASK)
+#define TAS2562_TDMCONFIGURATIONREG6_ISNSTX_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_DISABLE)
+#define TAS2562_TDMCONFIGURATIONREG6_ISNSTX_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE)
+#define TAS2562_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK)
+
+/* TDM Configuration Reg7 */
+#define TAS2562_TDMCONFIGURATIONREG7 (TAS256X_TDMCONFIGURATIONREG7)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATSLEN_MASK \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_MASK)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATSLEN_8BITS \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_8BITS)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATSLEN_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_16BITS)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATTX_MASK \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATTX_MASK)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATTX_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATTX_DISABLE)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATTX_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE)
+#define TAS2562_TDMCONFIGURATIONREG7_VBATSLOT50_MASK \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLOT50_MASK)
+
+/* TDM Configuration Reg8 */
+#define TAS2562_TDMCONFIGURATIONREG8 TAS256X_REG(0x0, 0x0, 0x0E)
+#define TAS2562_TDMCONFIGURATIONREG8_TEMPTX_MASK (0x1 << 6)
+#define TAS2562_TDMCONFIGURATIONREG8_TEMPTX_DISABLE (0x0 << 6)
+#define TAS2562_TDMCONFIGURATIONREG8_TEMPTX_ENABLE (0x1 << 6)
+#define TAS2562_TDMCONFIGURATIONREG8_TEMPSLOT50_MASK (0x3f << 0)
+
+/* TDM Configuration Reg9 */
+#define TAS2562_TDMCONFIGURATIONREG9 TAS256X_REG(0x0, 0x0, 0x0F)
+#define TAS2562_TDMCONFIGURATIONREG9_GAINTX_MASK (0x1 << 6)
+#define TAS2562_TDMCONFIGURATIONREG9_GAINTX_DISABLE (0x0 << 6)
+#define TAS2562_TDMCONFIGURATIONREG9_GAINTX_ENABLE (0x1 << 6)
+#define TAS2562_TDMCONFIGURATIONREG9_GAINSLOT50_MASK (0x3f << 0)
+
+/* Limiter Configuration Reg0 */
+#define TAS2562_LIMITERCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x12)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_MASK (0x3 << 4)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_1 (0x2 << 4)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_2 (0x3 << 4)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_0_25 (0x0 << 4)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKST54_0_5 (0x1 << 4)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_MASK (0x7 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_5 (0x0 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_10 (0x1 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_20 (0x2 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_40 (0x3 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_80 (0x4 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_160 (0x5 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_320 (0x6 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMATKRT31_640 (0x7 << 1)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMEN_MASK (0x1 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMEN_DISABLED (0x0 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG0_LIMEN_ENABLED (0x1 << 0)
+
+/* Limiter Configuration Reg1 */
+#define TAS2562_LIMITERCONFIGURATIONREG1 TAS256X_REG(0x0, 0x0, 0x13)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_MASK (0x3 << 6)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_1 (0x2 << 6)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_2 (0x3 << 6)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_25 (0x0 << 6)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_5 (0x1 << 6)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_MASK (0x7 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_10 (0x0 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_50 (0x1 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_100 (0x2 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_250 (0x3 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_500 (0x4 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_750 (0x5 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1000 (0x6 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1500 (0x7 << 3)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_MASK (0x7 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_0 (0x0 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_10 (0x1 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_25 (0x2 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_50 (0x3 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_100 (0x4 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_250 (0x5 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_500 (0x6 << 0)
+#define TAS2562_LIMITERCONFIGURATIONREG1_LIMHLDTM20_1000 (0x7 << 0)
+
+/* Brown Out Prevention Reg0 */
+#define TAS2562_BROWNOUTPREVENTIONREG0 TAS256X_REG(0x0, 0x0, 0x14)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPSDEN_MASK (0x1 << 4)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPSDEN_DISABLED (0x0 << 4)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPSDEN_ENABLED (0x1 << 4)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPHLDCLR_MASK (0x1 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPHLDCLR_DONTCLEAR (0x0 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPHLDCLR_CLEAR (0x1 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPINFHLD_MASK (0x1 << 2)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPINFHLD_USEHOLDTIME (0x0 << 2)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPINFHLD_HOLDUNTILCLEARED (0x1 << 2)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPMUTE_MASK (0x1 << 1)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPMUTE_DONOTMUTE (0x0 << 1)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPMUTE_MUTE (0x1 << 1)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPEN_MASK (0x1 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPEN_DISABLED (0x0 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG0_BOPEN_ENABLED (0x1 << 0)
+
+/* Brown Out Prevention Reg1 */
+#define TAS2562_BROWNOUTPREVENTIONREG1 TAS256X_REG(0x0, 0x0, 0x15)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_MASK (0x7 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_1 (0x0 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_2 (0x1 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_4 (0x2 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_8 (0x3 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_16 (0x4 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_32 (0x5 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_64 (0x6 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKRT75_128 (0x7 << 5)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_MASK (0x3 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_1 (0x1 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_2 (0x3 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_0_5 (0x0 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPATKST43_1_5 (0x2 << 3)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_MASK (0x7 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_0 (0x0 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_10 (0x1 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_25 (0x2 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_50 (0x3 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_100 (0x4 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_250 (0x5 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_500 (0x6 << 0)
+#define TAS2562_BROWNOUTPREVENTIONREG1_BOPHLDTM20_1000 (0x7 << 0)
+
+/* Interrupt Mask Reg0 */
+#define TAS2562_INTERRUPTMASKREG0 (TAS256X_INTERRUPTMASKREG0)
+#define TAS2562_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_OCEINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_OCEINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_OCEINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_OTEINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG0_OTEINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG0_OTEINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG0_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_DISABLE)
+
+/* Interrupt Mask Reg1 */
+#define TAS2562_INTERRUPTMASKREG1 \
+ (TAS256X_INTERRUPTMASKREG1)
+#define TAS2562_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG1_CRCINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG1_CRCINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG1_CRCINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK)
+#define TAS2562_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK)
+#define TAS2562_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE)
+#define TAS2562_INTERRUPTMASKREG1_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_DISABLE)
+
+/* Interrupt Mask Reg2 */
+#define TAS2562_INTERRUPTMASKREG2 TAS256X_REG(0x0, 0x0, 0x1C)
+#define TAS2562_INTERRUPTMASKREG2_DACLKINTMASK_MASK (0x1 << 7)
+#define TAS2562_INTERRUPTMASKREG2_DACLKINTMASK_UNMASK (0x0 << 7)
+#define TAS2562_INTERRUPTMASKREG2_DACLKINTMASK_DISABLE (0x1 << 7)
+#define TAS2562_INTERRUPTMASKREG2_BSTCLKINTMASK_MASK (0x1 << 6)
+#define TAS2562_INTERRUPTMASKREG2_BSTCLKINTMASK_UNMASK (0x0 << 6)
+#define TAS2562_INTERRUPTMASKREG2_BSTCLKINTMASK_DISABLE (0x1 << 6)
+#define TAS2562_INTERRUPTMASKREG2_VBATPORCLKINTMASK_MASK (0x1 << 5)
+#define TAS2562_INTERRUPTMASKREG2_VBATPORCLKINTMASK_UNMASK (0x0 << 5)
+#define TAS2562_INTERRUPTMASKREG2_VBATPORCLKINTMASK_DISABLE (0x1 << 5)
+#define TAS2562_INTERRUPTMASKREG2_PLLOCKINTMASK_MASK (0x1 << 4)
+#define TAS2562_INTERRUPTMASKREG2_PLLOCKINTMASK_UNMASK (0x0 << 4)
+#define TAS2562_INTERRUPTMASKREG2_PLLOCKINTMASK_DISABLE (0x1 << 4)
+#define TAS2562_INTERRUPTMASKREG2_DCDETECTINTMASK_MASK (0x1 << 3)
+#define TAS2562_INTERRUPTMASKREG2_DCDETECTINTMASK_UNMASK (0x0 << 3)
+#define TAS2562_INTERRUPTMASKREG2_DCDETECTINTMASK_DISABLE (0x1 << 3)
+
+/* Live-Interrupt Reg0 */
+#define TAS2562_LIVEINTERRUPTREG0 TAS256X_REG(0x0, 0x0, 0x1F)
+#define TAS2562_LIVEINTERRUPTREG0_LIMMUTE_MASK (0x1 << 7)
+#define TAS2562_LIVEINTERRUPTREG0_LIMMUTE_NOINTERRUPT (0x0 << 7)
+#define TAS2562_LIVEINTERRUPTREG0_LIMMUTE_INTERRUPT (0x1 << 7)
+#define TAS2562_LIVEINTERRUPTREG0_LIMINFHLD_MASK (0x1 << 6)
+#define TAS2562_LIVEINTERRUPTREG0_LIMINFHLD_NOINTERRUPT (0x0 << 6)
+#define TAS2562_LIVEINTERRUPTREG0_LIMINFHLD_INTERRUPT (0x1 << 6)
+#define TAS2562_LIVEINTERRUPTREG0_LIMMAXATN_MASK (0x1 << 5)
+#define TAS2562_LIVEINTERRUPTREG0_LIMMAXATN_NOINTERRUPT (0x0 << 5)
+#define TAS2562_LIVEINTERRUPTREG0_LIMMAXATN_INTERRUPT (0x1 << 5)
+#define TAS2562_LIVEINTERRUPTREG0_VBATLESSTHANINF_MASK (0x1 << 4)
+#define TAS2562_LIVEINTERRUPTREG0_VBATLESSTHANINF_NOINTERRUPT (0x0 << 4)
+#define TAS2562_LIVEINTERRUPTREG0_VBATLESSTHANINF_INTERRUPT (0x1 << 4)
+#define TAS2562_LIVEINTERRUPTREG0_LIMACTIVEFLAG_MASK (0x1 << 3)
+#define TAS2562_LIVEINTERRUPTREG0_LIMACTIVEFLAG_NOINTERRUPT (0x0 << 3)
+#define TAS2562_LIVEINTERRUPTREG0_LIMACTIVEFLAG_INTERRUPT (0x1 << 3)
+#define TAS2562_LIVEINTERRUPTREG0_TDMCLOCKERROR_MASK (0x1 << 2)
+#define TAS2562_LIVEINTERRUPTREG0_TDMCLOCKERROR_NOINTERRUPT (0x0 << 2)
+#define TAS2562_LIVEINTERRUPTREG0_TDMCLOCKERROR_INTERRUPT (0x1 << 2)
+#define TAS2562_LIVEINTERRUPTREG0_OCEFLAG_MASK (0x1 << 1)
+#define TAS2562_LIVEINTERRUPTREG0_OCEFLAG_NOINTERRUPT (0x0 << 1)
+#define TAS2562_LIVEINTERRUPTREG0_OCEFLAG_INTERRUPT (0x1 << 1)
+#define TAS2562_LIVEINTERRUPTREG0_OTEFLAG_MASK (0x1 << 0)
+#define TAS2562_LIVEINTERRUPTREG0_OTEFLAG_NOINTERRUPT (0x0 << 0)
+#define TAS2562_LIVEINTERRUPTREG0_OTEFLAG_INTERRUPT (0x1 << 0)
+
+/* Live-Interrupt Reg1 */
+#define TAS2562_LIVEINTERRUPTREG1 TAS256X_REG(0x0, 0x0, 0x20)
+#define TAS2562_LIVEINTERRUPTREG1_DSPINTOUTPUT_MASK (0x1 << 7)
+#define TAS2562_LIVEINTERRUPTREG1_DSPINTOUTPUT_NOINTERRUPT (0x0 << 7)
+#define TAS2562_LIVEINTERRUPTREG1_DSPINTOUTPUT_INTERRUPT (0x1 << 7)
+#define TAS2562_LIVEINTERRUPTREG1_OTPCRC_MASK (0x1 << 6)
+#define TAS2562_LIVEINTERRUPTREG1_OTPCRC_NOINTERRUPT (0x0 << 6)
+#define TAS2562_LIVEINTERRUPTREG1_OTPCRC_INTERRUPT (0x1 << 6)
+#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTFLAG_MASK (0x1 << 1)
+#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTFLAG_NOINTERRUPT (0x0 << 1)
+#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTFLAG_INTERRUPT (0x1 << 1)
+#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTDETECTED_MASK (0x1 << 1)
+#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTDETECTED_NOINTERRUPT (0x0 << 1)
+#define TAS2562_LIVEINTERRUPTREG1_BROWNOUTDETECTED_INTERRUPT (0x1 << 1)
+
+/* Latched-Interrupt Reg0 */
+#define TAS2562_LATCHEDINTERRUPTREG0 (TAS256X_LATCHEDINTERRUPTREG0)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT)
+
+/* Latched-Interrupt Reg1 */
+#define TAS2562_LATCHEDINTERRUPTREG1 (TAS256X_LATCHEDINTERRUPTREG1)
+#define TAS2562_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK)
+#define TAS2562_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT)
+#define TAS2562_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT)
+
+/* VBAT MSB */
+#define TAS2562_VBATMSB TAS256X_REG(0x0, 0x0, 0x2A)
+#define TAS2562_VBATMSB_VBATMSB70_MASK (0xff << 0)
+
+/* VBAT LSB */
+#define TAS2562_VBATLSB TAS256X_REG(0x0, 0x0, 0x2B)
+#define TAS2562_VBATLSB_VBATLSB74_MASK (0xf << 4)
+
+/* TEMP */
+#define TAS2562_TEMP TAS256X_REG(0x0, 0x0, 0x2C)
+#define TAS2562_TEMP_TEMPMSB70_MASK (0xff << 0)
+
+
+/* Interrupt Configuration */
+#define TAS2562_INTERRUPTCONFIGURATION (TAS256X_INTERRUPTCONFIGURATION)
+#define TAS2562_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK \
+ (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK)
+#define TAS2562_INTERRUPTCONFIGURATION_LTCHINTCLEAR \
+ (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR)
+#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK)
+#define TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS)
+#define \
+ TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS)
+#define \
+ TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS)
+#define \
+ TAS2562_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS)
+
+/* Digital Input Pin Pull Down */
+#define TAS2562_DIGITALINPUTPINPULLDOWN TAS256X_REG(0x0, 0x0, 0x31)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDOUT_MASK (0x1 << 7)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDOUT_DISABLED (0x0 << 7)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDOUT_ENABLED (0x1 << 7)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDIN_MASK (0x1 << 6)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDIN_DISABLED (0x0 << 6)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSDIN_ENABLED (0x1 << 6)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNFSYNC_MASK (0x1 << 5)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNFSYNC_DISABLED (0x0 << 5)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNFSYNC_ENABLED (0x1 << 5)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSBCLK_MASK (0x1 << 4)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSBCLK_DISABLED (0x0 << 4)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNSBCLK_ENABLED (0x1 << 4)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD0_MASK (0x1 << 3)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD0_DISABLED (0x0 << 3)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD0_ENABLED (0x1 << 3)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD1_MASK (0x1 << 2)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD1_DISABLED (0x0 << 2)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMD1_ENABLED (0x1 << 2)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK0_MASK (0x1 << 1)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK0_DISABLED (0x0 << 1)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK0_ENABLED (0x1 << 1)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK1_MASK (0x1 << 0)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK1_DISABLED (0x0 << 0)
+#define TAS2562_DIGITALINPUTPINPULLDOWN_WKPULLDOWNPDMCK1_ENABLED (0x1 << 0)
+
+/* Misc IRQ */
+#define TAS2562_MISCIRQ TAS256X_REG(0x0, 0x0, 0x32)
+#define TAS2562_MISCIRQ_IRQZREQD_MASK (0x1 << 7)
+#define TAS2562_MISCIRQ_IRQZREQD_ACTIVEHIGH (0x0 << 7)
+#define TAS2562_MISCIRQ_IRQZREQD_ACTIVELOW (0x1 << 7)
+#define TAS2562_MISCIRQ_IRQZBITBANG_MASK (0x1 << 0)
+#define TAS2562_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF0 (0x0 << 0)
+#define TAS2562_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF1 (0x1 << 0)
+
+#define TAS2562_BOOSTCONFIGURATION2 TAS256X_REG(0x0, 0x0, 0x34)
+#define TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK (0x0f << 0)
+#define TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_SHIFT 0
+#define TAS2562_BOOSTCONFIGURATION4 (TAS256X_BOOSTCONFIGURATION4)
+#define TAS2562_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK \
+ (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK)
+#define TAS2562_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT \
+ (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT)
+
+#define TAS2562_BOOSTSLOPE (TAS256X_BOOSTSLOPE)
+#define TAS2562_BOOSTSLOPE_MASK (TAS256X_BOOSTSLOPE_MASK)
+#define TAS2562_BOOSTSLOPE_3AV (0x1 << 2)
+#define TAS2562_BOOSTSLOPE_2AV (0x2 << 2)
+
+/* Clock Configuration */
+#define TAS2562_CLOCKCONFIGURATION (TAS256X_CLOCKCONFIGURATION)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKTOFS52_MASK \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKTOFS52_MASK)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_16 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_16)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_24 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_24)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_32 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_32)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_48 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_48)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_64 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_64)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_96 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_96)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_128 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_128)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_192 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_192)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_256 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_256)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_384 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_384)
+#define TAS2562_CLOCKCONFIGURATION_SBCLKtoFS52_512 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_512)
+#define TAS2562_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK \
+ (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK)
+#define TAS2562_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED \
+ (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED)
+#define TAS2562_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED \
+ (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED)
+
+#define TAS2562_VBATFILTER (TAS256X_VBATFILTER)
+#define TAS2562_CLASSHRELEASETIMER (TAS256X_CLASSHRELEASETIMER)
+
+#define TAS2562_BOOST_CFG4 (TAS256X_BOOST_CFG4)
+#define TAS2562_BOOST_CFG4_PEAK_CURRENT_LIMIT_MASK (0xff << 0)
+
+#define TAS2562_ICN_THRESHOLD_REG (TAS256X_ICN_THRESHOLD_REG)
+#define TAS2562_ICN_HYSTERESIS_REG (TAS256X_ICN_HYSTERESIS_REG)
+
+#define TAS2562_ICN_SW_REG (TAS256X_ICN_SW_REG)
+#define TAS2562_ICN_SW_MASK (TAS256X_ICN_SW_MASK)
+#define TAS2562_ICN_SW_ENABLE (TAS256X_ICN_SW_ENABLE)
+#define TAS2562_ICN_SW_DISABLE (TAS256X_ICN_SW_DISABLE)
+#define TAS2562_TESTPAGECONFIGURATION (TAS256X_TESTPAGECONFIGURATION)
+#define TAS2562_CLASSDCONFIGURATION1 (TAS256X_CLASSDCONFIGURATION1)
+#define TAS2562_CLASSDCONFIGURATION2 (TAS256X_CLASSDCONFIGURATION2)
+#define TAS2562_CLASSDCONFIGURATION3 (TAS256X_CLASSDCONFIGURATION3)
+#define TAS2562_CLASSDCONFIGURATION4 (TAS256X_CLASSDCONFIGURATION4)
+#define TAS2562_EFFICIENCYCONFIGURATION (TAS256X_EFFICIENCYCONFIGURATION)
+
+#define TAS2562_HPF (TAS256X_HPF)
+#define TAS2562_CLASSHHEADROOM (TAS256X_CLASSHHEADROOM)
+#define TAS2562_CLASSHHYSTERESIS (TAS256X_CLASSHHYSTERESIS)
+#define TAS2562_CLASSHMTCT (TAS256X_CLASSHMTCT)
+
+/* Revision and PG ID */
+#define TAS2562_REVISIONANDPGID TAS256X_REG(0x0, 0x0, 0x7D)
+#define TAS2562_REVISIONANDPGID_REVISIONID74_MASK (0xf << 4)
+#define TAS2562_REVISIONANDPGID_PGID30_MASK (0xf << 0)
+
+/* I2C Checksum */
+#define TAS2562_I2CCHECKSUM TAS256X_REG(0x0, 0x0, 0x7E)
+#define TAS2562_I2CCHECKSUM_I2CCHECKSUM70_MASK (0xff << 0)
+
+/* Book */
+#define TAS2562_BOOK (TAS256X_BOOK)
+#define TAS2562_BOOK_BOOK70_MASK (TAS256X_BOOK_BOOK70_MASK)
+#endif /* __TAS2562_ */
diff --git a/asoc/codecs/tas256x/physical_layer/inc/tas2564.h b/asoc/codecs/tas256x/physical_layer/inc/tas2564.h
new file mode 100644
index 00000000..63f1338f
--- /dev/null
+++ b/asoc/codecs/tas256x/physical_layer/inc/tas2564.h
@@ -0,0 +1,735 @@
+#ifndef __TAS2564_
+#define __TAS2564_
+/* Software Reset */
+#define TAS2564_SOFTWARERESET (TAS256X_SOFTWARERESET)
+#define TAS2564_SOFTWARERESET_SOFTWARERESET_MASK \
+ (TAS256X_SOFTWARERESET_SOFTWARERESET_MASK)
+#define TAS2564_SOFTWARERESET_SOFTWARERESET_DONTRESET \
+ (TAS256X_SOFTWARERESET_SOFTWARERESET_DONTRESET)
+#define TAS2564_SOFTWARERESET_SOFTWARERESET_RESET \
+ (TAS256X_SOFTWARERESET_SOFTWARERESET_RESET)
+
+/* Power Control */
+#define TAS2564_POWERCONTROL (TAS256X_POWERCONTROL)
+/* NEW Beging */
+#define TAS2564_POWERCONTROL_VSNS2_PD_MASK (0x1 << 7)
+#define TAS2564_POWERCONTROL_VSNS2_PD_ACTIVE (0x0 << 7)
+#define TAS2564_POWERCONTROL_VSNS2_PD_POWEREDDOWN (0x1 << 7)
+/* NEW End */
+#define TAS2564_POWERCONTROL_ISNSPOWER_MASK \
+ (TAS256X_POWERCONTROL_ISNSPOWER_MASK)
+#define TAS2564_POWERCONTROL_ISNSPOWER_ACTIVE \
+ (TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE)
+#define TAS2564_POWERCONTROL_ISNSPOWER_POWEREDDOWN \
+ (TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN)
+#define TAS2564_POWERCONTROL_VSNSPOWER_MASK \
+ (TAS256X_POWERCONTROL_VSNSPOWER_MASK)
+#define TAS2564_POWERCONTROL_VSNSPOWER_ACTIVE \
+ (TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE)
+#define TAS2564_POWERCONTROL_VSNSPOWER_POWEREDDOWN \
+ (TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN)
+#define TAS2564_POWERCONTROL_OPERATIONALMODE10_MASK \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK)
+#define TAS2564_POWERCONTROL_OPERATIONALMODE10_ACTIVE \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE)
+#define TAS2564_POWERCONTROL_OPERATIONALMODE10_MUTE \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE)
+#define TAS2564_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN \
+ (TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN)
+
+
+/* Playback Configuration Reg0 */
+#define TAS2564_PLAYBACKCONFIGURATIONREG0 \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0)
+#define TAS2564_PLAYBACKCONFIGURATION_AMP_LEVEL_MASK (0x1F << 1)
+#define TAS2564_AMP_LEVEL_16dBV (0x0D << 1)
+
+/* NEW Begin */
+#define TAS2564_PLAYBACKCONFIGURATIONREG_RX_SPKR_MODE_MASK \
+ (0x1 << 7)
+#define TAS2564_PLAYBACKCONFIGURATIONREG_SPKR_MODE \
+ (0x0 << 7)
+#define TAS2564_PLAYBACKCONFIGURATIONREG_RX_MODE \
+ (0x1 << 7)
+/* NEW End */
+#define TAS2564_BOOSTCONFIGURATION2 TAS256X_REG(0x0, 0x0, 0x48)
+#define TAS2564_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK (0x1f << 3)
+#define TAS2564_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK_SHIFT 3
+#define TAS2564_BOOSTCONFIGURATION4 (TAS256X_BOOSTCONFIGURATION4)
+#define TAS2564_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK \
+ (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK)
+#define TAS2564_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT \
+ (TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT)
+
+#define TAS2564_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK)
+#define TAS2564_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED)
+#define TAS2564_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED \
+ (TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED)
+#define TAS2564_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK (0x1f << 1)
+#define TAS2564_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_SHIFT (1)
+
+/* Misc Configuration Reg0 */
+#define TAS2564_MISCCONFIGURATIONREG0 (TAS256X_MISCCONFIGURATIONREG0)
+#define TAS2564_MISCCONFIGURATIONREG0_CPPGRETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_MASK)
+#define TAS2564_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK)
+#define TAS2564_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_OCERETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_MASK)
+#define TAS2564_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_OCERETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OCERETRY_RETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_OTERETRY_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_MASK)
+#define TAS2564_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_OTERETRY_RETRY \
+ (TAS256X_MISCCONFIGURATIONREG0_OTERETRY_RETRY)
+#define TAS2564_MISCCONFIGURATIONREG0_IRQZPULL_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_MASK)
+#define TAS2564_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED)
+#define TAS2564_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED)
+#define TAS2564_MISCCONFIGURATIONREG0_AMPSS_MASK \
+ (TAS256X_MISCCONFIGURATIONREG0_AMPSS_MASK)
+#define TAS2564_MISCCONFIGURATIONREG0_AMPSS_DISABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_AMPSS_DISABLED)
+#define TAS2564_MISCCONFIGURATIONREG0_AMPSS_ENABLED \
+ (TAS256X_MISCCONFIGURATIONREG0_AMPSS_ENABLED)
+
+/* TDM Configuration Reg0 */
+#define TAS2564_TDMCONFIGURATIONREG0 (TAS256X_TDMCONFIGURATIONREG0)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ)
+#define TAS2564_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK)
+#define TAS2564_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED \
+ (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED)
+#define TAS2564_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED \
+ (TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ)
+#define TAS2564_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ \
+ (TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ)
+#define TAS2564_TDMCONFIGURATIONREG0_FRAMESTART_MASK \
+ (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK)
+#define TAS2564_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH \
+ (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH)
+#define TAS2564_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW \
+ (TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW)
+
+/* TDM Configuration Reg1 */
+#define TAS2564_TDMCONFIGURATIONREG1 (TAS256X_TDMCONFIGURATIONREG1)
+#define TAS2564_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK \
+ (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK)
+#define TAS2564_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT \
+ (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT)
+#define TAS2564_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT \
+ (TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT)
+#define TAS2564_TDMCONFIGURATIONREG1_RXOFFSET51_MASK \
+ (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK)
+#define TAS2564_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT \
+ (TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT)
+#define TAS2564_TDMCONFIGURATIONREG1_RXEDGE_MASK \
+ (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK)
+#define TAS2564_TDMCONFIGURATIONREG1_RXEDGE_RISING \
+ (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING)
+#define TAS2564_TDMCONFIGURATIONREG1_RXEDGE_FALLING \
+ (TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING)
+
+/* TDM Configuration Reg2 */
+#define TAS2564_TDMCONFIGURATIONREG2 (TAS256X_TDMCONFIGURATIONREG2)
+#define TAS2564_TDMCONFIGURATIONREG2_IVLEN76_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK)
+#define TAS2564_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK)
+#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX)
+#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK)
+#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_20BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_20BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_24BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXWLEN32_32BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_MASK \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_24BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS)
+#define TAS2564_TDMCONFIGURATIONREG2_RXSLEN10_32BITS \
+ (TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS)
+
+/* TDM Configuration Reg3 */
+#define TAS2564_TDMCONFIGURATIONREG3 (TAS256X_TDMCONFIGURATIONREG3)
+#define TAS2564_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK \
+ (TAS256X_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK)
+#define TAS2564_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask \
+ (TAS256X_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask)
+
+/* TDM Configuration Reg4 */
+#define TAS2564_TDMConfigurationReg4 (TAS256X_TDMConfigurationReg4)
+#define TAS2564_TDMCONFIGURATIONREG4_TXKEEPER_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_MASK)
+#define TAS2564_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE)
+#define TAS2564_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE)
+#define TAS2564_TDMCONFIGURATIONREG4_TXFILL_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXFILL_MASK)
+#define TAS2564_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0 \
+ (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0)
+#define TAS2564_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ \
+ (TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ)
+#define TAS2564_TDMCONFIGURATIONREG4_TXOFFSET31_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK)
+#define TAS2564_TDMCONFIGURATIONREG4_TXEDGE_MASK \
+ (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK)
+#define TAS2564_TDMCONFIGURATIONREG4_TXEDGE_RISING \
+ (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_RISING)
+#define TAS2564_TDMCONFIGURATIONREG4_TXEDGE_FALLING \
+ (TAS256X_TDMCONFIGURATIONREG4_TXEDGE_FALLING)
+
+/* TDM Configuration Reg5 */
+#define TAS2564_TDMCONFIGURATIONREG5 (TAS256X_TDMCONFIGURATIONREG5)
+#define TAS2564_TDMCONFIGURATIONREG5_VSNSTX_MASK \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_MASK)
+#define TAS2564_TDMCONFIGURATIONREG5_VSNSTX_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_DISABLE)
+#define TAS2564_TDMCONFIGURATIONREG5_VSNSTX_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE)
+#define TAS2564_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK \
+ (TAS256X_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK)
+
+/* TDM Configuration Reg6 */
+#define TAS2564_TDMCONFIGURATIONREG6 (TAS256X_TDMCONFIGURATIONREG6)
+#define TAS2564_TDMCONFIGURATIONREG6_ISNSTX_MASK \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_MASK)
+#define TAS2564_TDMCONFIGURATIONREG6_ISNSTX_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_DISABLE)
+#define TAS2564_TDMCONFIGURATIONREG6_ISNSTX_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE)
+#define TAS2564_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK \
+ (TAS256X_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK)
+
+/* TDM Configuration Reg7 */
+#define TAS2564_TDMCONFIGURATIONREG7 (TAS256X_TDMCONFIGURATIONREG7)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATSLEN_MASK \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_MASK)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATSLEN_8BITS \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_8BITS)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATSLEN_16BITS \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_16BITS)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATTX_MASK \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATTX_MASK)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATTX_DISABLE \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATTX_DISABLE)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATTX_ENABLE \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE)
+#define TAS2564_TDMCONFIGURATIONREG7_VBATSLOT50_MASK \
+ (TAS256X_TDMCONFIGURATIONREG7_VBATSLOT50_MASK)
+
+/* TDM Configuration Reg8 */
+#define TAS2564_TDMCONFIGURATIONREG8 TAS256X_REG(0x0, 0x0, 0x0E)
+#define TAS2564_TDMCONFIGURATIONREG8_TEMPTX_MASK (0x1 << 6)
+#define TAS2564_TDMCONFIGURATIONREG8_TEMPTX_DISABLE (0x0 << 6)
+#define TAS2564_TDMCONFIGURATIONREG8_TEMPTX_ENABLE (0x1 << 6)
+#define TAS2564_TDMCONFIGURATIONREG8_TEMPSLOT50_MASK (0x3f << 0)
+
+/* TDM Configuration Reg9 */
+#define TAS2564_TDMCONFIGURATIONREG9 TAS256X_REG(0x0, 0x0, 0x0F)
+#define TAS2564_TDMCONFIGURATIONREG9_GAINTX_MASK (0x1 << 6)
+#define TAS2564_TDMCONFIGURATIONREG9_GAINTX_DISABLE (0x0 << 6)
+#define TAS2564_TDMCONFIGURATIONREG9_GAINTX_ENABLE (0x1 << 6)
+#define TAS2564_TDMCONFIGURATIONREG9_GAINSLOT50_MASK (0x3f << 0)
+
+/* Limiter Configuration Reg0 */
+#define TAS2564_LIMITERCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x12)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_MASK (0x3 << 4)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_1 (0x2 << 4)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_2 (0x3 << 4)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_0_25 (0x0 << 4)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKST54_0_5 (0x1 << 4)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_MASK (0x7 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_5 (0x0 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_10 (0x1 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_20 (0x2 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_40 (0x3 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_80 (0x4 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_160 (0x5 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_320 (0x6 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMATKRT31_640 (0x7 << 1)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMEN_MASK (0x1 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMEN_DISABLED (0x0 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG0_LIMEN_ENABLED (0x1 << 0)
+
+/* Limiter Configuration Reg1 */
+#define TAS2564_LIMITERCONFIGURATIONREG1 TAS256X_REG(0x0, 0x0, 0x13)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_MASK (0x3 << 6)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_1 (0x2 << 6)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_2 (0x3 << 6)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_25 (0x0 << 6)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSST76_0_5 (0x1 << 6)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_MASK (0x7 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_10 (0x0 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_50 (0x1 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_100 (0x2 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_250 (0x3 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_500 (0x4 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_750 (0x5 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1000 (0x6 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMRLSRT53_1500 (0x7 << 3)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_MASK (0x7 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_0 (0x0 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_10 (0x1 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_25 (0x2 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_50 (0x3 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_100 (0x4 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_250 (0x5 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_500 (0x6 << 0)
+#define TAS2564_LIMITERCONFIGURATIONREG1_LIMHLDTM20_1000 (0x7 << 0)
+
+/* Brown Out Prevention Reg0 */
+#define TAS2564_BROWNOUTPREVENTIONREG0 TAS256X_REG(0x0, 0x0, 0x14)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPSDEN_MASK (0x1 << 4)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPSDEN_DISABLED (0x0 << 4)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPSDEN_ENABLED (0x1 << 4)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPHLDCLR_MASK (0x1 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPHLDCLR_DONTCLEAR (0x0 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPHLDCLR_CLEAR (0x1 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPINFHLD_MASK (0x1 << 2)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPINFHLD_USEHOLDTIME (0x0 << 2)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPINFHLD_HOLDUNTILCLEARED (0x1 << 2)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPMUTE_MASK (0x1 << 1)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPMUTE_DONOTMUTE (0x0 << 1)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPMUTE_MUTE (0x1 << 1)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPEN_MASK (0x1 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPEN_DISABLED (0x0 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG0_BOPEN_ENABLED (0x1 << 0)
+
+/* Brown Out Prevention Reg1 */
+#define TAS2564_BROWNOUTPREVENTIONREG1 TAS256X_REG(0x0, 0x0, 0x15)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_MASK (0x7 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_1 (0x0 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_2 (0x1 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_4 (0x2 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_8 (0x3 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_16 (0x4 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_32 (0x5 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_64 (0x6 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKRT75_128 (0x7 << 5)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_MASK (0x3 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_1 (0x1 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_2 (0x3 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_0_5 (0x0 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPATKST43_1_5 (0x2 << 3)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_MASK (0x7 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_0 (0x0 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_10 (0x1 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_25 (0x2 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_50 (0x3 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_100 (0x4 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_250 (0x5 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_500 (0x6 << 0)
+#define TAS2564_BROWNOUTPREVENTIONREG1_BOPHLDTM20_1000 (0x7 << 0)
+
+/* Interrupt Mask Reg0 */
+#define TAS2564_INTERRUPTMASKREG0 (TAS256X_INTERRUPTMASKREG0)
+#define TAS2564_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_OCEINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_OCEINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_OCEINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_OCEINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_OTEINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG0_OTEINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG0_OTEINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_OTEINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG0_DISABLE \
+ (TAS256X_INTERRUPTMASKREG0_DISABLE)
+
+/* Interrupt Mask Reg1 */
+#define TAS2564_INTERRUPTMASKREG1 \
+ (TAS256X_INTERRUPTMASKREG1)
+#define TAS2564_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG1_CRCINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG1_CRCINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG1_CRCINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_CRCINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK \
+ (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK)
+#define TAS2564_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK \
+ (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK)
+#define TAS2564_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE)
+#define TAS2564_INTERRUPTMASKREG1_DISABLE \
+ (TAS256X_INTERRUPTMASKREG1_DISABLE)
+
+/* Interrupt Mask Reg2 */
+#define TAS2564_INTERRUPTMASKREG2 TAS256X_REG(0x0, 0x0, 0x1C)
+#define TAS2564_INTERRUPTMASKREG2_DACLKINTMASK_MASK (0x1 << 7)
+#define TAS2564_INTERRUPTMASKREG2_DACLKINTMASK_UNMASK (0x0 << 7)
+#define TAS2564_INTERRUPTMASKREG2_DACLKINTMASK_DISABLE (0x1 << 7)
+#define TAS2564_INTERRUPTMASKREG2_BSTCLKINTMASK_MASK (0x1 << 6)
+#define TAS2564_INTERRUPTMASKREG2_BSTCLKINTMASK_UNMASK (0x0 << 6)
+#define TAS2564_INTERRUPTMASKREG2_BSTCLKINTMASK_DISABLE (0x1 << 6)
+#define TAS2564_INTERRUPTMASKREG2_VBATPORCLKINTMASK_MASK (0x1 << 5)
+#define TAS2564_INTERRUPTMASKREG2_VBATPORCLKINTMASK_UNMASK (0x0 << 5)
+#define TAS2564_INTERRUPTMASKREG2_VBATPORCLKINTMASK_DISABLE (0x1 << 5)
+#define TAS2564_INTERRUPTMASKREG2_PLLOCKINTMASK_MASK (0x1 << 4)
+#define TAS2564_INTERRUPTMASKREG2_PLLOCKINTMASK_UNMASK (0x0 << 4)
+#define TAS2564_INTERRUPTMASKREG2_PLLOCKINTMASK_DISABLE (0x1 << 4)
+#define TAS2564_INTERRUPTMASKREG2_DCDETECTINTMASK_MASK (0x1 << 3)
+#define TAS2564_INTERRUPTMASKREG2_DCDETECTINTMASK_UNMASK (0x0 << 3)
+#define TAS2564_INTERRUPTMASKREG2_DCDETECTINTMASK_DISABLE (0x1 << 3)
+
+/* NEW Begin */
+/* Interrupt Mask Reg4 */
+#define TAS2564_INTERRUPTMASKREG4 TAS256X_REG(0x0, 0x0, 0x1E)
+#define TAS2564_INTERRUPTMASKREG4_DSP_DC_DETECT_FLAG_MASK (0x1 << 7)
+#define TAS2564_INTERRUPTMASKREG4_DSP_DC_DETECT_FLAG_UNMASK (0x0 << 7)
+#define TAS2564_INTERRUPTMASKREG4_DSP_DC_DETECT_FLAG_DISABLE (0x1 << 7)
+/* NEW End */
+
+/* Latched-Interrupt Reg0 */
+#define TAS2564_LATCHEDINTERRUPTREG0 (TAS256X_LATCHEDINTERRUPTREG0)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT)
+
+/* Latched-Interrupt Reg1 */
+#define TAS2564_LATCHEDINTERRUPTREG1 (TAS256X_LATCHEDINTERRUPTREG1)
+#define TAS2564_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK)
+#define TAS2564_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT)
+#define TAS2564_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT \
+ (TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT)
+
+/* NEW Begin */
+/* Latched-Interrupt Reg4 */
+#define TAS2564_LATCHEDINTERRUPTREG4 TAS256X_REG(0x0, 0x0, 0x28)
+#define TAS2564_LATCHEDINTERRUPTREG4_DSP_DC_DETECT_FLAG_MASK (0x1 << 7)
+#define TAS2564_LATCHEDINTERRUPTREG4_DSP_DC_DETECT_FLAG_UNMASK (0x0 << 7)
+#define TAS2564_LATCHEDINTERRUPTREG4_DSP_DC_DETECT_FLAG_DISABLE (0x1 << 7)
+/* NEW End */
+
+/* VBAT MSB */
+#define TAS2564_VBATMSB TAS256X_REG(0x0, 0x0, 0x2A)
+#define TAS2564_VBATMSB_VBATMSB70_MASK (0xff << 0)
+
+/* VBAT LSB */
+#define TAS2564_VBATLSB TAS256X_REG(0x0, 0x0, 0x2B)
+#define TAS2564_VBATLSB_VBATLSB74_MASK (0xf << 4)
+
+/* TEMP */
+#define TAS2564_TEMP TAS256X_REG(0x0, 0x0, 0x2C)
+#define TAS2564_TEMP_TEMPMSB70_MASK (0xff << 0)
+
+
+/* Interrupt Configuration */
+#define TAS2564_INTERRUPTCONFIGURATION (TAS256X_INTERRUPTCONFIGURATION)
+#define TAS2564_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK \
+ (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK)
+#define TAS2564_INTERRUPTCONFIGURATION_LTCHINTCLEAR \
+ (TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR)
+#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK)
+#define TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS)
+#define \
+ TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS)
+#define \
+ TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS)
+#define \
+ TAS2564_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS \
+ (TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS)
+
+/* Digital Input Pin Pull Down */
+/* NEW Begin */
+#define TAS2564_DIGITALINPUTPINPULLDOWN TAS256X_REG(0x0, 0x0, 0x31)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD1_MASK (0x1 << 5)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD1_DISABLED (0x0 << 5)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD1_ENABLED (0x1 << 5)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD0_MASK (0x1 << 4)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD0_DISABLED (0x0 << 4)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_AD0_ENABLED (0x1 << 4)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDOUT_MASK (0x1 << 3)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDOUT_DISABLED (0x0 << 3)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDOUT_ENABLED (0x1 << 3)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDIN_MASK (0x1 << 2)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDIN_DISABLED (0x0 << 2)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SDIN_ENABLED (0x1 << 2)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_FSYNC_MASK (0x1 << 1)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_FSYNC_DISABLED (0x0 << 1)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_FSYNC_ENABLED (0x1 << 1)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SBCLK_MASK (0x1 << 0)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SBCLK_DISABLED (0x0 << 0)
+#define TAS2564_DIGITALINPUTPINPULLDOWN_WKPULLDOWN_SBCLK_ENABLED (0x1 << 0)
+/* NEW End */
+
+/* Misc IRQ */
+#define TAS2564_MISCIRQ TAS256X_REG(0x0, 0x0, 0x32)
+#define TAS2564_MISCIRQ_IRQZREQD_MASK (0x1 << 7)
+#define TAS2564_MISCIRQ_IRQZREQD_ACTIVEHIGH (0x0 << 7)
+#define TAS2564_MISCIRQ_IRQZREQD_ACTIVELOW (0x1 << 7)
+#define TAS2564_MISCIRQ_IRQZBITBANG_MASK (0x1 << 0)
+#define TAS2564_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF0 (0x0 << 0)
+#define TAS2564_MISCIRQ_IRQZBITBANG_IRQZINPUTBUF1 (0x1 << 0)
+
+#define TAS2564_BOOSTSLOPE (TAS256X_BOOSTSLOPE)
+#define TAS2564_BOOSTSLOPE_MASK (TAS256X_BOOSTSLOPE_MASK)
+#define TAS2564_BOOSTSLOPE_3DOT67AV (0x1 << 2)
+#define TAS2564_BOOSTSLOPE_2DOT93AV (0x2 << 2)
+
+/* Clock Configuration */
+#define TAS2564_CLOCKCONFIGURATION (TAS256X_CLOCKCONFIGURATION)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKTOFS52_MASK \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKTOFS52_MASK)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_16 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_16)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_24 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_24)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_32 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_32)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_48 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_48)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_64 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_64)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_96 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_96)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_128 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_128)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_192 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_192)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_256 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_256)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_384 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_384)
+#define TAS2564_CLOCKCONFIGURATION_SBCLKtoFS52_512 \
+ (TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_512)
+#define TAS2564_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK \
+ (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK)
+#define TAS2564_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED \
+ (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED)
+#define TAS2564_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED \
+ (TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED)
+
+#define TAS2564_VBATFILTER (TAS256X_VBATFILTER)
+#define TAS2564_CLASSHRELEASETIMER (TAS256X_CLASSHRELEASETIMER)
+
+#define TAS2564_BOOST_CFG4 (TAS256X_BOOST_CFG4)
+#define TAS2564_BOOST_CFG4_PEAK_CURRENT_LIMIT_MASK (0x3f << 0)
+
+#define TAS2564_BOOST_CFG5 TAS256X_REG(0x0, 0x0, 0x48)
+#define TAS2564_BOOST_CFG5_BOOSTMAXVOLTAGE_MASK (0x1f << 3)
+#define TAS2564_BOOST_CFG5_BOOSTMAXVOLTAGE_6V (0x7 << 3)
+
+#define TAS2564_ICN_THRESHOLD_REG (TAS256X_ICN_THRESHOLD_REG)
+#define TAS2564_ICN_HYSTERESIS_REG (TAS256X_ICN_HYSTERESIS_REG)
+
+#define TAS2564_ICN_SW_REG (TAS256X_ICN_SW_REG)
+#define TAS2564_ICN_SW_MASK (TAS256X_ICN_SW_MASK)
+#define TAS2564_ICN_SW_ENABLE (TAS256X_ICN_SW_ENABLE)
+#define TAS2564_ICN_SW_DISABLE (TAS256X_ICN_SW_DISABLE)
+#define TAS2564_TESTPAGECONFIGURATION (TAS256X_TESTPAGECONFIGURATION)
+#define TAS2564_CLASSDCONFIGURATION1 (TAS256X_CLASSDCONFIGURATION1)
+#define TAS2564_CLASSDCONFIGURATION2 (TAS256X_CLASSDCONFIGURATION2)
+#define TAS2564_CLASSDCONFIGURATION3 (TAS256X_CLASSDCONFIGURATION3)
+#define TAS2564_CLASSDCONFIGURATION4 (TAS256X_CLASSDCONFIGURATION4)
+#define TAS2564_EFFICIENCYCONFIGURATION (TAS256X_EFFICIENCYCONFIGURATION)
+
+#define TAS2564_HPF (TAS256X_HPF)
+#define TAS2564_CLASSHHEADROOM (TAS256X_CLASSHHEADROOM)
+#define TAS2564_CLASSHHYSTERESIS (TAS256X_CLASSHHYSTERESIS)
+#define TAS2564_CLASSHMTCT (TAS256X_CLASSHMTCT)
+
+#define TAS2564_CLASSH_SLOPE TAS256X_REG(0x0, 0x0, 0x4a)
+
+/* Revision and PG ID */
+#define TAS2564_REVISIONANDPGID TAS256X_REG(0x0, 0x0, 0x7D)
+#define TAS2564_REVISIONANDPGID_REVISIONID74_MASK (0xf << 4)
+#define TAS2564_REVISIONANDPGID_PGID30_MASK (0xf << 0)
+
+/* I2C Checksum */
+#define TAS2564_I2CCHECKSUM TAS256X_REG(0x0, 0x0, 0x7E)
+#define TAS2564_I2CCHECKSUM_I2CCHECKSUM70_MASK (0xff << 0)
+
+/* Book */
+#define TAS2564_BOOK (TAS256X_BOOK)
+#define TAS2564_BOOK_BOOK70_MASK (TAS256X_BOOK_BOOK70_MASK)
+#endif /* __TAS2564_ */
diff --git a/asoc/codecs/tas256x/physical_layer/inc/tas256x-device.h b/asoc/codecs/tas256x/physical_layer/inc/tas256x-device.h
new file mode 100644
index 00000000..90687b5b
--- /dev/null
+++ b/asoc/codecs/tas256x/physical_layer/inc/tas256x-device.h
@@ -0,0 +1,203 @@
+#ifndef __TAS256X_DEVICE_
+#define __TAS256X_DEVICE_
+
+#include "tas256x.h"
+#include <stdbool.h>
+#define DEVICE_TAS2558 0x2558
+#define DEVICE_TAS2562 0x2562
+#define DEVICE_TAS2564 0x2564
+
+#define DVC_PCM 0x1
+#define LIM_MAX_ATN 0x2
+#define LIMB_TH_MAX 0x3
+#define LIMB_TH_MIN 0x4
+#define LIMB_INF_PT 0x5
+#define LIMB_SLOPE 0x6
+#define BOP_TH 0x7
+#define BOSD_TH 0x8
+#define LIMB_ATK_RT 0x9
+#define LIMB_RLS_RT 0xA
+#define LIMB_ATK_ST 0xB
+#define LIMB_RLS_ST 0xC
+#define BOP_ATK_RT 0xD
+#define BOP_ATK_ST 0xE
+#define BOP_HLD_TM 0xF
+#define BST_VREG 0x10
+#define BST_ILIM 0x11
+#define CLASSH_TIMER 0x12
+#define AMPOUTPUT_LVL 0x13
+
+#define TX_SLOT0 0
+#define TX_SLOT1 1
+#define TX_SLOT2 2
+#define TX_SLOT3 3
+#define TX_SLOT4 4
+#define TX_SLOT5 5
+#define TX_SLOT6 6
+#define TX_SLOT7 7
+#define TX_SLOT8 8
+#define TX_SLOT9 9
+#define TX_SLOTa 0xa
+#define TX_SLOTb 0xb
+#define TX_SLOTc 0xc
+#define TX_SLOTd 0xd
+#define TX_SLOTe 0xe
+#define TX_SLOTf 0xf
+
+int tas56x_software_reset(struct tas256x_priv *p_tas256x, int ch);
+
+int tas56x_get_chipid(struct tas256x_priv *p_tas256x, int *chipid, int ch);
+
+/* Power Up related functions */
+int tas256x_set_power_up(struct tas256x_priv *p_tas256x,
+ enum channel chn);
+
+int tas256x_set_power_mute(struct tas256x_priv *p_tas256x,
+ enum channel chn);
+
+int tas256x_set_power_shutdown(struct tas256x_priv *p_tas256x,
+ enum channel chn);
+
+int tas256x_power_check(struct tas256x_priv *p_tas256x, int *state,
+ int ch);
+
+/* IV Sense Format Related functions */
+int tas256x_iv_sense_enable_set(struct tas256x_priv *p_tas256x,
+ bool enable, int ch);
+
+bool tas256x_iv_sense_enable_get(struct tas256x_priv *p_tas256x, int ch);
+
+int tas256x_set_iv_slot(struct tas256x_priv *p_tas256x, int ch, int vslot, int islot);
+
+int tas256x_set_vbat_slot(struct tas256x_priv *p_tas256x, int ch, int slot);
+
+int tas256x_iv_bitwidth_config(struct tas256x_priv *p_tas256x, int bitwidth, int ch);
+
+int tas256x_tx_set_edge(struct tas256x_priv *p_tas256x,
+ unsigned int tx_edge, int ch);
+
+int tas256x_tx_set_start_slot(struct tas256x_priv *p_tas256x,
+ unsigned int tx_start_slot, int ch);
+
+int tas256x_set_tx_config(struct tas256x_priv *p_tas256x, int value, int ch);
+
+/* Rx Format Related functions */
+int tas256x_set_samplerate(struct tas256x_priv *p_tas256x,
+ int samplerate, int ch);
+
+int tas256x_rx_set_edge(struct tas256x_priv *p_tas256x,
+ unsigned int rx_edge, int ch);
+
+int tas256x_rx_set_start_slot(struct tas256x_priv *p_tas256x,
+ unsigned int rx_start_slot, int ch);
+
+int tas256x_rx_set_slot_len(struct tas256x_priv *p_tas256x,
+ int slot_width, int ch);
+
+int tas256x_rx_set_slot(struct tas256x_priv *p_tas256x,
+ int slot, int ch);
+
+int tas256x_rx_set_bitwidth(struct tas256x_priv *p_tas256x,
+ int bitwidth, int ch);
+
+/* Interrupt Related Functions */
+int tas256x_interrupt_clear(struct tas256x_priv *p_tas256x, int ch);
+
+int tas256x_interrupt_enable(struct tas256x_priv *p_tas256x,
+ int val, int ch);
+
+int tas256x_interrupt_read(struct tas256x_priv *p_tas256x,
+ int *intr1, int *intr2, int ch);
+
+int tas256x_interrupt_determine(struct tas256x_priv *p_tas256x, int ch,
+ int int1status, int int2status);
+
+/* ICN Related Functions */
+int tas256x_icn_disable(struct tas256x_priv *p_tas256x,
+ int disable, int ch);
+
+int tas256x_icn_data(struct tas256x_priv *p_tas256x, int ch);
+
+int tas256x_icn_config(struct tas256x_priv *p_tas256x, int value, int ch);
+
+/* Boost/Volt Related functions */
+int tas256x_boost_volt_update(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+
+int tas256x_set_misc_config(struct tas256x_priv *p_tas256x, int value, int ch);
+
+/* Clock Configuration */
+int tas256x_set_clock_config(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+
+/* ClassH Configuration*/
+int tas256x_set_classH_config(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+
+/* HPF Related functions*/
+int tas256x_HPF_FF_Bypass(struct tas256x_priv *p_tas256x, int value, int ch);
+
+int tas256x_HPF_FB_Bypass(struct tas256x_priv *p_tas256x, int value, int ch);
+
+/*Speaker Receiever mode - specific to TAS2564*/
+int tas2564_rx_mode_update(struct tas256x_priv *p_tas256x,
+ int rx_mode, int ch);
+
+/*Playback Volume*/
+int tas256x_update_playback_volume(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+
+/*Feature Control Functions*/
+int tas256x_update_lim_max_attenuation(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_lim_max_thr(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_lim_min_thr(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_lim_inflection_point(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_lim_slope(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_bop_thr(struct tas256x_priv *p_tas256x, int value, int ch);
+int tas256x_update_bosd_thr(struct tas256x_priv *p_tas256x, int value, int ch);
+int tas256x_update_boost_voltage(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_current_limit(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_limiter_enable(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_limiter_attack_rate(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_limiter_attack_step_size(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_limiter_release_rate(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_limiter_release_step_size(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_bop_enable(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_bop_mute(struct tas256x_priv *p_tas256x, int value, int ch);
+int tas256x_update_bop_shutdown_enable(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_bop_attack_rate(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_bop_attack_step_size(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_bop_hold_time(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_update_vbat_lpf(struct tas256x_priv *p_tas256x, int value, int ch);
+int tas256x_update_rx_cfg(struct tas256x_priv *p_tas256x, int value, int ch);
+int tas256x_rx_set_frame_start(struct tas256x_priv *p_tas256x,
+ unsigned int frame_start, int ch);
+int tas256x_update_classh_timer(struct tas256x_priv *p_tas256x, int value, int ch);
+int tas256x_set_auto_detect_clock(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+int tas256x_enable_reciever_mode(struct tas256x_priv *p_tas256x, int enable,
+ int ch);
+int tas256x_update_ampoutput_level(struct tas256x_priv *p_tas256x,
+ int value, int ch);
+
+/*Initialize to defaults*/
+int tas256x_update_default_params(struct tas256x_priv *p_tas256x, int ch);
+
+#endif /* __TAS256X_DEVICE_ */ \ No newline at end of file
diff --git a/asoc/codecs/tas256x/physical_layer/inc/tas256x.h b/asoc/codecs/tas256x/physical_layer/inc/tas256x.h
new file mode 100644
index 00000000..4e1677cb
--- /dev/null
+++ b/asoc/codecs/tas256x/physical_layer/inc/tas256x.h
@@ -0,0 +1,693 @@
+#ifndef __TAS256X_
+#define __TAS256X_
+
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/hrtimer.h>
+#include <linux/printk.h>
+#include <linux/delay.h>
+#include <sound/soc.h>
+#include <linux/version.h>
+
+#define TAS256X_DRIVER_TAG "TAS256X_REL_010306"
+
+/* Page Control Register */
+#define TAS256X_PAGECTL_REG 0
+
+/* Book Control Register (available in page0 of each book) */
+#define TAS256X_BOOKCTL_PAGE 0
+#define TAS256X_BOOKCTL_REG 127
+
+#define TAS256X_REG(book, page, reg) (((book * 256 * 128) + \
+ (page * 128)) + reg)
+
+#define TAS256X_BOOK_ID(reg) (reg / (256 * 128))
+
+#define TAS256X_PAGE_ID(reg) ((reg % (256 * 128)) / 128)
+
+#define TAS256X_BOOK_REG(reg) (reg % (256 * 128))
+
+#define TAS256X_PAGE_REG(reg) ((reg % (256 * 128)) % 128)
+
+/* Software Reset */
+#define TAS256X_SOFTWARERESET TAS256X_REG(0x0, 0x0, 0x01)
+#define TAS256X_SOFTWARERESET_SOFTWARERESET_MASK (0x1 << 0)
+#define TAS256X_SOFTWARERESET_SOFTWARERESET_DONTRESET (0x0 << 0)
+#define TAS256X_SOFTWARERESET_SOFTWARERESET_RESET (0x1 << 0)
+
+/* Power Control */
+#define TAS256X_POWERCONTROL TAS256X_REG(0x0, 0x0, 0x02)
+#define TAS256X_POWERCONTROL_ISNSPOWER_MASK (0x1 << 3)
+#define TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE (0x0 << 3)
+#define TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN (0x1 << 3)
+#define TAS256X_POWERCONTROL_VSNSPOWER_MASK (0x1 << 2)
+#define TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE (0x0 << 2)
+#define TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN (0x1 << 2)
+#define TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK (0x3 << 0)
+#define TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE (0x0 << 0)
+#define TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE (0x1 << 0)
+#define TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN (0x2 << 0)
+
+/* Playback Configuration Reg0 */
+#define TAS256X_PLAYBACKCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x03)
+#define TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK (0x1 << 6)
+#define TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_ENABLED (0x0 << 6)
+#define TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED (0x1 << 6)
+
+/* Misc Configuration Reg0 */
+#define TAS256X_MISCCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x04)
+#define TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_MASK (0x1 << 7)
+#define TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_DONOTRETRY (0x0 << 7)
+#define TAS256X_MISCCONFIGURATIONREG0_CPPGRETRY_RETRY (0x1 << 7)
+#define TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_MASK (0x1 << 6)
+#define TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_DONOTRETRY (0x0 << 6)
+#define TAS256X_MISCCONFIGURATIONREG0_VBATPRORETRY_RETRY (0x1 << 6)
+#define TAS256X_MISCCONFIGURATIONREG0_OCERETRY_MASK (0x1 << 5)
+#define TAS256X_MISCCONFIGURATIONREG0_OCERETRY_DONOTRETRY (0x0 << 5)
+#define TAS256X_MISCCONFIGURATIONREG0_OCERETRY_RETRY (0x1 << 5)
+#define TAS256X_MISCCONFIGURATIONREG0_OTERETRY_MASK (0x1 << 4)
+#define TAS256X_MISCCONFIGURATIONREG0_OTERETRY_DONOTRETRY (0x0 << 4)
+#define TAS256X_MISCCONFIGURATIONREG0_OTERETRY_RETRY (0x1 << 4)
+#define TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_MASK (0x1 << 3)
+#define TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_DISABLED (0x0 << 3)
+#define TAS256X_MISCCONFIGURATIONREG0_IRQZPULL_ENABLED (0x1 << 3)
+#define TAS256X_MISCCONFIGURATIONREG0_AMPSS_MASK (0x1 << 2)
+#define TAS256X_MISCCONFIGURATIONREG0_AMPSS_DISABLED (0x0 << 2)
+#define TAS256X_MISCCONFIGURATIONREG0_AMPSS_ENABLED (0x1 << 2)
+
+/* TDM Configuration Reg0 */
+#define TAS256X_TDMCONFIGURATIONREG0 TAS256X_REG(0x0, 0x0, 0x06)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK (0x1 << 5)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ (0x0 << 5)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ (0x1 << 5)
+#define TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK (0x1 << 4)
+#define TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED (0x1 << 4)
+#define TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED (0x0 << 4)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK (0x7 << 1)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_14_7_16KHZ (0x1 << 1)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ (0x4 << 1)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ (0x5 << 1)
+#define TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ (0x6 << 1)
+#define TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK (0x1 << 0)
+#define TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_LOWTOHIGH (0x0 << 0)
+#define TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_HIGHTOLOW (0x1 << 0)
+
+/* TDM Configuration Reg1 */
+#define TAS256X_TDMCONFIGURATIONREG1 TAS256X_REG(0x0, 0x0, 0x07)
+#define TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_MASK (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_LEFT (0x0 << 6)
+#define TAS256X_TDMCONFIGURATIONREG1_RXJUSTIFY_RIGHT (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK (0x1f << 1)
+#define TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT (1)
+#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK (0x1 << 0)
+#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_SHIFT (0)
+#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_RISING (0x0 << 0)
+#define TAS256X_TDMCONFIGURATIONREG1_RXEDGE_FALLING (0x1 << 0)
+
+/* TDM Configuration Reg2 */
+#define TAS256X_TDMCONFIGURATIONREG2 TAS256X_REG(0x0, 0x0, 0x08)
+#define TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK (0X3 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS (0x0 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_8BITS (0x2 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK (0x3 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS (0x2 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_12BITS (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_16BITS (0x0 << 6)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK (0x3 << 4)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C (0x0 << 4)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT (0x1 << 4)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT (0x2 << 4)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX (0x3 << 4)
+#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK (0x3 << 2)
+#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS (0x0 << 2)
+#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_20BITS (0x1 << 2)
+#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS (0x2 << 2)
+#define TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS (0x3 << 2)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK (0x3 << 0)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS (0x0 << 0)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_24BITS (0x1 << 0)
+#define TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS (0x2 << 0)
+
+/* TDM Configuration Reg3 */
+#define TAS256X_TDMCONFIGURATIONREG3 TAS256X_REG(0x0, 0x0, 0x09)
+#define TAS256X_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK (0xf << 4)
+#define TAS256X_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_SHIFT (4)
+#define TAS256X_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask (0xf << 0)
+#define TAS256X_TDMCONFIGURATIONREG3_RXSLOTLeft30_SHIFT (0)
+
+/* TDM Configuration Reg4 */
+#define TAS256X_TDMConfigurationReg4 TAS256X_REG(0x0, 0x0, 0x0A)
+#define TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_MASK (0x1 << 5)
+#define TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_DISABLE (0x0 << 5)
+#define TAS256X_TDMCONFIGURATIONREG4_TXKEEPER_ENABLE (0x1 << 5)
+#define TAS256X_TDMCONFIGURATIONREG4_TXFILL_MASK (0x1 << 4)
+#define TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMIT0 (0x0 << 4)
+#define TAS256X_TDMCONFIGURATIONREG4_TXFILL_TRANSMITHIZ (0x1 << 4)
+#define TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK (0x7 << 1)
+#define TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_SHIFT (1)
+#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK (0x1 << 0)
+#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_SHIFT (0)
+#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_RISING (0x0 << 0)
+#define TAS256X_TDMCONFIGURATIONREG4_TXEDGE_FALLING (0x1 << 0)
+
+/* TDM Configuration Reg5 */
+#define TAS256X_TDMCONFIGURATIONREG5 TAS256X_REG(0x0, 0x0, 0x0B)
+#define TAS256X_TDMCONFIGURATIONREG5_VSNSTX_MASK (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG5_VSNSTX_DISABLE (0x0 << 6)
+#define TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG5_VSNSSLOT50_MASK (0x3f << 0)
+
+/* TDM Configuration Reg6 */
+#define TAS256X_TDMCONFIGURATIONREG6 TAS256X_REG(0x0, 0x0, 0x0C)
+#define TAS256X_TDMCONFIGURATIONREG6_ISNSTX_MASK (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG6_ISNSTX_DISABLE (0x0 << 6)
+#define TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG6_ISNSSLOT50_MASK (0x3f << 0)
+
+/* TDM Configuration Reg7 */
+#define TAS256X_TDMCONFIGURATIONREG7 TAS256X_REG(0x0, 0x0, 0x0D)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_MASK (0x1 << 7)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_8BITS (0x0 << 7)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATSLEN_16BITS (0x1 << 7)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATTX_MASK (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATTX_DISABLE (0x0 << 6)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE (0x1 << 6)
+#define TAS256X_TDMCONFIGURATIONREG7_VBATSLOT50_MASK (0x3f << 0)
+
+/* Interrupt Mask Reg0 */
+#define TAS256X_INTERRUPTMASKREG0 TAS256X_REG(0x0, 0x0, 0x1A)
+#define TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_MASK (0x1 << 7)
+#define TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_UNMASK (0x0 << 7)
+#define TAS256X_INTERRUPTMASKREG0_LIMMUTEINTMASK_DISABLE (0x1 << 7)
+#define TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_MASK (0x1 << 6)
+#define TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_UNMASK (0x0 << 6)
+#define TAS256X_INTERRUPTMASKREG0_LIMINFHLDINTMASK_DISABLE (0x1 << 6)
+#define TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_MASK (0x1 << 5)
+#define TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_UNMASK (0x0 << 5)
+#define TAS256X_INTERRUPTMASKREG0_LIMMAXATNINTMASK_DISABLE (0x1 << 5)
+#define TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_MASK (0x1 << 4)
+#define TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_UNMASK (0x0 << 4)
+#define TAS256X_INTERRUPTMASKREG0_VBATLESSTHANINFINTMASK_DISABLE (0x1 << 4)
+#define TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_MASK (0x1 << 3)
+#define TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_UNMASK (0x0 << 3)
+#define TAS256X_INTERRUPTMASKREG0_LIMACTIVEFLAGINTMASK_DISABLE (0x1 << 3)
+#define TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_MASK (0x1 << 2)
+#define TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_UNMASK (0x0 << 2)
+#define TAS256X_INTERRUPTMASKREG0_TDMCLOCKERRORINTMASK_DISABLE (0x1 << 2)
+#define TAS256X_INTERRUPTMASKREG0_OCEINTMASK_MASK (0x1 << 1)
+#define TAS256X_INTERRUPTMASKREG0_OCEINTMASK_UNMASK (0x0 << 1)
+#define TAS256X_INTERRUPTMASKREG0_OCEINTMASK_DISABLE (0x1 << 1)
+#define TAS256X_INTERRUPTMASKREG0_OTEINTMASK_MASK (0x1 << 0)
+#define TAS256X_INTERRUPTMASKREG0_OTEINTMASK_UNMASK (0x0 << 0)
+#define TAS256X_INTERRUPTMASKREG0_OTEINTMASK_DISABLE (0x1 << 0)
+#define TAS256X_INTERRUPTMASKREG0_DISABLE 0xff
+
+/* Interrupt Mask Reg1 */
+#define TAS256X_INTERRUPTMASKREG1 TAS256X_REG(0x0, 0x0, 0x1B)
+#define TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_MASK (0x1 << 7)
+#define TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_UNMASK (0x0 << 7)
+#define TAS256X_INTERRUPTMASKREG1_DSPOUTPUTINTMASK_DISABLE (0x1 << 7)
+#define TAS256X_INTERRUPTMASKREG1_CRCINTMASK_MASK (0x1 << 6)
+#define TAS256X_INTERRUPTMASKREG1_CRCINTMASK_UNMASK (0x0 << 6)
+#define TAS256X_INTERRUPTMASKREG1_CRCINTMASK_DISABLE (0x1 << 6)
+#define TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_MASK (0x1 << 2)
+#define TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_UNMASK (0x0 << 2)
+#define TAS256X_INTERRUPTMASKREG1_VBATOVLOINTMASK_DISABLE (0x1 << 2)
+#define TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_MASK (0x1 << 1)
+#define TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_UNMASK (0x0 << 1)
+#define TAS256X_INTERRUPTMASKREG1_VBATUVLOINTMASK_DISABLE (0x1 << 1)
+#define TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_MASK (0x1 << 0)
+#define TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_UNMASK (0x0 << 0)
+#define TAS256X_INTERRUPTMASKREG1_BROWNOUTFLAGINTMASK_DISABLE (0x1 << 0)
+#define TAS256X_INTERRUPTMASKREG1_DISABLE 0xff
+
+/* Latched-Interrupt Reg0 */
+#define TAS256X_LATCHEDINTERRUPTREG0 TAS256X_REG(0x0, 0x0, 0x24)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_MASK (0x1 << 7)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_NOINTERRUPT (0x0 << 7)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMMUTESTICKY_INTERRUPT (0x1 << 7)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_MASK (0x1 << 6)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_NOINTERRUPT (0x0 << 6)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMINFHLDSTICKY_INTERRUPT (0x1 << 6)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_MASK (0x1 << 5)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_NOINTERRUPT (0x0 << 5)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMMAXATNSTICKY_INTERRUPT (0x1 << 5)
+#define TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_MASK (0x1 << 4)
+#define TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_NOINTERRUPT \
+ (0x0 << 4)
+#define TAS256X_LATCHEDINTERRUPTREG0_VBATLESSTHANINFSTICKY_INTERRUPT (0x1 << 4)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_MASK (0x1 << 3)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_NOINTERRUPT (0x0 << 3)
+#define TAS256X_LATCHEDINTERRUPTREG0_LIMACTIVEFLAGSTICKY_INTERRUPT (0x1 << 3)
+#define TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_MASK (0x1 << 2)
+#define TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_NOINTERRUPT (0x0 << 2)
+#define TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT (0x1 << 2)
+#define TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_MASK (0x1 << 1)
+#define TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_NOINTERRUPT (0x0 << 1)
+#define TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT (0x1 << 1)
+#define TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_MASK (0x1 << 0)
+#define TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_NOINTERRUPT (0x0 << 0)
+#define TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT (0x1 << 0)
+
+/* Latched-Interrupt Reg1 */
+#define TAS256X_LATCHEDINTERRUPTREG1 TAS256X_REG(0x0, 0x0, 0x25)
+#define TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_MASK (0x1 << 7)
+#define TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_NOINTERRUPT \
+ (0x0 << 7)
+#define TAS256X_LATCHEDINTERRUPTREG1_PDMAUDDATAINVALIDSTICKY_INTERRUPT \
+ (0x1 << 7)
+#define TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_MASK (0x1 << 3)
+#define TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_NOINTERRUPT (0x0 << 3)
+#define TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT (0x1 << 3)
+#define TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_MASK (0x1 << 2)
+#define TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_NOINTERRUPT (0x0 << 2)
+#define TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT (0x1 << 2)
+#define TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_MASK (0x1 << 1)
+#define TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_NOINTERRUPT (0x0 << 1)
+#define TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT (0x1 << 1)
+#define TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_MASK (0x1 << 0)
+#define TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_NOINTERRUPT (0x0 << 0)
+#define TAS256X_LATCHEDINTERRUPTREG1_PDMCLOCKERRORSTICKY_INTERRUPT (0x1 << 0)
+
+/* Interrupt Configuration */
+#define TAS256X_INTERRUPTCONFIGURATION TAS256X_REG(0x0, 0x0, 0x30)
+#define TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK (0x1 << 2)
+#define TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR (0x1 << 2)
+#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_MASK (0x3 << 0)
+#define TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLIVEINTERRUPTS \
+ (0x0 << 0)
+#define \
+ TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERTONLATCHEDINTERRUPTS \
+ (0x1 << 0)
+#define \
+ TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLIVEINTERRUPTS \
+ (0x2 << 0)
+#define \
+ TAS256X_INTERRUPTCONFIGURATION_PININTCONFIG10_ASSERT2MSONLATCHEDINTERRUPTS \
+ (0x3 << 0)
+
+#define TAS256X_CLOCK_HALT_TIMER_MASK (0x7 << 3)
+#define TAS256X_CLOCK_HALT_1MS (0x0 << 3)
+#define TAS256X_CLOCK_HALT_3MS (0x1 << 3)
+#define TAS256X_CLOCK_HALT_26MS (0x2 << 3)
+#define TAS256X_CLOCK_HALT_52MS (0x3 << 3)
+#define TAS256X_CLOCK_HALT_104MS (0x4 << 3)
+#define TAS256X_CLOCK_HALT_209MS (0x5 << 3)
+#define TAS256X_CLOCK_HALT_419MS (0x6 << 3)
+#define TAS256X_CLOCK_HALT_838MS (0x7 << 3)
+
+#define TAS256X_BOOSTSLOPE TAS256X_REG(0x0, 0x0, 0x35)
+#define TAS256X_BOOSTSLOPE_MASK (0x3 << 2)
+
+/* Clock Configuration */
+#define TAS256X_CLOCKCONFIGURATION TAS256X_REG(0x0, 0x0, 0x38)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKTOFS52_MASK (0xf << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_16 (0x0 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_24 (0x1 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_32 (0x2 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_48 (0x3 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_64 (0x4 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_96 (0x5 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_128 (0x6 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_192 (0x7 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_256 (0x8 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_384 (0x9 << 2)
+#define TAS256X_CLOCKCONFIGURATION_SBCLKtoFS52_512 (0xa << 2)
+#define TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_MASK (0x3 << 0)
+#define TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_DISABLED (0x1 << 0)
+#define TAS256X_CLOCKCONFIGURATION_DISCLKRATEDETECT10_ENABLED (0x0 << 0)
+
+#define TAS256X_VBATFILTER TAS256X_REG(0x0, 0x0, 0x3b)
+#define TAS256X_VBAT_LPF_MASK (0x3 << 5)
+#define TAS256X_VBAT_LPF_SHIFT 5
+
+#define TAS256X_CLASSHRELEASETIMER TAS256X_REG(0x0, 0x0, 0x3c)
+
+#define TAS256X_BOOST_CFG4 TAS256X_REG(0x0, 0x0, 0x40)
+
+#define TAS256X_CHIPID TAS256X_REG(0x0, 0x0, 0x7D)
+
+#define TAS256X_ICN_THRESHOLD_REG TAS256X_REG(0x0, 0x2, 0x64)
+#define TAS256X_ICN_HYSTERESIS_REG TAS256X_REG(0x0, 0x2, 0x6c)
+
+#define TAS256X_ICN_SW_REG TAS256X_REG(0x0, 0x0, 0x3e)
+#define TAS256X_ICN_SW_MASK (0x01 << 4)
+#define TAS256X_ICN_SW_ENABLE (0x10)
+#define TAS256X_ICN_SW_DISABLE (0x00)
+#define TAS256X_ICN_IVSENSE_MASK (0x01 << 1)
+
+#define TAS256X_TESTPAGECONFIGURATION TAS256X_REG(0x0, 0xfd, 0xd)
+#define TAS256X_CLASSDCONFIGURATION1 TAS256X_REG(0x0, 0xfd, 0x19)
+#define TAS256X_CLASSDCONFIGURATION2 TAS256X_REG(0x0, 0xfd, 0x32)
+#define TAS256X_CLASSDCONFIGURATION3 TAS256X_REG(0x0, 0xfd, 0x33)
+#define TAS256X_CLASSDCONFIGURATION4 TAS256X_REG(0x0, 0xfd, 0x3f)
+#define TAS256X_EFFICIENCYCONFIGURATION TAS256X_REG(0x0, 0xfd, 0x5f)
+
+#define TAS256X_HPF TAS256X_REG(0x0, 0x2, 0x70)
+#define TAS256X_CLASSHHEADROOM TAS256X_REG(0x64, 0x7, 0x48)
+#define TAS256X_CLASSHHYSTERESIS TAS256X_REG(0x64, 0x7, 0x4c)
+#define TAS256X_CLASSHMTCT TAS256X_REG(0x64, 0x5, 0x4c)
+
+/*PCM Digital Volume Control*/
+#define TAS256X_DVC_PCM TAS256X_REG(0x0, 0x2, 0x0c)
+
+/*Limiter Controls*/
+#define TAS256X_LIM_MAX_ATN TAS256X_REG(0x0, 0x2, 0x14)
+#define TAS256X_LIMB_TH_MAX TAS256X_REG(0x0, 0x2, 0x18)
+#define TAS256X_LIMB_TH_MIN TAS256X_REG(0x0, 0x2, 0x1c)
+#define TAS256X_LIMB_INF_PT TAS256X_REG(0x0, 0x2, 0x20)
+#define TAS256X_LIMB_SLOPE TAS256X_REG(0x0, 0x2, 0x24)
+
+/*Brown Out Protection Control*/
+#define TAS256X_BOP_TH TAS256X_REG(0x0, 0x2, 0x28)
+#define TAS256X_BOSD_TH TAS256X_REG(0x0, 0x2, 0x2c)
+
+#define TAS256X_BOOSTCONFIGURATION4 TAS256X_REG(0x0, 0x0, 0x40)
+#define TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK (0x3f << 0)
+#define TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT 0
+
+#define TAS256X_LIMITERCONFIGURATION0 TAS256X_REG(0x0, 0x0, 0x12)
+#define TAS256X_LIMITER_ENABLE_MASK (0x1 << 0)
+#define TAS256X_LIMITER_ENABLE_SHIFT 0x0
+#define TAS256X_LIMITER_ATTACKRATE_MASK (0x7 << 1)
+#define TAS256X_LIMITER_ATTACKRATE_SHIFT 0x1
+#define TAS256X_LIMITER_ATTACKSTEPSIZE_MASK (0x3 << 4)
+#define TAS256X_LIMITER_ATTACKSTEPSIZE_SHIFT 0x4
+
+#define TAS256X_LIMITERCONFIGURATION1 TAS256X_REG(0x0, 0x0, 0x13)
+#define TAS256X_LIMITER_RELEASERATE_MASK (0x7 << 3)
+#define TAS256X_LIMITER_RELEASERATE_SHIFT 0x3
+#define TAS256X_LIMITER_RELEASESTEPSIZE_MASK (0x3 << 6)
+#define TAS256X_LIMITER_RELEASESTEPSIZE_SHIFT 0x6
+
+#define TAS256X_BOPCONFIGURATION0 TAS256X_REG(0x0, 0x0, 0x14)
+#define TAS256X_BOP_ENABLE_MASK (0x1 << 0)
+#define TAS256X_BOP_ENABLE_SHIFT 0x0
+#define TAS256X_BOP_MUTE_MASK (0x1 << 1)
+#define TAS256X_BOP_MUTE_SHIFT 0x1
+#define TAS256X_BOP_SHUTDOWN_ENABLE_MASK (0x1 << 4)
+#define TAS256X_BOP_SHUTDOWN_ENABLE_SHIFT 0x4
+
+#define TAS256X_BOPCONFIGURATION1 TAS256X_REG(0x0, 0x0, 0x15)
+#define TAS256X_BOP_ATTACKRATE_MASK (0x7 << 5)
+#define TAS256X_BOP_ATTACKRATE_SHIFT 0x5
+#define TAS256X_BOP_ATTACKSTEPSIZE_MASK (0x3 << 0x3)
+#define TAS256X_BOP_ATTACKSTEPSIZE_SHIFT 0x3
+#define TAS256X_BOP_HOLDTIME_MASK (0x7 << 0x0)
+#define TAS256X_BOP_HOLDTIME_SHIFT 0x0
+
+#define TAS256X_MISC_CLASSD TAS256X_REG(0x0, 0x01, 0x21)
+#define TAS256X_CMP_HYST_MASK (0x1 << 3)
+#define TAS256X_CMP_HYST_SHIFT (0x3)
+
+#define TAS256X_CLASSH_TIMER TAS256X_REG(0x64, 0x8, 0x1c)
+#define TAS256X_CLASSH_TIMER_RELEASE TAS256X_REG(0x0, 0x0, 0x3c)
+#define TAS256X_CLASSH_TIMER_RELEASE_MASK (0x1f << 2)
+
+/*Test Page*/
+#define TAS256X_TEST_PAGE_LOCK TAS256X_REG(0x00, 0xfd, 0x0d)
+#define TAS256X_DAC_MODULATOR TAS256X_REG(0x00, 0xfd, 0x12)
+#define TAS256X_DAC_MUTE TAS256X_REG(0x00, 0xfd, 0x47)
+#define TAS256X_ICN_MODE TAS256X_REG(0x00, 0xfd, 0x64)
+#define TAS256X_ICN_IMPROVE TAS256X_REG(0x00, 0xfd, 0x46)
+
+/* Book */
+#define TAS256X_BOOK TAS256X_REG(0x0, 0x0, 0x7F)
+#define TAS256X_BOOK_BOOK70_MASK (0xff << 0)
+
+/* data format */
+#define TAS256X_DATAFORMAT_SHIFT 2
+#define TAS256X_DATAFORMAT_I2S 0x0
+#define TAS256X_DATAFORMAT_DSP 0x1
+#define TAS256X_DATAFORMAT_RIGHT_J 0x2
+#define TAS256X_DATAFORMAT_LEFT_J 0x3
+
+#define TAS256X_DAI_FMT_MASK (0x7 << TAS256X_DATAFORMAT_SHIFT)
+
+#define TAS256X_POWER_ACTIVE 0
+#define TAS256X_POWER_MUTE 1
+#define TAS256X_POWER_SHUTDOWN 2
+
+#define ERROR_NONE 0x0000000
+#define ERROR_PLL_ABSENT 0x0000001
+#define ERROR_DEVA_I2C_COMM 0x0000002
+#define ERROR_DEVB_I2C_COMM 0x0000004
+#define ERROR_CLOCK 0x0000008
+#define ERROR_YRAM_CRCCHK 0x0000010
+#define ERROR_OVER_CURRENT 0x0000020
+#define ERROR_DIE_OVERTEMP 0x0000040
+#define ERROR_OVER_VOLTAGE 0x0000080
+#define ERROR_UNDER_VOLTAGE 0x0000100
+#define ERROR_BROWNOUT 0x0000200
+#define ERROR_CLASSD_PWR 0x0000400
+#define ERROR_FAILSAFE 0x0000800
+
+/* 5 second */
+#define CHECK_PERIOD 5000
+
+#define TAS256X_I2C_RETRY_COUNT 3
+#define ERROR_I2C_SUSPEND -1
+#define ERROR_I2C_FAILED -2
+
+#define TAS256X_LEFT_SWITCH 0x10000001
+#define TAS256X_RIGHT_SWITCH 0x10000002
+#define RX_SCFG_LEFT 0x10000003
+#define RX_SCFG_RIGHT 0x10000004
+
+#define RESTART_MAX 3
+
+struct tas256x_priv;
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+struct snd_soc_component;
+#else
+struct snd_soc_codec;
+#endif
+
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+#define TAS256X_CONFIG_SIZE (10)
+#define TAS256X_DEVICE_SUM (8)
+
+#define TAS256X_CMD_SING_W (0x1)
+#define TAS256X_CMD_BURST (0x2)
+#define TAS256X_CMD_DELAY (0x3)
+#define TAS256X_CMD_FIELD_W (0x4)
+
+#define SMS_HTONS(a, b) ((((a)&0x00FF) << 8) | \
+ ((b) & 0x00FF))
+#define SMS_HTONL(a, b, c, d) ((((a) & 0x000000FF) << 24) |\
+ (((b) & 0x000000FF) << 16) | \
+ (((c) & 0x000000FF) << 8) | \
+ ((d) & 0x000000FF))
+
+enum tas256x_dsp_fw_state {
+ TAS256X_DSP_FW_NONE = 0,
+ TAS256X_DSP_FW_PENDING,
+ TAS256X_DSP_FW_FAIL,
+ TAS256X_DSP_FW_OK,
+};
+
+enum tas256x_bin_blk_type {
+ TAS256X_BIN_BLK_COEFF = 1,
+ TAS256X_BIN_BLK_POST_POWER_UP,
+ TAS256X_BIN_BLK_PRE_SHUTDOWN,
+ TAS256X_BIN_BLK_PRE_POWER_UP,
+ TAS256X_BIN_BLK_POST_SHUTDOWN
+};
+
+struct tas256x_fw_hdr {
+ unsigned int img_sz;
+ unsigned int checksum;
+ unsigned int binnary_version_num;
+ unsigned int drv_fw_version;
+ unsigned int timestamp;
+ unsigned char plat_type;
+ unsigned char dev_family;
+ unsigned char reserve;
+ unsigned char ndev;
+ unsigned char devs[TAS256X_DEVICE_SUM];
+ unsigned int nconfig;
+ unsigned int config_size[TAS256X_CONFIG_SIZE];
+};
+
+struct tas256x_block_data {
+ unsigned char dev_idx;
+ unsigned char block_type;
+ unsigned short yram_checksum;
+ unsigned int block_size;
+ unsigned int nSublocks;
+ unsigned char *regdata;
+};
+
+struct tas256x_config_info {
+ unsigned int nblocks;
+ unsigned int real_nblocks;
+ struct tas256x_block_data **blk_data;
+};
+
+void tas256x_select_cfg_blk(void *pContext, int conf_no, unsigned char block_type);
+int tas256x_load_container(struct tas256x_priv *pTAS256x);
+void tas256x_config_info_remove(void *pContext);
+#endif /*CONFIG_TAS256X_REGBIN_PARSER*/
+
+struct tas256x_register {
+int book;
+int page;
+int reg;
+};
+
+struct tas256x_dai_cfg {
+unsigned int dai_fmt;
+unsigned int tdm_delay;
+};
+
+/*struct tas256x_buf_cfg {
+ unsigned short bufSize;
+ unsigned char *buf;
+};
+*/
+
+enum channel {
+ channel_left = 0x01,
+ channel_right = 0x02,
+ channel_both = channel_left | channel_right
+};
+
+/*
+ * device ops function structure
+ */
+struct tas_device_ops {
+ /**< init typically for loading optimal settings */
+ int (*tas_init)(struct tas256x_priv *p_tas256x, int chn);
+#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE
+ int (*tas_probe)(struct tas256x_priv *p_tas256x,
+ struct snd_soc_component *codec, int chn);
+#else
+ int (*tas_probe)(struct tas256x_priv *p_tas256x,
+ struct snd_soc_codec *codec, int chn);
+#endif
+/*TODO:*/
+};
+
+
+struct tas_device {
+ int mn_chip_id;
+ int mn_current_book;
+ int mn_current_page;
+ int mn_addr;
+ int mn_reset_gpio;
+ int mn_irq_gpio;
+ int mn_irq;
+ int spk_control;
+ int device_id;
+ int rx_mode;
+ int dvc_pcm;
+ int bst_vltg;
+ int bst_ilm;
+ int ampoutput_lvl;
+ int lim_switch;
+ int lim_max_attn;
+ int lim_thr_max;
+ int lim_thr_min;
+ int lim_att_rate;
+ int lim_rel_rate;
+ int lim_att_stp_size;
+ int lim_rel_stp_size;
+ int lim_max_thd;
+ int lim_min_thd;
+ int lim_infl_pt;
+ int lim_trk_slp;
+ int bop_enable;
+ int bop_thd;
+ int bop_att_rate;
+ int bop_att_stp_size;
+ int bop_hld_time;
+ int bop_mute;
+ int bosd_enable;
+ int bosd_thd;
+ int vbat_lpf;
+ int rx_cfg;
+ int classh_timer;
+ int reciever_enable;
+ struct tas_device_ops dev_ops;
+};
+
+struct tas256x_priv {
+ void *platform_data;
+ bool mb_power_up;
+ int mn_power_state;
+ bool mb_irq_eable;
+ int mn_sampling_rate;
+ int mn_frame_size;
+ int mn_ppg;
+ int mn_ch_size;
+ int mn_rx_slot_width;
+ int mn_rx_width;
+ int mn_tx_slot_width;
+ int mn_iv_width;
+ int mn_vbat;
+ bool mb_mute;
+ bool dac_mute;
+ int mn_channels;
+ int mn_slots;
+ int mn_rx_slot_map[2];
+ int mn_fmt;
+ int mn_fmt_mode;
+ int mn_frame_start;
+ int mn_rx_edge;
+ int mn_rx_offset;
+ int mn_tx_edge;
+ int mn_tx_offset;
+ struct tas_device **devs;
+ int icn_sw;
+ int (*read)(struct tas256x_priv *p_tas256x, enum channel chn,
+ unsigned int reg, unsigned int *pValue);
+ int (*write)(struct tas256x_priv *p_tas256x, enum channel chn,
+ unsigned int reg, unsigned int Value);
+ int (*bulk_read)(struct tas256x_priv *p_tas256x, enum channel chn,
+ unsigned int reg, unsigned char *p_data, unsigned int len);
+ int (*bulk_write)(struct tas256x_priv *p_tas256x, enum channel chn,
+ unsigned int reg, unsigned char *p_data, unsigned int len);
+ int (*update_bits)(struct tas256x_priv *p_tas256x, enum channel chn,
+ unsigned int reg, unsigned int mask, unsigned int value);
+ void (*hw_reset)(struct tas256x_priv *p_tas256x);
+ void (*clear_irq)(struct tas256x_priv *p_tas256x);
+ void (*enable_irq)(struct tas256x_priv *p_tas256x, bool enable);
+ unsigned int mn_err_code;
+ unsigned int mn_restart;
+ int (*plat_write)(void *plat_data,
+ unsigned int i2c_addr, unsigned int reg, unsigned int value);
+ int (*plat_bulk_write)(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned char *pData,
+ unsigned int nLength);
+ int (*plat_read)(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned int *value);
+ int (*plat_bulk_read)(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned char *pData,
+ unsigned int nLength);
+ int (*plat_update_bits)(void *plat_data, unsigned int i2c_addr,
+ unsigned int reg, unsigned int mask,
+ unsigned int value);
+ void (*schedule_init_work)(struct tas256x_priv *p_tas256x);
+
+ struct mutex dev_lock;
+#if IS_ENABLED(CONFIG_TAS256X_CODEC)
+ struct mutex codec_lock;
+#endif
+#if IS_ENABLED(CONFIG_TAS256X_MISC)
+ struct mutex file_lock;
+#endif
+ struct delayed_work irq_work;
+ struct delayed_work init_work;
+ struct delayed_work dc_work;
+ int iv_enable;
+#if IS_ENABLED(CONFIG_TAS256X_REGBIN_PARSER)
+ int fw_state;
+ struct tas256x_fw_hdr fw_hdr;
+ int ncfgs;
+ struct tas256x_config_info **cfg_info;
+ int profile_cfg_id;
+#endif
+};
+
+#endif /* __TAS256X_ */
diff --git a/asoc/codecs/tas256x/physical_layer/src/tas256x.c b/asoc/codecs/tas256x/physical_layer/src/tas256x.c
new file mode 100644
index 00000000..86febd5f
--- /dev/null
+++ b/asoc/codecs/tas256x/physical_layer/src/tas256x.c
@@ -0,0 +1,1588 @@
+#include "physical_layer/inc/tas256x.h"
+#include "physical_layer/inc/tas2562.h"
+#include "physical_layer/inc/tas2564.h"
+#include "physical_layer/inc/tas256x-device.h"
+
+#define LOG_TAG "[tas256x]"
+
+#define TAS256X_MDELAY 0xFFFFFFFE
+#define TAS256X_MSLEEP 0xFFFFFFFD
+#define TAS256X_IVSENSER_ENABLE 1
+#define TAS256X_IVSENSER_DISABLE 0
+static char p_icn_threshold[] = {0x00, 0x01, 0x2f, 0x2c};
+static char p_icn_hysteresis[] = {0x00, 0x01, 0x5d, 0xc0};
+
+static unsigned int p_tas256x_classh_d_data[] = {
+ /* reg address size values */
+ TAS256X_CLASSHHEADROOM, 0x4, 0x09, 0x99, 0x99, 0x9a,
+ TAS256X_CLASSHHYSTERESIS, 0x4, 0x0, 0x0, 0x0, 0x0,
+ TAS256X_CLASSHMTCT, 0x4, 0xb, 0x0, 0x0, 0x0,
+ TAS256X_VBATFILTER, 0x1, 0x38,
+ TAS256X_CLASSHRELEASETIMER, 0x1, 0x3c,
+ TAS256X_BOOSTSLOPE, 0x1, 0x78,
+ TAS256X_TESTPAGECONFIGURATION, 0x1, 0xd,
+ TAS256X_CLASSDCONFIGURATION3, 0x1, 0x8e,
+ TAS256X_CLASSDCONFIGURATION2, 0x1, 0x49,
+ TAS256X_CLASSDCONFIGURATION4, 0x1, 0x21,
+ TAS256X_CLASSDCONFIGURATION1, 0x1, 0x80,
+ TAS256X_EFFICIENCYCONFIGURATION, 0x1, 0xc1,
+ 0xFFFFFFFF, 0xFFFFFFFF
+};
+
+static char HPF_reverse_path[] = {
+ 0x7F, 0xFF, 0xFF, 0xFF,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00};
+
+static char dvc_pcm[57][4] = {
+ {0x00, 0x00, 0x0D, 0x43}, {0x00, 0x00, 0x10, 0xB3}, {0x00, 0x00, 0x15, 0x05},
+ {0x00, 0x00, 0x1A, 0x77}, {0x00, 0x00, 0x21, 0x51}, {0x00, 0x00, 0x29, 0xF1},
+ {0x00, 0x00, 0x34, 0xCE}, {0x00, 0x00, 0x42, 0x7A}, {0x00, 0x00, 0x53, 0xB0},
+ {0x00, 0x00, 0x69, 0x5B}, {0x00, 0x00, 0x84, 0xA3}, {0x00, 0x00, 0xA6, 0xFA},
+ {0x00, 0x00, 0xD2, 0x37}, {0x00, 0x01, 0x08, 0xA5}, {0x00, 0x01, 0x4D, 0x2A},
+ {0x00, 0x01, 0xA3, 0x6E}, {0x00, 0x02, 0x10, 0x08}, {0x00, 0x02, 0x98, 0xC1},
+ {0x00, 0x03, 0x44, 0xE0}, {0x00, 0x04, 0x1D, 0x90}, {0x00, 0x05, 0x2E, 0x5B},
+ {0x00, 0x06, 0x85, 0xC8}, {0x00, 0x08, 0x36, 0x22}, {0x00, 0x0A, 0x56, 0x6D},
+ {0x00, 0x0D, 0x03, 0xA7}, {0x00, 0x10, 0x62, 0x4E}, {0x00, 0x14, 0xA0, 0x51},
+ {0x00, 0x19, 0xF7, 0x86}, {0x00, 0x20, 0xB0, 0xBD}, {0x00, 0x29, 0x27, 0x9E},
+ {0x00, 0x33, 0xCF, 0x8E}, {0x00, 0x41, 0x39, 0xD3}, {0x00, 0x52, 0x1D, 0x51},
+ {0x00, 0x67, 0x60, 0x45}, {0x00, 0x82, 0x24, 0x8A}, {0x00, 0xA3, 0xD7, 0x0A},
+ {0x00, 0xCE, 0x43, 0x29}, {0x01, 0x03, 0xAB, 0x3D}, {0x01, 0x46, 0xE7, 0x5E},
+ {0x01, 0x9B, 0x8C, 0x27}, {0x02, 0x06, 0x1B, 0x8A}, {0x02, 0x8C, 0x42, 0x40},
+ {0x03, 0x35, 0x25, 0x29}, {0x04, 0x09, 0xC2, 0xB1}, {0x05, 0x15, 0x6D, 0x69},
+ {0x06, 0x66, 0x66, 0x66}, {0x08, 0x0E, 0x9F, 0x97}, {0x0A, 0x24, 0xB0, 0x63},
+ {0x0C, 0xC5, 0x09, 0xAC}, {0x10, 0x13, 0x79, 0x88}, {0x14, 0x3D, 0x13, 0x62},
+ {0x19, 0x7A, 0x96, 0x7F}, {0x20, 0x13, 0x73, 0x9E}, {0x28, 0x61, 0x9A, 0xEA},
+ {0x32, 0xD6, 0x46, 0x18}, {0x40, 0x00, 0x00, 0x00}, {0x50, 0x92, 0x3B, 0xE4}
+};
+
+static char lim_max_attn[16][4] = {
+ {0x14, 0x49, 0x60, 0xC5}, {0x16, 0xC3, 0x10, 0xE3}, {0x19, 0x8A, 0x13, 0x57},
+ {0x1C, 0xA7, 0xD7, 0x68}, {0x20, 0x26, 0xF3, 0x10}, {0x24, 0x13, 0x46, 0xF6},
+ {0x28, 0x7A, 0x26, 0xC5}, {0x2D, 0x6A, 0x86, 0x6F}, {0x32, 0xF5, 0x2C, 0xFF},
+ {0x39, 0x2C, 0xED, 0x8E}, {0x40, 0x26, 0xE7, 0x3D}, {0x47, 0xFA, 0xCC, 0xF0},
+ {0x50, 0xC3, 0x35, 0xD4}, {0x5A, 0x9D, 0xF7, 0xAC}, {0x65, 0xAC, 0x8C, 0x2F},
+ {0x72, 0x14, 0x82, 0xC0}
+};
+
+static char vbat_lim_max_thd[27][4] = {
+ {0x14, 0x00, 0x00, 0x00}, {0x18, 0x00, 0x00, 0x00}, {0x1C, 0x00, 0x00, 0x00},
+ {0x20, 0x00, 0x00, 0x00}, {0x24, 0x00, 0x00, 0x00}, {0x28, 0x00, 0x00, 0x00},
+ {0x2C, 0x00, 0x00, 0x00}, {0x30, 0x00, 0x00, 0x00}, {0x34, 0x00, 0x00, 0x00},
+ {0x38, 0x00, 0x00, 0x00}, {0x3C, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00},
+ {0x44, 0x00, 0x00, 0x00}, {0x48, 0x00, 0x00, 0x00}, {0x4C, 0x00, 0x00, 0x00},
+ {0x50, 0x00, 0x00, 0x00}, {0x54, 0x00, 0x00, 0x00}, {0x58, 0x00, 0x00, 0x00},
+ {0x5C, 0x00, 0x00, 0x00}, {0x60, 0x00, 0x00, 0x00}, {0x64, 0x00, 0x00, 0x00},
+ {0x68, 0x00, 0x00, 0x00}, {0x6C, 0x00, 0x00, 0x00}, {0x70, 0x00, 0x00, 0x00},
+ {0x74, 0x00, 0x00, 0x00}, {0x78, 0x00, 0x00, 0x00}, {0x7C, 0x00, 0x00, 0x00}
+};
+
+static char vbat_lim_min_thd[27][4] = {
+ {0x14, 0x00, 0x00, 0x00}, {0x18, 0x00, 0x00, 0x00}, {0x1C, 0x00, 0x00, 0x00},
+ {0x20, 0x00, 0x00, 0x00}, {0x24, 0x00, 0x00, 0x00}, {0x28, 0x00, 0x00, 0x00},
+ {0x2C, 0x00, 0x00, 0x00}, {0x30, 0x00, 0x00, 0x00}, {0x34, 0x00, 0x00, 0x00},
+ {0x38, 0x00, 0x00, 0x00}, {0x3C, 0x00, 0x00, 0x00}, {0x40, 0x00, 0x00, 0x00},
+ {0x44, 0x00, 0x00, 0x00}, {0x48, 0x00, 0x00, 0x00}, {0x4C, 0x00, 0x00, 0x00},
+ {0x50, 0x00, 0x00, 0x00}, {0x54, 0x00, 0x00, 0x00}, {0x58, 0x00, 0x00, 0x00},
+ {0x5C, 0x00, 0x00, 0x00}, {0x60, 0x00, 0x00, 0x00}, {0x64, 0x00, 0x00, 0x00},
+ {0x68, 0x00, 0x00, 0x00}, {0x6C, 0x00, 0x00, 0x00}, {0x70, 0x00, 0x00, 0x00},
+ {0x74, 0x00, 0x00, 0x00}, {0x78, 0x00, 0x00, 0x00}, {0x7C, 0x00, 0x00, 0x00}
+};
+
+static char vbat_lim_infl_pt[41][4] = {
+ {0x20, 0x00, 0x00, 0x00}, {0x21, 0x99, 0x99, 0x99}, {0x23, 0x33, 0x33, 0x33},
+ {0x24, 0xCC, 0xCC, 0xCC}, {0x26, 0x66, 0x66, 0x66}, {0x28, 0x00, 0x00, 0x00},
+ {0x29, 0x99, 0x99, 0x99}, {0x2B, 0x33, 0x33, 0x33}, {0x2C, 0xCC, 0xCC, 0xCC},
+ {0x2E, 0x66, 0x66, 0x66}, {0x30, 0x00, 0x00, 0x00}, {0x31, 0x99, 0x99, 0x99},
+ {0x33, 0x33, 0x33, 0x33}, {0x34, 0xCC, 0xCC, 0xCC}, {0x36, 0x66, 0x66, 0x66},
+ {0x38, 0x00, 0x00, 0x00}, {0x39, 0x99, 0x99, 0x99}, {0x3B, 0x33, 0x33, 0x33},
+ {0x3C, 0xCC, 0xCC, 0xCC}, {0x3E, 0x66, 0x66, 0x66}, {0x40, 0x00, 0x00, 0x00},
+ {0x41, 0x99, 0x99, 0x99}, {0x43, 0x33, 0x33, 0x33}, {0x44, 0xCC, 0xCC, 0xCC},
+ {0x46, 0x66, 0x66, 0x66}, {0x48, 0x00, 0x00, 0x00}, {0x49, 0x99, 0x99, 0x99},
+ {0x4B, 0x33, 0x33, 0x33}, {0x4C, 0xCC, 0xCC, 0xCC}, {0x4E, 0x66, 0x66, 0x66},
+ {0x4F, 0xFF, 0xFF, 0xFF}, {0x51, 0x99, 0x99, 0x99}, {0x53, 0x33, 0x33, 0x33},
+ {0x54, 0xCC, 0xCC, 0xCC}, {0x56, 0x66, 0x66, 0x66}, {0x57, 0xFF, 0xFF, 0xFF},
+ {0x59, 0x99, 0x99, 0x99}, {0x5B, 0x33, 0x33, 0x33}, {0x5C, 0xCC, 0xCC, 0xCC},
+ {0x5E, 0x66, 0x66, 0x66}, {0x5F, 0xFF, 0xFF, 0xFF}
+};
+
+static char vbat_lim_track_slope[7][4] = {
+ {0x10, 0x00, 0x00, 0x00}, {0x18, 0x00, 0x00, 0x00}, {0x20, 0x00, 0x00, 0x00},
+ {0x28, 0x00, 0x00, 0x00}, {0x30, 0x00, 0x00, 0x00}, {0x38, 0x00, 0x00, 0x00},
+ {0x40, 0x00, 0x00, 0x00}
+};
+
+static char bop_thd[16][4] = {
+ {0x28, 0x00, 0x00, 0x00}, {0x29, 0x99, 0x99, 0x99}, {0x2B, 0x33, 0x33, 0x33},
+ {0x2C, 0xCC, 0xCC, 0xCC}, {0x2E, 0x66, 0x66, 0x66}, {0x30, 0x00, 0x00, 0x00},
+ {0x31, 0x99, 0x99, 0x99}, {0x33, 0x33, 0x33, 0x33}, {0x34, 0xCC, 0xCC, 0xCC},
+ {0x36, 0x66, 0x66, 0x66}, {0x38, 0x00, 0x00, 0x00}, {0x39, 0x99, 0x99, 0x99},
+ {0x3B, 0x33, 0x33, 0x33}, {0x3C, 0xCC, 0xCC, 0xCC}, {0x3E, 0x66, 0x66, 0x66},
+ {0x40, 0x00, 0x00, 0x00}
+};
+
+static char bsd_thd[16][4] = {
+ {0x28, 0x00, 0x00, 0x00}, {0x29, 0x99, 0x99, 0x99}, {0x2B, 0x33, 0x33, 0x33},
+ {0x2C, 0xCC, 0xCC, 0xCC}, {0x2E, 0x66, 0x66, 0x66}, {0x30, 0x00, 0x00, 0x00},
+ {0x31, 0x99, 0x99, 0x99}, {0x33, 0x33, 0x33, 0x33}, {0x34, 0xCC, 0xCC, 0xCC},
+ {0x36, 0x66, 0x66, 0x66}, {0x38, 0x00, 0x00, 0x00}, {0x39, 0x99, 0x99, 0x99},
+ {0x3B, 0x33, 0x33, 0x33}, {0x3C, 0xCC, 0xCC, 0xCC}, {0x3E, 0x66, 0x66, 0x66},
+ {0x40, 0x00, 0x00, 0x00}
+};
+
+static char classH_timer[23][4] = {
+ {0x40, 0x0F, 0x01, 0xC0}, {0x50, 0x11, 0x01, 0xC0}, {0x50, 0x13, 0x01, 0xC0},
+ {0x50, 0x15, 0x01, 0xC0}, {0x50, 0x17, 0x01, 0xC0}, {0x50, 0x19, 0x01, 0xC0},
+ {0x50, 0x1B, 0x01, 0xC0}, {0x50, 0x1D, 0x01, 0xC0}, {0x50, 0x1F, 0x01, 0xC0},
+ {0x60, 0x21, 0x01, 0xC0}, {0x60, 0x23, 0x01, 0xC0}, {0x60, 0x25, 0x01, 0xC0},
+ {0x60, 0x27, 0x01, 0xC0}, {0x60, 0x29, 0x01, 0xC0}, {0x60, 0x2B, 0x01, 0xC0},
+ {0x60, 0x2D, 0x01, 0xC0}, {0x60, 0x2F, 0x01, 0xC0}, {0x60, 0x31, 0x01, 0xC0},
+ {0x60, 0x33, 0x01, 0xC0}, {0x60, 0x35, 0x01, 0xC0}, {0x60, 0x37, 0x01, 0xC0},
+ {0x60, 0x39, 0x01, 0xC0}, {0x60, 0x3B, 0x01, 0xC0}
+};
+
+static char classH_slope[23] = {
+ 0x2E, 0x28, 0x24, 0x21, 0x1E, 0x1C, 0x1A, 0x18, 0x17, 0x15,
+ 0x14, 0x13, 0x12, 0x11, 0x11, 0x10, 0xF, 0xF, 0xE, 0xD, 0xD,
+ 0xD, 0xC
+};
+
+static int tas256x_i2c_load_data(struct tas256x_priv *p_tas256x,
+ enum channel chn,
+ unsigned int *p_data)
+{
+ unsigned int n_register;
+ unsigned int *n_data;
+ unsigned char buf[128] = {0};
+ unsigned int n_length = 0;
+ unsigned int i = 0;
+ unsigned int n_size = 0;
+ int n_result = 0;
+
+ do {
+ n_register = p_data[n_length];
+ n_size = p_data[n_length + 1];
+ n_data = &p_data[n_length + 2];
+ if (n_register == TAS256X_MSLEEP) {
+ msleep(n_data[0]);
+ pr_debug("%s %s, msleep = %d\n", LOG_TAG,
+ __func__, n_data[0]);
+ } else if (n_register == TAS256X_MDELAY) {
+ msleep(n_data[0]);
+ pr_debug("%s %s, mdelay = %d\n", LOG_TAG,
+ __func__, n_data[0]);
+ } else {
+ if (n_register != 0xFFFFFFFF) {
+ if (n_size > 128) {
+ pr_err("%s %s, Line=%d, invalid size, maximum is 128 bytes!\n",
+ LOG_TAG, __func__, __LINE__);
+ break;
+ }
+ if (n_size > 1) {
+ for (i = 0; i < n_size; i++)
+ buf[i] = (unsigned char)n_data[i];
+ n_result = p_tas256x->bulk_write(
+ p_tas256x, chn,
+ n_register, buf, n_size);
+ if (n_result < 0)
+ break;
+ } else if (n_size == 1) {
+ n_result = p_tas256x->write(p_tas256x,
+ chn,
+ n_register, n_data[0]);
+ if (n_result < 0)
+ break;
+ } else {
+ pr_err("%s %s, Line=%d,invalid size, minimum is 1 bytes!\n",
+ LOG_TAG, __func__, __LINE__);
+ }
+ }
+ }
+ n_length = n_length + 2 + p_data[n_length + 1];
+ } while (n_register != 0xFFFFFFFF);
+ return n_result;
+}
+
+int tas256x_update_default_params(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ /*Initialize to default values*/
+ if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2562) {
+ p_tas256x->devs[ch-1]->dvc_pcm = 55; /*0dB*/
+ p_tas256x->devs[ch-1]->lim_max_attn = 7; /*-9dB*/
+ p_tas256x->devs[ch-1]->lim_thr_max = 13; /*9V*/
+ p_tas256x->devs[ch-1]->lim_thr_min = 3; /*4V*/
+ p_tas256x->devs[ch-1]->lim_infl_pt = 13; /*3.3V*/
+ p_tas256x->devs[ch-1]->lim_trk_slp = 0; /*1 V/V*/
+ p_tas256x->devs[ch-1]->bop_thd = 4; /*2.9 V*/
+ p_tas256x->devs[ch-1]->bosd_thd = 2; /*2.7 V*/
+ p_tas256x->devs[ch-1]->bst_vltg = 0xA; /*Mode = speaker*/
+ p_tas256x->devs[ch-1]->bst_ilm = 0x36; /*0dB*/
+ p_tas256x->devs[ch-1]->ampoutput_lvl = 0x10; /*15.5dBV: 8 + 0.5 * ampoutput_lvl */
+ p_tas256x->devs[ch-1]->lim_switch = 0; /*-9dB*/
+ p_tas256x->devs[ch-1]->lim_att_rate = 1; /*9V*/
+ p_tas256x->devs[ch-1]->lim_att_stp_size = 1; /*4V*/
+ p_tas256x->devs[ch-1]->lim_rel_rate = 6; /*3.3V*/
+ p_tas256x->devs[ch-1]->lim_rel_stp_size = 1; /*1 V/V*/
+ p_tas256x->devs[ch-1]->bop_enable = 1; /*2.9 V*/
+ p_tas256x->devs[ch-1]->bop_mute = 0; /*2.7 V*/
+ p_tas256x->devs[ch-1]->bosd_enable = 0; /*3.3V*/
+ p_tas256x->devs[ch-1]->bop_att_rate = 1; /*1 V/V*/
+ p_tas256x->devs[ch-1]->bop_att_stp_size = 1; /*2.9 V*/
+ p_tas256x->devs[ch-1]->bop_hld_time = 6; /*2.7 V*/
+ p_tas256x->devs[ch-1]->vbat_lpf = 2; /*2.7 V*/
+ p_tas256x->devs[ch-1]->rx_cfg = 0;
+ p_tas256x->devs[ch-1]->classh_timer = 5;
+ p_tas256x->devs[ch-1]->reciever_enable = 0;
+ } else if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2564) {
+ p_tas256x->devs[ch-1]->rx_mode = 0; /*Mode = speaker*/
+ p_tas256x->devs[ch-1]->dvc_pcm = 55; /*0dB*/
+ p_tas256x->devs[ch-1]->lim_max_attn = 7; /*-9dB*/
+ p_tas256x->devs[ch-1]->lim_thr_max = 13; /*9V*/
+ p_tas256x->devs[ch-1]->lim_thr_min = 3; /*4V*/
+ p_tas256x->devs[ch-1]->lim_infl_pt = 13; /*3.3V*/
+ p_tas256x->devs[ch-1]->lim_trk_slp = 0; /*1 V/V*/
+ p_tas256x->devs[ch-1]->bop_thd = 4; /*2.9 V*/
+ p_tas256x->devs[ch-1]->bosd_thd = 2; /*2.7 V*/
+ p_tas256x->devs[ch-1]->bst_vltg = 13; /*Mode = speaker*/
+ p_tas256x->devs[ch-1]->bst_ilm = 0x39; /*0dB*/
+ p_tas256x->devs[ch-1]->ampoutput_lvl = 0xD; /*16dBV: 9.5 + 0.5 * ampoutput_lvl */
+ p_tas256x->devs[ch-1]->lim_switch = 0; /*-9dB*/
+ p_tas256x->devs[ch-1]->lim_att_rate = 1; /*9V*/
+ p_tas256x->devs[ch-1]->lim_att_stp_size = 1; /*4V*/
+ p_tas256x->devs[ch-1]->lim_rel_rate = 6; /*3.3V*/
+ p_tas256x->devs[ch-1]->lim_rel_stp_size = 1; /*1 V/V*/
+ p_tas256x->devs[ch-1]->bop_enable = 1; /*2.9 V*/
+ p_tas256x->devs[ch-1]->bop_mute = 0; /*2.7 V*/
+ p_tas256x->devs[ch-1]->bosd_enable = 0; /*3.3V*/
+ p_tas256x->devs[ch-1]->bop_att_rate = 1; /*1 V/V*/
+ p_tas256x->devs[ch-1]->bop_att_stp_size = 1; /*2.9 V*/
+ p_tas256x->devs[ch-1]->bop_hld_time = 6; /*2.7 V*/
+ p_tas256x->devs[ch-1]->vbat_lpf = 2; /*2.7 V*/
+ p_tas256x->devs[ch-1]->rx_cfg = 0;
+ p_tas256x->devs[ch-1]->classh_timer = 5;
+ p_tas256x->devs[ch-1]->reciever_enable = 0;
+ }
+ p_tas256x->icn_sw = 0;
+ p_tas256x->mn_rx_slot_map[0] = 0;
+ p_tas256x->mn_rx_slot_map[1] = 1;
+ return n_result;
+}
+
+int tas256x_set_power_up(struct tas256x_priv *p_tas256x,
+ enum channel chn)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->update_bits(p_tas256x,
+ chn, TAS256X_POWERCONTROL,
+ TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK,
+ TAS256X_POWERCONTROL_OPERATIONALMODE10_ACTIVE);
+
+ /* Let Power on the device */
+ usleep_range(2000, 2100);
+ /* Enable Comparator Hysteresis */
+ n_result = p_tas256x->update_bits(p_tas256x, chn,
+ TAS256X_MISC_CLASSD,
+ TAS256X_CMP_HYST_MASK,
+ (0x01 << TAS256X_CMP_HYST_SHIFT));
+
+ return n_result;
+}
+
+int tas256x_set_power_mute(struct tas256x_priv *p_tas256x,
+ enum channel chn)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->update_bits(p_tas256x, chn,
+ TAS256X_POWERCONTROL,
+ TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK,
+ TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE);
+
+ return n_result;
+}
+
+int tas256x_set_power_shutdown(struct tas256x_priv *p_tas256x,
+ enum channel chn)
+{
+ int n_result = 0;
+
+ /*Disable Comparator Hysteresis befor Power Down */
+ n_result = p_tas256x->update_bits(p_tas256x, chn,
+ TAS256X_MISC_CLASSD,
+ TAS256X_CMP_HYST_MASK,
+ (0x00 << TAS256X_CMP_HYST_SHIFT));
+
+ n_result = p_tas256x->update_bits(p_tas256x, chn,
+ TAS256X_POWERCONTROL,
+ TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK,
+ TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN);
+
+ return n_result;
+}
+
+int tas256x_power_check(struct tas256x_priv *p_tas256x, int *state, int ch)
+{
+ int n_result = 0;
+ int status;
+
+ n_result = p_tas256x->read(p_tas256x, ch,
+ TAS256X_POWERCONTROL, &status);
+
+ status &= TAS256X_POWERCONTROL_OPERATIONALMODE10_MASK;
+
+ if ((status != TAS256X_POWERCONTROL_OPERATIONALMODE10_SHUTDOWN)
+ && (status != TAS256X_POWERCONTROL_OPERATIONALMODE10_MUTE))
+ *state = 1;
+ else
+ *state = 0;
+
+ return n_result;
+}
+
+/*
+ *bool enable = 1; IV Sense Power UP = 0;
+ * IV Sense Power Down
+ */
+int tas256x_iv_sense_enable_set(struct tas256x_priv *p_tas256x, bool enable,
+ int ch)
+{
+ int n_result = 0;
+
+ if (enable) /*IV Sense Power Up*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_POWERCONTROL,
+ TAS256X_POWERCONTROL_ISNSPOWER_MASK |
+ TAS256X_POWERCONTROL_VSNSPOWER_MASK,
+ TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE |
+ TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE);
+ else /*IV Sense Power Down*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_POWERCONTROL,
+ TAS256X_POWERCONTROL_ISNSPOWER_MASK |
+ TAS256X_POWERCONTROL_VSNSPOWER_MASK,
+ TAS256X_POWERCONTROL_VSNSPOWER_POWEREDDOWN |
+ TAS256X_POWERCONTROL_ISNSPOWER_POWEREDDOWN);
+
+ p_tas256x->iv_enable = enable;
+ return n_result;
+}
+
+bool tas256x_iv_sense_enable_get(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+ bool enable = 0;
+ int value = 0;
+
+ n_result = p_tas256x->read(p_tas256x, ch,
+ TAS256X_POWERCONTROL, &value);
+ if (n_result < 0)
+ pr_err("%s can't get ivsensor state %s, L=%d\n",
+ LOG_TAG, __func__, __LINE__);
+ else if (((value & TAS256X_POWERCONTROL_ISNSPOWER_MASK)
+ == TAS256X_POWERCONTROL_ISNSPOWER_ACTIVE)
+ && ((value & TAS256X_POWERCONTROL_VSNSPOWER_MASK)
+ == TAS256X_POWERCONTROL_VSNSPOWER_ACTIVE)) {
+ enable = TAS256X_IVSENSER_ENABLE;
+ } else {
+ enable = TAS256X_IVSENSER_DISABLE;
+ }
+ return enable;
+}
+
+/*No need channel argument*/
+int tas256x_set_iv_slot(struct tas256x_priv *p_tas256x, int ch, int vslot,
+ int islot)
+{
+ int n_result = 0;
+
+ vslot |= TAS256X_TDMCONFIGURATIONREG5_VSNSTX_ENABLE;
+ islot |= TAS256X_TDMCONFIGURATIONREG6_ISNSTX_ENABLE;
+ n_result |= p_tas256x->write(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG5, vslot);
+
+ n_result |= p_tas256x->write(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG6, islot);
+
+ return n_result;
+}
+
+int tas256x_set_vbat_slot(struct tas256x_priv *p_tas256x, int ch, int slot)
+{
+ int n_result = 0;
+
+ slot |= TAS256X_TDMCONFIGURATIONREG7_VBATTX_ENABLE;
+ n_result |= p_tas256x->write(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG7,
+ slot);
+
+ return n_result;
+}
+
+/*No need channel argument*/
+int tas256x_iv_bitwidth_config(struct tas256x_priv *p_tas256x, int bitwidth,
+ int ch)
+{
+ int n_result = 0;
+
+ if (bitwidth == 8)
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_IVMONLEN76_8BITS);
+ else if (p_tas256x->mn_iv_width == 12)
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_12BITS);
+ else /*mn_iv_width == 16*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_IVLEN76_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_IVLENCFG76_16BITS);
+
+ return n_result;
+}
+
+int tas256x_set_auto_detect_clock(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = 0;
+
+ if (value == 0)
+ value = TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_DISABLED;
+ else
+ value = TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_ENABLED;
+
+ /*Set Sample Rate for auto detection only in case of TDM*/
+ n_result = p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_DETECTSAMPRATE_MASK,
+ value);
+
+ return n_result;
+}
+
+/**/
+int tas256x_set_samplerate(struct tas256x_priv *p_tas256x,
+ int samplerate, int ch)
+{
+ int n_result = 0;
+
+ switch (samplerate) {
+ case 48000:
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ);
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ);
+ break;
+ case 44100:
+ n_result = p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ);
+ n_result |= p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_44_1_48KHZ);
+ break;
+ case 96000:
+ n_result = p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ);
+ n_result |= p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ);
+ break;
+ case 88200:
+ n_result = p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ);
+ n_result |= p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_88_2_96KHZ);
+ break;
+ case 19200:
+ n_result = p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_48KHZ);
+ n_result |= p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ);
+ break;
+ case 17640:
+ n_result = p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATERAMP_44_1KHZ);
+ n_result |= p_tas256x->update_bits(p_tas256x, channel_both,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_MASK,
+ TAS256X_TDMCONFIGURATIONREG0_SAMPRATE31_176_4_192KHZ);
+ break;
+ default:
+ n_result = -1;
+ pr_info("%s %s, unsupported sample rate, %d\n",
+ LOG_TAG, __func__, samplerate);
+ }
+
+ if (n_result == 0)
+ p_tas256x->mn_sampling_rate = samplerate;
+
+ return n_result;
+}
+
+/*
+ *rx_edge = 0; Rising
+ *= 1; Falling
+ */
+int tas256x_tx_set_edge(struct tas256x_priv *p_tas256x,
+ unsigned int tx_edge, int ch)
+{
+ int n_result = 0;
+
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMConfigurationReg4,
+ TAS256X_TDMCONFIGURATIONREG4_TXEDGE_MASK,
+ (tx_edge << TAS256X_TDMCONFIGURATIONREG4_TXEDGE_SHIFT));
+
+ if (n_result == 0)
+ p_tas256x->mn_tx_edge = tx_edge;
+
+ return n_result;
+}
+
+/*
+ *rx_edge = 0; Rising
+ *= 1; Falling
+ */
+int tas256x_rx_set_edge(struct tas256x_priv *p_tas256x,
+ unsigned int rx_edge, int ch)
+{
+ int n_result = 0;
+
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG1,
+ TAS256X_TDMCONFIGURATIONREG1_RXEDGE_MASK,
+ (rx_edge << TAS256X_TDMCONFIGURATIONREG1_RXEDGE_SHIFT));
+
+ if (n_result == 0)
+ p_tas256x->mn_rx_edge = rx_edge;
+
+ return n_result;
+}
+int tas256x_rx_set_start_slot(struct tas256x_priv *p_tas256x,
+ unsigned int rx_start_slot, int ch)
+{
+ int n_result = 0;
+
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG1,
+ TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_MASK,
+ (rx_start_slot <<
+ TAS256X_TDMCONFIGURATIONREG1_RXOFFSET51_SHIFT));
+
+ if (n_result == 0)
+ p_tas256x->mn_rx_offset = rx_start_slot;
+
+ return n_result;
+}
+
+int tas256x_tx_set_start_slot(struct tas256x_priv *p_tas256x,
+ unsigned int tx_start_slot, int ch)
+{
+ int n_result = 0;
+
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMConfigurationReg4,
+ TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_MASK,
+ (tx_start_slot <<
+ TAS256X_TDMCONFIGURATIONREG4_TXOFFSET31_SHIFT));
+
+ if (n_result == 0)
+ p_tas256x->mn_tx_offset = tx_start_slot;
+
+ return n_result;
+}
+
+int tas256x_rx_set_frame_start(struct tas256x_priv *p_tas256x,
+ unsigned int frame_start, int ch)
+{
+ int n_result = 0;
+
+ p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG0,
+ TAS256X_TDMCONFIGURATIONREG0_FRAMESTART_MASK,
+ frame_start);
+
+ if (n_result == 0)
+ p_tas256x->mn_frame_start = frame_start;
+
+ return n_result;
+}
+
+int tas256x_rx_set_slot_len(struct tas256x_priv *p_tas256x,
+ int slot_width, int ch)
+{
+ int n_result = -1;
+
+ switch (slot_width) {
+ case 16:
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_16BITS);
+ break;
+ case 24:
+ case 32:
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_RXSLEN10_32BITS);
+ break;
+ case 0:
+ /* Do not change slot width */
+ break;
+ }
+
+ if (n_result == 0)
+ p_tas256x->mn_rx_slot_width = slot_width;
+
+ return n_result;
+}
+
+int tas256x_rx_set_slot(struct tas256x_priv *p_tas256x,
+ int slot, int ch)
+{
+ int n_result = -1;
+ if (ch == channel_right)
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG3,
+ TAS256X_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_MASK,
+ (slot << TAS256X_TDMCONFIGURATIONREG3_RXSLOTRIGHT74_SHIFT));
+ else/*Assumed Left*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG3,
+ TAS256X_TDMCONFIGURATIONREG3_RXSLOTLeft30_Mask,
+ (slot << TAS256X_TDMCONFIGURATIONREG3_RXSLOTLeft30_SHIFT));
+
+ if (n_result == 0)
+ p_tas256x->mn_rx_slot_map[ch-1] = slot;
+ return n_result;
+}
+
+int tas256x_rx_set_bitwidth(struct tas256x_priv *p_tas256x,
+ int bitwidth, int ch)
+{
+ int n_result = -1;
+
+ switch (bitwidth) {
+ case 16:
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_16BITS);
+ break;
+ case 24:
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_24BITS);
+ break;
+ case 32:
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_MASK,
+ TAS256X_TDMCONFIGURATIONREG2_RXWLEN32_32BITS);
+ break;
+ default:
+ pr_info("%s Not supported params format\n", LOG_TAG);
+ break;
+ }
+
+ if (n_result == 0)
+ p_tas256x->mn_rx_width = bitwidth;
+
+ return n_result;
+}
+
+int tas256x_interrupt_clear(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_INTERRUPTCONFIGURATION,
+ TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR_MASK,
+ TAS256X_INTERRUPTCONFIGURATION_LTCHINTCLEAR);
+
+ return n_result;
+}
+
+int tas256x_interrupt_enable(struct tas256x_priv *p_tas256x,
+ int val, int ch)
+{
+ int n_result = 0;
+
+ if (val) {
+ /*Enable Interrupts*/
+ n_result = p_tas256x->write(p_tas256x, ch,
+ TAS256X_INTERRUPTMASKREG0, 0xf8);
+ n_result |= p_tas256x->write(p_tas256x, ch,
+ TAS256X_INTERRUPTMASKREG1, 0xb1);
+ } else {
+ /*Disable Interrupts*/
+ n_result = p_tas256x->write(p_tas256x, ch,
+ TAS256X_INTERRUPTMASKREG0,
+ TAS256X_INTERRUPTMASKREG0_DISABLE);
+ n_result |= p_tas256x->write(p_tas256x, ch,
+ TAS256X_INTERRUPTMASKREG1,
+ TAS256X_INTERRUPTMASKREG1_DISABLE);
+ }
+
+ return n_result;
+}
+
+int tas256x_interrupt_read(struct tas256x_priv *p_tas256x,
+ int *intr1, int *intr2, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->read(p_tas256x, ch,
+ TAS256X_LATCHEDINTERRUPTREG0, intr1);
+ n_result |= p_tas256x->read(p_tas256x, ch,
+ TAS256X_LATCHEDINTERRUPTREG1, intr2);
+
+ return n_result;
+}
+
+int tas256x_icn_disable(struct tas256x_priv *p_tas256x, int disable, int ch)
+{
+ int n_result = 0;
+
+ if (disable) { /*Disable*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_ICN_SW_REG,
+ TAS256X_ICN_SW_MASK,
+ TAS256X_ICN_SW_DISABLE);
+ pr_info("%s %s: ICN Disable!\n", LOG_TAG, __func__);
+ } else { /*Enable*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_ICN_SW_REG,
+ TAS256X_ICN_SW_MASK,
+ TAS256X_ICN_SW_ENABLE);
+ pr_info("%s %s: ICN Enable!\n", LOG_TAG, __func__);
+ }
+
+ if (n_result == 0)
+ p_tas256x->icn_sw = disable;
+
+ return n_result;
+}
+
+/* icn_hysteresis & p_icn_thresholds*/
+int tas256x_icn_data(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_ICN_THRESHOLD_REG,
+ p_icn_threshold,
+ sizeof(p_icn_threshold));
+ n_result |= p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_ICN_HYSTERESIS_REG,
+ p_icn_hysteresis,
+ sizeof(p_icn_hysteresis));
+
+ return n_result;
+}
+
+int tas256x_icn_config(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->write(p_tas256x, ch,
+ TAS256X_REG(0, 253, 13), 0x0d);
+
+ n_result |= p_tas256x->write(p_tas256x, ch,
+ TAS256X_REG(0, 253, 25), 0x80);
+
+ return n_result;
+}
+
+int tas256x_boost_volt_update(struct tas256x_priv *p_tas256x, int value,
+ int ch)
+{
+ int n_result = 0;
+
+ if (value == DEVICE_TAS2558) {
+ /* Max voltage to 9V */
+ /*TODO: Need to be fixed*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS2562_BOOSTCONFIGURATION2,
+ TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK,
+ 0x7);
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS2562_PLAYBACKCONFIGURATIONREG0,
+ TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK,
+ 0xd << 1);
+ } else if (value == DEVICE_TAS2562) {
+ /*TODO: ??*/
+ } else if (value == DEVICE_TAS2564) {
+ /*Update Channel Gain to 16dBV*/
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS2564_PLAYBACKCONFIGURATIONREG0,
+ TAS2564_PLAYBACKCONFIGURATION_AMP_LEVEL_MASK,
+ TAS2564_AMP_LEVEL_16dBV);
+ }
+ return n_result;
+}
+
+int tas256x_set_misc_config(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->write(p_tas256x, ch,
+ TAS256X_MISCCONFIGURATIONREG0, 0xcf);
+
+ return n_result;
+
+}
+
+int tas256x_set_tx_config(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = 0;
+
+#if IS_ENABLED(CONFIG_PLATFORM_EXYNOS)
+ if (p_tas256x->mn_channels == 2) {
+ n_result = p_tas256x->write(p_tas256x, channel_left,
+ TAS256X_TDMConfigurationReg4, 0xf3);
+ if (n_result < 0)
+ return n_result;
+ n_result = p_tas256x->write(p_tas256x, channel_right,
+ TAS256X_TDMConfigurationReg4, 0x13);
+ if (n_result < 0)
+ return n_result;
+ } else {
+ n_result = p_tas256x->write(p_tas256x, channel_both,
+ TAS256X_TDMConfigurationReg4, 0x03);
+ if (n_result < 0)
+ return n_result;
+ }
+#else
+ if (p_tas256x->mn_channels == 2) {
+ n_result = p_tas256x->write(p_tas256x, channel_left,
+ TAS256X_TDMConfigurationReg4, 0xf1);
+ if (n_result < 0)
+ return n_result;
+ n_result = p_tas256x->write(p_tas256x, channel_right,
+ TAS256X_TDMConfigurationReg4, 0x11);
+ if (n_result < 0)
+ return n_result;
+ } else {
+ n_result = p_tas256x->write(p_tas256x, channel_both,
+ TAS256X_TDMConfigurationReg4, 0x01);
+ if (n_result < 0)
+ return n_result;
+ }
+#endif
+
+ return n_result;
+}
+
+int tas256x_set_clock_config(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = 0;
+
+ if (p_tas256x->mn_fmt_mode == 2) {/*TDM Mode*/
+ n_result = p_tas256x->write(p_tas256x, ch,
+ TAS256X_CLOCKCONFIGURATION, 0x19);
+ } else {
+ n_result = p_tas256x->write(p_tas256x, ch,
+ TAS256X_CLOCKCONFIGURATION, 0x0c);
+ }
+ /* Increase the clock halt timer to 838ms to avoid
+ * TDM Clock errors during playback start/stop
+ */
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_INTERRUPTCONFIGURATION,
+ TAS256X_CLOCK_HALT_TIMER_MASK,
+ TAS256X_CLOCK_HALT_838MS);
+
+ return n_result;
+}
+
+int tas256x_set_classH_config(struct tas256x_priv *p_tas256x, int value,
+ int ch)
+{
+ int n_result = 0;
+
+ n_result = tas256x_i2c_load_data(p_tas256x, ch,
+ p_tas256x_classh_d_data);
+
+ return n_result;
+}
+
+int tas256x_HPF_FF_Bypass(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_PLAYBACKCONFIGURATIONREG0,
+ TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_MASK,
+ TAS256X_PLAYBACKCONFIGURATIONREG0_DCBLOCKER_DISABLED);
+
+ return n_result;
+}
+
+int tas256x_HPF_FB_Bypass(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_HPF, HPF_reverse_path,
+ sizeof(HPF_reverse_path)/sizeof(HPF_reverse_path[0]));
+
+ return n_result;
+
+}
+
+int tas56x_software_reset(struct tas256x_priv *p_tas256x, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->write(p_tas256x, ch, TAS256X_SOFTWARERESET,
+ TAS256X_SOFTWARERESET_SOFTWARERESET_RESET);
+
+ msleep(20);
+
+ return n_result;
+}
+
+int tas256x_interrupt_determine(struct tas256x_priv *p_tas256x, int ch,
+ int int1status, int int2status)
+{
+ int mn_err_code = 0;
+
+ if (((int1status & 0x7) != 0)
+ || ((int2status & 0x0f) != 0)) {
+
+ if (int1status &
+ TAS256X_LATCHEDINTERRUPTREG0_TDMCLOCKERRORSTICKY_INTERRUPT) {
+ mn_err_code |= ERROR_CLOCK;
+ pr_err("%s TDM clock error!\n", LOG_TAG);
+ }
+
+ if (int1status &
+ TAS256X_LATCHEDINTERRUPTREG0_OCEFLAGSTICKY_INTERRUPT) {
+ mn_err_code |= ERROR_OVER_CURRENT;
+ pr_err("%s SPK over current!\n", LOG_TAG);
+ }
+
+ if (int1status &
+ TAS256X_LATCHEDINTERRUPTREG0_OTEFLAGSTICKY_INTERRUPT) {
+ mn_err_code |= ERROR_DIE_OVERTEMP;
+ pr_err("%s die over temperature!\n", LOG_TAG);
+ }
+
+ if (int2status &
+ TAS256X_LATCHEDINTERRUPTREG1_VBATOVLOSTICKY_INTERRUPT) {
+ mn_err_code |= ERROR_OVER_VOLTAGE;
+ pr_err("%s SPK over voltage!\n", LOG_TAG);
+ }
+
+ if (int2status &
+ TAS256X_LATCHEDINTERRUPTREG1_VBATUVLOSTICKY_INTERRUPT) {
+ mn_err_code |= ERROR_UNDER_VOLTAGE;
+ pr_err("%s SPK under voltage!\n", LOG_TAG);
+ }
+
+ if (int2status &
+ TAS256X_LATCHEDINTERRUPTREG1_BROWNOUTFLAGSTICKY_INTERRUPT) {
+ mn_err_code |= ERROR_BROWNOUT;
+ pr_err("%s brownout!\n", LOG_TAG);
+ }
+ } else {
+ return 0;
+ }
+
+ return mn_err_code;
+}
+
+int tas56x_get_chipid(struct tas256x_priv *p_tas256x, int *chipid, int ch)
+{
+ int n_result = 0;
+
+ n_result = p_tas256x->read(p_tas256x, ch,
+ TAS256X_CHIPID, chipid);
+
+ return n_result;
+}
+
+int tas2564_rx_mode_update(struct tas256x_priv *p_tas256x, int rx_mode, int ch)
+{
+ int n_result = 0;
+
+ if (rx_mode)
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS2564_PLAYBACKCONFIGURATIONREG0,
+ TAS2564_PLAYBACKCONFIGURATIONREG_RX_SPKR_MODE_MASK,
+ TAS2564_PLAYBACKCONFIGURATIONREG_RX_MODE);
+ else
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS2564_PLAYBACKCONFIGURATIONREG0,
+ TAS2564_PLAYBACKCONFIGURATIONREG_RX_SPKR_MODE_MASK,
+ TAS2564_PLAYBACKCONFIGURATIONREG_SPKR_MODE);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->rx_mode = rx_mode;
+
+ return n_result;
+}
+
+int tas256x_update_playback_volume(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 57)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_DVC_PCM,
+ (char *)&(dvc_pcm[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->dvc_pcm = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_lim_max_attenuation(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 16)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_LIM_MAX_ATN,
+ (char *)&(lim_max_attn[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_max_attn = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_lim_max_thr(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 27)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_LIMB_TH_MAX,
+ (char *)&(vbat_lim_max_thd[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_thr_max = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_lim_min_thr(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 27)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_LIMB_TH_MIN,
+ (char *)&(vbat_lim_min_thd[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_thr_min = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_lim_inflection_point(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 41)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_LIMB_INF_PT,
+ (char *)&(vbat_lim_infl_pt[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_infl_pt = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_lim_slope(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 7)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_LIMB_SLOPE,
+ (char *)&(vbat_lim_track_slope[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_trk_slp = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_bop_thr(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 16)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_BOP_TH,
+ (char *)&(bop_thd[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bop_thd = value;
+ }
+ return n_result;
+}
+
+int tas256x_update_bosd_thr(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 16)) {
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_BOSD_TH,
+ (char *)&(bsd_thd[value][0]), sizeof(int));
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bosd_thd = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_boost_voltage(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2562) {
+ if ((value >= 0) && (value < 16))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS2562_BOOSTCONFIGURATION2,
+ TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK,
+ (value+1) << TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_SHIFT);
+ } else if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2564) {
+ if ((value >= 0) && (value < 32))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS2564_BOOSTCONFIGURATION2,
+ TAS2564_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_MASK,
+ (value+7) << TAS2562_BOOSTCONFIGURATION2_BOOSTMAXVOLTAGE_SHIFT);
+ }
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bst_vltg = value;
+
+ return n_result;
+}
+
+int tas256x_update_ampoutput_level(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 1) && (value < 0x1C)) {
+ if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2562) {
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS2562_PLAYBACKCONFIGURATIONREG0,
+ TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK,
+ value << TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_SHIFT);
+ } else if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2564) {
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS2564_PLAYBACKCONFIGURATIONREG0,
+ TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_MASK,
+ value << TAS2562_PLAYBACKCONFIGURATIONREG0_AMPLIFIERLEVEL51_SHIFT);
+ }
+ }
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->ampoutput_lvl = value;
+
+ return n_result;
+}
+
+int tas256x_update_current_limit(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 64))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOOSTCONFIGURATION4,
+ TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_MASK,
+ (value) << TAS256X_BOOSTCONFIGURATION4_BOOSTCURRENTLIMIT_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bst_ilm = value;
+
+ return n_result;
+}
+
+int tas256x_update_limiter_enable(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 2))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_LIMITERCONFIGURATION0,
+ TAS256X_LIMITER_ENABLE_MASK,
+ (value) << TAS256X_LIMITER_ENABLE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_switch = value;
+
+ return n_result;
+}
+
+int tas256x_update_limiter_attack_rate(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 8))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_LIMITERCONFIGURATION0,
+ TAS256X_LIMITER_ATTACKRATE_MASK,
+ (value) << TAS256X_LIMITER_ATTACKRATE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_att_rate = value;
+
+ return n_result;
+}
+
+int tas256x_update_limiter_attack_step_size(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 4))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_LIMITERCONFIGURATION0,
+ TAS256X_LIMITER_ATTACKSTEPSIZE_MASK,
+ (value) << TAS256X_LIMITER_ATTACKSTEPSIZE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_att_stp_size = value;
+
+ return n_result;
+}
+
+int tas256x_update_limiter_release_rate(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 8))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_LIMITERCONFIGURATION1,
+ TAS256X_LIMITER_RELEASERATE_MASK,
+ (value) << TAS256X_LIMITER_RELEASERATE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_rel_rate = value;
+
+ return n_result;
+}
+
+int tas256x_update_limiter_release_step_size(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 4))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_LIMITERCONFIGURATION1,
+ TAS256X_LIMITER_RELEASESTEPSIZE_MASK,
+ (value) << TAS256X_LIMITER_RELEASESTEPSIZE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->lim_rel_stp_size = value;
+
+ return n_result;
+}
+
+int tas256x_update_bop_enable(struct tas256x_priv *p_tas256x, int value,
+ int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 2))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOPCONFIGURATION0,
+ TAS256X_BOP_ENABLE_MASK,
+ (value) << TAS256X_BOP_ENABLE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bop_enable = value;
+
+ return n_result;
+}
+
+int tas256x_update_bop_mute(struct tas256x_priv *p_tas256x, int value,
+ int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 2))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOPCONFIGURATION0,
+ TAS256X_BOP_MUTE_MASK,
+ (value) << TAS256X_BOP_MUTE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bop_mute = value;
+
+ return n_result;
+}
+
+int tas256x_update_bop_shutdown_enable(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 2))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOPCONFIGURATION0,
+ TAS256X_BOP_SHUTDOWN_ENABLE_MASK,
+ (value) << TAS256X_BOP_SHUTDOWN_ENABLE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bosd_enable = value;
+
+ return n_result;
+}
+
+int tas256x_update_bop_attack_rate(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 8))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOPCONFIGURATION1,
+ TAS256X_BOP_ATTACKRATE_MASK,
+ (value) << TAS256X_BOP_ATTACKRATE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bop_att_rate = value;
+
+ return n_result;
+}
+
+int tas256x_update_bop_attack_step_size(struct tas256x_priv *p_tas256x,
+ int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 4))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOPCONFIGURATION1,
+ TAS256X_BOP_ATTACKSTEPSIZE_MASK,
+ (value) << TAS256X_BOP_ATTACKSTEPSIZE_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bop_att_stp_size = value;
+
+ return n_result;
+}
+
+int tas256x_update_bop_hold_time(struct tas256x_priv *p_tas256x, int value,
+ int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 8))
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_BOPCONFIGURATION1,
+ TAS256X_BOP_HOLDTIME_MASK,
+ (value) << TAS256X_BOP_HOLDTIME_SHIFT);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->bop_hld_time = value;
+
+ return n_result;
+}
+
+int tas256x_update_vbat_lpf(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = -1;
+
+ if ((value >= 0) && (value < 4)) {
+ n_result = p_tas256x->update_bits(p_tas256x,
+ ch, TAS256X_VBATFILTER,
+ TAS256X_VBAT_LPF_MASK,
+ (value) << TAS256X_VBAT_LPF_SHIFT);
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->vbat_lpf = value;
+ }
+
+ return n_result;
+}
+
+int tas256x_update_rx_cfg(struct tas256x_priv *p_tas256x, int value, int ch)
+{
+ int n_result = -1;
+ int data = -1;
+
+ switch (value) {
+ case 0:
+ data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_I2C;
+ break;
+ case 1:
+ data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_LEFT;
+ break;
+ case 2:
+ data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MONO_RIGHT;
+ break;
+ case 3:
+ data = TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_STEREO_DOWNMIX;
+ break;
+ }
+
+ if (data >= 0)
+ n_result = p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_TDMCONFIGURATIONREG2,
+ TAS256X_TDMCONFIGURATIONREG2_RXSCFG54_MASK,
+ data);
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->rx_cfg = value;
+
+ return n_result;
+}
+
+int tas256x_update_classh_timer(struct tas256x_priv *p_tas256x, int value,
+ int ch)
+{
+ int n_result = -1;
+
+ /*value = 255/(0.07*value)*/
+ if (p_tas256x->devs[ch-1]->device_id == DEVICE_TAS2564) {
+ n_result =
+ p_tas256x->write(p_tas256x, ch, TAS2564_CLASSH_SLOPE,
+ classH_slope[value]);
+ }
+
+ n_result = p_tas256x->bulk_write(p_tas256x, ch,
+ TAS256X_CLASSH_TIMER,
+ (char *)&(classH_timer[value][0]), sizeof(int));
+
+ value += 8; /*Offset*/
+
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_CLASSH_TIMER_RELEASE,
+ TAS256X_CLASSH_TIMER_RELEASE_MASK,
+ value+1);
+
+ value -= 8;
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->classh_timer = value;
+
+ return n_result;
+}
+
+int tas256x_enable_reciever_mode(struct tas256x_priv *p_tas256x, int enable,
+ int ch)
+{
+ int n_result = -1;
+
+ if (enable) {
+ /*Unlock test page*/
+ n_result =
+ p_tas256x->write(p_tas256x, ch, TAS256X_TEST_PAGE_LOCK,
+ 0xd);
+ /*Keep DAC modulator dither to minimum*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_DAC_MODULATOR,
+ 0xc0);
+ /*Force DAC unmute*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_DAC_MUTE,
+ 0x04);
+ /*Force the device in idle channel mode*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_ICN_MODE,
+ 0x14);
+ /* ICN improvement*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_ICN_IMPROVE,
+ 0x1f);
+ /*Enable IRQ pull-up, disable SSM*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch,
+ TAS256X_MISCCONFIGURATIONREG0,
+ 0xca);
+ /*Mask reaction of idle channel detect on IV sense*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_ICN_SW_REG,
+ 0x02);
+ } else {
+ /*Unlock test page*/
+ n_result =
+ p_tas256x->write(p_tas256x, ch, TAS256X_TEST_PAGE_LOCK,
+ 0xd);
+ /*Keep DAC modulator dither to minimum*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_DAC_MODULATOR,
+ 0x00);
+ /*Force DAC unmute*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_DAC_MUTE,
+ 0x00);
+ /*Force the device in idle channel mode*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_ICN_MODE,
+ 0x10);
+ /* ICN improvement*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch, TAS256X_ICN_IMPROVE,
+ 0x1d);
+ /*Enable IRQ pull-up, disable SSM*/
+ n_result |=
+ p_tas256x->write(p_tas256x, ch,
+ TAS256X_MISCCONFIGURATIONREG0,
+ 0xcf);
+ /*Mask reaction of idle channel detect on IV sense*/
+ n_result |= p_tas256x->update_bits(p_tas256x, ch,
+ TAS256X_ICN_SW_REG,
+ TAS256X_ICN_IVSENSE_MASK,
+ 0x00);
+ n_result |=
+ tas256x_icn_disable(p_tas256x, p_tas256x->icn_sw, ch);
+ }
+
+ if (n_result == 0)
+ p_tas256x->devs[ch-1]->reciever_enable = enable;
+
+ return n_result;
+} \ No newline at end of file
diff --git a/asoc/kona.c b/asoc/kona.c
index acf81a80..edacc1f8 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -4841,6 +4841,10 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
}
}
#endif
+#if IS_ENABLED(CONFIG_SND_SOC_TAS256X)
+ if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX)
+ slots = 4;
+#endif
/*2 slot config - bits 0 and 1 set for the first two slots */
slot_mask = 0x0000FFFF >> (16 - slots);
@@ -4864,6 +4868,27 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
__func__, ret);
goto end;
}
+#if IS_ENABLED(CONFIG_SND_SOC_TAS256X)
+ if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_RX) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, slot_mask,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm tx slot for codec, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_CBS_CFS |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_DSP_A);
+ if (ret < 0) {
+ pr_err("%s: failed to set rx fmt for codec, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+#endif
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
#if IS_ENABLED(CONFIG_SND_SOC_CS35L41)
if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX) {
@@ -4877,6 +4902,10 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
}
}
#endif
+#if IS_ENABLED(CONFIG_SND_SOC_TAS256X)
+ if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX)
+ slots = 4;
+#endif
/*2 slot config - bits 0 and 1 set for the first two slots */
slot_mask = 0x0000FFFF >> (16 - slots);
@@ -4904,6 +4933,27 @@ static int kona_tdm_snd_hw_params(struct snd_pcm_substream *substream,
__func__, ret);
goto end;
}
+#if IS_ENABLED(CONFIG_SND_SOC_TAS256X)
+ if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX) {
+ ret = snd_soc_dai_set_tdm_slot(codec_dai, slot_mask, 0,
+ slots, slot_width);
+ if (ret < 0) {
+ pr_err("%s: failed to set tdm tx slot for codec, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_CBS_CFS |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_DSP_A);
+ if (ret < 0) {
+ pr_err("%s: failed to set rx fmt for codec, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+ }
+#endif
} else {
ret = -EINVAL;
pr_err("%s: invalid use case, err:%d\n",
@@ -7425,7 +7475,7 @@ static struct snd_soc_dai_link msm_tdm_fe_dai_link[] = {
.codec_dai_name = "snd-soc-dummy-dai",
.codec_name = "snd-soc-dummy",
},
-#if IS_ENABLED(CONFIG_SND_SOC_CS35L41)
+#if IS_ENABLED(CONFIG_SND_SOC_CS35L41) || IS_ENABLED(CONFIG_SND_SOC_TAS256X)
{
.name = "Quinary TDM TX 0 Hostless",
.stream_name = "Quinary TDM TX 0 Hostless",
diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c
index 6fce8798..667c7f8e 100644
--- a/asoc/msm-dai-fe.c
+++ b/asoc/msm-dai-fe.c
@@ -2105,7 +2105,7 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
.name = "QUIN_TDM_RX_0_HOSTLESS",
.probe = fe_dai_probe,
},
-#if IS_ENABLED(CONFIG_SND_SOC_CS35L41)
+#if IS_ENABLED(CONFIG_SND_SOC_CS35L41) || IS_ENABLED(CONFIG_SND_SOC_TAS256X)
{
.capture = {
.stream_name = "Quinary TDM0 Hostless Capture",
diff --git a/config/litoauto.conf b/config/litoauto.conf
index 25d8031f..0af06d24 100644
--- a/config/litoauto.conf
+++ b/config/litoauto.conf
@@ -42,3 +42,8 @@ CONFIG_SND_SOC_RT5514=m
CONFIG_SND_SOC_RT5514_SPI=m
CONFIG_MI2S_DISABLE=m
CONFIG_AUXPCM_DISABLE=m
+CONFIG_SND_SOC_TAS256X=m
+CONFIG_TAS256X_MISC=y
+CONFIG_PLATFORM_QCOM=y
+CONFIG_TAS25XX_ALGO=y
+CONFIG_TISA_KBIN_INTF=y
diff --git a/config/litoautoconf.h b/config/litoautoconf.h
index e0da4d17..cfd489c4 100644
--- a/config/litoautoconf.h
+++ b/config/litoautoconf.h
@@ -45,3 +45,12 @@
#define CONFIG_SND_SOC_RT5514 1
#define CONFIG_SND_SOC_RT5514_SPI 1
#define CONFIG_AUXPCM_DISABLE 1
+#define CONFIG_SND_SOC_TAS256X 1
+#define CONFIG_TAS256X_REGMAP 1
+#define CONFIG_TAS256X_CODEC 1
+#define CONFIG_TAS256X_MISC 1
+#define CONFIG_TAS256X_REGBIN_PARSER 1
+#define CONFIG_TAS25XX_ALGO 1
+#define CONFIG_PLATFORM_QCOM 1
+#define CONFIG_TISA_KBIN_INTF 1
+#define CONFIG_TAS25XX_ALGO_STEREO 1
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 65796915..e7cba919 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -22,6 +22,19 @@
#include <ipc/apr_tal.h>
#include "adsp_err.h"
#include "q6afecal-hwdep.h"
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#include <dsp/tas_qualcomm.h>
+#endif
+
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+#ifdef INSTANCE_ID_0 /*APR Version 3*/
+static int32_t tas_smartamp_algo_callback(uint32_t opcode, uint32_t *payload,
+ uint32_t payload_size);
+#else /*APR Version 2*/
+static int32_t tas_smartamp_algo_callback(uint32_t *payload,
+ uint32_t payload_size);
+#endif /*INSTANCE_ID_0*/
+#endif /*CONFIG_TAS25XX_ALGO*/
#define WAKELOCK_TIMEOUT 5000
#define AFE_CLK_TOKEN 1024
@@ -247,6 +260,11 @@ struct afe_ctl {
/* FTM spk params */
uint32_t initial_cal;
uint32_t v_vali_flag;
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+ struct afe_smartamp_calib_get_resp tas_calib_data;
+ uint32_t tas_module_rx;
+ uint32_t tas_module_tx;
+#endif /*CONFIG_TAS25XX_ALGO*/
uint32_t num_spkrs;
uint32_t cps_ch_mask;
struct afe_cps_hw_intf_cfg *cps_config;
@@ -945,9 +963,28 @@ static int32_t afe_callback(struct apr_client_data *data, void *priv)
av_dev_drift_afe_cb_handler(data->opcode, data->payload,
data->payload_size);
} else {
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+ u32 *payload32 = data->payload;
+ pr_debug("TI-SmartPA: payload1 = 0x%x, 0x%x", payload32[0], payload32[1]);
+
+ if ((payload32[1] == this_afe.tas_module_rx) ||
+ (payload32[1] == this_afe.tas_module_tx)) {
+#ifdef INSTANCE_ID_0 /*APR Version 3*/
+ if (tas_smartamp_algo_callback(data->opcode, data->payload, data->payload_size))
+ return -EINVAL;
+#else /*APR Version 2*/
+ if (tas_smartamp_algo_callback(data->payload, data->payload_size))
+ return -EINVAL;
+#endif /* INSTANCE_ID_0 */
+ } else if (sp_make_afe_callback(data->opcode, data->payload,
+ data->payload_size)) {
+ return -EINVAL;
+ }
+#else
if (sp_make_afe_callback(data->opcode, data->payload,
data->payload_size))
return -EINVAL;
+#endif /*CONFIG_TAS25XX_ALGO*/
}
if (afe_token_is_valid(data->token))
wake_up(&this_afe.wait[data->token]);
@@ -6529,6 +6566,406 @@ int afe_start_pseudo_port(u16 port_id)
return ret;
}
+#if IS_ENABLED(CONFIG_TAS25XX_ALGO)
+/*For DC Detection*/
+void (*tas256x_sw_reset)(void *data);
+dc_detection_data_t *s_dc_detect;
+void register_tas256x_reset_func(void *fptr, dc_detection_data_t *data)
+{
+ pr_info("[TI-SmartPA:%s] ", __func__);
+ tas256x_sw_reset = fptr;
+ s_dc_detect = data;
+}
+EXPORT_SYMBOL(register_tas256x_reset_func);
+
+void afe_tas_smartamp_init(uint32_t module_id_rx, uint32_t module_id_tx)
+{
+ this_afe.tas_module_rx = module_id_rx;
+ this_afe.tas_module_tx = module_id_tx;
+}
+EXPORT_SYMBOL(afe_tas_smartamp_init);
+
+#ifdef INSTANCE_ID_0 /* APR Version 3 */
+static int32_t tas_smartamp_algo_callback(uint32_t opcode, uint32_t *payload,
+ uint32_t payload_size)
+{
+ struct param_hdr_v3 param_hdr;
+ u32 *data_dest = NULL;
+ u32 *data_start = NULL;
+
+ pr_debug("[TI-SmartPA:%s] ", __func__);
+ memset(&param_hdr, 0, sizeof(param_hdr));
+ switch (opcode) {
+ case AFE_PORT_CMDRSP_GET_PARAM_V2:
+ param_hdr.module_id = payload[1];
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = payload[2];
+ param_hdr.param_size = payload[3];
+ data_start = &payload[4];
+ break;
+ case AFE_PORT_CMDRSP_GET_PARAM_V3:
+ memcpy(&param_hdr, &payload[1], sizeof(struct param_hdr_v3));
+ data_start = &payload[5];
+ break;
+ default:
+ pr_err("[TI-SmartPA:%s] Unrecognized command %d\n", __func__, opcode);
+ return -EINVAL;
+ }
+ data_dest = (u32 *) &this_afe.tas_calib_data;
+ data_dest[0] = payload[0];
+ memcpy(&data_dest[1], &param_hdr, sizeof(struct param_hdr_v3));
+ memcpy(&data_dest[5], data_start, param_hdr.param_size);
+ if (param_hdr.param_id == CAPI_V2_TAS_SA_DC_DETECT) {
+ pr_err("[TI-SmartPA:%s] Detected DC, Calling TAS256X Software Reset \n", __func__);
+ s_dc_detect->channel = this_afe.tas_calib_data.res_cfg.payload[0];
+ tas256x_sw_reset(s_dc_detect);
+ }
+ if (!data_dest[0]) {
+ atomic_set(&this_afe.state, 0);
+ } else {
+ pr_debug("[TI-SmartPA:%s] status: %d", __func__, data_dest[0]);
+ atomic_set(&this_afe.state, -1);
+ }
+ return 0;
+}
+
+int afe_tas_smartamp_get_calib_data(uint32_t module_id, uint32_t param_id,
+ int32_t length, uint8_t *data, uint16_t port_id)
+{
+ int ret = -EINVAL;
+ struct param_hdr_v3 param_hdr;
+ uint32_t port = 0x0;
+
+ if (!data || length <= 0) {
+ pr_err("[TI-SmartPA:%s] Invalid params, length: %d\n",
+ __func__, length);
+ goto fail_cmd;
+ }
+
+ pr_debug("[TI-SmartPA:%s] module id : 0x%x ", __func__, module_id);
+ if (module_id == this_afe.tas_module_rx) {
+ port = port_id;
+ } else if (module_id == this_afe.tas_module_tx) {
+ port = port_id + 1;
+ } else {
+ pr_err("[TI-SmartPA:%s] invalid module id %d\n", module_id);
+ goto fail_cmd;
+ }
+
+ memset(&param_hdr, 0, sizeof(param_hdr));
+ param_hdr.module_id = module_id;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = param_id;
+ param_hdr.param_size = sizeof(struct afe_smartamp_get_calib);
+ ret = q6afe_get_params(port, NULL, &param_hdr);
+ if (ret < 0) {
+ pr_err("[TI-SmartPA:%s] get param port 0x%x param id[0x%x]failed %d\n",
+ __func__, port, param_hdr.param_id, ret);
+ goto fail_cmd;
+ }
+
+ memcpy(data, &this_afe.tas_calib_data.res_cfg, length);
+
+ ret = 0;
+fail_cmd:
+ return ret;
+}
+EXPORT_SYMBOL(afe_tas_smartamp_get_calib_data);
+
+int afe_tas_smartamp_set_calib_data(uint32_t module_id, uint32_t param_id,
+ int32_t length, uint8_t *data, uint16_t port_id)
+{
+ int ret = -EINVAL;
+ uint32_t port = 0x0;
+ struct param_hdr_v3 param_hdr;
+
+ u8 *packed_param_data = NULL;
+ u32 packed_param_size = 0;
+ u32 single_param_size = 0;
+ pr_debug("[TI-SmartPA:%s] length: %d\n", __func__, length);
+ if (!data || (length < 0)) {
+ pr_err("[TI-SmartPA:%s] Invalid params\n", __func__);
+ return ret;
+ }
+
+ pr_debug("[TI-SmartPA:%s] module id : 0x%x \n", __func__, module_id);
+ if (module_id == this_afe.tas_module_rx) {
+ port = port_id;
+ } else if (module_id == this_afe.tas_module_tx) {
+ port = port_id + 1;
+ } else {
+ pr_err("[TI-SmartPA:%s] invalid module id %d\n", module_id);
+ return ret;
+ }
+
+ packed_param_size = sizeof(param_hdr) + length;
+ packed_param_data = kzalloc(packed_param_size, GFP_KERNEL);
+ if (!packed_param_data)
+ return -ENOMEM;
+
+ packed_param_size = 0;
+ param_hdr.module_id = module_id;
+ param_hdr.instance_id = INSTANCE_ID_0;
+ param_hdr.param_id = param_id;
+ param_hdr.param_size = length;
+ ret = q6common_pack_pp_params(packed_param_data, &param_hdr,
+ (u8 *) data, &single_param_size);
+ if (ret) {
+ pr_err("[TI-SmartPA:%s] Failed to pack param data, error %d\n", __func__,
+ ret);
+ goto done;
+ }
+ packed_param_size += single_param_size;
+ ret = q6afe_set_params(port, q6audio_get_port_index(port),
+ NULL, packed_param_data, packed_param_size);
+done:
+ kfree(packed_param_data);
+ return ret;
+}
+EXPORT_SYMBOL(afe_tas_smartamp_set_calib_data);
+
+#else /* APR Version 2 */
+static int32_t tas_smartamp_algo_callback(uint32_t *payload, uint32_t payload_size)
+{
+ struct afe_smartamp_calib_get_resp *resp =
+ (struct afe_smartamp_calib_get_resp *) payload;
+
+ pr_debug("[TI-SmartPA:%s] callback\n", __func__);
+
+ if (!(&(resp->pdata))) {
+ pr_err("[TI-SmartPA:%s] Error: resp pdata is NULL", __func__);
+ return -EINVAL;
+ }
+
+ memcpy(&this_afe.tas_calib_data, payload,
+ sizeof(this_afe.tas_calib_data));
+
+ pr_debug("[TI-SmartPA:%s] callback, 0x%x\n", __func__, resp->pdata.param_id);
+
+ if (resp->pdata.param_id == CAPI_V2_TAS_SA_DC_DETECT) {
+ s_dc_detect->channel = resp->res_cfg.payload[0];
+ pr_err("[TI-SmartPA:%s] Detected DC, Calling TAS256X Software Reset Channel-%s\n", __func__,
+ (s_dc_detect->channel == 0)?"Left":"Right");
+ tas256x_sw_reset(s_dc_detect);
+ }
+
+ if (!this_afe.tas_calib_data.status) {
+ atomic_set(&this_afe.state, 0);
+ } else {
+ pr_debug("[TI-SmartPA:%s] calib resp status: %d", __func__,
+ this_afe.tas_calib_data.status);
+ atomic_set(&this_afe.state, -1);
+ }
+
+ return 0;
+}
+
+/*
+* data is writable memroy
+* length is the max size of the data
+* retuns number of bytes returned by the algorithm
+* -ve error number in case of failure.
+*/
+int afe_tas_smartamp_get_calib_data(uint32_t module_id, uint32_t param_id,
+ int32_t length, uint8_t *data, uint16_t port_id)
+{
+ int ret = -EINVAL;
+ int index = 0;
+ struct afe_smartamp_get_calib calib_resp_o;
+ struct afe_smartamp_get_calib *calib_resp = &calib_resp_o;
+
+ if (!data || (length <= 0)) {
+ pr_err("[TI-SmartPA: %s] Invalid params\n", __func__);
+ goto fail_cmd;
+ }
+ if ((q6audio_validate_port(port_id) < 0)) {
+ pr_err("%s invalid port %d\n", __func__, port_id);
+ goto fail_cmd;
+ }
+
+ index = q6audio_get_port_index(port_id);
+ memset (calib_resp, 0, sizeof(*calib_resp));
+
+ //header
+ calib_resp->hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ calib_resp->hdr.src_svc = APR_SVC_AFE;
+ calib_resp->hdr.src_domain = APR_DOMAIN_APPS;
+ calib_resp->hdr.dest_svc = APR_SVC_AFE;
+ calib_resp->hdr.dest_domain = APR_DOMAIN_ADSP;
+ calib_resp->hdr.pkt_size = sizeof(*calib_resp);
+ calib_resp->hdr.src_port = 0;
+ calib_resp->hdr.dest_port = 0;
+ calib_resp->hdr.token = index;
+ calib_resp->hdr.opcode = AFE_PORT_CMD_GET_PARAM_V2;
+
+ //parameter
+ calib_resp->get_param.mem_map_handle = 0;
+ calib_resp->get_param.module_id = module_id;
+ calib_resp->get_param.param_id = param_id;
+ calib_resp->get_param.payload_address_lsw = 0;
+ calib_resp->get_param.payload_address_msw = 0;
+ calib_resp->get_param.payload_size = sizeof(*calib_resp)
+ - sizeof(calib_resp->hdr)
+ - sizeof(calib_resp->get_param);
+ calib_resp->get_param.port_id = q6audio_get_port_id(port_id);
+
+ //data
+ calib_resp->pdata.module_id = module_id;
+ calib_resp->pdata.param_id = param_id;
+ calib_resp->pdata.param_size = sizeof(calib_resp->res_cfg);
+ calib_resp->pdata.reserved = 0;
+ atomic_set(&this_afe.state, 1);
+
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *)calib_resp);
+
+ if (ret < 0) {
+ pr_err("[TI-SmartPA %s]: get param port %d param id[0x%x]failed",
+ __func__, port_id, calib_resp->get_param.param_id);
+ goto fail_cmd;
+ }
+
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS * 5));
+ if (!ret) {
+ pr_err("[TI-SmartPA %s]: wait_event timeout", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&this_afe.status) != 0) {
+ pr_err("[TI-SmartPA %s]: config cmd failed", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+
+ if (length <= sizeof (this_afe.tas_calib_data.res_cfg)) {
+ memcpy(data, &this_afe.tas_calib_data.res_cfg, length);
+ ret = 0;
+ } else {
+ ret = -EINVAL;
+ memcpy(data, &this_afe.tas_calib_data.res_cfg, length);
+ }
+ pr_debug("[TI-SmartPA: %s] ret=%d", __func__, ret);
+
+fail_cmd:
+ return ret;
+}
+EXPORT_SYMBOL(afe_tas_smartamp_get_calib_data);
+
+/*
+* length -> length in bytes of 'data'
+*/
+int afe_tas_smartamp_set_calib_data(uint32_t module_id, uint32_t param_id,
+ int32_t length, uint8_t *data, uint16_t port_id)
+{
+ int ret = -EINVAL;
+ int index = 0;
+ struct afe_smartamp_config_command *config = NULL;
+ u8 *cfg = NULL;
+
+ int size = sizeof(struct afe_smartamp_config_command)
+ - sizeof(struct afe_smartamp_get_set_params_t)
+ + length;
+ if (!data) {
+ pr_err("[TI-SmartPA:%s] Invalid params\n", __func__);
+ goto fail_cmd;
+ }
+
+ cfg = kzalloc(size, GFP_KERNEL);
+ if (!cfg) {
+ pr_err("[TI-SmartPA:%s] memory allocation failed\n", __func__);
+ ret = -ENOMEM;
+ goto fail_cmd;
+ }
+
+ config = (struct afe_smartamp_config_command *)cfg;
+ if (module_id == this_afe.tas_module_rx) {
+ port_id = port_id;
+ } else if (module_id == this_afe.tas_module_tx) {
+ port_id = port_id + 1;
+ } else {
+ pr_err("[TI-SmartPA: %s] invalid module id %d", __func__, module_id);
+ goto fail_cmd;
+ }
+
+ if ((q6audio_validate_port(port_id) < 0)) {
+ pr_err("[TI-SmartPA: %s] invalid port %d", __func__, port_id);
+ goto fail_cmd;
+ }
+
+ index = q6audio_get_port_index(port_id);
+
+ //header
+ config->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER);
+ config->hdr.pkt_size = sizeof(struct afe_smartamp_config_command)
+ - sizeof(struct afe_smartamp_get_set_params_t)
+ + length;
+ config->hdr.src_port = 0;
+ config->hdr.dest_port = 0;
+ config->hdr.token = index;
+ config->hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2;
+
+ //param
+ config->param.port_id = q6audio_get_port_id(port_id);
+ config->param.payload_size = sizeof(struct afe_smartamp_config_command)
+ - sizeof(struct apr_hdr)
+ - sizeof(struct afe_port_cmd_set_param_v2)
+ - sizeof(struct afe_smartamp_get_set_params_t)
+ + length;
+
+ //data
+ config->pdata.module_id = module_id;
+ config->pdata.param_id = param_id;
+ config->pdata.param_size = length; //should be same as
+ /*
+ sizeof(struct afe_smartamp_config_command)
+ - sizeof(struct apr_hdr)
+ - sizeof(struct afe_port_cmd_set_param_v2)
+ - sizeof(struct afe_port_param_data_v2);
+ */
+
+ //access payload pointer
+ cfg += (size - length);
+ memcpy(cfg, data, length);
+ atomic_set(&this_afe.state, 1);
+ ret = apr_send_pkt(this_afe.apr, (uint32_t *) config);
+
+ if (ret < 0) {
+ pr_err("[TI-SmartPA %s]: Setting param for port %d param[0x%x]failed\n",
+ __func__, port_id, param_id);
+ goto fail_cmd;
+ }
+
+ ret = wait_event_timeout(this_afe.wait[index],
+ (atomic_read(&this_afe.state) == 0),
+ msecs_to_jiffies(TIMEOUT_MS*10));
+ if (!ret) {
+ pr_err("[TI-SmartPA %s]: wait_event timeout\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ if (atomic_read(&this_afe.status) != 0) {
+ pr_err("[TI-SmartPA %s]: config cmd failed\n", __func__);
+ ret = -EINVAL;
+ goto fail_cmd;
+ }
+ ret = 0;
+
+fail_cmd:
+ pr_debug("[TI-SmartPA %s]: config->pdata.param_id %x status %d\n",
+ __func__, config->pdata.param_id, ret);
+
+ kfree(config);
+
+ return ret;
+}
+EXPORT_SYMBOL(afe_tas_smartamp_set_calib_data);
+#endif /* INSTANCE_ID_0 */
+#endif /*CONFIG_TAS25XX_ALGO*/
+
int afe_pseudo_port_stop_nowait(u16 port_id)
{
int ret = 0;
diff --git a/include/dsp/tas_qualcomm.h b/include/dsp/tas_qualcomm.h
new file mode 100644
index 00000000..e08f6505
--- /dev/null
+++ b/include/dsp/tas_qualcomm.h
@@ -0,0 +1,69 @@
+/*
+ * TAS256X Algorithm Support
+ * Qualcomm Platform Support File
+ *
+ * Author: Vijeth P O
+ * Date: 21-05-20
+ */
+
+#ifndef __TAS_QUALCOMM__
+#define __TAS_QUALCOMM__
+
+#include <dsp/apr_audio-v2.h>
+
+/*Added for DC Detection*/
+#define CAPI_V2_TAS_SA_DC_DETECT 0x40404040
+
+#define TAS_PAYLOAD_SIZE 14
+
+struct afe_smartamp_get_set_params_t {
+ uint32_t payload[TAS_PAYLOAD_SIZE];
+} __packed;
+
+#ifdef INSTANCE_ID_0
+struct afe_smartamp_get_calib {
+ struct apr_hdr hdr;
+ struct mem_mapping_hdr mem_hdr;
+ struct param_hdr_v3 pdata;
+ struct afe_smartamp_get_set_params_t res_cfg;
+} __packed;
+
+struct afe_smartamp_calib_get_resp {
+ uint32_t status;
+ struct param_hdr_v3 pdata;
+ struct afe_smartamp_get_set_params_t res_cfg;
+} __packed;
+#else
+struct afe_smartamp_config_command {
+ struct apr_hdr hdr;
+ struct afe_port_cmd_set_param_v2 param;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_smartamp_get_set_params_t prot_config;
+} __packed;
+
+struct afe_smartamp_get_calib {
+ struct apr_hdr hdr;
+ struct afe_port_cmd_get_param_v2 get_param;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_smartamp_get_set_params_t res_cfg;
+} __packed;
+
+struct afe_smartamp_calib_get_resp {
+ uint32_t status;
+ struct afe_port_param_data_v2 pdata;
+ struct afe_smartamp_get_set_params_t res_cfg;
+} __packed;
+#endif /*APR_VERSION_V3*/
+
+typedef struct {
+ int channel;
+} dc_detection_data_t;
+
+void register_tas256x_reset_func(void *fptr, dc_detection_data_t *data);
+void afe_tas_smartamp_init(uint32_t rx_module_id, uint32_t tx_module_id);
+int afe_tas_smartamp_get_calib_data(uint32_t module_id, uint32_t param_id,
+ int32_t length, uint8_t *data, uint16_t port_id);
+int afe_tas_smartamp_set_calib_data(uint32_t module_id, uint32_t param_id,
+ int32_t length, uint8_t *data, uint16_t port_id);
+
+#endif /*__TAS_QUALCOMM__*/