(SHIFT) techpack: audio: import TFA98XX codec

Change-Id: I6debfb1626a90f1bca4a3dc4ebf769788aa6320c
Signed-off-by: Alexander Martinz <amartinz@shiftphones.com>
diff --git a/techpack/audio/Kconfig b/techpack/audio/Kconfig
index 0327a3eb..56d5a49 100644
--- a/techpack/audio/Kconfig
+++ b/techpack/audio/Kconfig
@@ -102,6 +102,9 @@
 config SND_SOC_SDM845
 	tristate "SND_SOC_SDM845"
 
+config SND_SOC_TFA98XX
+	tristate "SND_SOC_TFA98XX"
+
 config SND_SOC_WCD9335
 	tristate "SND_SOC_WCD9335"
 
diff --git a/techpack/audio/asoc/codecs/Makefile b/techpack/audio/asoc/codecs/Makefile
index 9b02c8a..73c8a99 100644
--- a/techpack/audio/asoc/codecs/Makefile
+++ b/techpack/audio/asoc/codecs/Makefile
@@ -20,6 +20,7 @@
 obj-$(CONFIG_SND_SOC_SDM660_CDC) += sdm660_cdc/
 obj-$(CONFIG_SND_SOC_MSM_SDW) += msm_sdw/
 
+obj-$(CONFIG_SND_SOC_TFA98XX) +=tfa98xx/
 obj-$(CONFIG_SND_SOC_WCD9XXX_V2) += snd-soc-wcd9xxx.o
 obj-$(CONFIG_SND_SOC_WCD_MBHC)  += snd-soc-wcd-mbhc.o
 obj-$(CONFIG_SND_SOC_WSA881X)	+= snd-soc-wsa881x.o
diff --git a/techpack/audio/asoc/codecs/tfa98xx/Makefile b/techpack/audio/asoc/codecs/tfa98xx/Makefile
new file mode 100644
index 0000000..f34ce6d
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/Makefile
@@ -0,0 +1,37 @@
+# make sure that the environment variables ARCH and CROSS_COMPILE 
+# are set for your architecture and cross compiler
+#
+# e.g. for Beaglebone black:
+# export ARCH := arm
+# export CROSS_COMPILE := arm-linux-gnueabihf-
+#
+# e.g. Samsung Galaxy S6:
+# export ARCH := arm64
+# export CROSS_COMPILE := aarch64-linux-android-
+
+#MODULE_NAME = snd-soc-tfa98xx
+
+# additional debugging
+#TFA_DEBUG=1
+
+# debugging support (also enables trace_printk)
+EXTRA_CFLAGS += -DDEBUG
+EXTRA_CFLAGS += -Werror
+
+obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o
+#obj-m += snd-soc-tfa98xx.o
+
+snd-soc-tfa98xx-objs += tfa98xx.o
+snd-soc-tfa98xx-objs += tfa_container.o
+snd-soc-tfa98xx-objs += tfa_dsp.o
+snd-soc-tfa98xx-objs += tfa9888_init.o
+snd-soc-tfa98xx-objs += tfa9891_init.o
+snd-soc-tfa98xx-objs += tfa9897_init.o
+snd-soc-tfa98xx-objs += tfa9890_init.o
+snd-soc-tfa98xx-objs += tfa9887B_init.o
+snd-soc-tfa98xx-objs += tfa9887_init.o
+
+ifdef TFA_DEBUG
+EXTRA_CFLAGS += -DTFA_DEBUG -DDEBUG
+snd-soc-tfa98xx-objs += tfa_debug.o
+endif
diff --git a/techpack/audio/asoc/codecs/tfa98xx/config.h b/techpack/audio/asoc/codecs/tfa98xx/config.h
new file mode 100644
index 0000000..d83c737
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/config.h
@@ -0,0 +1,138 @@
+#ifndef __CONFIG_LINUX_KERNEL_INC__
+#define __CONFIG_LINUX_KERNEL_INC__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/crc32.h>
+#include <linux/ftrace.h>
+#include <sound/pcm.h>
+
+/* 
+	i2c transaction on Linux limited to 64k
+	(See Linux kernel documentation: Documentation/i2c/writing-clients)
+*/
+#define MAX_I2C_BUFFER_SIZE 65536
+
+/* max. length of a alsa mixer control name */
+#define MAX_CONTROL_NAME        48
+
+/* dbgprint.h */
+#define PRINT(fmt) "%s: " fmt, __func__
+
+#define _ASSERT(e)
+#define PRINT_ASSERT(e)if ((e)) printk(KERN_ERR "PrintAssert:%s (%s:%d) error code:%d\n",__FUNCTION__,__FILE__,__LINE__, e)
+
+#define TFA98XX_MAX_REGISTER              0xff
+
+#define TFA98XX_FLAG_DSP_START_ON_MUTE	(1 << 0)
+#define TFA98XX_FLAG_SKIP_INTERRUPTS	(1 << 1)
+#define TFA98XX_FLAG_SAAM_AVAILABLE	(1 << 2)
+#define TFA98XX_FLAG_STEREO_DEVICE	(1 << 3)
+#define TFA98XX_FLAG_MULTI_MIC_INPUTS	(1 << 4)
+#define TFA98XX_FLAG_TAPDET_AVAILABLE	(1 << 5)
+#define TFA98XX_FLAG_TFA9890_FAM_DEV	(1 << 6)
+#define TFA98XX_FLAG_TFA9897_FAM_DEV	(1 << 7)
+
+#define TFA98XX_NUM_RATES		9
+/* DSP init status */
+enum tfa98xx_dsp_init_state {
+	TFA98XX_DSP_INIT_STOPPED,	/* DSP not running */
+	TFA98XX_DSP_INIT_RECOVER,	/* DSP error detected at runtime */
+	TFA98XX_DSP_INIT_FAIL,		/* DSP init failed */
+	TFA98XX_DSP_INIT_PENDING,	/* DSP start requested */
+	TFA98XX_DSP_INIT_DONE,		/* DSP running */
+	TFA98XX_DSP_INIT_INVALIDATED,	/* DSP was running, requires re-init */
+};
+
+enum tfa98xx_dsp_fw_state {
+       TFA98XX_DSP_FW_NONE = 0,
+       TFA98XX_DSP_FW_PENDING,
+       TFA98XX_DSP_FW_FAIL,
+       TFA98XX_DSP_FW_OK,
+};
+
+struct tfa98xx_firmware {
+	void			*base;
+	struct tfa98xx_device	*dev;
+	char			name[9];	//TODO get length from tfa parameter defs
+};
+
+struct tfa98xx_baseprofile {
+	char basename[MAX_CONTROL_NAME];    /* profile basename */
+	int len;                            /* profile length */
+	int item_id;                        /* profile id */
+	int sr_rate_sup[TFA98XX_NUM_RATES]; /* sample rates supported by this profile */
+	struct list_head list;              /* list of all profiles */
+};
+
+struct tfa98xx {
+	struct regmap *regmap;
+	struct i2c_client *i2c;
+	struct regulator *vdd;
+	struct snd_soc_codec *codec;
+	struct workqueue_struct *tfa98xx_wq;
+	struct delayed_work init_work;
+	struct delayed_work monitor_work;
+	struct delayed_work interrupt_work;
+	struct delayed_work tapdet_work;
+	struct mutex dsp_lock;
+	int dsp_init;
+	int dsp_fw_state;
+	int sysclk;
+	int rst_gpio;
+	u16 rev;
+	int has_drc;
+	int audio_mode;
+	struct tfa98xx_firmware fw;
+	char *fw_name;
+	int rate;
+	wait_queue_head_t wq;
+	struct device *dev;
+	unsigned int init_count;
+	int pstream;
+	int cstream;
+	struct input_dev *input;
+	bool tapdet_enabled;		/* service enabled */
+	bool tapdet_open;		/* device file opened */
+	unsigned int tapdet_profiles;	/* tapdet profile bitfield */
+	bool tapdet_poll;		/* tapdet running on polling mode */
+
+	unsigned int rate_constraint_list[TFA98XX_NUM_RATES];
+	struct snd_pcm_hw_constraint_list rate_constraint;
+
+	int reset_gpio;
+	int power_gpio;
+	int irq_gpio;
+
+	int handle;
+
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *dbg_dir;
+#endif
+	u8 reg;
+
+	unsigned int count_wait_for_source_state;
+	unsigned int count_noclk;
+	unsigned int flags;
+};
+
+#if defined(CONFIG_TRACING) && defined(DEBUG)
+	#define tfa98xx_trace_printk(...) trace_printk(__VA_ARGS__)
+#else
+	#define tfa98xx_trace_printk(...)
+#endif
+
+/*
+	i2c transaction on Linux limited to 64k
+	(See Linux kernel documentation: Documentation/i2c/writing-clients)
+*/
+static inline int NXP_I2C_BufferSize(void)
+{
+	return 65536;
+}
+
+#endif /* __CONFIG_LINUX_KERNEL_INC__ */
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa.h b/techpack/audio/asoc/codecs/tfa98xx/tfa.h
new file mode 100644
index 0000000..02ee52c
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa.h
@@ -0,0 +1,117 @@
+/*
+ *Copyright 2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+
+#ifndef TFA_H_
+#define TFA_H_
+
+/* set the limit for the container file length */
+#define TFA_MAX_CNT_LENGTH (256*1024)
+
+/**
+ * tfa error returns
+ */
+enum tfa_error {
+	tfa_error_ok, /**< no error */
+	tfa_error_device, /**< no response from device */
+	tfa_error_bad_param, /**< parameter no accepted */
+	tfa_error_noclock, /**< required clock not present */
+	tfa_error_timeout, /**< a timeout occurred */
+	tfa_error_dsp, /**< a DSP error was returned */
+	tfa_error_container, /**< no or wrong container file */
+	tfa_error_max /**< impossible value, max enum */
+};
+
+/**
+ * Pass the container buffer, initialize and allocate internal memory.
+ *
+ * Note that this buffer will be kept and should not be freed until
+ * tfa_deinit() has been called
+ *
+ * @param pointer to the start of the buffer holding the container file
+ * @param length of the data in bytes
+ * @return
+ *  - tfa_error_ok if normal
+ *  - tfa_error_container invalid container data
+ *  - tfa_error_bad_param invalid parameter
+ *
+ */
+enum tfa_error tfa_load_cnt(void *cnt, int length);
+
+/**
+ * Probe/init the device.
+ *
+ * This function should only be called when the container file is loaded.
+ * It checks if an device with slave address is available in the container file.
+ * When a container file is available its assigns an handle matching the index
+ * in the container file and otherwise it will assign the first handle.
+ * It will check the device type and fill the device specific structures and
+ * functions.
+ *
+ * @param slave_address i2c slave address (8 bit format)
+ * @param pDevice the index in the conainer file
+ * @return enum tfa_error
+ */
+enum Tfa98xx_Error
+tfa_probe(unsigned char slave_address, int *pDevice);
+
+/**
+ * Start/Restart the SpeakerBoost on all devices/channels.
+ *
+ * This should only be called when the audio input clock is active.\n
+ * When the device is in coldstart-state (ACS=1) then a full initialization
+ * will be performed.\n
+ * In case of a warm start only a power-on and un-mute will be executed.\n
+ *
+ * @param profile the profile to load, if -1 then don't change profile
+ * @param vsteps the volume step selections for each channel, if -1 then softmute
+ *                        0 sets the maximum volume
+ * @return enum tfa_error
+ */
+enum tfa_error tfa_start(int profile, int *vstep);
+
+/**
+ * Stop SpeakerBoost on all devices/channels.
+ *
+ * This the notification of the audio clock to be taken away by the host.
+ *
+ * Note that the function will block until the amplifiers are actually switched
+ * off unless timed-out.
+ *
+ * @return enum tfa_error
+ */
+enum tfa_error tfa_stop(void);
+
+/**
+ * discard container buffer and free all resources.\n
+ * This includes discarding all callbacks.
+ */
+void tfa_deinit(void);
+
+/**
+ * bring all devices/channels in the cold state (ACS==1).\n
+ * This will cause reloading of all data at the next start
+ *
+ * @return
+ *  - tfa_error_ok if normal
+ *  - tfa_error_container invalid container data
+ *  - tfa_error_device channel error
+ *  - tfa_error_noclock only register level init could be preformed
+ */
+enum tfa_error tfa_reset(void);
+
+enum Tfa98xx_Error tfa_write_filters(int dev_idx, int prof_idx);
+
+#endif /* TFA_H_ */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa1_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/tfa1_tfafieldnames.h
new file mode 100644
index 0000000..6cafe7d
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa1_tfafieldnames.h
@@ -0,0 +1,900 @@
+/** Filename: Tfa1_TfaFieldnames.h
+ *  This file was generated automatically on 03/20/2015 at 01:55:46 PM. 
+ *  Source file: TFA9897N1B_I2C_list_URT_Source_v34.xls
+ */
+
+typedef enum nxpTfa1BfEnumList {
+    TFA1_BF_VDDS  = 0x0000,    /*!< Power-on-reset flag                                */
+    TFA1_BF_PLLS  = 0x0010,    /*!< PLL lock                                           */
+    TFA1_BF_OTDS  = 0x0020,    /*!< Over Temperature Protection alarm                  */
+    TFA1_BF_OVDS  = 0x0030,    /*!< Over Voltage Protection alarm                      */
+    TFA1_BF_UVDS  = 0x0040,    /*!< Under Voltage Protection alarm                     */
+    TFA1_BF_OCDS  = 0x0050,    /*!< Over Current Protection alarm                      */
+    TFA1_BF_CLKS  = 0x0060,    /*!< Clocks stable flag                                 */
+    TFA1_BF_CLIPS = 0x0070,    /*!< Amplifier clipping                                 */
+    TFA1_BF_MTPB  = 0x0080,    /*!< MTP busy                                           */
+    TFA1_BF_NOCLK = 0x0090,    /*!< Flag lost clock from clock generation unit         */
+    TFA1_BF_SPKS  = 0x00a0,    /*!< Speaker error flag                                 */
+    TFA1_BF_ACS   = 0x00b0,    /*!< Cold Start flag                                    */
+    TFA1_BF_SWS   = 0x00c0,    /*!< Flag Engage                                        */
+    TFA1_BF_WDS   = 0x00d0,    /*!< Flag watchdog reset                                */
+    TFA1_BF_AMPS  = 0x00e0,    /*!< Amplifier is enabled by manager                    */
+    TFA1_BF_AREFS = 0x00f0,    /*!< References are enabled by manager                  */
+    TFA1_BF_BATS  = 0x0109,    /*!< Battery voltage readout; 0 .. 5.5 [V]              */
+    TFA1_BF_TEMPS = 0x0208,    /*!< Temperature readout from the temperature sensor    */
+    TFA1_BF_REV   = 0x030b,    /*!< Device type number is B97                          */
+    TFA1_BF_RCV   = 0x0420,    /*!< Enable Receiver Mode                               */
+    TFA1_BF_CHS12 = 0x0431,    /*!< Channel Selection TDM input for Coolflux           */
+    TFA1_BF_INPLVL= 0x0450,    /*!< Input level selection control                      */
+    TFA1_BF_CHSA  = 0x0461,    /*!< Input selection for amplifier                      */
+    TFA1_BF_I2SDOE= 0x04b0,    /*!< Enable data output                                 */
+    TFA1_BF_AUDFS = 0x04c3,    /*!< Audio sample rate setting                          */
+    TFA1_BF_BSSCR = 0x0501,    /*!< Protection Attack Time                             */
+    TFA1_BF_BSST  = 0x0523,    /*!< ProtectionThreshold                                */
+    TFA1_BF_BSSRL = 0x0561,    /*!< Protection Maximum Reduction                       */
+    TFA1_BF_BSSRR = 0x0582,    /*!< Battery Protection Release Time                    */
+    TFA1_BF_BSSHY = 0x05b1,    /*!< Battery Protection Hysteresis                      */
+    TFA1_BF_BSSR  = 0x05e0,    /*!< battery voltage for I2C read out only              */
+    TFA1_BF_BSSBY = 0x05f0,    /*!< bypass clipper battery protection                  */
+    TFA1_BF_DPSA  = 0x0600,    /*!< Enable dynamic powerstage activation               */
+    TFA1_BF_CFSM  = 0x0650,    /*!< Soft mute in CoolFlux                              */
+    TFA1_BF_BSSS  = 0x0670,    /*!< BatSenseSteepness                                  */
+    TFA1_BF_VOL   = 0x0687,    /*!< volume control (in CoolFlux)                       */
+    TFA1_BF_DCVO  = 0x0702,    /*!< Boost Voltage                                      */
+    TFA1_BF_DCMCC = 0x0733,    /*!< Max boost coil current - step of 175 mA            */
+    TFA1_BF_DCIE  = 0x07a0,    /*!< Adaptive boost mode                                */
+    TFA1_BF_DCSR  = 0x07b0,    /*!< Soft RampUp/Down mode for DCDC controller          */
+    TFA1_BF_DCPAVG= 0x07c0,    /*!< ctrl_peak2avg for analog part of DCDC              */
+    TFA1_BF_TROS  = 0x0800,    /*!< Select external temperature also the ext_temp will be put on the temp read out  */
+    TFA1_BF_EXTTS = 0x0818,    /*!< external temperature setting to be given by host   */
+    TFA1_BF_PWDN  = 0x0900,    /*!< Device Mode                                        */
+    TFA1_BF_I2CR  = 0x0910,    /*!< I2C Reset                                          */
+    TFA1_BF_CFE   = 0x0920,    /*!< Enable CoolFlux                                    */
+    TFA1_BF_AMPE  = 0x0930,    /*!< Enable Amplifier                                   */
+    TFA1_BF_DCA   = 0x0940,    /*!< EnableBoost                                        */
+    TFA1_BF_SBSL  = 0x0950,    /*!< Coolflux configured                                */
+    TFA1_BF_AMPC  = 0x0960,    /*!< Selection on how Amplifier is enabled              */
+    TFA1_BF_DCDIS = 0x0970,    /*!< DCDC not connected                                 */
+    TFA1_BF_PSDR  = 0x0980,    /*!< IDDQ test amplifier                                */
+    TFA1_BF_DCCV  = 0x0991,    /*!< Coil Value                                         */
+    TFA1_BF_CCFD  = 0x09b0,    /*!< Selection CoolFlux Clock                           */
+    TFA1_BF_INTPAD= 0x09c1,    /*!< INT pad configuration control                      */
+    TFA1_BF_IPLL  = 0x09e0,    /*!< PLL input reference clock selection                */
+    TFA1_BF_MTPK  = 0x0b07,    /*!< 5Ah, 90d To access KEY1_Protected registers (Default for engineering) */
+    TFA1_BF_CVFDLY= 0x0c25,    /*!< Fractional delay adjustment between current and voltage sense */
+    TFA1_BF_TDMPRF= 0x1011,    /*!< TDM_usecase                                        */
+    TFA1_BF_TDMEN = 0x1030,    /*!< TDM interface control                              */
+    TFA1_BF_TDMCKINV= 0x1040,    /*!< TDM clock inversion                                */
+    TFA1_BF_TDMFSLN= 0x1053,    /*!< TDM FS length                                      */
+    TFA1_BF_TDMFSPOL= 0x1090,    /*!< TDM FS polarity                                    */
+    TFA1_BF_TDMSAMSZ= 0x10a4,    /*!< TDM Sample Size for all tdm sinks/sources          */
+    TFA1_BF_TDMSLOTS= 0x1103,    /*!< Number of slots                                    */
+    TFA1_BF_TDMSLLN= 0x1144,    /*!< Slot length                                        */
+    TFA1_BF_TDMBRMG= 0x1194,    /*!< Bits remaining                                     */
+    TFA1_BF_TDMDDEL= 0x11e0,    /*!< Data delay                                         */
+    TFA1_BF_TDMDADJ= 0x11f0,    /*!< Data adjustment                                    */
+    TFA1_BF_TDMTXFRM= 0x1201,    /*!< TXDATA format                                      */
+    TFA1_BF_TDMUUS0= 0x1221,    /*!< TXDATA format unused slot sd0                      */
+    TFA1_BF_TDMUUS1= 0x1241,    /*!< TXDATA format unused slot sd1                      */
+    TFA1_BF_TDMSI0EN= 0x1270,    /*!< TDM sink0 enable                                   */
+    TFA1_BF_TDMSI1EN= 0x1280,    /*!< TDM sink1 enable                                   */
+    TFA1_BF_TDMSI2EN= 0x1290,    /*!< TDM sink2 enable                                   */
+    TFA1_BF_TDMSO0EN= 0x12a0,    /*!< TDM source0 enable                                 */
+    TFA1_BF_TDMSO1EN= 0x12b0,    /*!< TDM source1 enable                                 */
+    TFA1_BF_TDMSO2EN= 0x12c0,    /*!< TDM source2 enable                                 */
+    TFA1_BF_TDMSI0IO= 0x12d0,    /*!< tdm_sink0_io                                       */
+    TFA1_BF_TDMSI1IO= 0x12e0,    /*!< tdm_sink1_io                                       */
+    TFA1_BF_TDMSI2IO= 0x12f0,    /*!< tdm_sink2_io                                       */
+    TFA1_BF_TDMSO0IO= 0x1300,    /*!< tdm_source0_io                                     */
+    TFA1_BF_TDMSO1IO= 0x1310,    /*!< tdm_source1_io                                     */
+    TFA1_BF_TDMSO2IO= 0x1320,    /*!< tdm_source2_io                                     */
+    TFA1_BF_TDMSI0SL= 0x1333,    /*!< sink0_slot [GAIN IN]                               */
+    TFA1_BF_TDMSI1SL= 0x1373,    /*!< sink1_slot [CH1 IN]                                */
+    TFA1_BF_TDMSI2SL= 0x13b3,    /*!< sink2_slot [CH2 IN]                                */
+    TFA1_BF_TDMSO0SL= 0x1403,    /*!< source0_slot [GAIN OUT]                            */
+    TFA1_BF_TDMSO1SL= 0x1443,    /*!< source1_slot [Voltage Sense]                       */
+    TFA1_BF_TDMSO2SL= 0x1483,    /*!< source2_slot [Current Sense]                       */
+    TFA1_BF_NBCK  = 0x14c3,    /*!< NBCK                                               */
+    TFA1_BF_INTOVDDS= 0x2000,    /*!< flag_por_int_out                                   */
+    TFA1_BF_INTOPLLS= 0x2010,    /*!< flag_pll_lock_int_out                              */
+    TFA1_BF_INTOOTDS= 0x2020,    /*!< flag_otpok_int_out                                 */
+    TFA1_BF_INTOOVDS= 0x2030,    /*!< flag_ovpok_int_out                                 */
+    TFA1_BF_INTOUVDS= 0x2040,    /*!< flag_uvpok_int_out                                 */
+    TFA1_BF_INTOOCDS= 0x2050,    /*!< flag_ocp_alarm_int_out                             */
+    TFA1_BF_INTOCLKS= 0x2060,    /*!< flag_clocks_stable_int_out                         */
+    TFA1_BF_INTOCLIPS= 0x2070,    /*!< flag_clip_int_out                                  */
+    TFA1_BF_INTOMTPB= 0x2080,    /*!< mtp_busy_int_out                                   */
+    TFA1_BF_INTONOCLK= 0x2090,    /*!< flag_lost_clk_int_out                              */
+    TFA1_BF_INTOSPKS= 0x20a0,    /*!< flag_cf_speakererror_int_out                       */
+    TFA1_BF_INTOACS= 0x20b0,    /*!< flag_cold_started_int_out                          */
+    TFA1_BF_INTOSWS= 0x20c0,    /*!< flag_engage_int_out                                */
+    TFA1_BF_INTOWDS= 0x20d0,    /*!< flag_watchdog_reset_int_out                        */
+    TFA1_BF_INTOAMPS= 0x20e0,    /*!< flag_enbl_amp_int_out                              */
+    TFA1_BF_INTOAREFS= 0x20f0,    /*!< flag_enbl_ref_int_out                              */
+    TFA1_BF_INTOACK= 0x2201,    /*!< Interrupt status register output - Corresponding flag */
+    TFA1_BF_INTIVDDS= 0x2300,    /*!< flag_por_int_in                                    */
+    TFA1_BF_INTIPLLS= 0x2310,    /*!< flag_pll_lock_int_in                               */
+    TFA1_BF_INTIOTDS= 0x2320,    /*!< flag_otpok_int_in                                  */
+    TFA1_BF_INTIOVDS= 0x2330,    /*!< flag_ovpok_int_in                                  */
+    TFA1_BF_INTIUVDS= 0x2340,    /*!< flag_uvpok_int_in                                  */
+    TFA1_BF_INTIOCDS= 0x2350,    /*!< flag_ocp_alarm_int_in                              */
+    TFA1_BF_INTICLKS= 0x2360,    /*!< flag_clocks_stable_int_in                          */
+    TFA1_BF_INTICLIPS= 0x2370,    /*!< flag_clip_int_in                                   */
+    TFA1_BF_INTIMTPB= 0x2380,    /*!< mtp_busy_int_in                                    */
+    TFA1_BF_INTINOCLK= 0x2390,    /*!< flag_lost_clk_int_in                               */
+    TFA1_BF_INTISPKS= 0x23a0,    /*!< flag_cf_speakererror_int_in                        */
+    TFA1_BF_INTIACS= 0x23b0,    /*!< flag_cold_started_int_in                           */
+    TFA1_BF_INTISWS= 0x23c0,    /*!< flag_engage_int_in                                 */
+    TFA1_BF_INTIWDS= 0x23d0,    /*!< flag_watchdog_reset_int_in                         */
+    TFA1_BF_INTIAMPS= 0x23e0,    /*!< flag_enbl_amp_int_in                               */
+    TFA1_BF_INTIAREFS= 0x23f0,    /*!< flag_enbl_ref_int_in                               */
+    TFA1_BF_INTIACK= 0x2501,    /*!< Interrupt register input                           */
+    TFA1_BF_INTENVDDS= 0x2600,    /*!< flag_por_int_enable                                */
+    TFA1_BF_INTENPLLS= 0x2610,    /*!< flag_pll_lock_int_enable                           */
+    TFA1_BF_INTENOTDS= 0x2620,    /*!< flag_otpok_int_enable                              */
+    TFA1_BF_INTENOVDS= 0x2630,    /*!< flag_ovpok_int_enable                              */
+    TFA1_BF_INTENUVDS= 0x2640,    /*!< flag_uvpok_int_enable                              */
+    TFA1_BF_INTENOCDS= 0x2650,    /*!< flag_ocp_alarm_int_enable                          */
+    TFA1_BF_INTENCLKS= 0x2660,    /*!< flag_clocks_stable_int_enable                      */
+    TFA1_BF_INTENCLIPS= 0x2670,    /*!< flag_clip_int_enable                               */
+    TFA1_BF_INTENMTPB= 0x2680,    /*!< mtp_busy_int_enable                                */
+    TFA1_BF_INTENNOCLK= 0x2690,    /*!< flag_lost_clk_int_enable                           */
+    TFA1_BF_INTENSPKS= 0x26a0,    /*!< flag_cf_speakererror_int_enable                    */
+    TFA1_BF_INTENACS= 0x26b0,    /*!< flag_cold_started_int_enable                       */
+    TFA1_BF_INTENSWS= 0x26c0,    /*!< flag_engage_int_enable                             */
+    TFA1_BF_INTENWDS= 0x26d0,    /*!< flag_watchdog_reset_int_enable                     */
+    TFA1_BF_INTENAMPS= 0x26e0,    /*!< flag_enbl_amp_int_enable                           */
+    TFA1_BF_INTENAREFS= 0x26f0,    /*!< flag_enbl_ref_int_enable                           */
+    TFA1_BF_INTENACK= 0x2801,    /*!< Interrupt enable register                          */
+    TFA1_BF_INTPOLVDDS= 0x2900,    /*!< flag_por_int_pol                                   */
+    TFA1_BF_INTPOLPLLS= 0x2910,    /*!< flag_pll_lock_int_pol                              */
+    TFA1_BF_INTPOLOTDS= 0x2920,    /*!< flag_otpok_int_pol                                 */
+    TFA1_BF_INTPOLOVDS= 0x2930,    /*!< flag_ovpok_int_pol                                 */
+    TFA1_BF_INTPOLUVDS= 0x2940,    /*!< flag_uvpok_int_pol                                 */
+    TFA1_BF_INTPOLOCDS= 0x2950,    /*!< flag_ocp_alarm_int_pol                             */
+    TFA1_BF_INTPOLCLKS= 0x2960,    /*!< flag_clocks_stable_int_pol                         */
+    TFA1_BF_INTPOLCLIPS= 0x2970,    /*!< flag_clip_int_pol                                  */
+    TFA1_BF_INTPOLMTPB= 0x2980,    /*!< mtp_busy_int_pol                                   */
+    TFA1_BF_INTPOLNOCLK= 0x2990,    /*!< flag_lost_clk_int_pol                              */
+    TFA1_BF_INTPOLSPKS= 0x29a0,    /*!< flag_cf_speakererror_int_pol                       */
+    TFA1_BF_INTPOLACS= 0x29b0,    /*!< flag_cold_started_int_pol                          */
+    TFA1_BF_INTPOLSWS= 0x29c0,    /*!< flag_engage_int_pol                                */
+    TFA1_BF_INTPOLWDS= 0x29d0,    /*!< flag_watchdog_reset_int_pol                        */
+    TFA1_BF_INTPOLAMPS= 0x29e0,    /*!< flag_enbl_amp_int_pol                              */
+    TFA1_BF_INTPOLAREFS= 0x29f0,    /*!< flag_enbl_ref_int_pol                              */
+    TFA1_BF_INTPOLACK= 0x2b01,    /*!< Interrupt status flags polarity register           */
+    TFA1_BF_CLIP  = 0x4900,    /*!< Bypass clip control                                */
+    TFA1_BF_CIMTP = 0x62b0,    /*!< start copying all the data from i2cregs_mtp to mtp [Key 2 protected] */
+    TFA1_BF_RST   = 0x7000,    /*!< Reset CoolFlux DSP                                 */
+    TFA1_BF_DMEM  = 0x7011,    /*!< Target memory for access                           */
+    TFA1_BF_AIF   = 0x7030,    /*!< Autoincrement-flag for memory-address              */
+    TFA1_BF_CFINT = 0x7040,    /*!< Interrupt CoolFlux DSP                             */
+    TFA1_BF_REQ   = 0x7087,    /*!< request for access (8 channels)                    */
+    TFA1_BF_REQCMD= 0x7080,    /*!< Firmware event request rpc command                 */
+    TFA1_BF_REQRST= 0x7090,    /*!< Firmware event request reset restart               */
+    TFA1_BF_REQMIPS= 0x70a0,    /*!< Firmware event request short on mips               */
+    TFA1_BF_REQMUTED= 0x70b0,    /*!< Firmware event request mute sequence ready         */
+    TFA1_BF_REQVOL= 0x70c0,    /*!< Firmware event request volume ready                */
+    TFA1_BF_REQDMG= 0x70d0,    /*!< Firmware event request speaker damage detected     */
+    TFA1_BF_REQCAL= 0x70e0,    /*!< Firmware event request calibration completed       */
+    TFA1_BF_REQRSV= 0x70f0,    /*!< Firmware event request reserved                    */
+    TFA1_BF_MADD  = 0x710f,    /*!< memory-address to be accessed                      */
+    TFA1_BF_MEMA  = 0x720f,    /*!< activate memory access (24- or 32-bits data is written/read to/from memory */
+    TFA1_BF_ERR   = 0x7307,    /*!< Coolflux error flags                               */
+    TFA1_BF_ACK   = 0x7387,    /*!< acknowledge of requests (8 channels)               */
+    TFA1_BF_MTPOTC= 0x8000,    /*!< Calibration schedule (key2 protected)              */
+    TFA1_BF_MTPEX = 0x8010,    /*!< (key2 protected)                                   */
+} nxpTfa1BfEnumList_t;
+#define TFA1_NAMETABLE static tfaBfName_t Tfa1DatasheetNames[]= {\
+   { 0x0, "VDDS"},    /* Power-on-reset flag                               , */\
+   { 0x10, "PLLS"},    /* PLL lock                                          , */\
+   { 0x20, "OTDS"},    /* Over Temperature Protection alarm                 , */\
+   { 0x30, "OVDS"},    /* Over Voltage Protection alarm                     , */\
+   { 0x40, "UVDS"},    /* Under Voltage Protection alarm                    , */\
+   { 0x50, "OCDS"},    /* Over Current Protection alarm                     , */\
+   { 0x60, "CLKS"},    /* Clocks stable flag                                , */\
+   { 0x70, "CLIPS"},    /* Amplifier clipping                                , */\
+   { 0x80, "MTPB"},    /* MTP busy                                          , */\
+   { 0x90, "NOCLK"},    /* Flag lost clock from clock generation unit        , */\
+   { 0xa0, "SPKS"},    /* Speaker error flag                                , */\
+   { 0xb0, "ACS"},    /* Cold Start flag                                   , */\
+   { 0xc0, "SWS"},    /* Flag Engage                                       , */\
+   { 0xd0, "WDS"},    /* Flag watchdog reset                               , */\
+   { 0xe0, "AMPS"},    /* Amplifier is enabled by manager                   , */\
+   { 0xf0, "AREFS"},    /* References are enabled by manager                 , */\
+   { 0x109, "BATS"},    /* Battery voltage readout; 0 .. 5.5 [V]             , */\
+   { 0x208, "TEMPS"},    /* Temperature readout from the temperature sensor   , */\
+   { 0x30b, "REV"},    /* Device type number is B97                         , */\
+   { 0x420, "RCV"},    /* Enable Receiver Mode                              , */\
+   { 0x431, "CHS12"},    /* Channel Selection TDM input for Coolflux          , */\
+   { 0x450, "INPLVL"},    /* Input level selection control                     , */\
+   { 0x461, "CHSA"},    /* Input selection for amplifier                     , */\
+   { 0x4b0, "I2SDOE"},    /* Enable data output                                , */\
+   { 0x4c3, "AUDFS"},    /* Audio sample rate setting                         , */\
+   { 0x501, "SSCR"},    /* Protection Attack Time                            , */\
+   { 0x523, "SST"},    /* ProtectionThreshold                               , */\
+   { 0x561, "SSRL"},    /* Protection Maximum Reduction                      , */\
+   { 0x582, "SSRR"},    /* Battery Protection Release Time                   , */\
+   { 0x5b1, "SSHY"},    /* Battery Protection Hysteresis                     , */\
+   { 0x5e0, "SSR"},    /* battery voltage for I2C read out only             , */\
+   { 0x5f0, "SSBY"},    /* bypass clipper battery protection                 , */\
+   { 0x600, "DPSA"},    /* Enable dynamic powerstage activation              , */\
+   { 0x650, "CFSM"},    /* Soft mute in CoolFlux                             , */\
+   { 0x670, "SSS"},    /* BatSenseSteepness                                 , */\
+   { 0x687, "VOL"},    /* volume control (in CoolFlux)                      , */\
+   { 0x702, "DCVO"},    /* Boost Voltage                                     , */\
+   { 0x733, "DCMCC"},    /* Max boost coil current - step of 175 mA           , */\
+   { 0x7a0, "DCIE"},    /* Adaptive boost mode                               , */\
+   { 0x7b0, "DCSR"},    /* Soft RampUp/Down mode for DCDC controller         , */\
+   { 0x7c0, "DCPAVG"},    /* ctrl_peak2avg for analog part of DCDC             , */\
+   { 0x800, "TROS"},    /* Select external temperature also the ext_temp will be put on the temp read out , */\
+   { 0x818, "EXTTS"},    /* external temperature setting to be given by host  , */\
+   { 0x900, "PWDN"},    /* Device Mode                                       , */\
+   { 0x910, "I2CR"},    /* I2C Reset                                         , */\
+   { 0x920, "CFE"},    /* Enable CoolFlux                                   , */\
+   { 0x930, "AMPE"},    /* Enable Amplifier                                  , */\
+   { 0x940, "DCA"},    /* EnableBoost                                       , */\
+   { 0x950, "SBSL"},    /* Coolflux configured                               , */\
+   { 0x960, "AMPC"},    /* Selection on how Amplifier is enabled             , */\
+   { 0x970, "DCDIS"},    /* DCDC not connected                                , */\
+   { 0x980, "PSDR"},    /* IDDQ test amplifier                               , */\
+   { 0x991, "DCCV"},    /* Coil Value                                        , */\
+   { 0x9b0, "CCFD"},    /* Selection CoolFlux Clock                          , */\
+   { 0x9c1, "INTPAD"},    /* INT pad configuration control                     , */\
+   { 0x9e0, "IPLL"},    /* PLL input reference clock selection               , */\
+   { 0xb07, "MTPK"},    /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */\
+   { 0xc25, "CVFDLY"},    /* Fractional delay adjustment between current and voltage sense, */\
+   { 0x1011, "TDMPRF"},    /* TDM_usecase                                       , */\
+   { 0x1030, "TDMEN"},    /* TDM interface control                             , */\
+   { 0x1040, "TDMCKINV"},    /* TDM clock inversion                               , */\
+   { 0x1053, "TDMFSLN"},    /* TDM FS length                                     , */\
+   { 0x1090, "TDMFSPOL"},    /* TDM FS polarity                                   , */\
+   { 0x10a4, "TDMSAMSZ"},    /* TDM Sample Size for all tdm sinks/sources         , */\
+   { 0x1103, "TDMSLOTS"},    /* Number of slots                                   , */\
+   { 0x1144, "TDMSLLN"},    /* Slot length                                       , */\
+   { 0x1194, "TDMBRMG"},    /* Bits remaining                                    , */\
+   { 0x11e0, "TDMDDEL"},    /* Data delay                                        , */\
+   { 0x11f0, "TDMDADJ"},    /* Data adjustment                                   , */\
+   { 0x1201, "TDMTXFRM"},    /* TXDATA format                                     , */\
+   { 0x1221, "TDMUUS0"},    /* TXDATA format unused slot sd0                     , */\
+   { 0x1241, "TDMUUS1"},    /* TXDATA format unused slot sd1                     , */\
+   { 0x1270, "TDMSI0EN"},    /* TDM sink0 enable                                  , */\
+   { 0x1280, "TDMSI1EN"},    /* TDM sink1 enable                                  , */\
+   { 0x1290, "TDMSI2EN"},    /* TDM sink2 enable                                  , */\
+   { 0x12a0, "TDMSO0EN"},    /* TDM source0 enable                                , */\
+   { 0x12b0, "TDMSO1EN"},    /* TDM source1 enable                                , */\
+   { 0x12c0, "TDMSO2EN"},    /* TDM source2 enable                                , */\
+   { 0x12d0, "TDMSI0IO"},    /* tdm_sink0_io                                      , */\
+   { 0x12e0, "TDMSI1IO"},    /* tdm_sink1_io                                      , */\
+   { 0x12f0, "TDMSI2IO"},    /* tdm_sink2_io                                      , */\
+   { 0x1300, "TDMSO0IO"},    /* tdm_source0_io                                    , */\
+   { 0x1310, "TDMSO1IO"},    /* tdm_source1_io                                    , */\
+   { 0x1320, "TDMSO2IO"},    /* tdm_source2_io                                    , */\
+   { 0x1333, "TDMSI0SL"},    /* sink0_slot [GAIN IN]                              , */\
+   { 0x1373, "TDMSI1SL"},    /* sink1_slot [CH1 IN]                               , */\
+   { 0x13b3, "TDMSI2SL"},    /* sink2_slot [CH2 IN]                               , */\
+   { 0x1403, "TDMSO0SL"},    /* source0_slot [GAIN OUT]                           , */\
+   { 0x1443, "TDMSO1SL"},    /* source1_slot [Voltage Sense]                      , */\
+   { 0x1483, "TDMSO2SL"},    /* source2_slot [Current Sense]                      , */\
+   { 0x14c3, "NBCK"},    /* NBCK                                              , */\
+   { 0x2000, "INTOVDDS"},    /* flag_por_int_out                                  , */\
+   { 0x2010, "INTOPLLS"},    /* flag_pll_lock_int_out                             , */\
+   { 0x2020, "INTOOTDS"},    /* flag_otpok_int_out                                , */\
+   { 0x2030, "INTOOVDS"},    /* flag_ovpok_int_out                                , */\
+   { 0x2040, "INTOUVDS"},    /* flag_uvpok_int_out                                , */\
+   { 0x2050, "INTOOCDS"},    /* flag_ocp_alarm_int_out                            , */\
+   { 0x2060, "INTOCLKS"},    /* flag_clocks_stable_int_out                        , */\
+   { 0x2070, "INTOCLIPS"},    /* flag_clip_int_out                                 , */\
+   { 0x2080, "INTOMTPB"},    /* mtp_busy_int_out                                  , */\
+   { 0x2090, "INTONOCLK"},    /* flag_lost_clk_int_out                             , */\
+   { 0x20a0, "INTOSPKS"},    /* flag_cf_speakererror_int_out                      , */\
+   { 0x20b0, "INTOACS"},    /* flag_cold_started_int_out                         , */\
+   { 0x20c0, "INTOSWS"},    /* flag_engage_int_out                               , */\
+   { 0x20d0, "INTOWDS"},    /* flag_watchdog_reset_int_out                       , */\
+   { 0x20e0, "INTOAMPS"},    /* flag_enbl_amp_int_out                             , */\
+   { 0x20f0, "INTOAREFS"},    /* flag_enbl_ref_int_out                             , */\
+   { 0x2201, "INTOACK"},    /* Interrupt status register output - Corresponding flag, */\
+   { 0x2300, "INTIVDDS"},    /* flag_por_int_in                                   , */\
+   { 0x2310, "INTIPLLS"},    /* flag_pll_lock_int_in                              , */\
+   { 0x2320, "INTIOTDS"},    /* flag_otpok_int_in                                 , */\
+   { 0x2330, "INTIOVDS"},    /* flag_ovpok_int_in                                 , */\
+   { 0x2340, "INTIUVDS"},    /* flag_uvpok_int_in                                 , */\
+   { 0x2350, "INTIOCDS"},    /* flag_ocp_alarm_int_in                             , */\
+   { 0x2360, "INTICLKS"},    /* flag_clocks_stable_int_in                         , */\
+   { 0x2370, "INTICLIPS"},    /* flag_clip_int_in                                  , */\
+   { 0x2380, "INTIMTPB"},    /* mtp_busy_int_in                                   , */\
+   { 0x2390, "INTINOCLK"},    /* flag_lost_clk_int_in                              , */\
+   { 0x23a0, "INTISPKS"},    /* flag_cf_speakererror_int_in                       , */\
+   { 0x23b0, "INTIACS"},    /* flag_cold_started_int_in                          , */\
+   { 0x23c0, "INTISWS"},    /* flag_engage_int_in                                , */\
+   { 0x23d0, "INTIWDS"},    /* flag_watchdog_reset_int_in                        , */\
+   { 0x23e0, "INTIAMPS"},    /* flag_enbl_amp_int_in                              , */\
+   { 0x23f0, "INTIAREFS"},    /* flag_enbl_ref_int_in                              , */\
+   { 0x2501, "INTIACK"},    /* Interrupt register input                          , */\
+   { 0x2600, "INTENVDDS"},    /* flag_por_int_enable                               , */\
+   { 0x2610, "INTENPLLS"},    /* flag_pll_lock_int_enable                          , */\
+   { 0x2620, "INTENOTDS"},    /* flag_otpok_int_enable                             , */\
+   { 0x2630, "INTENOVDS"},    /* flag_ovpok_int_enable                             , */\
+   { 0x2640, "INTENUVDS"},    /* flag_uvpok_int_enable                             , */\
+   { 0x2650, "INTENOCDS"},    /* flag_ocp_alarm_int_enable                         , */\
+   { 0x2660, "INTENCLKS"},    /* flag_clocks_stable_int_enable                     , */\
+   { 0x2670, "INTENCLIPS"},    /* flag_clip_int_enable                              , */\
+   { 0x2680, "INTENMTPB"},    /* mtp_busy_int_enable                               , */\
+   { 0x2690, "INTENNOCLK"},    /* flag_lost_clk_int_enable                          , */\
+   { 0x26a0, "INTENSPKS"},    /* flag_cf_speakererror_int_enable                   , */\
+   { 0x26b0, "INTENACS"},    /* flag_cold_started_int_enable                      , */\
+   { 0x26c0, "INTENSWS"},    /* flag_engage_int_enable                            , */\
+   { 0x26d0, "INTENWDS"},    /* flag_watchdog_reset_int_enable                    , */\
+   { 0x26e0, "INTENAMPS"},    /* flag_enbl_amp_int_enable                          , */\
+   { 0x26f0, "INTENAREFS"},    /* flag_enbl_ref_int_enable                          , */\
+   { 0x2801, "INTENACK"},    /* Interrupt enable register                         , */\
+   { 0x2900, "INTPOLVDDS"},    /* flag_por_int_pol                                  , */\
+   { 0x2910, "INTPOLPLLS"},    /* flag_pll_lock_int_pol                             , */\
+   { 0x2920, "INTPOLOTDS"},    /* flag_otpok_int_pol                                , */\
+   { 0x2930, "INTPOLOVDS"},    /* flag_ovpok_int_pol                                , */\
+   { 0x2940, "INTPOLUVDS"},    /* flag_uvpok_int_pol                                , */\
+   { 0x2950, "INTPOLOCDS"},    /* flag_ocp_alarm_int_pol                            , */\
+   { 0x2960, "INTPOLCLKS"},    /* flag_clocks_stable_int_pol                        , */\
+   { 0x2970, "INTPOLCLIPS"},    /* flag_clip_int_pol                                 , */\
+   { 0x2980, "INTPOLMTPB"},    /* mtp_busy_int_pol                                  , */\
+   { 0x2990, "INTPOLNOCLK"},    /* flag_lost_clk_int_pol                             , */\
+   { 0x29a0, "INTPOLSPKS"},    /* flag_cf_speakererror_int_pol                      , */\
+   { 0x29b0, "INTPOLACS"},    /* flag_cold_started_int_pol                         , */\
+   { 0x29c0, "INTPOLSWS"},    /* flag_engage_int_pol                               , */\
+   { 0x29d0, "INTPOLWDS"},    /* flag_watchdog_reset_int_pol                       , */\
+   { 0x29e0, "INTPOLAMPS"},    /* flag_enbl_amp_int_pol                             , */\
+   { 0x29f0, "INTPOLAREFS"},    /* flag_enbl_ref_int_pol                             , */\
+   { 0x2b01, "INTPOLACK"},    /* Interrupt status flags polarity register          , */\
+   { 0x4900, "CLIP"},    /* Bypass clip control                               , */\
+   { 0x62b0, "CIMTP"},    /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */\
+   { 0x7000, "RST"},    /* Reset CoolFlux DSP                                , */\
+   { 0x7011, "DMEM"},    /* Target memory for access                          , */\
+   { 0x7030, "AIF"},    /* Autoincrement-flag for memory-address             , */\
+   { 0x7040, "CFINT"},    /* Interrupt CoolFlux DSP                            , */\
+   { 0x7087, "REQ"},    /* request for access (8 channels)                   , */\
+   { 0x7080, "REQCMD"},    /* Firmware event request rpc command                , */\
+   { 0x7090, "REQRST"},    /* Firmware event request reset restart              , */\
+   { 0x70a0, "REQMIPS"},    /* Firmware event request short on mips              , */\
+   { 0x70b0, "REQMUTED"},    /* Firmware event request mute sequence ready        , */\
+   { 0x70c0, "REQVOL"},    /* Firmware event request volume ready               , */\
+   { 0x70d0, "REQDMG"},    /* Firmware event request speaker damage detected    , */\
+   { 0x70e0, "REQCAL"},    /* Firmware event request calibration completed      , */\
+   { 0x70f0, "REQRSV"},    /* Firmware event request reserved                   , */\
+   { 0x710f, "MADD"},    /* memory-address to be accessed                     , */\
+   { 0x720f, "MEMA"},    /* activate memory access (24- or 32-bits data is written/read to/from memory, */\
+   { 0x7307, "ERR"},    /* Coolflux error flags                              , */\
+   { 0x7387, "ACK"},    /* acknowledge of requests (8 channels)              , */\
+   { 0x7380, "ACKCMD"},    /* Firmware event acknowledge rpc command            , */\
+   { 0x7390, "ACKRST"},    /* Firmware event acknowledge reset restart          , */\
+   { 0x73a0, "ACKMIPS"},    /* Firmware event acknowledge short on mips          , */\
+   { 0x73b0, "ACKMUTED"},    /* Firmware event acknowledge mute sequence ready    , */\
+   { 0x73c0, "ACKVOL"},    /* Firmware event acknowledge volume ready           , */\
+   { 0x73d0, "ACKDMG"},    /* Firmware event acknowledge speaker damage detected, */\
+   { 0x73e0, "ACKCAL"},    /* Firmware event acknowledge calibration completed  , */\
+   { 0x73f0, "ACKRSV"},    /* Firmware event acknowledge reserved               , */\
+   { 0x8000, "MTPOTC"},    /* Calibration schedule (key2 protected)             , */\
+   { 0x8010, "MTPEX"},    /* (key2 protected)                                  , */\
+   { 0x8045, "SWPROFIL" },\
+   { 0x80a5, "SWVSTEP" },\
+   { 0xffff,"Unknown bitfield enum" }   /* not found */\
+};
+
+#define TFA1_BITNAMETABLE static tfaBfName_t Tfa1BitNames[]= {\
+   { 0x0, "flag_por"},    /* Power-on-reset flag                               , */\
+   { 0x10, "flag_pll_lock"},    /* PLL lock                                          , */\
+   { 0x20, "flag_otpok"},    /* Over Temperature Protection alarm                 , */\
+   { 0x30, "flag_ovpok"},    /* Over Voltage Protection alarm                     , */\
+   { 0x40, "flag_uvpok"},    /* Under Voltage Protection alarm                    , */\
+   { 0x50, "flag_ocp_alarm"},    /* Over Current Protection alarm                     , */\
+   { 0x60, "flag_clocks_stable"},    /* Clocks stable flag                                , */\
+   { 0x70, "flag_clip"},    /* Amplifier clipping                                , */\
+   { 0x80, "mtp_busy"},    /* MTP busy                                          , */\
+   { 0x90, "flag_lost_clk"},    /* Flag lost clock from clock generation unit        , */\
+   { 0xa0, "flag_cf_speakererror"},    /* Speaker error flag                                , */\
+   { 0xb0, "flag_cold_started"},    /* Cold Start flag                                   , */\
+   { 0xc0, "flag_engage"},    /* Flag Engage                                       , */\
+   { 0xd0, "flag_watchdog_reset"},    /* Flag watchdog reset                               , */\
+   { 0xe0, "flag_enbl_amp"},    /* Amplifier is enabled by manager                   , */\
+   { 0xf0, "flag_enbl_ref"},    /* References are enabled by manager                 , */\
+   { 0x109, "bat_adc"},    /* Battery voltage readout; 0 .. 5.5 [V]             , */\
+   { 0x208, "temp_adc"},    /* Temperature readout from the temperature sensor   , */\
+   { 0x30b, "rev_reg"},    /* Device type number is B97                         , */\
+   { 0x420, "ctrl_rcv"},    /* Enable Receiver Mode                              , */\
+   { 0x431, "chan_sel"},    /* Channel Selection TDM input for Coolflux          , */\
+   { 0x450, "input_level"},    /* Input level selection control                     , */\
+   { 0x461, "vamp_sel"},    /* Input selection for amplifier                     , */\
+   { 0x4c3, "audio_fs"},    /* Audio sample rate setting                         , */\
+   { 0x501, "vbat_prot_attacktime"},    /* Protection Attack Time                            , */\
+   { 0x523, "vbat_prot_thlevel"},    /* ProtectionThreshold                               , */\
+   { 0x561, "vbat_prot_max_reduct"},    /* Protection Maximum Reduction                      , */\
+   { 0x582, "vbat_prot_release_t"},    /* Battery Protection Release Time                   , */\
+   { 0x5b1, "vbat_prot_hysterese"},    /* Battery Protection Hysteresis                     , */\
+   { 0x5d0, "reset_min_vbat"},    /* reset clipper                                     , */\
+   { 0x5e0, "sel_vbat"},    /* battery voltage for I2C read out only             , */\
+   { 0x5f0, "bypass_clipper"},    /* bypass clipper battery protection                 , */\
+   { 0x600, "dpsa"},    /* Enable dynamic powerstage activation              , */\
+   { 0x650, "cf_mute"},    /* Soft mute in CoolFlux                             , */\
+   { 0x670, "batsense_steepness"},    /* BatSenseSteepness                                 , */\
+   { 0x687, "vol"},    /* volume control (in CoolFlux)                      , */\
+   { 0x702, "boost_volt"},    /* Boost Voltage                                     , */\
+   { 0x733, "boost_cur"},    /* Max boost coil current - step of 175 mA           , */\
+   { 0x7a0, "boost_intel"},    /* Adaptive boost mode                               , */\
+   { 0x7b0, "boost_speed"},    /* Soft RampUp/Down mode for DCDC controller         , */\
+   { 0x7c0, "boost_peak2avg"},    /* ctrl_peak2avg for analog part of DCDC             , */\
+   { 0x800, "ext_temp_sel"},    /* Select external temperature also the ext_temp will be put on the temp read out , */\
+   { 0x818, "ext_temp"},    /* external temperature setting to be given by host  , */\
+   { 0x8b2, "dcdc_synchronisation"},    /* DCDC synchronisation off + 7 positions            , */\
+   { 0x900, "powerdown"},    /* Device Mode                                       , */\
+   { 0x910, "reset"},    /* I2C Reset                                         , */\
+   { 0x920, "enbl_coolflux"},    /* Enable CoolFlux                                   , */\
+   { 0x930, "enbl_amplifier"},    /* Enable Amplifier                                  , */\
+   { 0x940, "enbl_boost"},    /* EnableBoost                                       , */\
+   { 0x950, "coolflux_configured"},    /* Coolflux configured                               , */\
+   { 0x960, "sel_enbl_amplifier"},    /* Selection on how Amplifier is enabled             , */\
+   { 0x970, "dcdcoff_mode"},    /* DCDC not connected                                , */\
+   { 0x980, "iddqtest"},    /* IDDQ test amplifier                               , */\
+   { 0x991, "coil_value"},    /* Coil Value                                        , */\
+   { 0x9b0, "sel_cf_clock"},    /* Selection CoolFlux Clock                          , */\
+   { 0x9c1, "int_pad_io"},    /* INT pad configuration control                     , */\
+   { 0x9e0, "sel_fs_bck"},    /* PLL input reference clock selection               , */\
+   { 0x9f0, "sel_scl_cf_clock"},    /* Coolflux sub-system clock                         , */\
+   { 0xb07, "mtpkey2"},    /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */\
+   { 0xc00, "enbl_volt_sense"},    /* Voltage sense enabling control bit                , */\
+   { 0xc10, "vsense_pwm_sel"},    /* Voltage sense PWM source selection control        , */\
+   { 0xc25, "vi_frac_delay"},    /* Fractional delay adjustment between current and voltage sense, */\
+   { 0xc80, "sel_voltsense_out"},    /* TDM output data selection control                 , */\
+   { 0xc90, "vsense_bypass_avg"},    /* Voltage Sense Average Block Bypass                , */\
+   { 0xd05, "cf_frac_delay"},    /* Fractional delay adjustment between current and voltage sense by firmware, */\
+   { 0xe00, "bypass_dcdc_curr_prot"},    /* Control to switch off dcdc current reduction with bat protection, */\
+   { 0xe80, "disable_clock_sh_prot"},    /* disable clock_sh protection                       , */\
+   { 0xe96, "reserve_reg_1_15_9"},    /*                                                   , */\
+   { 0x1011, "tdm_usecase"},    /* TDM_usecase                                       , */\
+   { 0x1030, "tdm_enable"},    /* TDM interface control                             , */\
+   { 0x1040, "tdm_clk_inversion"},    /* TDM clock inversion                               , */\
+   { 0x1053, "tdm_fs_ws_length"},    /* TDM FS length                                     , */\
+   { 0x1090, "tdm_fs_ws_polarity"},    /* TDM FS polarity                                   , */\
+   { 0x10a4, "tdm_sample_size"},    /* TDM Sample Size for all tdm sinks/sources         , */\
+   { 0x1103, "tdm_nb_of_slots"},    /* Number of slots                                   , */\
+   { 0x1144, "tdm_slot_length"},    /* Slot length                                       , */\
+   { 0x1194, "tdm_bits_remaining"},    /* Bits remaining                                    , */\
+   { 0x11e0, "tdm_data_delay"},    /* Data delay                                        , */\
+   { 0x11f0, "tdm_data_adjustment"},    /* Data adjustment                                   , */\
+   { 0x1201, "tdm_txdata_format"},    /* TXDATA format                                     , */\
+   { 0x1221, "tdm_txdata_format_unused_slot_sd0"},    /* TXDATA format unused slot sd0                     , */\
+   { 0x1241, "tdm_txdata_format_unused_slot_sd1"},    /* TXDATA format unused slot sd1                     , */\
+   { 0x1270, "tdm_sink0_enable"},    /* TDM sink0 enable                                  , */\
+   { 0x1280, "tdm_sink1_enable"},    /* TDM sink1 enable                                  , */\
+   { 0x1290, "tdm_sink2_enable"},    /* TDM sink2 enable                                  , */\
+   { 0x12a0, "tdm_source0_enable"},    /* TDM source0 enable                                , */\
+   { 0x12b0, "tdm_source1_enable"},    /* TDM source1 enable                                , */\
+   { 0x12c0, "tdm_source2_enable"},    /* TDM source2 enable                                , */\
+   { 0x12d0, "tdm_sink0_io"},    /* tdm_sink0_io                                      , */\
+   { 0x12e0, "tdm_sink1_io"},    /* tdm_sink1_io                                      , */\
+   { 0x12f0, "tdm_sink2_io"},    /* tdm_sink2_io                                      , */\
+   { 0x1300, "tdm_source0_io"},    /* tdm_source0_io                                    , */\
+   { 0x1310, "tdm_source1_io"},    /* tdm_source1_io                                    , */\
+   { 0x1320, "tdm_source2_io"},    /* tdm_source2_io                                    , */\
+   { 0x1333, "tdm_sink0_slot"},    /* sink0_slot [GAIN IN]                              , */\
+   { 0x1373, "tdm_sink1_slot"},    /* sink1_slot [CH1 IN]                               , */\
+   { 0x13b3, "tdm_sink2_slot"},    /* sink2_slot [CH2 IN]                               , */\
+   { 0x1403, "tdm_source0_slot"},    /* source0_slot [GAIN OUT]                           , */\
+   { 0x1443, "tdm_source1_slot"},    /* source1_slot [Voltage Sense]                      , */\
+   { 0x1483, "tdm_source2_slot"},    /* source2_slot [Current Sense]                      , */\
+   { 0x14c3, "tdm_nbck"},    /* NBCK                                              , */\
+   { 0x1500, "flag_tdm_lut_error"},    /* TDM LUT error flag                                , */\
+   { 0x1512, "flag_tdm_status"},    /* TDM interface status bits                         , */\
+   { 0x1540, "flag_tdm_error"},    /* TDM interface error indicator                     , */\
+   { 0x2000, "flag_por_int_out"},    /* flag_por_int_out                                  , */\
+   { 0x2010, "flag_pll_lock_int_out"},    /* flag_pll_lock_int_out                             , */\
+   { 0x2020, "flag_otpok_int_out"},    /* flag_otpok_int_out                                , */\
+   { 0x2030, "flag_ovpok_int_out"},    /* flag_ovpok_int_out                                , */\
+   { 0x2040, "flag_uvpok_int_out"},    /* flag_uvpok_int_out                                , */\
+   { 0x2050, "flag_ocp_alarm_int_out"},    /* flag_ocp_alarm_int_out                            , */\
+   { 0x2060, "flag_clocks_stable_int_out"},    /* flag_clocks_stable_int_out                        , */\
+   { 0x2070, "flag_clip_int_out"},    /* flag_clip_int_out                                 , */\
+   { 0x2080, "mtp_busy_int_out"},    /* mtp_busy_int_out                                  , */\
+   { 0x2090, "flag_lost_clk_int_out"},    /* flag_lost_clk_int_out                             , */\
+   { 0x20a0, "flag_cf_speakererror_int_out"},    /* flag_cf_speakererror_int_out                      , */\
+   { 0x20b0, "flag_cold_started_int_out"},    /* flag_cold_started_int_out                         , */\
+   { 0x20c0, "flag_engage_int_out"},    /* flag_engage_int_out                               , */\
+   { 0x20d0, "flag_watchdog_reset_int_out"},    /* flag_watchdog_reset_int_out                       , */\
+   { 0x20e0, "flag_enbl_amp_int_out"},    /* flag_enbl_amp_int_out                             , */\
+   { 0x20f0, "flag_enbl_ref_int_out"},    /* flag_enbl_ref_int_out                             , */\
+   { 0x2100, "flag_voutcomp_int_out"},    /* flag_voutcomp_int_out                             , */\
+   { 0x2110, "flag_voutcomp93_int_out"},    /* flag_voutcomp93_int_out                           , */\
+   { 0x2120, "flag_voutcomp86_int_out"},    /* flag_voutcomp86_int_out                           , */\
+   { 0x2130, "flag_hiz_int_out"},    /* flag_hiz_int_out                                  , */\
+   { 0x2140, "flag_ocpokbst_int_out"},    /* flag_ocpokbst_int_out                             , */\
+   { 0x2150, "flag_peakcur_int_out"},    /* flag_peakcur_int_out                              , */\
+   { 0x2160, "flag_ocpokap_int_out"},    /* flag_ocpokap_int_out                              , */\
+   { 0x2170, "flag_ocpokan_int_out"},    /* flag_ocpokan_int_out                              , */\
+   { 0x2180, "flag_ocpokbp_int_out"},    /* flag_ocpokbp_int_out                              , */\
+   { 0x2190, "flag_ocpokbn_int_out"},    /* flag_ocpokbn_int_out                              , */\
+   { 0x21a0, "flag_adc10_ready_int_out"},    /* flag_adc10_ready_int_out                          , */\
+   { 0x21b0, "flag_clipa_high_int_out"},    /* flag_clipa_high_int_out                           , */\
+   { 0x21c0, "flag_clipa_low_int_out"},    /* flag_clipa_low_int_out                            , */\
+   { 0x21d0, "flag_clipb_high_int_out"},    /* flag_clipb_high_int_out                           , */\
+   { 0x21e0, "flag_clipb_low_int_out"},    /* flag_clipb_low_int_out                            , */\
+   { 0x21f0, "flag_tdm_error_int_out"},    /* flag_tdm_error_int_out                            , */\
+   { 0x2201, "interrupt_out3"},    /* Interrupt status register output - Corresponding flag, */\
+   { 0x2300, "flag_por_int_in"},    /* flag_por_int_in                                   , */\
+   { 0x2310, "flag_pll_lock_int_in"},    /* flag_pll_lock_int_in                              , */\
+   { 0x2320, "flag_otpok_int_in"},    /* flag_otpok_int_in                                 , */\
+   { 0x2330, "flag_ovpok_int_in"},    /* flag_ovpok_int_in                                 , */\
+   { 0x2340, "flag_uvpok_int_in"},    /* flag_uvpok_int_in                                 , */\
+   { 0x2350, "flag_ocp_alarm_int_in"},    /* flag_ocp_alarm_int_in                             , */\
+   { 0x2360, "flag_clocks_stable_int_in"},    /* flag_clocks_stable_int_in                         , */\
+   { 0x2370, "flag_clip_int_in"},    /* flag_clip_int_in                                  , */\
+   { 0x2380, "mtp_busy_int_in"},    /* mtp_busy_int_in                                   , */\
+   { 0x2390, "flag_lost_clk_int_in"},    /* flag_lost_clk_int_in                              , */\
+   { 0x23a0, "flag_cf_speakererror_int_in"},    /* flag_cf_speakererror_int_in                       , */\
+   { 0x23b0, "flag_cold_started_int_in"},    /* flag_cold_started_int_in                          , */\
+   { 0x23c0, "flag_engage_int_in"},    /* flag_engage_int_in                                , */\
+   { 0x23d0, "flag_watchdog_reset_int_in"},    /* flag_watchdog_reset_int_in                        , */\
+   { 0x23e0, "flag_enbl_amp_int_in"},    /* flag_enbl_amp_int_in                              , */\
+   { 0x23f0, "flag_enbl_ref_int_in"},    /* flag_enbl_ref_int_in                              , */\
+   { 0x2400, "flag_voutcomp_int_in"},    /* flag_voutcomp_int_in                              , */\
+   { 0x2410, "flag_voutcomp93_int_in"},    /* flag_voutcomp93_int_in                            , */\
+   { 0x2420, "flag_voutcomp86_int_in"},    /* flag_voutcomp86_int_in                            , */\
+   { 0x2430, "flag_hiz_int_in"},    /* flag_hiz_int_in                                   , */\
+   { 0x2440, "flag_ocpokbst_int_in"},    /* flag_ocpokbst_int_in                              , */\
+   { 0x2450, "flag_peakcur_int_in"},    /* flag_peakcur_int_in                               , */\
+   { 0x2460, "flag_ocpokap_int_in"},    /* flag_ocpokap_int_in                               , */\
+   { 0x2470, "flag_ocpokan_int_in"},    /* flag_ocpokan_int_in                               , */\
+   { 0x2480, "flag_ocpokbp_int_in"},    /* flag_ocpokbp_int_in                               , */\
+   { 0x2490, "flag_ocpokbn_int_in"},    /* flag_ocpokbn_int_in                               , */\
+   { 0x24a0, "flag_adc10_ready_int_in"},    /* flag_adc10_ready_int_in                           , */\
+   { 0x24b0, "flag_clipa_high_int_in"},    /* flag_clipa_high_int_in                            , */\
+   { 0x24c0, "flag_clipa_low_int_in"},    /* flag_clipa_low_int_in                             , */\
+   { 0x24d0, "flag_clipb_high_int_in"},    /* flag_clipb_high_int_in                            , */\
+   { 0x24e0, "flag_clipb_low_int_in"},    /* flag_clipb_low_int_in                             , */\
+   { 0x24f0, "flag_tdm_error_int_in"},    /* flag_tdm_error_int_in                             , */\
+   { 0x2501, "interrupt_in3"},    /* Interrupt register input                          , */\
+   { 0x2600, "flag_por_int_enable"},    /* flag_por_int_enable                               , */\
+   { 0x2610, "flag_pll_lock_int_enable"},    /* flag_pll_lock_int_enable                          , */\
+   { 0x2620, "flag_otpok_int_enable"},    /* flag_otpok_int_enable                             , */\
+   { 0x2630, "flag_ovpok_int_enable"},    /* flag_ovpok_int_enable                             , */\
+   { 0x2640, "flag_uvpok_int_enable"},    /* flag_uvpok_int_enable                             , */\
+   { 0x2650, "flag_ocp_alarm_int_enable"},    /* flag_ocp_alarm_int_enable                         , */\
+   { 0x2660, "flag_clocks_stable_int_enable"},    /* flag_clocks_stable_int_enable                     , */\
+   { 0x2670, "flag_clip_int_enable"},    /* flag_clip_int_enable                              , */\
+   { 0x2680, "mtp_busy_int_enable"},    /* mtp_busy_int_enable                               , */\
+   { 0x2690, "flag_lost_clk_int_enable"},    /* flag_lost_clk_int_enable                          , */\
+   { 0x26a0, "flag_cf_speakererror_int_enable"},    /* flag_cf_speakererror_int_enable                   , */\
+   { 0x26b0, "flag_cold_started_int_enable"},    /* flag_cold_started_int_enable                      , */\
+   { 0x26c0, "flag_engage_int_enable"},    /* flag_engage_int_enable                            , */\
+   { 0x26d0, "flag_watchdog_reset_int_enable"},    /* flag_watchdog_reset_int_enable                    , */\
+   { 0x26e0, "flag_enbl_amp_int_enable"},    /* flag_enbl_amp_int_enable                          , */\
+   { 0x26f0, "flag_enbl_ref_int_enable"},    /* flag_enbl_ref_int_enable                          , */\
+   { 0x2700, "flag_voutcomp_int_enable"},    /* flag_voutcomp_int_enable                          , */\
+   { 0x2710, "flag_voutcomp93_int_enable"},    /* flag_voutcomp93_int_enable                        , */\
+   { 0x2720, "flag_voutcomp86_int_enable"},    /* flag_voutcomp86_int_enable                        , */\
+   { 0x2730, "flag_hiz_int_enable"},    /* flag_hiz_int_enable                               , */\
+   { 0x2740, "flag_ocpokbst_int_enable"},    /* flag_ocpokbst_int_enable                          , */\
+   { 0x2750, "flag_peakcur_int_enable"},    /* flag_peakcur_int_enable                           , */\
+   { 0x2760, "flag_ocpokap_int_enable"},    /* flag_ocpokap_int_enable                           , */\
+   { 0x2770, "flag_ocpokan_int_enable"},    /* flag_ocpokan_int_enable                           , */\
+   { 0x2780, "flag_ocpokbp_int_enable"},    /* flag_ocpokbp_int_enable                           , */\
+   { 0x2790, "flag_ocpokbn_int_enable"},    /* flag_ocpokbn_int_enable                           , */\
+   { 0x27a0, "flag_adc10_ready_int_enable"},    /* flag_adc10_ready_int_enable                       , */\
+   { 0x27b0, "flag_clipa_high_int_enable"},    /* flag_clipa_high_int_enable                        , */\
+   { 0x27c0, "flag_clipa_low_int_enable"},    /* flag_clipa_low_int_enable                         , */\
+   { 0x27d0, "flag_clipb_high_int_enable"},    /* flag_clipb_high_int_enable                        , */\
+   { 0x27e0, "flag_clipb_low_int_enable"},    /* flag_clipb_low_int_enable                         , */\
+   { 0x27f0, "flag_tdm_error_int_enable"},    /* flag_tdm_error_int_enable                         , */\
+   { 0x2801, "interrupt_enable3"},    /* Interrupt enable register                         , */\
+   { 0x2900, "flag_por_int_pol"},    /* flag_por_int_pol                                  , */\
+   { 0x2910, "flag_pll_lock_int_pol"},    /* flag_pll_lock_int_pol                             , */\
+   { 0x2920, "flag_otpok_int_pol"},    /* flag_otpok_int_pol                                , */\
+   { 0x2930, "flag_ovpok_int_pol"},    /* flag_ovpok_int_pol                                , */\
+   { 0x2940, "flag_uvpok_int_pol"},    /* flag_uvpok_int_pol                                , */\
+   { 0x2950, "flag_ocp_alarm_int_pol"},    /* flag_ocp_alarm_int_pol                            , */\
+   { 0x2960, "flag_clocks_stable_int_pol"},    /* flag_clocks_stable_int_pol                        , */\
+   { 0x2970, "flag_clip_int_pol"},    /* flag_clip_int_pol                                 , */\
+   { 0x2980, "mtp_busy_int_pol"},    /* mtp_busy_int_pol                                  , */\
+   { 0x2990, "flag_lost_clk_int_pol"},    /* flag_lost_clk_int_pol                             , */\
+   { 0x29a0, "flag_cf_speakererror_int_pol"},    /* flag_cf_speakererror_int_pol                      , */\
+   { 0x29b0, "flag_cold_started_int_pol"},    /* flag_cold_started_int_pol                         , */\
+   { 0x29c0, "flag_engage_int_pol"},    /* flag_engage_int_pol                               , */\
+   { 0x29d0, "flag_watchdog_reset_int_pol"},    /* flag_watchdog_reset_int_pol                       , */\
+   { 0x29e0, "flag_enbl_amp_int_pol"},    /* flag_enbl_amp_int_pol                             , */\
+   { 0x29f0, "flag_enbl_ref_int_pol"},    /* flag_enbl_ref_int_pol                             , */\
+   { 0x2a00, "flag_voutcomp_int_pol"},    /* flag_voutcomp_int_pol                             , */\
+   { 0x2a10, "flag_voutcomp93_int_pol"},    /* flag_voutcomp93_int_pol                           , */\
+   { 0x2a20, "flag_voutcomp86_int_pol"},    /* flag_voutcomp86_int_pol                           , */\
+   { 0x2a30, "flag_hiz_int_pol"},    /* flag_hiz_int_pol                                  , */\
+   { 0x2a40, "flag_ocpokbst_int_pol"},    /* flag_ocpokbst_int_pol                             , */\
+   { 0x2a50, "flag_peakcur_int_pol"},    /* flag_peakcur_int_pol                              , */\
+   { 0x2a60, "flag_ocpokap_int_pol"},    /* flag_ocpokap_int_pol                              , */\
+   { 0x2a70, "flag_ocpokan_int_pol"},    /* flag_ocpokan_int_pol                              , */\
+   { 0x2a80, "flag_ocpokbp_int_pol"},    /* flag_ocpokbp_int_pol                              , */\
+   { 0x2a90, "flag_ocpokbn_int_pol"},    /* flag_ocpokbn_int_pol                              , */\
+   { 0x2aa0, "flag_adc10_ready_int_pol"},    /* flag_adc10_ready_int_pol                          , */\
+   { 0x2ab0, "flag_clipa_high_int_pol"},    /* flag_clipa_high_int_pol                           , */\
+   { 0x2ac0, "flag_clipa_low_int_pol"},    /* flag_clipa_low_int_pol                            , */\
+   { 0x2ad0, "flag_clipb_high_int_pol"},    /* flag_clipb_high_int_pol                           , */\
+   { 0x2ae0, "flag_clipb_low_int_pol"},    /* flag_clipb_low_int_pol                            , */\
+   { 0x2af0, "flag_tdm_error_int_pol"},    /* flag_tdm_error_int_pol                            , */\
+   { 0x2b01, "status_polarity3"},    /* Interrupt status flags polarity register          , */\
+   { 0x3000, "flag_voutcomp"},    /* flag_voutcomp, indication Vset is larger than Vbat, */\
+   { 0x3010, "flag_voutcomp93"},    /* flag_voutcomp93, indication Vset is larger than 1.07* Vbat, */\
+   { 0x3020, "flag_voutcomp86"},    /* flag_voutcomp86, indication Vset is larger than 1.14* Vbat, */\
+   { 0x3030, "flag_hiz"},    /* flag_hiz, indication Vbst is larger than  Vbat    , */\
+   { 0x3040, "flag_ocpokbst"},    /* flag_ocpokbst, indication no over current in boost converter pmos switch, */\
+   { 0x3050, "flag_peakcur"},    /* flag_peakcur, indication current is max in dcdc converter, */\
+   { 0x3060, "flag_ocpokap"},    /* flag_ocpokap, indication no over current in amplifier "a" pmos output stage, */\
+   { 0x3070, "flag_ocpokan"},    /* flag_ocpokan, indication no over current in amplifier "a" nmos output stage, */\
+   { 0x3080, "flag_ocpokbp"},    /* flag_ocpokbp, indication no over current in amplifier "b" pmos output stage, */\
+   { 0x3090, "flag_ocpokbn"},    /* flag_ocpokbn, indication no over current in amplifier"b" nmos output stage, */\
+   { 0x30a0, "flag_adc10_ready"},    /* flag_adc10_ready, indication adc10 is ready       , */\
+   { 0x30b0, "flag_clipa_high"},    /* flag_clipa_high, indication pmos amplifier "a" is clipping, */\
+   { 0x30c0, "flag_clipa_low"},    /* flag_clipa_low, indication nmos amplifier "a" is clipping, */\
+   { 0x30d0, "flag_clipb_high"},    /* flag_clipb_high, indication pmos amplifier "b" is clipping, */\
+   { 0x30e0, "flag_clipb_low"},    /* flag_clipb_low, indication nmos amplifier "b" is clipping, */\
+   { 0x310f, "mtp_man_data_out"},    /* single word read from MTP (manual copy)           , */\
+   { 0x3200, "key01_locked"},    /* key01_locked, indication key 1 is locked          , */\
+   { 0x3210, "key02_locked"},    /* key02_locked, indication key 2 is locked          , */\
+   { 0x3225, "mtp_ecc_tcout"},    /* mtp_ecc_tcout                                     , */\
+   { 0x3280, "mtpctrl_valid_test_rd"},    /* mtp test readout for read                         , */\
+   { 0x3290, "mtpctrl_valid_test_wr"},    /* mtp test readout for write                        , */\
+   { 0x32a0, "flag_in_alarm_state"},    /* Alarm state                                       , */\
+   { 0x32b0, "mtp_ecc_err2"},    /* two or more bit errors detected in MTP, can not reconstruct value, */\
+   { 0x32c0, "mtp_ecc_err1"},    /* one bit error detected in MTP, reconstructed value, */\
+   { 0x32d0, "mtp_mtp_hvf"},    /* high voltage ready flag for MTP                   , */\
+   { 0x32f0, "mtp_zero_check_fail"},    /* zero check failed (tbd) for MTP                   , */\
+   { 0x3309, "data_adc10_tempbat"},    /* data_adc10_tempbat[9;0], adc 10 data output for testing, */\
+   { 0x400f, "hid_code"},    /* 5A6Bh, 23147d to access registers (Default for engineering), */\
+   { 0x4100, "bypass_hp"},    /* Bypass_High Pass Filter                           , */\
+   { 0x4110, "hard_mute"},    /* Hard Mute                                         , */\
+   { 0x4120, "soft_mute"},    /* Soft Mute                                         , */\
+   { 0x4134, "pwm_delay"},    /* PWM DelayBits to set the delay                    , */\
+   { 0x4180, "pwm_shape"},    /* PWM Shape                                         , */\
+   { 0x4190, "pwm_bitlength"},    /* PWM Bitlength in noise shaper                     , */\
+   { 0x4203, "drive"},    /* Drive bits to select amount of power stage amplifier, */\
+   { 0x4240, "reclock_pwm"},    /*                                                   , */\
+   { 0x4250, "reclock_voltsense"},    /*                                                   , */\
+   { 0x4281, "dpsalevel"},    /* DPSA Threshold level                              , */\
+   { 0x42a1, "dpsa_release"},    /* DPSA Release time                                 , */\
+   { 0x42c0, "coincidence"},    /* Prevent simultaneously switching of output stage  , */\
+   { 0x42d0, "kickback"},    /* Prevent double pulses of output stage             , */\
+   { 0x4306, "drivebst"},    /* Drive bits to select the powertransistor sections boost converter, */\
+   { 0x43a0, "ocptestbst"},    /* Boost OCP. For old ocp (ctrl_reversebst is 0);For new ocp (ctrl_reversebst is 1);, */\
+   { 0x43d0, "test_abistfft_enbl"},    /* FFT coolflux                                      , */\
+   { 0x43f0, "test_bcontrol"},    /* test _bcontrol                                    , */\
+   { 0x4400, "reversebst"},    /* OverCurrent Protection selection of power stage boost converter, */\
+   { 0x4410, "sensetest"},    /* Test option for the sense NMOS in booster for current mode control., */\
+   { 0x4420, "enbl_engagebst"},    /* Enable power stage dcdc controller                , */\
+   { 0x4470, "enbl_slopecur"},    /* Enable bit of max-current dac                     , */\
+   { 0x4480, "enbl_voutcomp"},    /* Enable vout comparators                           , */\
+   { 0x4490, "enbl_voutcomp93"},    /* Enable vout-93 comparators                        , */\
+   { 0x44a0, "enbl_voutcomp86"},    /* Enable vout-86 comparators                        , */\
+   { 0x44b0, "enbl_hizcom"},    /* Enable hiz comparator                             , */\
+   { 0x44c0, "enbl_peakcur"},    /* Enable peak current                               , */\
+   { 0x44d0, "bypass_ovpglitch"},    /* Bypass OVP Glitch Filter                          , */\
+   { 0x44e0, "enbl_windac"},    /* Enable window dac                                 , */\
+   { 0x44f0, "enbl_powerbst"},    /* Enable line of the powerstage                     , */\
+   { 0x4507, "ocp_thr"},    /* ocp_thr threshold level for OCP                   , */\
+   { 0x4580, "bypass_glitchfilter"},    /* Bypass glitch filter                              , */\
+   { 0x4590, "bypass_ovp"},    /* Bypass OVP                                        , */\
+   { 0x45a0, "bypass_uvp"},    /* Bypass UVP                                        , */\
+   { 0x45b0, "bypass_otp"},    /* Bypass OTP                                        , */\
+   { 0x45c0, "bypass_ocp"},    /* Bypass OCP                                        , */\
+   { 0x45d0, "bypass_ocpcounter"},    /* BypassOCPCounter                                  , */\
+   { 0x45e0, "bypass_lost_clk"},    /* Bypasslost_clk detector                           , */\
+   { 0x45f0, "vpalarm"},    /* vpalarm (uvp ovp handling)                        , */\
+   { 0x4600, "bypass_gc"},    /* bypass_gc, bypasses the CS gain correction        , */\
+   { 0x4610, "cs_gain_control"},    /* gain control by means of MTP or i2c; 0 is MTP     , */\
+   { 0x4627, "cs_gain"},    /* + / - 128 steps in steps of 1/4 percent  2's compliment, */\
+   { 0x46a0, "bypass_lp"},    /* bypass Low-Pass filter in temperature sensor      , */\
+   { 0x46b0, "bypass_pwmcounter"},    /* bypass_pwmcounter                                 , */\
+   { 0x46c0, "cs_negfixed"},    /* does not switch to neg                            , */\
+   { 0x46d2, "cs_neghyst"},    /* switches to neg depending on level                , */\
+   { 0x4700, "switch_fb"},    /* switch_fb                                         , */\
+   { 0x4713, "se_hyst"},    /* se_hyst                                           , */\
+   { 0x4754, "se_level"},    /* se_level                                          , */\
+   { 0x47a5, "ktemp"},    /* temperature compensation trimming                 , */\
+   { 0x4800, "cs_negin"},    /* negin                                             , */\
+   { 0x4810, "cs_sein"},    /* cs_sein                                           , */\
+   { 0x4820, "cs_coincidence"},    /* Coincidence current sense                         , */\
+   { 0x4830, "iddqtestbst"},    /* for iddq testing in powerstage of boost convertor , */\
+   { 0x4840, "coincidencebst"},    /* Switch protection on to prevent simultaneously switching power stages bst and amp, */\
+   { 0x4876, "delay_se_neg"},    /* delay of se and neg                               , */\
+   { 0x48e1, "cs_ttrack"},    /* sample & hold track time                          , */\
+   { 0x4900, "bypass_clip"},    /* Bypass clip control                               , */\
+   { 0x4920, "cf_cgate_off"},    /* to disable clock gating in the coolflux           , */\
+   { 0x4940, "clipfast"},    /* clock switch for battery protection clipper, it switches back to old frequency, */\
+   { 0x4950, "cs_8ohm"},    /* 8 ohm mode for current sense (gain mode)          , */\
+   { 0x4974, "delay_clock_sh"},    /* delay_sh, tunes S7H delay                         , */\
+   { 0x49c0, "inv_clksh"},    /* Invert the sample/hold clock for current sense ADC, */\
+   { 0x49d0, "inv_neg"},    /* Invert neg signal                                 , */\
+   { 0x49e0, "inv_se"},    /* Invert se signal                                  , */\
+   { 0x49f0, "setse"},    /* switches between Single Ende and differential mode; 1 is single ended, */\
+   { 0x4a12, "adc10_sel"},    /* select the input to convert the 10b ADC           , */\
+   { 0x4a60, "adc10_reset"},    /* Global asynchronous reset (active HIGH) 10 bit ADC, */\
+   { 0x4a81, "adc10_test"},    /* Test mode selection signal 10 bit ADC             , */\
+   { 0x4aa0, "bypass_lp_vbat"},    /* lp filter in batt sensor                          , */\
+   { 0x4ae0, "dc_offset"},    /* switch offset control on/off, is decimator offset control, */\
+   { 0x4af0, "tsense_hibias"},    /* bit to set the biasing in temp sensor to high     , */\
+   { 0x4b00, "adc13_iset"},    /* Micadc Setting of current consumption. Debug use only, */\
+   { 0x4b14, "adc13_gain"},    /* Micadc gain setting (2-compl)                     , */\
+   { 0x4b61, "adc13_slowdel"},    /* Micadc Delay setting for internal clock. Debug use only, */\
+   { 0x4b83, "adc13_offset"},    /* Micadc ADC offset setting                         , */\
+   { 0x4bc0, "adc13_bsoinv"},    /* Micadc bit stream output invert mode for test     , */\
+   { 0x4bd0, "adc13_resonator_enable"},    /* Micadc Give extra SNR with less stability. Debug use only, */\
+   { 0x4be0, "testmicadc"},    /* Mux at input of MICADC for test purpose           , */\
+   { 0x4c0f, "abist_offset"},    /* offset control for ABIST testing                  , */\
+   { 0x4d05, "windac"},    /* for testing direct control windac                 , */\
+   { 0x4dc3, "pwm_dcc_cnt"},    /* control pwm duty cycle when enbl_pwm_dcc is 1     , */\
+   { 0x4e04, "slopecur"},    /* for testing direct control slopecur               , */\
+   { 0x4e50, "ctrl_dem"},    /* dyn element matching control, rest of codes are optional, */\
+   { 0x4ed0, "enbl_pwm_dcc"},    /* to enable direct control of pwm duty cycle        , */\
+   { 0x5007, "gain"},    /* Gain setting of the gain multiplier               , */\
+   { 0x5081, "sourceb"},    /* Set OUTB to                                       , */\
+   { 0x50a1, "sourcea"},    /* Set OUTA to                                       , */\
+   { 0x50c1, "sourcebst"},    /* Sets the source of the pwmbst output to boost converter input for testing, */\
+   { 0x50e0, "tdm_enable_loopback"},    /* TDM loopback test                                 , */\
+   { 0x5104, "pulselengthbst"},    /* pulse length setting test input for boost converter, */\
+   { 0x5150, "bypasslatchbst"},    /* bypass_latch in boost converter                   , */\
+   { 0x5160, "invertbst"},    /* invert pwmbst test signal                         , */\
+   { 0x5174, "pulselength"},    /* pulse length setting test input for amplifier     , */\
+   { 0x51c0, "bypasslatch"},    /* bypass_latch in PWM source selection module       , */\
+   { 0x51d0, "invertb"},    /* invert pwmb test signal                           , */\
+   { 0x51e0, "inverta"},    /* invert pwma test signal                           , */\
+   { 0x51f0, "bypass_ctrlloop"},    /* bypass_ctrlloop bypasses the control loop of the amplifier, */\
+   { 0x5210, "test_rdsona"},    /* tbd for rdson testing                             , */\
+   { 0x5220, "test_rdsonb"},    /* tbd for rdson testing                             , */\
+   { 0x5230, "test_rdsonbst"},    /* tbd for rdson testing                             , */\
+   { 0x5240, "test_cvia"},    /* tbd for rdson testing                             , */\
+   { 0x5250, "test_cvib"},    /* tbd for rdson testing                             , */\
+   { 0x5260, "test_cvibst"},    /* tbd for rdson testing                             , */\
+   { 0x5306, "digimuxa_sel"},    /* DigimuxA input selection control (see Digimux list for details), */\
+   { 0x5376, "digimuxb_sel"},    /* DigimuxB input selection control (see Digimux list for details), */\
+   { 0x5400, "hs_mode"},    /* hs_mode, high speed mode I2C bus                  , */\
+   { 0x5412, "test_parametric_io"},    /* test_parametric_io for testing pads               , */\
+   { 0x5440, "enbl_ringo"},    /* enbl_ringo, for test purpose to check with ringo  , */\
+   { 0x5456, "digimuxc_sel"},    /* DigimuxC input selection control (see Digimux list for details), */\
+   { 0x54c0, "dio_ehs"},    /* Slew control for DIO in output mode               , */\
+   { 0x54d0, "gainio_ehs"},    /* Slew control for GAINIO in output mode            , */\
+   { 0x550d, "enbl_amp"},    /* enbl_amp for testing to enable all analoge blocks in amplifier, */\
+   { 0x5600, "use_direct_ctrls"},    /* use_direct_ctrls, to overrule several functions direct for testing, */\
+   { 0x5610, "rst_datapath"},    /* rst_datapath, datapath reset                      , */\
+   { 0x5620, "rst_cgu"},    /* rst_cgu, cgu reset                                , */\
+   { 0x5637, "enbl_ref"},    /* for testing to enable all analoge blocks in references, */\
+   { 0x56b0, "enbl_engage"},    /* Enable output stage amplifier                     , */\
+   { 0x56c0, "use_direct_clk_ctrl"},    /* use_direct_clk_ctrl, to overrule several functions direct for testing, */\
+   { 0x56d0, "use_direct_pll_ctrl"},    /* use_direct_pll_ctrl, to overrule several functions direct for testing, */\
+   { 0x56e0, "use_direct_ctrls_2"},    /* use_direct_sourseamp_ctrls, to overrule several functions direct for testing, */\
+   { 0x5707, "anamux"},    /* Anamux control                                    , */\
+   { 0x57c0, "ocptest"},    /* ctrl_ocptest, deactivates the over current protection in the power stages of the amplifier. The ocp flag signals stay active., */\
+   { 0x57e0, "otptest"},    /* otptest, test mode otp amplifier                  , */\
+   { 0x57f0, "reverse"},    /* 1: Normal mode, slope is controlled               , */\
+   { 0x5813, "pll_selr"},    /* pll_selr                                          , */\
+   { 0x5854, "pll_selp"},    /* pll_selp                                          , */\
+   { 0x58a5, "pll_seli"},    /* pll_seli                                          , */\
+   { 0x5950, "pll_mdec_msb"},    /* most significant bits of pll_mdec[16]             , */\
+   { 0x5960, "pll_ndec_msb"},    /* most significant bits of pll_ndec[9]              , */\
+   { 0x5970, "pll_frm"},    /* pll_frm                                           , */\
+   { 0x5980, "pll_directi"},    /* pll_directi                                       , */\
+   { 0x5990, "pll_directo"},    /* pll_directo                                       , */\
+   { 0x59a0, "enbl_pll"},    /* enbl_pll                                          , */\
+   { 0x59f0, "pll_bypass"},    /* pll_bypass                                        , */\
+   { 0x5a0f, "tsig_freq"},    /* tsig_freq, internal sinus test generator, frequency control, */\
+   { 0x5b02, "tsig_freq_msb"},    /* select internal sinus test generator, frequency control msb bits, */\
+   { 0x5b30, "inject_tsig"},    /* inject_tsig, control bit to switch to internal sinus test generator, */\
+   { 0x5b44, "adc10_prog_sample"},    /* control ADC10                                     , */\
+   { 0x5c0f, "pll_mdec"},    /* bits 15..0 of pll_mdec[16;0]                      , */\
+   { 0x5d06, "pll_pdec"},    /* pll_pdec                                          , */\
+   { 0x5d78, "pll_ndec"},    /* bits 8..0 of pll_ndec[9;0]                        , */\
+   { 0x6007, "mtpkey1"},    /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */\
+   { 0x6185, "mtp_ecc_tcin"},    /* Mtp_ecc_tcin                                      , */\
+   { 0x6203, "mtp_man_address_in"},    /* address from I2C regs for writing one word single mtp, */\
+   { 0x6260, "mtp_ecc_eeb"},    /* enable code bit generation (active low!)          , */\
+   { 0x6270, "mtp_ecc_ecb"},    /* enable correction signal (active low!)            , */\
+   { 0x6280, "man_copy_mtp_to_iic"},    /* start copying single word from mtp to i2cregs_mtp , */\
+   { 0x6290, "man_copy_iic_to_mtp"},    /* start copying single word from i2cregs_mtp to mtp [Key 1 protected], */\
+   { 0x62a0, "auto_copy_mtp_to_iic"},    /* start copying all the data from mtp to i2cregs_mtp, */\
+   { 0x62b0, "auto_copy_iic_to_mtp"},    /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */\
+   { 0x62d2, "mtp_speed_mode"},    /* Speed mode                                        , */\
+   { 0x6340, "mtp_direct_enable"},    /* mtp_direct_enable (key1 protected)                , */\
+   { 0x6350, "mtp_direct_wr"},    /* mtp_direct_wr (key1 protected)                    , */\
+   { 0x6360, "mtp_direct_rd"},    /* mtp_direct_rd  (key1 protected)                   , */\
+   { 0x6370, "mtp_direct_rst"},    /* mtp_direct_rst  (key1 protected)                  , */\
+   { 0x6380, "mtp_direct_ers"},    /* mtp_direct_ers  (key1 protected)                  , */\
+   { 0x6390, "mtp_direct_prg"},    /* mtp_direct_prg  (key1 protected)                  , */\
+   { 0x63a0, "mtp_direct_epp"},    /* mtp_direct_epp  (key1 protected)                  , */\
+   { 0x63b4, "mtp_direct_test"},    /* mtp_direct_test  (key1 protected)                 , */\
+   { 0x640f, "mtp_man_data_in"},    /* single word to be written to MTP (manual copy)    , */\
+   { 0x7000, "cf_rst_dsp"},    /* Reset CoolFlux DSP                                , */\
+   { 0x7011, "cf_dmem"},    /* Target memory for access                          , */\
+   { 0x7030, "cf_aif"},    /* Autoincrement-flag for memory-address             , */\
+   { 0x7040, "cf_int"},    /* Interrupt CoolFlux DSP                            , */\
+   { 0x7087, "cf_req"},    /* request for access (8 channels)                   , */\
+   { 0x710f, "cf_madd"},    /* memory-address to be accessed                     , */\
+   { 0x720f, "cf_mema"},    /* activate memory access (24- or 32-bits data is written/read to/from memory, */\
+   { 0x7307, "cf_err"},    /* Coolflux error flags                              , */\
+   { 0x7387, "cf_ack"},    /* acknowledge of requests (8 channels)              , */\
+   { 0x8000, "calibration_onetime"},    /* Calibration schedule (key2 protected)             , */\
+   { 0x8010, "calibr_ron_done"},    /* (key2 protected)                                  , */\
+   { 0x8105, "calibr_vout_offset"},    /* calibr_vout_offset (DCDCoffset) 2's compliment (key1 protected), */\
+   { 0x8163, "calibr_delta_gain"},    /* delta gain for vamp (alpha) 2's compliment (key1 protected), */\
+   { 0x81a5, "calibr_offs_amp"},    /* offset for vamp (Ampoffset) 2's compliment (key1 protected), */\
+   { 0x8207, "calibr_gain_cs"},    /* gain current sense (Imeasalpha) 2's compliment (key1 protected), */\
+   { 0x8284, "calibr_temp_offset"},    /* temperature offset 2's compliment (key1 protected), */\
+   { 0x82d2, "calibr_temp_gain"},    /* temperature gain 2's compliment (key1 protected)  , */\
+   { 0x830f, "calibr_ron"},    /* Ron resistance of coil (key1 protected)           , */\
+   { 0x8505, "type_bits_HW"},    /* Key1_Protected_MTP5                               , */\
+   { 0x8601, "type_bits_1_0_SW"},    /* MTP-control SW                                    , */\
+   { 0x8681, "type_bits_8_9_SW"},    /* MTP-control SW                                    , */\
+   { 0x870f, "type_bits2_SW"},    /* MTP-control SW2                                   , */\
+   { 0x8806, "htol_iic_addr"},    /* 7-bit I2C address to be used during HTOL testing  , */\
+   { 0x8870, "htol_iic_addr_en"},    /* HTOL_I2C_Address_Enable                           , */\
+   { 0x8881, "ctrl_ovp_response"},    /* OVP response control                              , */\
+   { 0x88a0, "disable_ovp_alarm_state"},    /* OVP alarm state control                           , */\
+   { 0x88b0, "enbl_stretch_ovp"},    /* OVP alram strech control                          , */\
+   { 0x88c0, "cf_debug_mode"},    /* Coolflux debug mode                               , */\
+   { 0x8a0f, "production_data1"},    /* (key1 protected)                                  , */\
+   { 0x8b0f, "production_data2"},    /* (key1 protected)                                  , */\
+   { 0x8c0f, "production_data3"},    /* (key1 protected)                                  , */\
+   { 0x8d0f, "production_data4"},    /* (key1 protected)                                  , */\
+   { 0x8e0f, "production_data5"},    /* (key1 protected)                                  , */\
+   { 0x8f0f, "production_data6"},    /* (key1 protected)                                  , */\
+   { 0xffff,"Unknown bitfield enum" }    /* not found */\
+};
+
+enum tfa1_irq {
+	tfa1_irq_vdds = 0,
+	tfa1_irq_plls = 1,
+	tfa1_irq_ds = 2,
+	tfa1_irq_vds = 3,
+	tfa1_irq_uvds = 4,
+	tfa1_irq_cds = 5,
+	tfa1_irq_clks = 6,
+	tfa1_irq_clips = 7,
+	tfa1_irq_mtpb = 8,
+	tfa1_irq_clk = 9,
+	tfa1_irq_spks = 10,
+	tfa1_irq_acs = 11,
+	tfa1_irq_sws = 12,
+	tfa1_irq_wds = 13,
+	tfa1_irq_amps = 14,
+	tfa1_irq_arefs = 15,
+	tfa1_irq_ack = 32,
+	tfa1_irq_max = 33,
+	tfa1_irq_all = -1 /* all irqs */};
+
+#define TFA1_IRQ_NAMETABLE static tfaIrqName_t Tfa1IrqNames[]= {\
+	{ 0, "VDDS"},\
+	{ 1, "PLLS"},\
+	{ 2, "DS"},\
+	{ 3, "VDS"},\
+	{ 4, "UVDS"},\
+	{ 5, "CDS"},\
+	{ 6, "CLKS"},\
+	{ 7, "CLIPS"},\
+	{ 8, "MTPB"},\
+	{ 9, "CLK"},\
+	{ 10, "SPKS"},\
+	{ 11, "ACS"},\
+	{ 12, "SWS"},\
+	{ 13, "WDS"},\
+	{ 14, "AMPS"},\
+	{ 15, "AREFS"},\
+	{ 16, "16"},\
+	{ 17, "17"},\
+	{ 18, "18"},\
+	{ 19, "19"},\
+	{ 20, "20"},\
+	{ 21, "21"},\
+	{ 22, "22"},\
+	{ 23, "23"},\
+	{ 24, "24"},\
+	{ 25, "25"},\
+	{ 26, "26"},\
+	{ 27, "27"},\
+	{ 28, "28"},\
+	{ 29, "29"},\
+	{ 30, "30"},\
+	{ 31, "31"},\
+	{ 32, "ACK"},\
+	{ 33, "33"},\
+};
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa2_tfafieldnames_N1C.h b/techpack/audio/asoc/codecs/tfa98xx/tfa2_tfafieldnames_N1C.h
new file mode 100644
index 0000000..107028e
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa2_tfafieldnames_N1C.h
@@ -0,0 +1,1522 @@
+/** Filename: Tfa98xx_TfaFieldnames.h
+ *  This file was generated automatically on 09/01/15 at 09:40:28. 
+ *  Source file: TFA9888_N1C_I2C_regmap_V1.xlsx
+ */
+
+typedef enum nxpTfa2BfEnumList {
+    TFA2_BF_PWDN  = 0x0000,    /*!< Powerdown selection                                */
+    TFA2_BF_I2CR  = 0x0010,    /*!< I2C Reset - Auto clear                             */
+    TFA2_BF_CFE   = 0x0020,    /*!< Enable CoolFlux                                    */
+    TFA2_BF_AMPE  = 0x0030,    /*!< Activate Amplifier                                 */
+    TFA2_BF_DCA   = 0x0040,    /*!< Activate DC-to-DC converter                        */
+    TFA2_BF_SBSL  = 0x0050,    /*!< Coolflux configured                                */
+    TFA2_BF_AMPC  = 0x0060,    /*!< CoolFlux controls amplifier                        */
+    TFA2_BF_INTP  = 0x0071,    /*!< Interrupt config                                   */
+    TFA2_BF_FSSSEL= 0x0091,    /*!< Audio sample reference                             */
+    TFA2_BF_BYPOCP= 0x00b0,    /*!< Bypass OCP                                         */
+    TFA2_BF_TSTOCP= 0x00c0,    /*!< OCP testing control                                */
+    TFA2_BF_AMPINSEL= 0x0101,    /*!< Amplifier input selection                          */
+    TFA2_BF_MANSCONF= 0x0120,    /*!< I2C configured                                     */
+    TFA2_BF_MANCOLD= 0x0130,    /*!< Execute cold start                                 */
+    TFA2_BF_MANAOOSC= 0x0140,    /*!< Internal osc off at PWDN                           */
+    TFA2_BF_MANROBOD= 0x0150,    /*!< Reaction on BOD                                    */
+    TFA2_BF_BODE  = 0x0160,    /*!< BOD Enable                                         */
+    TFA2_BF_BODHYS= 0x0170,    /*!< BOD Hysteresis                                     */
+    TFA2_BF_BODFILT= 0x0181,    /*!< BOD filter                                         */
+    TFA2_BF_BODTHLVL= 0x01a1,    /*!< BOD threshold                                      */
+    TFA2_BF_MUTETO= 0x01d0,    /*!< Time out SB mute sequence                          */
+    TFA2_BF_RCVNS = 0x01e0,    /*!< Noise shaper selection                             */
+    TFA2_BF_MANWDE= 0x01f0,    /*!< Watchdog manager reaction                          */
+    TFA2_BF_AUDFS = 0x0203,    /*!< Sample rate (fs)                                   */
+    TFA2_BF_INPLEV= 0x0240,    /*!< TDM output attenuation                             */
+    TFA2_BF_FRACTDEL= 0x0255,    /*!< V/I Fractional delay                               */
+    TFA2_BF_BYPHVBF= 0x02b0,    /*!< Bypass HVBAT filter                                */
+    TFA2_BF_LDOBYP= 0x02c0,    /*!< Receiver LDO bypass                                */
+    TFA2_BF_REV   = 0x030f,    /*!< Revision info                                      */
+    TFA2_BF_REFCKEXT= 0x0401,    /*!< PLL external ref clock                             */
+    TFA2_BF_REFCKSEL= 0x0420,    /*!< PLL internal ref clock                             */
+    TFA2_BF_SSLEFTE= 0x0500,    /*!< Enable left channel                                */
+    TFA2_BF_SSRIGHTE= 0x0510,    /*!< Enable right channel                               */
+    TFA2_BF_VSLEFTE= 0x0520,    /*!< Voltage sense left                                 */
+    TFA2_BF_VSRIGHTE= 0x0530,    /*!< Voltage sense right                                */
+    TFA2_BF_CSLEFTE= 0x0540,    /*!< Current sense left                                 */
+    TFA2_BF_CSRIGHTE= 0x0550,    /*!< Current sense right                                */
+    TFA2_BF_SSPDME= 0x0560,    /*!< Sub-system PDM                                     */
+    TFA2_BF_STGAIN= 0x0d18,    /*!< Side tone gain                                     */
+    TFA2_BF_PDMSMUTE= 0x0da0,    /*!< Side tone soft mute                                */
+    TFA2_BF_SWVSTEP= 0x0e06,    /*!< Register for the host SW to record the current active vstep */
+    TFA2_BF_VDDS  = 0x1000,    /*!< POR                                                */
+    TFA2_BF_PLLS  = 0x1010,    /*!< PLL lock                                           */
+    TFA2_BF_OTDS  = 0x1020,    /*!< OTP alarm                                          */
+    TFA2_BF_OVDS  = 0x1030,    /*!< OVP alarm                                          */
+    TFA2_BF_UVDS  = 0x1040,    /*!< UVP alarm                                          */
+    TFA2_BF_CLKS  = 0x1050,    /*!< Clocks stable                                      */
+    TFA2_BF_MTPB  = 0x1060,    /*!< MTP busy                                           */
+    TFA2_BF_NOCLK = 0x1070,    /*!< Lost clock                                         */
+    TFA2_BF_SPKS  = 0x1080,    /*!< Speaker error                                      */
+    TFA2_BF_ACS   = 0x1090,    /*!< Cold Start                                         */
+    TFA2_BF_SWS   = 0x10a0,    /*!< Amplifier engage                                   */
+    TFA2_BF_WDS   = 0x10b0,    /*!< Watchdog                                           */
+    TFA2_BF_AMPS  = 0x10c0,    /*!< Amplifier enable                                   */
+    TFA2_BF_AREFS = 0x10d0,    /*!< References enable                                  */
+    TFA2_BF_ADCCR = 0x10e0,    /*!< Control ADC                                        */
+    TFA2_BF_BODNOK= 0x10f0,    /*!< BOD                                                */
+    TFA2_BF_DCIL  = 0x1100,    /*!< DCDC current limiting                              */
+    TFA2_BF_DCDCA = 0x1110,    /*!< DCDC active                                        */
+    TFA2_BF_DCOCPOK= 0x1120,    /*!< DCDC OCP nmos                                      */
+    TFA2_BF_DCHVBAT= 0x1140,    /*!< DCDC level 1x                                      */
+    TFA2_BF_DCH114= 0x1150,    /*!< DCDC level 1.14x                                   */
+    TFA2_BF_DCH107= 0x1160,    /*!< DCDC level 1.07x                                   */
+    TFA2_BF_STMUTEB= 0x1170,    /*!< side tone (un)mute busy                            */
+    TFA2_BF_STMUTE= 0x1180,    /*!< side tone mute state                               */
+    TFA2_BF_TDMLUTER= 0x1190,    /*!< TDM LUT error                                      */
+    TFA2_BF_TDMSTAT= 0x11a2,    /*!< TDM status bits                                    */
+    TFA2_BF_TDMERR= 0x11d0,    /*!< TDM error                                          */
+    TFA2_BF_HAPTIC= 0x11e0,    /*!< Status haptic driver                               */
+    TFA2_BF_OCPOAPL= 0x1200,    /*!< OCPOK pmos A left                                  */
+    TFA2_BF_OCPOANL= 0x1210,    /*!< OCPOK nmos A left                                  */
+    TFA2_BF_OCPOBPL= 0x1220,    /*!< OCPOK pmos B left                                  */
+    TFA2_BF_OCPOBNL= 0x1230,    /*!< OCPOK nmos B left                                  */
+    TFA2_BF_CLIPAHL= 0x1240,    /*!< Clipping A left to Vddp                            */
+    TFA2_BF_CLIPALL= 0x1250,    /*!< Clipping A left to gnd                             */
+    TFA2_BF_CLIPBHL= 0x1260,    /*!< Clipping B left to Vddp                            */
+    TFA2_BF_CLIPBLL= 0x1270,    /*!< Clipping B left to gnd                             */
+    TFA2_BF_OCPOAPRC= 0x1280,    /*!< OCPOK pmos A RCV                                   */
+    TFA2_BF_OCPOANRC= 0x1290,    /*!< OCPOK nmos A RCV                                   */
+    TFA2_BF_OCPOBPRC= 0x12a0,    /*!< OCPOK pmos B RCV                                   */
+    TFA2_BF_OCPOBNRC= 0x12b0,    /*!< OCPOK nmos B RCV                                   */
+    TFA2_BF_RCVLDOR= 0x12c0,    /*!< RCV LDO regulates                                  */
+    TFA2_BF_RCVLDOBR= 0x12d0,    /*!< Receiver LDO ready                                 */
+    TFA2_BF_OCDSL = 0x12e0,    /*!< OCP left amplifier                                 */
+    TFA2_BF_CLIPSL= 0x12f0,    /*!< Amplifier left clipping                            */
+    TFA2_BF_OCPOAPR= 0x1300,    /*!< OCPOK pmos A right                                 */
+    TFA2_BF_OCPOANR= 0x1310,    /*!< OCPOK nmos A right                                 */
+    TFA2_BF_OCPOBPR= 0x1320,    /*!< OCPOK pmos B right                                 */
+    TFA2_BF_OCPOBNR= 0x1330,    /*!< OCPOK nmos B right                                 */
+    TFA2_BF_CLIPAHR= 0x1340,    /*!< Clipping A right to Vddp                           */
+    TFA2_BF_CLIPALR= 0x1350,    /*!< Clipping A right to gnd                            */
+    TFA2_BF_CLIPBHR= 0x1360,    /*!< Clipping B left to Vddp                            */
+    TFA2_BF_CLIPBLR= 0x1370,    /*!< Clipping B right to gnd                            */
+    TFA2_BF_OCDSR = 0x1380,    /*!< OCP right amplifier                                */
+    TFA2_BF_CLIPSR= 0x1390,    /*!< Amplifier right clipping                           */
+    TFA2_BF_OCPOKMC= 0x13a0,    /*!< OCPOK MICVDD                                       */
+    TFA2_BF_MANALARM= 0x13b0,    /*!< Alarm state                                        */
+    TFA2_BF_MANWAIT1= 0x13c0,    /*!< Wait HW I2C settings                               */
+    TFA2_BF_MANWAIT2= 0x13d0,    /*!< Wait CF config                                     */
+    TFA2_BF_MANMUTE= 0x13e0,    /*!< Audio mute sequence                                */
+    TFA2_BF_MANOPER= 0x13f0,    /*!< Operating state                                    */
+    TFA2_BF_SPKSL = 0x1400,    /*!< Left speaker status                                */
+    TFA2_BF_SPKSR = 0x1410,    /*!< Right speaker status                               */
+    TFA2_BF_CLKOOR= 0x1420,    /*!< External clock status                              */
+    TFA2_BF_MANSTATE= 0x1433,    /*!< Device manager status                              */
+    TFA2_BF_BATS  = 0x1509,    /*!< Battery voltage (V)                                */
+    TFA2_BF_TEMPS = 0x1608,    /*!< IC Temperature (C)                                 */
+    TFA2_BF_TDMUC = 0x2003,    /*!< Usecase setting                                    */
+    TFA2_BF_TDME  = 0x2040,    /*!< Enable interface                                   */
+    TFA2_BF_TDMMODE= 0x2050,    /*!< Slave/master                                       */
+    TFA2_BF_TDMCLINV= 0x2060,    /*!< Reception data to BCK clock                        */
+    TFA2_BF_TDMFSLN= 0x2073,    /*!< FS length (master mode only)                       */
+    TFA2_BF_TDMFSPOL= 0x20b0,    /*!< FS polarity                                        */
+    TFA2_BF_TDMNBCK= 0x20c3,    /*!< N-BCK's in FS                                      */
+    TFA2_BF_TDMSLOTS= 0x2103,    /*!< N-slots in Frame                                   */
+    TFA2_BF_TDMSLLN= 0x2144,    /*!< N-bits in slot                                     */
+    TFA2_BF_TDMBRMG= 0x2194,    /*!< N-bits remaining                                   */
+    TFA2_BF_TDMDEL= 0x21e0,    /*!< data delay to FS                                   */
+    TFA2_BF_TDMADJ= 0x21f0,    /*!< data adjustment                                    */
+    TFA2_BF_TDMOOMP= 0x2201,    /*!< Received audio compression                         */
+    TFA2_BF_TDMSSIZE= 0x2224,    /*!< Sample size per slot                               */
+    TFA2_BF_TDMTXDFO= 0x2271,    /*!< Format unused bits                                 */
+    TFA2_BF_TDMTXUS0= 0x2291,    /*!< Format unused slots GAINIO                         */
+    TFA2_BF_TDMTXUS1= 0x22b1,    /*!< Format unused slots DIO1                           */
+    TFA2_BF_TDMTXUS2= 0x22d1,    /*!< Format unused slots DIO2                           */
+    TFA2_BF_TDMLE = 0x2310,    /*!< Control audio left                                 */
+    TFA2_BF_TDMRE = 0x2320,    /*!< Control audio right                                */
+    TFA2_BF_TDMVSRE= 0x2340,    /*!< Control voltage sense right                        */
+    TFA2_BF_TDMCSRE= 0x2350,    /*!< Control current sense right                        */
+    TFA2_BF_TDMVSLE= 0x2360,    /*!< Voltage sense left control                         */
+    TFA2_BF_TDMCSLE= 0x2370,    /*!< Current sense left control                         */
+    TFA2_BF_TDMCFRE= 0x2380,    /*!< DSP out right control                              */
+    TFA2_BF_TDMCFLE= 0x2390,    /*!< DSP out left control                               */
+    TFA2_BF_TDMCF3E= 0x23a0,    /*!< AEC ref left control                               */
+    TFA2_BF_TDMCF4E= 0x23b0,    /*!< AEC ref right control                              */
+    TFA2_BF_TDMPD1E= 0x23c0,    /*!< PDM 1 control                                      */
+    TFA2_BF_TDMPD2E= 0x23d0,    /*!< PDM 2 control                                      */
+    TFA2_BF_TDMLIO= 0x2421,    /*!< IO audio left                                      */
+    TFA2_BF_TDMRIO= 0x2441,    /*!< IO audio right                                     */
+    TFA2_BF_TDMVSRIO= 0x2481,    /*!< IO voltage sense right                             */
+    TFA2_BF_TDMCSRIO= 0x24a1,    /*!< IO current sense right                             */
+    TFA2_BF_TDMVSLIO= 0x24c1,    /*!< IO voltage sense left                              */
+    TFA2_BF_TDMCSLIO= 0x24e1,    /*!< IO current sense left                              */
+    TFA2_BF_TDMCFRIO= 0x2501,    /*!< IO dspout right                                    */
+    TFA2_BF_TDMCFLIO= 0x2521,    /*!< IO dspout left                                     */
+    TFA2_BF_TDMCF3IO= 0x2541,    /*!< IO AEC ref left control                            */
+    TFA2_BF_TDMCF4IO= 0x2561,    /*!< IO AEC ref right control                           */
+    TFA2_BF_TDMPD1IO= 0x2581,    /*!< IO pdm1                                            */
+    TFA2_BF_TDMPD2IO= 0x25a1,    /*!< IO pdm2                                            */
+    TFA2_BF_TDMLS = 0x2643,    /*!< Position audio left                                */
+    TFA2_BF_TDMRS = 0x2683,    /*!< Position audio right                               */
+    TFA2_BF_TDMVSRS= 0x2703,    /*!< Position voltage sense right                       */
+    TFA2_BF_TDMCSRS= 0x2743,    /*!< Position current sense right                       */
+    TFA2_BF_TDMVSLS= 0x2783,    /*!< Position voltage sense left                        */
+    TFA2_BF_TDMCSLS= 0x27c3,    /*!< Position current sense left                        */
+    TFA2_BF_TDMCFRS= 0x2803,    /*!< Position dspout right                              */
+    TFA2_BF_TDMCFLS= 0x2843,    /*!< Position dspout left                               */
+    TFA2_BF_TDMCF3S= 0x2883,    /*!< Position AEC ref left control                      */
+    TFA2_BF_TDMCF4S= 0x28c3,    /*!< Position AEC ref right control                     */
+    TFA2_BF_TDMPD1S= 0x2903,    /*!< Position pdm1                                      */
+    TFA2_BF_TDMPD2S= 0x2943,    /*!< Position pdm2                                      */
+    TFA2_BF_PDMSM = 0x3100,    /*!< PDM control                                        */
+    TFA2_BF_PDMSTSEL= 0x3111,    /*!< Side tone input                                    */
+    TFA2_BF_PDMLSEL= 0x3130,    /*!< PDM data selection for left channel during PDM direct mode */
+    TFA2_BF_PDMRSEL= 0x3140,    /*!< PDM data selection for right channel during PDM direct mode */
+    TFA2_BF_MICVDDE= 0x3150,    /*!< Enable MICVDD                                      */
+    TFA2_BF_PDMCLRAT= 0x3201,    /*!< PDM BCK/Fs ratio                                   */
+    TFA2_BF_PDMGAIN= 0x3223,    /*!< PDM gain                                           */
+    TFA2_BF_PDMOSEL= 0x3263,    /*!< PDM output selection - RE/FE data combination      */
+    TFA2_BF_SELCFHAPD= 0x32a0,    /*!< Select the source for haptic data output (not for customer) */
+    TFA2_BF_HAPTIME= 0x3307,    /*!< Duration (ms)                                      */
+    TFA2_BF_HAPLEVEL= 0x3387,    /*!< DC value (FFS)                                     */
+    TFA2_BF_GPIODIN= 0x3403,    /*!< Receiving value                                    */
+    TFA2_BF_GPIOCTRL= 0x3500,    /*!< GPIO master control over GPIO1/2 ports (not for customer) */
+    TFA2_BF_GPIOCONF= 0x3513,    /*!< Configuration                                      */
+    TFA2_BF_GPIODOUT= 0x3553,    /*!< Transmitting value                                 */
+    TFA2_BF_ISTVDDS= 0x4000,    /*!< Status POR                                         */
+    TFA2_BF_ISTPLLS= 0x4010,    /*!< Status PLL lock                                    */
+    TFA2_BF_ISTOTDS= 0x4020,    /*!< Status OTP alarm                                   */
+    TFA2_BF_ISTOVDS= 0x4030,    /*!< Status OVP alarm                                   */
+    TFA2_BF_ISTUVDS= 0x4040,    /*!< Status UVP alarm                                   */
+    TFA2_BF_ISTCLKS= 0x4050,    /*!< Status clocks stable                               */
+    TFA2_BF_ISTMTPB= 0x4060,    /*!< Status MTP busy                                    */
+    TFA2_BF_ISTNOCLK= 0x4070,    /*!< Status lost clock                                  */
+    TFA2_BF_ISTSPKS= 0x4080,    /*!< Status speaker error                               */
+    TFA2_BF_ISTACS= 0x4090,    /*!< Status cold start                                  */
+    TFA2_BF_ISTSWS= 0x40a0,    /*!< Status amplifier engage                            */
+    TFA2_BF_ISTWDS= 0x40b0,    /*!< Status watchdog                                    */
+    TFA2_BF_ISTAMPS= 0x40c0,    /*!< Status amplifier enable                            */
+    TFA2_BF_ISTAREFS= 0x40d0,    /*!< Status Ref enable                                  */
+    TFA2_BF_ISTADCCR= 0x40e0,    /*!< Status Control ADC                                 */
+    TFA2_BF_ISTBODNOK= 0x40f0,    /*!< Status BOD                                         */
+    TFA2_BF_ISTBSTCU= 0x4100,    /*!< Status DCDC current limiting                       */
+    TFA2_BF_ISTBSTHI= 0x4110,    /*!< Status DCDC active                                 */
+    TFA2_BF_ISTBSTOC= 0x4120,    /*!< Status DCDC OCP                                    */
+    TFA2_BF_ISTBSTPKCUR= 0x4130,    /*!< Status bst peakcur                                 */
+    TFA2_BF_ISTBSTVC= 0x4140,    /*!< Status DCDC level 1x                               */
+    TFA2_BF_ISTBST86= 0x4150,    /*!< Status DCDC level 1.14x                            */
+    TFA2_BF_ISTBST93= 0x4160,    /*!< Status DCDC level 1.07x                            */
+    TFA2_BF_ISTRCVLD= 0x4170,    /*!< Status rcvldop ready                               */
+    TFA2_BF_ISTOCPL= 0x4180,    /*!< Status ocp alarm left                              */
+    TFA2_BF_ISTOCPR= 0x4190,    /*!< Status ocp alarm right                             */
+    TFA2_BF_ISTMWSRC= 0x41a0,    /*!< Status Waits HW I2C settings                       */
+    TFA2_BF_ISTMWCFC= 0x41b0,    /*!< Status waits CF config                             */
+    TFA2_BF_ISTMWSMU= 0x41c0,    /*!< Status Audio mute sequence                         */
+    TFA2_BF_ISTCFMER= 0x41d0,    /*!< Status cfma error                                  */
+    TFA2_BF_ISTCFMAC= 0x41e0,    /*!< Status cfma ack                                    */
+    TFA2_BF_ISTCLKOOR= 0x41f0,    /*!< Status flag_clk_out_of_range                       */
+    TFA2_BF_ISTTDMER= 0x4200,    /*!< Status tdm error                                   */
+    TFA2_BF_ISTCLPL= 0x4210,    /*!< Status clip left                                   */
+    TFA2_BF_ISTCLPR= 0x4220,    /*!< Status clip right                                  */
+    TFA2_BF_ISTOCPM= 0x4230,    /*!< Status mic ocpok                                   */
+    TFA2_BF_ICLVDDS= 0x4400,    /*!< Clear POR                                          */
+    TFA2_BF_ICLPLLS= 0x4410,    /*!< Clear PLL lock                                     */
+    TFA2_BF_ICLOTDS= 0x4420,    /*!< Clear OTP alarm                                    */
+    TFA2_BF_ICLOVDS= 0x4430,    /*!< Clear OVP alarm                                    */
+    TFA2_BF_ICLUVDS= 0x4440,    /*!< Clear UVP alarm                                    */
+    TFA2_BF_ICLCLKS= 0x4450,    /*!< Clear clocks stable                                */
+    TFA2_BF_ICLMTPB= 0x4460,    /*!< Clear mtp busy                                     */
+    TFA2_BF_ICLNOCLK= 0x4470,    /*!< Clear lost clk                                     */
+    TFA2_BF_ICLSPKS= 0x4480,    /*!< Clear speaker error                                */
+    TFA2_BF_ICLACS= 0x4490,    /*!< Clear cold started                                 */
+    TFA2_BF_ICLSWS= 0x44a0,    /*!< Clear amplifier engage                             */
+    TFA2_BF_ICLWDS= 0x44b0,    /*!< Clear watchdog                                     */
+    TFA2_BF_ICLAMPS= 0x44c0,    /*!< Clear enbl amp                                     */
+    TFA2_BF_ICLAREFS= 0x44d0,    /*!< Clear ref enable                                   */
+    TFA2_BF_ICLADCCR= 0x44e0,    /*!< Clear control ADC                                  */
+    TFA2_BF_ICLBODNOK= 0x44f0,    /*!< Clear BOD                                          */
+    TFA2_BF_ICLBSTCU= 0x4500,    /*!< Clear DCDC current limiting                        */
+    TFA2_BF_ICLBSTHI= 0x4510,    /*!< Clear DCDC active                                  */
+    TFA2_BF_ICLBSTOC= 0x4520,    /*!< Clear DCDC OCP                                     */
+    TFA2_BF_ICLBSTPC= 0x4530,    /*!< Clear bst peakcur                                  */
+    TFA2_BF_ICLBSTVC= 0x4540,    /*!< Clear DCDC level 1x                                */
+    TFA2_BF_ICLBST86= 0x4550,    /*!< Clear DCDC level 1.14x                             */
+    TFA2_BF_ICLBST93= 0x4560,    /*!< Clear DCDC level 1.07x                             */
+    TFA2_BF_ICLRCVLD= 0x4570,    /*!< Clear rcvldop ready                                */
+    TFA2_BF_ICLOCPL= 0x4580,    /*!< Clear ocp alarm left                               */
+    TFA2_BF_ICLOCPR= 0x4590,    /*!< Clear ocp alarm right                              */
+    TFA2_BF_ICLMWSRC= 0x45a0,    /*!< Clear wait HW I2C settings                         */
+    TFA2_BF_ICLMWCFC= 0x45b0,    /*!< Clear wait cf config                               */
+    TFA2_BF_ICLMWSMU= 0x45c0,    /*!< Clear audio mute sequence                          */
+    TFA2_BF_ICLCFMER= 0x45d0,    /*!< Clear cfma err                                     */
+    TFA2_BF_ICLCFMAC= 0x45e0,    /*!< Clear cfma ack                                     */
+    TFA2_BF_ICLCLKOOR= 0x45f0,    /*!< Clear flag_clk_out_of_range                        */
+    TFA2_BF_ICLTDMER= 0x4600,    /*!< Clear tdm error                                    */
+    TFA2_BF_ICLCLPL= 0x4610,    /*!< Clear clip left                                    */
+    TFA2_BF_ICLCLPR= 0x4620,    /*!< Clear clip right                                   */
+    TFA2_BF_ICLOCPM= 0x4630,    /*!< Clear mic ocpok                                    */
+    TFA2_BF_IEVDDS= 0x4800,    /*!< Enable por                                         */
+    TFA2_BF_IEPLLS= 0x4810,    /*!< Enable pll lock                                    */
+    TFA2_BF_IEOTDS= 0x4820,    /*!< Enable OTP alarm                                   */
+    TFA2_BF_IEOVDS= 0x4830,    /*!< Enable OVP alarm                                   */
+    TFA2_BF_IEUVDS= 0x4840,    /*!< Enable UVP alarm                                   */
+    TFA2_BF_IECLKS= 0x4850,    /*!< Enable clocks stable                               */
+    TFA2_BF_IEMTPB= 0x4860,    /*!< Enable mtp busy                                    */
+    TFA2_BF_IENOCLK= 0x4870,    /*!< Enable lost clk                                    */
+    TFA2_BF_IESPKS= 0x4880,    /*!< Enable speaker error                               */
+    TFA2_BF_IEACS = 0x4890,    /*!< Enable cold started                                */
+    TFA2_BF_IESWS = 0x48a0,    /*!< Enable amplifier engage                            */
+    TFA2_BF_IEWDS = 0x48b0,    /*!< Enable watchdog                                    */
+    TFA2_BF_IEAMPS= 0x48c0,    /*!< Enable enbl amp                                    */
+    TFA2_BF_IEAREFS= 0x48d0,    /*!< Enable ref enable                                  */
+    TFA2_BF_IEADCCR= 0x48e0,    /*!< Enable Control ADC                                 */
+    TFA2_BF_IEBODNOK= 0x48f0,    /*!< Enable BOD                                         */
+    TFA2_BF_IEBSTCU= 0x4900,    /*!< Enable DCDC current limiting                       */
+    TFA2_BF_IEBSTHI= 0x4910,    /*!< Enable DCDC active                                 */
+    TFA2_BF_IEBSTOC= 0x4920,    /*!< Enable DCDC OCP                                    */
+    TFA2_BF_IEBSTPC= 0x4930,    /*!< Enable bst peakcur                                 */
+    TFA2_BF_IEBSTVC= 0x4940,    /*!< Enable DCDC level 1x                               */
+    TFA2_BF_IEBST86= 0x4950,    /*!< Enable DCDC level 1.14x                            */
+    TFA2_BF_IEBST93= 0x4960,    /*!< Enable DCDC level 1.07x                            */
+    TFA2_BF_IERCVLD= 0x4970,    /*!< Enable rcvldop ready                               */
+    TFA2_BF_IEOCPL= 0x4980,    /*!< Enable ocp alarm left                              */
+    TFA2_BF_IEOCPR= 0x4990,    /*!< Enable ocp alarm right                             */
+    TFA2_BF_IEMWSRC= 0x49a0,    /*!< Enable waits HW I2C settings                       */
+    TFA2_BF_IEMWCFC= 0x49b0,    /*!< Enable man wait cf config                          */
+    TFA2_BF_IEMWSMU= 0x49c0,    /*!< Enable man Audio mute sequence                     */
+    TFA2_BF_IECFMER= 0x49d0,    /*!< Enable cfma err                                    */
+    TFA2_BF_IECFMAC= 0x49e0,    /*!< Enable cfma ack                                    */
+    TFA2_BF_IECLKOOR= 0x49f0,    /*!< Enable flag_clk_out_of_range                       */
+    TFA2_BF_IETDMER= 0x4a00,    /*!< Enable tdm error                                   */
+    TFA2_BF_IECLPL= 0x4a10,    /*!< Enable clip left                                   */
+    TFA2_BF_IECLPR= 0x4a20,    /*!< Enable clip right                                  */
+    TFA2_BF_IEOCPM1= 0x4a30,    /*!< Enable mic ocpok                                   */
+    TFA2_BF_IPOVDDS= 0x4c00,    /*!< Polarity por                                       */
+    TFA2_BF_IPOPLLS= 0x4c10,    /*!< Polarity pll lock                                  */
+    TFA2_BF_IPOOTDS= 0x4c20,    /*!< Polarity OTP alarm                                 */
+    TFA2_BF_IPOOVDS= 0x4c30,    /*!< Polarity OVP alarm                                 */
+    TFA2_BF_IPOUVDS= 0x4c40,    /*!< Polarity UVP alarm                                 */
+    TFA2_BF_IPOCLKS= 0x4c50,    /*!< Polarity clocks stable                             */
+    TFA2_BF_IPOMTPB= 0x4c60,    /*!< Polarity mtp busy                                  */
+    TFA2_BF_IPONOCLK= 0x4c70,    /*!< Polarity lost clk                                  */
+    TFA2_BF_IPOSPKS= 0x4c80,    /*!< Polarity speaker error                             */
+    TFA2_BF_IPOACS= 0x4c90,    /*!< Polarity cold started                              */
+    TFA2_BF_IPOSWS= 0x4ca0,    /*!< Polarity amplifier engage                          */
+    TFA2_BF_IPOWDS= 0x4cb0,    /*!< Polarity watchdog                                  */
+    TFA2_BF_IPOAMPS= 0x4cc0,    /*!< Polarity enbl amp                                  */
+    TFA2_BF_IPOAREFS= 0x4cd0,    /*!< Polarity ref enable                                */
+    TFA2_BF_IPOADCCR= 0x4ce0,    /*!< Polarity Control ADC                               */
+    TFA2_BF_IPOBODNOK= 0x4cf0,    /*!< Polarity BOD                                       */
+    TFA2_BF_IPOBSTCU= 0x4d00,    /*!< Polarity DCDC current limiting                     */
+    TFA2_BF_IPOBSTHI= 0x4d10,    /*!< Polarity DCDC active                               */
+    TFA2_BF_IPOBSTOC= 0x4d20,    /*!< Polarity DCDC OCP                                  */
+    TFA2_BF_IPOBSTPC= 0x4d30,    /*!< Polarity bst peakcur                               */
+    TFA2_BF_IPOBSTVC= 0x4d40,    /*!< Polarity DCDC level 1x                             */
+    TFA2_BF_IPOBST86= 0x4d50,    /*!< Polarity DCDC level 1.14x                          */
+    TFA2_BF_IPOBST93= 0x4d60,    /*!< Polarity DCDC level 1.07x                          */
+    TFA2_BF_IPORCVLD= 0x4d70,    /*!< Polarity rcvldop ready                             */
+    TFA2_BF_IPOOCPL= 0x4d80,    /*!< Polarity ocp alarm left                            */
+    TFA2_BF_IPOOCPR= 0x4d90,    /*!< Polarity ocp alarm right                           */
+    TFA2_BF_IPOMWSRC= 0x4da0,    /*!< Polarity waits HW I2C settings                     */
+    TFA2_BF_IPOMWCFC= 0x4db0,    /*!< Polarity man wait cf config                        */
+    TFA2_BF_IPOMWSMU= 0x4dc0,    /*!< Polarity man audio mute sequence                   */
+    TFA2_BF_IPOCFMER= 0x4dd0,    /*!< Polarity cfma err                                  */
+    TFA2_BF_IPOCFMAC= 0x4de0,    /*!< Polarity cfma ack                                  */
+    TFA2_BF_IPCLKOOR= 0x4df0,    /*!< Polarity flag_clk_out_of_range                     */
+    TFA2_BF_IPOTDMER= 0x4e00,    /*!< Polarity tdm error                                 */
+    TFA2_BF_IPOCLPL= 0x4e10,    /*!< Polarity clip left                                 */
+    TFA2_BF_IPOCLPR= 0x4e20,    /*!< Polarity clip right                                */
+    TFA2_BF_IPOOCPM= 0x4e30,    /*!< Polarity mic ocpok                                 */
+    TFA2_BF_BSSCR = 0x5001,    /*!< Battery protection attack Time                     */
+    TFA2_BF_BSST  = 0x5023,    /*!< Battery protection threshold voltage level         */
+    TFA2_BF_BSSRL = 0x5061,    /*!< Battery protection maximum reduction               */
+    TFA2_BF_BSSRR = 0x5082,    /*!< Battery protection release time                    */
+    TFA2_BF_BSSHY = 0x50b1,    /*!< Battery protection hysteresis                      */
+    TFA2_BF_BSSR  = 0x50e0,    /*!< Battery voltage read out                           */
+    TFA2_BF_BSSBY = 0x50f0,    /*!< Bypass HW clipper                                  */
+    TFA2_BF_BSSS  = 0x5100,    /*!< Vbat prot steepness                                */
+    TFA2_BF_INTSMUTE= 0x5110,    /*!< Soft mute HW                                       */
+    TFA2_BF_CFSML = 0x5120,    /*!< Soft mute FW left                                  */
+    TFA2_BF_CFSMR = 0x5130,    /*!< Soft mute FW right                                 */
+    TFA2_BF_HPFBYPL= 0x5140,    /*!< Bypass HPF left                                    */
+    TFA2_BF_HPFBYPR= 0x5150,    /*!< Bypass HPF right                                   */
+    TFA2_BF_DPSAL = 0x5160,    /*!< Enable DPSA left                                   */
+    TFA2_BF_DPSAR = 0x5170,    /*!< Enable DPSA right                                  */
+    TFA2_BF_VOL   = 0x5187,    /*!< FW volume control for primary audio channel        */
+    TFA2_BF_HNDSFRCV= 0x5200,    /*!< Selection receiver                                 */
+    TFA2_BF_CLIPCTRL= 0x5222,    /*!< Clip control setting                               */
+    TFA2_BF_AMPGAIN= 0x5257,    /*!< Amplifier gain                                     */
+    TFA2_BF_SLOPEE= 0x52d0,    /*!< Enables slope control                              */
+    TFA2_BF_SLOPESET= 0x52e1,    /*!< Set slope                                          */
+    TFA2_BF_VOLSEC= 0x5a07,    /*!< FW volume control for secondary audio channel      */
+    TFA2_BF_SWPROFIL= 0x5a87,    /*!< Software profile data                              */
+    TFA2_BF_DCVO  = 0x7002,    /*!< Boost voltage                                      */
+    TFA2_BF_DCMCC = 0x7033,    /*!< Max coil current                                   */
+    TFA2_BF_DCCV  = 0x7071,    /*!< Coil Value                                         */
+    TFA2_BF_DCIE  = 0x7090,    /*!< Adaptive boost mode                                */
+    TFA2_BF_DCSR  = 0x70a0,    /*!< Soft ramp up/down                                  */
+    TFA2_BF_DCSYNCP= 0x70b2,    /*!< DCDC synchronization off + 7 positions             */
+    TFA2_BF_DCDIS = 0x70e0,    /*!< DCDC on/off                                        */
+    TFA2_BF_RST   = 0x9000,    /*!< Reset                                              */
+    TFA2_BF_DMEM  = 0x9011,    /*!< Target memory                                      */
+    TFA2_BF_AIF   = 0x9030,    /*!< Auto increment                                     */
+    TFA2_BF_CFINT = 0x9040,    /*!< Interrupt - auto clear                             */
+    TFA2_BF_CFCGATE= 0x9050,    /*!< Coolflux clock gating disabling control            */
+    TFA2_BF_REQ   = 0x9087,    /*!< request for access (8 channels)                    */
+    TFA2_BF_REQCMD= 0x9080,    /*!< Firmware event request rpc command                 */
+    TFA2_BF_REQRST= 0x9090,    /*!< Firmware event request reset restart               */
+    TFA2_BF_REQMIPS= 0x90a0,    /*!< Firmware event request short on mips               */
+    TFA2_BF_REQMUTED= 0x90b0,    /*!< Firmware event request mute sequence ready         */
+    TFA2_BF_REQVOL= 0x90c0,    /*!< Firmware event request volume ready                */
+    TFA2_BF_REQDMG= 0x90d0,    /*!< Firmware event request speaker damage detected     */
+    TFA2_BF_REQCAL= 0x90e0,    /*!< Firmware event request calibration completed       */
+    TFA2_BF_REQRSV= 0x90f0,    /*!< Firmware event request reserved                    */
+    TFA2_BF_MADD  = 0x910f,    /*!< Memory address                                     */
+    TFA2_BF_MEMA  = 0x920f,    /*!< Activate memory access                             */
+    TFA2_BF_ERR   = 0x9307,    /*!< Error flags                                        */
+    TFA2_BF_ACK   = 0x9387,    /*!< Acknowledge of requests                            */
+    TFA2_BF_ACKCMD= 0x9380,    /*!< Firmware event acknowledge rpc command             */
+    TFA2_BF_ACKRST= 0x9390,    /*!< Firmware event acknowledge reset restart           */
+    TFA2_BF_ACKMIPS= 0x93a0,    /*!< Firmware event acknowledge short on mips           */
+    TFA2_BF_ACKMUTED= 0x93b0,    /*!< Firmware event acknowledge mute sequence ready     */
+    TFA2_BF_ACKVOL= 0x93c0,    /*!< Firmware event acknowledge volume ready            */
+    TFA2_BF_ACKDMG= 0x93d0,    /*!< Firmware event acknowledge speaker damage detected */
+    TFA2_BF_ACKCAL= 0x93e0,    /*!< Firmware event acknowledge calibration completed   */
+    TFA2_BF_ACKRSV= 0x93f0,    /*!< Firmware event acknowledge reserved                */
+    TFA2_BF_MTPK  = 0xa107,    /*!< MTP KEY2 register                                  */
+    TFA2_BF_KEY1LOCKED= 0xa200,    /*!< Indicates KEY1 is locked                           */
+    TFA2_BF_KEY2LOCKED= 0xa210,    /*!< Indicates KEY2 is locked                           */
+    TFA2_BF_CIMTP = 0xa360,    /*!< Start copying data from I2C mtp registers to mtp   */
+    TFA2_BF_MTPRDMSB= 0xa50f,    /*!< MSB word of MTP manual read data                   */
+    TFA2_BF_MTPRDLSB= 0xa60f,    /*!< LSB word of MTP manual read data                   */
+    TFA2_BF_EXTTS = 0xb108,    /*!< External temperature (C)                           */
+    TFA2_BF_TROS  = 0xb190,    /*!< Select temp Speaker calibration                    */
+    TFA2_BF_MTPOTC= 0xf000,    /*!< Calibration schedule                               */
+    TFA2_BF_MTPEX = 0xf010,    /*!< Calibration Ron executed                           */
+    TFA2_BF_DCMCCAPI= 0xf020,    /*!< Calibration current limit DCDC                     */
+    TFA2_BF_DCMCCSB= 0xf030,    /*!< Sign bit for delta calibration current limit DCDC  */
+    TFA2_BF_USERDEF= 0xf042,    /*!< Calibration delta current limit DCDC               */
+    TFA2_BF_R25CL = 0xf40f,    /*!< Ron resistance of left channel speaker coil        */
+    TFA2_BF_R25CR = 0xf50f,    /*!< Ron resistance of right channel speaker coil       */
+} nxpTfa2BfEnumList_t;
+#define TFA2_NAMETABLE static tfaBfName_t Tfa2DatasheetNames[]= {\
+   { 0x0, "PWDN"},    /* Powerdown selection                               , */\
+   { 0x10, "I2CR"},    /* I2C Reset - Auto clear                            , */\
+   { 0x20, "CFE"},    /* Enable CoolFlux                                   , */\
+   { 0x30, "AMPE"},    /* Activate Amplifier                                , */\
+   { 0x40, "DCA"},    /* Activate DC-to-DC converter                       , */\
+   { 0x50, "SBSL"},    /* Coolflux configured                               , */\
+   { 0x60, "AMPC"},    /* CoolFlux controls amplifier                       , */\
+   { 0x71, "INTP"},    /* Interrupt config                                  , */\
+   { 0x91, "FSSSEL"},    /* Audio sample reference                            , */\
+   { 0xb0, "BYPOCP"},    /* Bypass OCP                                        , */\
+   { 0xc0, "TSTOCP"},    /* OCP testing control                               , */\
+   { 0x101, "AMPINSEL"},    /* Amplifier input selection                         , */\
+   { 0x120, "MANSCONF"},    /* I2C configured                                    , */\
+   { 0x130, "MANCOLD"},    /* Execute cold start                                , */\
+   { 0x140, "MANAOOSC"},    /* Internal osc off at PWDN                          , */\
+   { 0x150, "MANROBOD"},    /* Reaction on BOD                                   , */\
+   { 0x160, "BODE"},    /* BOD Enable                                        , */\
+   { 0x170, "BODHYS"},    /* BOD Hysteresis                                    , */\
+   { 0x181, "BODFILT"},    /* BOD filter                                        , */\
+   { 0x1a1, "BODTHLVL"},    /* BOD threshold                                     , */\
+   { 0x1d0, "MUTETO"},    /* Time out SB mute sequence                         , */\
+   { 0x1e0, "RCVNS"},    /* Noise shaper selection                            , */\
+   { 0x1f0, "MANWDE"},    /* Watchdog manager reaction                         , */\
+   { 0x203, "AUDFS"},    /* Sample rate (fs)                                  , */\
+   { 0x240, "INPLEV"},    /* TDM output attenuation                            , */\
+   { 0x255, "FRACTDEL"},    /* V/I Fractional delay                              , */\
+   { 0x2b0, "BYPHVBF"},    /* Bypass HVBAT filter                               , */\
+   { 0x2c0, "LDOBYP"},    /* Receiver LDO bypass                               , */\
+   { 0x30f, "REV"},    /* Revision info                                     , */\
+   { 0x401, "REFCKEXT"},    /* PLL external ref clock                            , */\
+   { 0x420, "REFCKSEL"},    /* PLL internal ref clock                            , */\
+   { 0x500, "SSLEFTE"},    /* Enable left channel                               , */\
+   { 0x510, "SSRIGHTE"},    /* Enable right channel                              , */\
+   { 0x520, "VSLEFTE"},    /* Voltage sense left                                , */\
+   { 0x530, "VSRIGHTE"},    /* Voltage sense right                               , */\
+   { 0x540, "CSLEFTE"},    /* Current sense left                                , */\
+   { 0x550, "CSRIGHTE"},    /* Current sense right                               , */\
+   { 0x560, "SSPDME"},    /* Sub-system PDM                                    , */\
+   { 0xd18, "STGAIN"},    /* Side tone gain                                    , */\
+   { 0xda0, "PDMSMUTE"},    /* Side tone soft mute                               , */\
+   { 0xe06, "SWVSTEP"},    /* Register for the host SW to record the current active vstep, */\
+   { 0x1000, "VDDS"},    /* POR                                               , */\
+   { 0x1010, "PLLS"},    /* PLL lock                                          , */\
+   { 0x1020, "OTDS"},    /* OTP alarm                                         , */\
+   { 0x1030, "OVDS"},    /* OVP alarm                                         , */\
+   { 0x1040, "UVDS"},    /* UVP alarm                                         , */\
+   { 0x1050, "CLKS"},    /* Clocks stable                                     , */\
+   { 0x1060, "MTPB"},    /* MTP busy                                          , */\
+   { 0x1070, "NOCLK"},    /* Lost clock                                        , */\
+   { 0x1080, "SPKS"},    /* Speaker error                                     , */\
+   { 0x1090, "ACS"},    /* Cold Start                                        , */\
+   { 0x10a0, "SWS"},    /* Amplifier engage                                  , */\
+   { 0x10b0, "WDS"},    /* Watchdog                                          , */\
+   { 0x10c0, "AMPS"},    /* Amplifier enable                                  , */\
+   { 0x10d0, "AREFS"},    /* References enable                                 , */\
+   { 0x10e0, "ADCCR"},    /* Control ADC                                       , */\
+   { 0x10f0, "BODNOK"},    /* BOD                                               , */\
+   { 0x1100, "DCIL"},    /* DCDC current limiting                             , */\
+   { 0x1110, "DCDCA"},    /* DCDC active                                       , */\
+   { 0x1120, "DCOCPOK"},    /* DCDC OCP nmos                                     , */\
+   { 0x1140, "DCHVBAT"},    /* DCDC level 1x                                     , */\
+   { 0x1150, "DCH114"},    /* DCDC level 1.14x                                  , */\
+   { 0x1160, "DCH107"},    /* DCDC level 1.07x                                  , */\
+   { 0x1170, "STMUTEB"},    /* side tone (un)mute busy                           , */\
+   { 0x1180, "STMUTE"},    /* side tone mute state                              , */\
+   { 0x1190, "TDMLUTER"},    /* TDM LUT error                                     , */\
+   { 0x11a2, "TDMSTAT"},    /* TDM status bits                                   , */\
+   { 0x11d0, "TDMERR"},    /* TDM error                                         , */\
+   { 0x11e0, "HAPTIC"},    /* Status haptic driver                              , */\
+   { 0x1200, "OCPOAPL"},    /* OCPOK pmos A left                                 , */\
+   { 0x1210, "OCPOANL"},    /* OCPOK nmos A left                                 , */\
+   { 0x1220, "OCPOBPL"},    /* OCPOK pmos B left                                 , */\
+   { 0x1230, "OCPOBNL"},    /* OCPOK nmos B left                                 , */\
+   { 0x1240, "CLIPAHL"},    /* Clipping A left to Vddp                           , */\
+   { 0x1250, "CLIPALL"},    /* Clipping A left to gnd                            , */\
+   { 0x1260, "CLIPBHL"},    /* Clipping B left to Vddp                           , */\
+   { 0x1270, "CLIPBLL"},    /* Clipping B left to gnd                            , */\
+   { 0x1280, "OCPOAPRC"},    /* OCPOK pmos A RCV                                  , */\
+   { 0x1290, "OCPOANRC"},    /* OCPOK nmos A RCV                                  , */\
+   { 0x12a0, "OCPOBPRC"},    /* OCPOK pmos B RCV                                  , */\
+   { 0x12b0, "OCPOBNRC"},    /* OCPOK nmos B RCV                                  , */\
+   { 0x12c0, "RCVLDOR"},    /* RCV LDO regulates                                 , */\
+   { 0x12d0, "RCVLDOBR"},    /* Receiver LDO ready                                , */\
+   { 0x12e0, "OCDSL"},    /* OCP left amplifier                                , */\
+   { 0x12f0, "CLIPSL"},    /* Amplifier left clipping                           , */\
+   { 0x1300, "OCPOAPR"},    /* OCPOK pmos A right                                , */\
+   { 0x1310, "OCPOANR"},    /* OCPOK nmos A right                                , */\
+   { 0x1320, "OCPOBPR"},    /* OCPOK pmos B right                                , */\
+   { 0x1330, "OCPOBNR"},    /* OCPOK nmos B right                                , */\
+   { 0x1340, "CLIPAHR"},    /* Clipping A right to Vddp                          , */\
+   { 0x1350, "CLIPALR"},    /* Clipping A right to gnd                           , */\
+   { 0x1360, "CLIPBHR"},    /* Clipping B left to Vddp                           , */\
+   { 0x1370, "CLIPBLR"},    /* Clipping B right to gnd                           , */\
+   { 0x1380, "OCDSR"},    /* OCP right amplifier                               , */\
+   { 0x1390, "CLIPSR"},    /* Amplifier right clipping                          , */\
+   { 0x13a0, "OCPOKMC"},    /* OCPOK MICVDD                                      , */\
+   { 0x13b0, "MANALARM"},    /* Alarm state                                       , */\
+   { 0x13c0, "MANWAIT1"},    /* Wait HW I2C settings                              , */\
+   { 0x13d0, "MANWAIT2"},    /* Wait CF config                                    , */\
+   { 0x13e0, "MANMUTE"},    /* Audio mute sequence                               , */\
+   { 0x13f0, "MANOPER"},    /* Operating state                                   , */\
+   { 0x1400, "SPKSL"},    /* Left speaker status                               , */\
+   { 0x1410, "SPKSR"},    /* Right speaker status                              , */\
+   { 0x1420, "CLKOOR"},    /* External clock status                             , */\
+   { 0x1433, "MANSTATE"},    /* Device manager status                             , */\
+   { 0x1509, "BATS"},    /* Battery voltage (V)                               , */\
+   { 0x1608, "TEMPS"},    /* IC Temperature (C)                                , */\
+   { 0x2003, "TDMUC"},    /* Usecase setting                                   , */\
+   { 0x2040, "TDME"},    /* Enable interface                                  , */\
+   { 0x2050, "TDMMODE"},    /* Slave/master                                      , */\
+   { 0x2060, "TDMCLINV"},    /* Reception data to BCK clock                       , */\
+   { 0x2073, "TDMFSLN"},    /* FS length (master mode only)                      , */\
+   { 0x20b0, "TDMFSPOL"},    /* FS polarity                                       , */\
+   { 0x20c3, "TDMNBCK"},    /* N-BCK's in FS                                     , */\
+   { 0x2103, "TDMSLOTS"},    /* N-slots in Frame                                  , */\
+   { 0x2144, "TDMSLLN"},    /* N-bits in slot                                    , */\
+   { 0x2194, "TDMBRMG"},    /* N-bits remaining                                  , */\
+   { 0x21e0, "TDMDEL"},    /* data delay to FS                                  , */\
+   { 0x21f0, "TDMADJ"},    /* data adjustment                                   , */\
+   { 0x2201, "TDMOOMP"},    /* Received audio compression                        , */\
+   { 0x2224, "TDMSSIZE"},    /* Sample size per slot                              , */\
+   { 0x2271, "TDMTXDFO"},    /* Format unused bits                                , */\
+   { 0x2291, "TDMTXUS0"},    /* Format unused slots GAINIO                        , */\
+   { 0x22b1, "TDMTXUS1"},    /* Format unused slots DIO1                          , */\
+   { 0x22d1, "TDMTXUS2"},    /* Format unused slots DIO2                          , */\
+   { 0x2310, "TDMLE"},    /* Control audio left                                , */\
+   { 0x2320, "TDMRE"},    /* Control audio right                               , */\
+   { 0x2340, "TDMVSRE"},    /* Control voltage sense right                       , */\
+   { 0x2350, "TDMCSRE"},    /* Control current sense right                       , */\
+   { 0x2360, "TDMVSLE"},    /* Voltage sense left control                        , */\
+   { 0x2370, "TDMCSLE"},    /* Current sense left control                        , */\
+   { 0x2380, "TDMCFRE"},    /* DSP out right control                             , */\
+   { 0x2390, "TDMCFLE"},    /* DSP out left control                              , */\
+   { 0x23a0, "TDMCF3E"},    /* AEC ref left control                              , */\
+   { 0x23b0, "TDMCF4E"},    /* AEC ref right control                             , */\
+   { 0x23c0, "TDMPD1E"},    /* PDM 1 control                                     , */\
+   { 0x23d0, "TDMPD2E"},    /* PDM 2 control                                     , */\
+   { 0x2421, "TDMLIO"},    /* IO audio left                                     , */\
+   { 0x2441, "TDMRIO"},    /* IO audio right                                    , */\
+   { 0x2481, "TDMVSRIO"},    /* IO voltage sense right                            , */\
+   { 0x24a1, "TDMCSRIO"},    /* IO current sense right                            , */\
+   { 0x24c1, "TDMVSLIO"},    /* IO voltage sense left                             , */\
+   { 0x24e1, "TDMCSLIO"},    /* IO current sense left                             , */\
+   { 0x2501, "TDMCFRIO"},    /* IO dspout right                                   , */\
+   { 0x2521, "TDMCFLIO"},    /* IO dspout left                                    , */\
+   { 0x2541, "TDMCF3IO"},    /* IO AEC ref left control                           , */\
+   { 0x2561, "TDMCF4IO"},    /* IO AEC ref right control                          , */\
+   { 0x2581, "TDMPD1IO"},    /* IO pdm1                                           , */\
+   { 0x25a1, "TDMPD2IO"},    /* IO pdm2                                           , */\
+   { 0x2643, "TDMLS"},    /* Position audio left                               , */\
+   { 0x2683, "TDMRS"},    /* Position audio right                              , */\
+   { 0x2703, "TDMVSRS"},    /* Position voltage sense right                      , */\
+   { 0x2743, "TDMCSRS"},    /* Position current sense right                      , */\
+   { 0x2783, "TDMVSLS"},    /* Position voltage sense left                       , */\
+   { 0x27c3, "TDMCSLS"},    /* Position current sense left                       , */\
+   { 0x2803, "TDMCFRS"},    /* Position dspout right                             , */\
+   { 0x2843, "TDMCFLS"},    /* Position dspout left                              , */\
+   { 0x2883, "TDMCF3S"},    /* Position AEC ref left control                     , */\
+   { 0x28c3, "TDMCF4S"},    /* Position AEC ref right control                    , */\
+   { 0x2903, "TDMPD1S"},    /* Position pdm1                                     , */\
+   { 0x2943, "TDMPD2S"},    /* Position pdm2                                     , */\
+   { 0x3100, "PDMSM"},    /* PDM control                                       , */\
+   { 0x3111, "PDMSTSEL"},    /* Side tone input                                   , */\
+   { 0x3130, "PDMLSEL"},    /* PDM data selection for left channel during PDM direct mode, */\
+   { 0x3140, "PDMRSEL"},    /* PDM data selection for right channel during PDM direct mode, */\
+   { 0x3150, "MICVDDE"},    /* Enable MICVDD                                     , */\
+   { 0x3201, "PDMCLRAT"},    /* PDM BCK/Fs ratio                                  , */\
+   { 0x3223, "PDMGAIN"},    /* PDM gain                                          , */\
+   { 0x3263, "PDMOSEL"},    /* PDM output selection - RE/FE data combination     , */\
+   { 0x32a0, "SELCFHAPD"},    /* Select the source for haptic data output (not for customer), */\
+   { 0x3307, "HAPTIME"},    /* Duration (ms)                                     , */\
+   { 0x3387, "HAPLEVEL"},    /* DC value (FFS)                                    , */\
+   { 0x3403, "GPIODIN"},    /* Receiving value                                   , */\
+   { 0x3500, "GPIOCTRL"},    /* GPIO master control over GPIO1/2 ports (not for customer), */\
+   { 0x3513, "GPIOCONF"},    /* Configuration                                     , */\
+   { 0x3553, "GPIODOUT"},    /* Transmitting value                                , */\
+   { 0x4000, "ISTVDDS"},    /* Status POR                                        , */\
+   { 0x4010, "ISTPLLS"},    /* Status PLL lock                                   , */\
+   { 0x4020, "ISTOTDS"},    /* Status OTP alarm                                  , */\
+   { 0x4030, "ISTOVDS"},    /* Status OVP alarm                                  , */\
+   { 0x4040, "ISTUVDS"},    /* Status UVP alarm                                  , */\
+   { 0x4050, "ISTCLKS"},    /* Status clocks stable                              , */\
+   { 0x4060, "ISTMTPB"},    /* Status MTP busy                                   , */\
+   { 0x4070, "ISTNOCLK"},    /* Status lost clock                                 , */\
+   { 0x4080, "ISTSPKS"},    /* Status speaker error                              , */\
+   { 0x4090, "ISTACS"},    /* Status cold start                                 , */\
+   { 0x40a0, "ISTSWS"},    /* Status amplifier engage                           , */\
+   { 0x40b0, "ISTWDS"},    /* Status watchdog                                   , */\
+   { 0x40c0, "ISTAMPS"},    /* Status amplifier enable                           , */\
+   { 0x40d0, "ISTAREFS"},    /* Status Ref enable                                 , */\
+   { 0x40e0, "ISTADCCR"},    /* Status Control ADC                                , */\
+   { 0x40f0, "ISTBODNOK"},    /* Status BOD                                        , */\
+   { 0x4100, "ISTBSTCU"},    /* Status DCDC current limiting                      , */\
+   { 0x4110, "ISTBSTHI"},    /* Status DCDC active                                , */\
+   { 0x4120, "ISTBSTOC"},    /* Status DCDC OCP                                   , */\
+   { 0x4130, "ISTBSTPKCUR"},    /* Status bst peakcur                                , */\
+   { 0x4140, "ISTBSTVC"},    /* Status DCDC level 1x                              , */\
+   { 0x4150, "ISTBST86"},    /* Status DCDC level 1.14x                           , */\
+   { 0x4160, "ISTBST93"},    /* Status DCDC level 1.07x                           , */\
+   { 0x4170, "ISTRCVLD"},    /* Status rcvldop ready                              , */\
+   { 0x4180, "ISTOCPL"},    /* Status ocp alarm left                             , */\
+   { 0x4190, "ISTOCPR"},    /* Status ocp alarm right                            , */\
+   { 0x41a0, "ISTMWSRC"},    /* Status Waits HW I2C settings                      , */\
+   { 0x41b0, "ISTMWCFC"},    /* Status waits CF config                            , */\
+   { 0x41c0, "ISTMWSMU"},    /* Status Audio mute sequence                        , */\
+   { 0x41d0, "ISTCFMER"},    /* Status cfma error                                 , */\
+   { 0x41e0, "ISTCFMAC"},    /* Status cfma ack                                   , */\
+   { 0x41f0, "ISTCLKOOR"},    /* Status flag_clk_out_of_range                      , */\
+   { 0x4200, "ISTTDMER"},    /* Status tdm error                                  , */\
+   { 0x4210, "ISTCLPL"},    /* Status clip left                                  , */\
+   { 0x4220, "ISTCLPR"},    /* Status clip right                                 , */\
+   { 0x4230, "ISTOCPM"},    /* Status mic ocpok                                  , */\
+   { 0x4400, "ICLVDDS"},    /* Clear POR                                         , */\
+   { 0x4410, "ICLPLLS"},    /* Clear PLL lock                                    , */\
+   { 0x4420, "ICLOTDS"},    /* Clear OTP alarm                                   , */\
+   { 0x4430, "ICLOVDS"},    /* Clear OVP alarm                                   , */\
+   { 0x4440, "ICLUVDS"},    /* Clear UVP alarm                                   , */\
+   { 0x4450, "ICLCLKS"},    /* Clear clocks stable                               , */\
+   { 0x4460, "ICLMTPB"},    /* Clear mtp busy                                    , */\
+   { 0x4470, "ICLNOCLK"},    /* Clear lost clk                                    , */\
+   { 0x4480, "ICLSPKS"},    /* Clear speaker error                               , */\
+   { 0x4490, "ICLACS"},    /* Clear cold started                                , */\
+   { 0x44a0, "ICLSWS"},    /* Clear amplifier engage                            , */\
+   { 0x44b0, "ICLWDS"},    /* Clear watchdog                                    , */\
+   { 0x44c0, "ICLAMPS"},    /* Clear enbl amp                                    , */\
+   { 0x44d0, "ICLAREFS"},    /* Clear ref enable                                  , */\
+   { 0x44e0, "ICLADCCR"},    /* Clear control ADC                                 , */\
+   { 0x44f0, "ICLBODNOK"},    /* Clear BOD                                         , */\
+   { 0x4500, "ICLBSTCU"},    /* Clear DCDC current limiting                       , */\
+   { 0x4510, "ICLBSTHI"},    /* Clear DCDC active                                 , */\
+   { 0x4520, "ICLBSTOC"},    /* Clear DCDC OCP                                    , */\
+   { 0x4530, "ICLBSTPC"},    /* Clear bst peakcur                                 , */\
+   { 0x4540, "ICLBSTVC"},    /* Clear DCDC level 1x                               , */\
+   { 0x4550, "ICLBST86"},    /* Clear DCDC level 1.14x                            , */\
+   { 0x4560, "ICLBST93"},    /* Clear DCDC level 1.07x                            , */\
+   { 0x4570, "ICLRCVLD"},    /* Clear rcvldop ready                               , */\
+   { 0x4580, "ICLOCPL"},    /* Clear ocp alarm left                              , */\
+   { 0x4590, "ICLOCPR"},    /* Clear ocp alarm right                             , */\
+   { 0x45a0, "ICLMWSRC"},    /* Clear wait HW I2C settings                        , */\
+   { 0x45b0, "ICLMWCFC"},    /* Clear wait cf config                              , */\
+   { 0x45c0, "ICLMWSMU"},    /* Clear audio mute sequence                         , */\
+   { 0x45d0, "ICLCFMER"},    /* Clear cfma err                                    , */\
+   { 0x45e0, "ICLCFMAC"},    /* Clear cfma ack                                    , */\
+   { 0x45f0, "ICLCLKOOR"},    /* Clear flag_clk_out_of_range                       , */\
+   { 0x4600, "ICLTDMER"},    /* Clear tdm error                                   , */\
+   { 0x4610, "ICLCLPL"},    /* Clear clip left                                   , */\
+   { 0x4620, "ICLCLPR"},    /* Clear clip right                                  , */\
+   { 0x4630, "ICLOCPM"},    /* Clear mic ocpok                                   , */\
+   { 0x4800, "IEVDDS"},    /* Enable por                                        , */\
+   { 0x4810, "IEPLLS"},    /* Enable pll lock                                   , */\
+   { 0x4820, "IEOTDS"},    /* Enable OTP alarm                                  , */\
+   { 0x4830, "IEOVDS"},    /* Enable OVP alarm                                  , */\
+   { 0x4840, "IEUVDS"},    /* Enable UVP alarm                                  , */\
+   { 0x4850, "IECLKS"},    /* Enable clocks stable                              , */\
+   { 0x4860, "IEMTPB"},    /* Enable mtp busy                                   , */\
+   { 0x4870, "IENOCLK"},    /* Enable lost clk                                   , */\
+   { 0x4880, "IESPKS"},    /* Enable speaker error                              , */\
+   { 0x4890, "IEACS"},    /* Enable cold started                               , */\
+   { 0x48a0, "IESWS"},    /* Enable amplifier engage                           , */\
+   { 0x48b0, "IEWDS"},    /* Enable watchdog                                   , */\
+   { 0x48c0, "IEAMPS"},    /* Enable enbl amp                                   , */\
+   { 0x48d0, "IEAREFS"},    /* Enable ref enable                                 , */\
+   { 0x48e0, "IEADCCR"},    /* Enable Control ADC                                , */\
+   { 0x48f0, "IEBODNOK"},    /* Enable BOD                                        , */\
+   { 0x4900, "IEBSTCU"},    /* Enable DCDC current limiting                      , */\
+   { 0x4910, "IEBSTHI"},    /* Enable DCDC active                                , */\
+   { 0x4920, "IEBSTOC"},    /* Enable DCDC OCP                                   , */\
+   { 0x4930, "IEBSTPC"},    /* Enable bst peakcur                                , */\
+   { 0x4940, "IEBSTVC"},    /* Enable DCDC level 1x                              , */\
+   { 0x4950, "IEBST86"},    /* Enable DCDC level 1.14x                           , */\
+   { 0x4960, "IEBST93"},    /* Enable DCDC level 1.07x                           , */\
+   { 0x4970, "IERCVLD"},    /* Enable rcvldop ready                              , */\
+   { 0x4980, "IEOCPL"},    /* Enable ocp alarm left                             , */\
+   { 0x4990, "IEOCPR"},    /* Enable ocp alarm right                            , */\
+   { 0x49a0, "IEMWSRC"},    /* Enable waits HW I2C settings                      , */\
+   { 0x49b0, "IEMWCFC"},    /* Enable man wait cf config                         , */\
+   { 0x49c0, "IEMWSMU"},    /* Enable man Audio mute sequence                    , */\
+   { 0x49d0, "IECFMER"},    /* Enable cfma err                                   , */\
+   { 0x49e0, "IECFMAC"},    /* Enable cfma ack                                   , */\
+   { 0x49f0, "IECLKOOR"},    /* Enable flag_clk_out_of_range                      , */\
+   { 0x4a00, "IETDMER"},    /* Enable tdm error                                  , */\
+   { 0x4a10, "IECLPL"},    /* Enable clip left                                  , */\
+   { 0x4a20, "IECLPR"},    /* Enable clip right                                 , */\
+   { 0x4a30, "IEOCPM1"},    /* Enable mic ocpok                                  , */\
+   { 0x4c00, "IPOVDDS"},    /* Polarity por                                      , */\
+   { 0x4c10, "IPOPLLS"},    /* Polarity pll lock                                 , */\
+   { 0x4c20, "IPOOTDS"},    /* Polarity OTP alarm                                , */\
+   { 0x4c30, "IPOOVDS"},    /* Polarity OVP alarm                                , */\
+   { 0x4c40, "IPOUVDS"},    /* Polarity UVP alarm                                , */\
+   { 0x4c50, "IPOCLKS"},    /* Polarity clocks stable                            , */\
+   { 0x4c60, "IPOMTPB"},    /* Polarity mtp busy                                 , */\
+   { 0x4c70, "IPONOCLK"},    /* Polarity lost clk                                 , */\
+   { 0x4c80, "IPOSPKS"},    /* Polarity speaker error                            , */\
+   { 0x4c90, "IPOACS"},    /* Polarity cold started                             , */\
+   { 0x4ca0, "IPOSWS"},    /* Polarity amplifier engage                         , */\
+   { 0x4cb0, "IPOWDS"},    /* Polarity watchdog                                 , */\
+   { 0x4cc0, "IPOAMPS"},    /* Polarity enbl amp                                 , */\
+   { 0x4cd0, "IPOAREFS"},    /* Polarity ref enable                               , */\
+   { 0x4ce0, "IPOADCCR"},    /* Polarity Control ADC                              , */\
+   { 0x4cf0, "IPOBODNOK"},    /* Polarity BOD                                      , */\
+   { 0x4d00, "IPOBSTCU"},    /* Polarity DCDC current limiting                    , */\
+   { 0x4d10, "IPOBSTHI"},    /* Polarity DCDC active                              , */\
+   { 0x4d20, "IPOBSTOC"},    /* Polarity DCDC OCP                                 , */\
+   { 0x4d30, "IPOBSTPC"},    /* Polarity bst peakcur                              , */\
+   { 0x4d40, "IPOBSTVC"},    /* Polarity DCDC level 1x                            , */\
+   { 0x4d50, "IPOBST86"},    /* Polarity DCDC level 1.14x                         , */\
+   { 0x4d60, "IPOBST93"},    /* Polarity DCDC level 1.07x                         , */\
+   { 0x4d70, "IPORCVLD"},    /* Polarity rcvldop ready                            , */\
+   { 0x4d80, "IPOOCPL"},    /* Polarity ocp alarm left                           , */\
+   { 0x4d90, "IPOOCPR"},    /* Polarity ocp alarm right                          , */\
+   { 0x4da0, "IPOMWSRC"},    /* Polarity waits HW I2C settings                    , */\
+   { 0x4db0, "IPOMWCFC"},    /* Polarity man wait cf config                       , */\
+   { 0x4dc0, "IPOMWSMU"},    /* Polarity man audio mute sequence                  , */\
+   { 0x4dd0, "IPOCFMER"},    /* Polarity cfma err                                 , */\
+   { 0x4de0, "IPOCFMAC"},    /* Polarity cfma ack                                 , */\
+   { 0x4df0, "IPCLKOOR"},    /* Polarity flag_clk_out_of_range                    , */\
+   { 0x4e00, "IPOTDMER"},    /* Polarity tdm error                                , */\
+   { 0x4e10, "IPOCLPL"},    /* Polarity clip left                                , */\
+   { 0x4e20, "IPOCLPR"},    /* Polarity clip right                               , */\
+   { 0x4e30, "IPOOCPM"},    /* Polarity mic ocpok                                , */\
+   { 0x5001, "BSSCR"},    /* Battery protection attack Time                    , */\
+   { 0x5023, "BSST"},    /* Battery protection threshold voltage level        , */\
+   { 0x5061, "BSSRL"},    /* Battery protection maximum reduction              , */\
+   { 0x5082, "BSSRR"},    /* Battery protection release time                   , */\
+   { 0x50b1, "BSSHY"},    /* Battery protection hysteresis                     , */\
+   { 0x50e0, "BSSR"},    /* Battery voltage read out                          , */\
+   { 0x50f0, "BSSBY"},    /* Bypass HW clipper                                 , */\
+   { 0x5100, "BSSS"},    /* Vbat prot steepness                               , */\
+   { 0x5110, "INTSMUTE"},    /* Soft mute HW                                      , */\
+   { 0x5120, "CFSML"},    /* Soft mute FW left                                 , */\
+   { 0x5130, "CFSMR"},    /* Soft mute FW right                                , */\
+   { 0x5140, "HPFBYPL"},    /* Bypass HPF left                                   , */\
+   { 0x5150, "HPFBYPR"},    /* Bypass HPF right                                  , */\
+   { 0x5160, "DPSAL"},    /* Enable DPSA left                                  , */\
+   { 0x5170, "DPSAR"},    /* Enable DPSA right                                 , */\
+   { 0x5187, "VOL"},    /* FW volume control for primary audio channel       , */\
+   { 0x5200, "HNDSFRCV"},    /* Selection receiver                                , */\
+   { 0x5222, "CLIPCTRL"},    /* Clip control setting                              , */\
+   { 0x5257, "AMPGAIN"},    /* Amplifier gain                                    , */\
+   { 0x52d0, "SLOPEE"},    /* Enables slope control                             , */\
+   { 0x52e1, "SLOPESET"},    /* Set slope                                         , */\
+   { 0x5a07, "VOLSEC"},    /* FW volume control for secondary audio channel     , */\
+   { 0x5a87, "SWPROFIL"},    /* Software profile data                             , */\
+   { 0x7002, "DCVO"},    /* Boost voltage                                     , */\
+   { 0x7033, "DCMCC"},    /* Max coil current                                  , */\
+   { 0x7071, "DCCV"},    /* Coil Value                                        , */\
+   { 0x7090, "DCIE"},    /* Adaptive boost mode                               , */\
+   { 0x70a0, "DCSR"},    /* Soft ramp up/down                                 , */\
+   { 0x70b2, "DCSYNCP"},    /* DCDC synchronization off + 7 positions            , */\
+   { 0x70e0, "DCDIS"},    /* DCDC on/off                                       , */\
+   { 0x9000, "RST"},    /* Reset                                             , */\
+   { 0x9011, "DMEM"},    /* Target memory                                     , */\
+   { 0x9030, "AIF"},    /* Auto increment                                    , */\
+   { 0x9040, "CFINT"},    /* Interrupt - auto clear                            , */\
+   { 0x9050, "CFCGATE"},    /* Coolflux clock gating disabling control           , */\
+   { 0x9080, "REQCMD"},    /* Firmware event request rpc command                , */\
+   { 0x9090, "REQRST"},    /* Firmware event request reset restart              , */\
+   { 0x90a0, "REQMIPS"},    /* Firmware event request short on mips              , */\
+   { 0x90b0, "REQMUTED"},    /* Firmware event request mute sequence ready        , */\
+   { 0x90c0, "REQVOL"},    /* Firmware event request volume ready               , */\
+   { 0x90d0, "REQDMG"},    /* Firmware event request speaker damage detected    , */\
+   { 0x90e0, "REQCAL"},    /* Firmware event request calibration completed      , */\
+   { 0x90f0, "REQRSV"},    /* Firmware event request reserved                   , */\
+   { 0x910f, "MADD"},    /* Memory address                                    , */\
+   { 0x920f, "MEMA"},    /* Activate memory access                            , */\
+   { 0x9307, "ERR"},    /* Error flags                                       , */\
+   { 0x9387, "ACK"},    /* Acknowledge of requests                           , */\
+   { 0x9380, "ACKCMD"},    /* Firmware event acknowledge rpc command            , */\
+   { 0x9390, "ACKRST"},    /* Firmware event acknowledge reset restart          , */\
+   { 0x93a0, "ACKMIPS"},    /* Firmware event acknowledge short on mips          , */\
+   { 0x93b0, "ACKMUTED"},    /* Firmware event acknowledge mute sequence ready    , */\
+   { 0x93c0, "ACKVOL"},    /* Firmware event acknowledge volume ready           , */\
+   { 0x93d0, "ACKDMG"},    /* Firmware event acknowledge speaker damage detected, */\
+   { 0x93e0, "ACKCAL"},    /* Firmware event acknowledge calibration completed  , */\
+   { 0x93f0, "ACKRSV"},    /* Firmware event acknowledge reserved               , */\
+   { 0xa107, "MTPK"},    /* MTP KEY2 register                                 , */\
+   { 0xa200, "KEY1LOCKED"},    /* Indicates KEY1 is locked                          , */\
+   { 0xa210, "KEY2LOCKED"},    /* Indicates KEY2 is locked                          , */\
+   { 0xa360, "CIMTP"},    /* Start copying data from I2C mtp registers to mtp  , */\
+   { 0xa50f, "MTPRDMSB"},    /* MSB word of MTP manual read data                  , */\
+   { 0xa60f, "MTPRDLSB"},    /* LSB word of MTP manual read data                  , */\
+   { 0xb108, "EXTTS"},    /* External temperature (C)                          , */\
+   { 0xb190, "TROS"},    /* Select temp Speaker calibration                   , */\
+   { 0xf000, "MTPOTC"},    /* Calibration schedule                              , */\
+   { 0xf010, "MTPEX"},    /* Calibration Ron executed                          , */\
+   { 0xf020, "DCMCCAPI"},    /* Calibration current limit DCDC                    , */\
+   { 0xf030, "DCMCCSB"},    /* Sign bit for delta calibration current limit DCDC , */\
+   { 0xf042, "USERDEF"},    /* Calibration delta current limit DCDC              , */\
+   { 0xf40f, "R25CL"},    /* Ron resistance of left channel speaker coil       , */\
+   { 0xf50f, "R25CR"},    /* Ron resistance of right channel speaker coil      , */\
+   { 0xffff,"Unknown bitfield enum" }   /* not found */\
+};
+
+#define TFA2_BITNAMETABLE static tfaBfName_t Tfa2BitNames[]= {\
+   { 0x0, "powerdown"},    /* Powerdown selection                               , */\
+   { 0x10, "reset"},    /* I2C Reset - Auto clear                            , */\
+   { 0x20, "enbl_coolflux"},    /* Enable CoolFlux                                   , */\
+   { 0x30, "enbl_amplifier"},    /* Activate Amplifier                                , */\
+   { 0x40, "enbl_boost"},    /* Activate DC-to-DC converter                       , */\
+   { 0x50, "coolflux_configured"},    /* Coolflux configured                               , */\
+   { 0x60, "sel_enbl_amplifier"},    /* CoolFlux controls amplifier                       , */\
+   { 0x71, "int_pad_io"},    /* Interrupt config                                  , */\
+   { 0x91, "fs_pulse_sel"},    /* Audio sample reference                            , */\
+   { 0xb0, "bypass_ocp"},    /* Bypass OCP                                        , */\
+   { 0xc0, "test_ocp"},    /* OCP testing control                               , */\
+   { 0x101, "vamp_sel"},    /* Amplifier input selection                         , */\
+   { 0x120, "src_set_configured"},    /* I2C configured                                    , */\
+   { 0x130, "execute_cold_start"},    /* Execute cold start                                , */\
+   { 0x140, "enbl_osc1m_auto_off"},    /* Internal osc off at PWDN                          , */\
+   { 0x150, "man_enbl_brown_out"},    /* Reaction on BOD                                   , */\
+   { 0x160, "enbl_bod"},    /* BOD Enable                                        , */\
+   { 0x170, "enbl_bod_hyst"},    /* BOD Hysteresis                                    , */\
+   { 0x181, "bod_delay"},    /* BOD filter                                        , */\
+   { 0x1a1, "bod_lvlsel"},    /* BOD threshold                                     , */\
+   { 0x1d0, "disable_mute_time_out"},    /* Time out SB mute sequence                         , */\
+   { 0x1e0, "pwm_sel_rcv_ns"},    /* Noise shaper selection                            , */\
+   { 0x1f0, "man_enbl_watchdog"},    /* Watchdog manager reaction                         , */\
+   { 0x203, "audio_fs"},    /* Sample rate (fs)                                  , */\
+   { 0x240, "input_level"},    /* TDM output attenuation                            , */\
+   { 0x255, "cs_frac_delay"},    /* V/I Fractional delay                              , */\
+   { 0x2b0, "bypass_hvbat_filter"},    /* Bypass HVBAT filter                               , */\
+   { 0x2c0, "ctrl_rcvldop_bypass"},    /* Receiver LDO bypass                               , */\
+   { 0x30f, "device_rev"},    /* Revision info                                     , */\
+   { 0x401, "pll_clkin_sel"},    /* PLL external ref clock                            , */\
+   { 0x420, "pll_clkin_sel_osc"},    /* PLL internal ref clock                            , */\
+   { 0x500, "enbl_spkr_ss_left"},    /* Enable left channel                               , */\
+   { 0x510, "enbl_spkr_ss_right"},    /* Enable right channel                              , */\
+   { 0x520, "enbl_volsense_left"},    /* Voltage sense left                                , */\
+   { 0x530, "enbl_volsense_right"},    /* Voltage sense right                               , */\
+   { 0x540, "enbl_cursense_left"},    /* Current sense left                                , */\
+   { 0x550, "enbl_cursense_right"},    /* Current sense right                               , */\
+   { 0x560, "enbl_pdm_ss"},    /* Sub-system PDM                                    , */\
+   { 0xd00, "side_tone_gain_sel"},    /* PDM side tone gain selector                       , */\
+   { 0xd18, "side_tone_gain"},    /* Side tone gain                                    , */\
+   { 0xda0, "mute_side_tone"},    /* Side tone soft mute                               , */\
+   { 0xe06, "ctrl_digtoana"},    /* Register for the host SW to record the current active vstep, */\
+   { 0xe70, "enbl_cmfb_left"},    /* Current sense common mode feedback control for left channel, */\
+   { 0xf0f, "hidden_code"},    /* 5A6Bh, 23147d to access registers (default for engineering), */\
+   { 0x1000, "flag_por"},    /* POR                                               , */\
+   { 0x1010, "flag_pll_lock"},    /* PLL lock                                          , */\
+   { 0x1020, "flag_otpok"},    /* OTP alarm                                         , */\
+   { 0x1030, "flag_ovpok"},    /* OVP alarm                                         , */\
+   { 0x1040, "flag_uvpok"},    /* UVP alarm                                         , */\
+   { 0x1050, "flag_clocks_stable"},    /* Clocks stable                                     , */\
+   { 0x1060, "flag_mtp_busy"},    /* MTP busy                                          , */\
+   { 0x1070, "flag_lost_clk"},    /* Lost clock                                        , */\
+   { 0x1080, "flag_cf_speakererror"},    /* Speaker error                                     , */\
+   { 0x1090, "flag_cold_started"},    /* Cold Start                                        , */\
+   { 0x10a0, "flag_engage"},    /* Amplifier engage                                  , */\
+   { 0x10b0, "flag_watchdog_reset"},    /* Watchdog                                          , */\
+   { 0x10c0, "flag_enbl_amp"},    /* Amplifier enable                                  , */\
+   { 0x10d0, "flag_enbl_ref"},    /* References enable                                 , */\
+   { 0x10e0, "flag_adc10_ready"},    /* Control ADC                                       , */\
+   { 0x10f0, "flag_bod_vddd_nok"},    /* BOD                                               , */\
+   { 0x1100, "flag_bst_bstcur"},    /* DCDC current limiting                             , */\
+   { 0x1110, "flag_bst_hiz"},    /* DCDC active                                       , */\
+   { 0x1120, "flag_bst_ocpok"},    /* DCDC OCP nmos                                     , */\
+   { 0x1130, "flag_bst_peakcur"},    /* Indicates current is max in DC-to-DC converter    , */\
+   { 0x1140, "flag_bst_voutcomp"},    /* DCDC level 1x                                     , */\
+   { 0x1150, "flag_bst_voutcomp86"},    /* DCDC level 1.14x                                  , */\
+   { 0x1160, "flag_bst_voutcomp93"},    /* DCDC level 1.07x                                  , */\
+   { 0x1170, "flag_soft_mute_busy"},    /* side tone (un)mute busy                           , */\
+   { 0x1180, "flag_soft_mute_state"},    /* side tone mute state                              , */\
+   { 0x1190, "flag_tdm_lut_error"},    /* TDM LUT error                                     , */\
+   { 0x11a2, "flag_tdm_status"},    /* TDM status bits                                   , */\
+   { 0x11d0, "flag_tdm_error"},    /* TDM error                                         , */\
+   { 0x11e0, "flag_haptic_busy"},    /* Status haptic driver                              , */\
+   { 0x1200, "flag_ocpokap_left"},    /* OCPOK pmos A left                                 , */\
+   { 0x1210, "flag_ocpokan_left"},    /* OCPOK nmos A left                                 , */\
+   { 0x1220, "flag_ocpokbp_left"},    /* OCPOK pmos B left                                 , */\
+   { 0x1230, "flag_ocpokbn_left"},    /* OCPOK nmos B left                                 , */\
+   { 0x1240, "flag_clipa_high_left"},    /* Clipping A left to Vddp                           , */\
+   { 0x1250, "flag_clipa_low_left"},    /* Clipping A left to gnd                            , */\
+   { 0x1260, "flag_clipb_high_left"},    /* Clipping B left to Vddp                           , */\
+   { 0x1270, "flag_clipb_low_left"},    /* Clipping B left to gnd                            , */\
+   { 0x1280, "flag_ocpokap_rcv"},    /* OCPOK pmos A RCV                                  , */\
+   { 0x1290, "flag_ocpokan_rcv"},    /* OCPOK nmos A RCV                                  , */\
+   { 0x12a0, "flag_ocpokbp_rcv"},    /* OCPOK pmos B RCV                                  , */\
+   { 0x12b0, "flag_ocpokbn_rcv"},    /* OCPOK nmos B RCV                                  , */\
+   { 0x12c0, "flag_rcvldop_ready"},    /* RCV LDO regulates                                 , */\
+   { 0x12d0, "flag_rcvldop_bypassready"},    /* Receiver LDO ready                                , */\
+   { 0x12e0, "flag_ocp_alarm_left"},    /* OCP left amplifier                                , */\
+   { 0x12f0, "flag_clip_left"},    /* Amplifier left clipping                           , */\
+   { 0x1300, "flag_ocpokap_right"},    /* OCPOK pmos A right                                , */\
+   { 0x1310, "flag_ocpokan_right"},    /* OCPOK nmos A right                                , */\
+   { 0x1320, "flag_ocpokbp_right"},    /* OCPOK pmos B right                                , */\
+   { 0x1330, "flag_ocpokbn_right"},    /* OCPOK nmos B right                                , */\
+   { 0x1340, "flag_clipa_high_right"},    /* Clipping A right to Vddp                          , */\
+   { 0x1350, "flag_clipa_low_right"},    /* Clipping A right to gnd                           , */\
+   { 0x1360, "flag_clipb_high_right"},    /* Clipping B left to Vddp                           , */\
+   { 0x1370, "flag_clipb_low_right"},    /* Clipping B right to gnd                           , */\
+   { 0x1380, "flag_ocp_alarm_right"},    /* OCP right amplifier                               , */\
+   { 0x1390, "flag_clip_right"},    /* Amplifier right clipping                          , */\
+   { 0x13a0, "flag_mic_ocpok"},    /* OCPOK MICVDD                                      , */\
+   { 0x13b0, "flag_man_alarm_state"},    /* Alarm state                                       , */\
+   { 0x13c0, "flag_man_wait_src_settings"},    /* Wait HW I2C settings                              , */\
+   { 0x13d0, "flag_man_wait_cf_config"},    /* Wait CF config                                    , */\
+   { 0x13e0, "flag_man_start_mute_audio"},    /* Audio mute sequence                               , */\
+   { 0x13f0, "flag_man_operating_state"},    /* Operating state                                   , */\
+   { 0x1400, "flag_cf_speakererror_left"},    /* Left speaker status                               , */\
+   { 0x1410, "flag_cf_speakererror_right"},    /* Right speaker status                              , */\
+   { 0x1420, "flag_clk_out_of_range"},    /* External clock status                             , */\
+   { 0x1433, "man_state"},    /* Device manager status                             , */\
+   { 0x1509, "bat_adc"},    /* Battery voltage (V)                               , */\
+   { 0x1608, "temp_adc"},    /* IC Temperature (C)                                , */\
+   { 0x2003, "tdm_usecase"},    /* Usecase setting                                   , */\
+   { 0x2040, "tdm_enable"},    /* Enable interface                                  , */\
+   { 0x2050, "tdm_mode"},    /* Slave/master                                      , */\
+   { 0x2060, "tdm_clk_inversion"},    /* Reception data to BCK clock                       , */\
+   { 0x2073, "tdm_fs_ws_length"},    /* FS length (master mode only)                      , */\
+   { 0x20b0, "tdm_fs_ws_polarity"},    /* FS polarity                                       , */\
+   { 0x20c3, "tdm_nbck"},    /* N-BCK's in FS                                     , */\
+   { 0x2103, "tdm_nb_of_slots"},    /* N-slots in Frame                                  , */\
+   { 0x2144, "tdm_slot_length"},    /* N-bits in slot                                    , */\
+   { 0x2194, "tdm_bits_remaining"},    /* N-bits remaining                                  , */\
+   { 0x21e0, "tdm_data_delay"},    /* data delay to FS                                  , */\
+   { 0x21f0, "tdm_data_adjustment"},    /* data adjustment                                   , */\
+   { 0x2201, "tdm_audio_sample_compression"},    /* Received audio compression                        , */\
+   { 0x2224, "tdm_sample_size"},    /* Sample size per slot                              , */\
+   { 0x2271, "tdm_txdata_format"},    /* Format unused bits                                , */\
+   { 0x2291, "tdm_txdata_format_unused_slot_sd0"},    /* Format unused slots GAINIO                        , */\
+   { 0x22b1, "tdm_txdata_format_unused_slot_sd1"},    /* Format unused slots DIO1                          , */\
+   { 0x22d1, "tdm_txdata_format_unused_slot_sd2"},    /* Format unused slots DIO2                          , */\
+   { 0x2300, "tdm_sink0_enable"},    /* Control gainin (not used in DSP)                  , */\
+   { 0x2310, "tdm_sink1_enable"},    /* Control audio left                                , */\
+   { 0x2320, "tdm_sink2_enable"},    /* Control audio right                               , */\
+   { 0x2330, "tdm_source0_enable"},    /* Control gainout (not used in DSP)                 , */\
+   { 0x2340, "tdm_source1_enable"},    /* Control voltage sense right                       , */\
+   { 0x2350, "tdm_source2_enable"},    /* Control current sense right                       , */\
+   { 0x2360, "tdm_source3_enable"},    /* Voltage sense left control                        , */\
+   { 0x2370, "tdm_source4_enable"},    /* Current sense left control                        , */\
+   { 0x2380, "tdm_source5_enable"},    /* DSP out right control                             , */\
+   { 0x2390, "tdm_source6_enable"},    /* DSP out left control                              , */\
+   { 0x23a0, "tdm_source7_enable"},    /* AEC ref left control                              , */\
+   { 0x23b0, "tdm_source8_enable"},    /* AEC ref right control                             , */\
+   { 0x23c0, "tdm_source9_enable"},    /* PDM 1 control                                     , */\
+   { 0x23d0, "tdm_source10_enable"},    /* PDM 2 control                                     , */\
+   { 0x2401, "tdm_sink0_io"},    /* IO gainin (not used in DSP)                       , */\
+   { 0x2421, "tdm_sink1_io"},    /* IO audio left                                     , */\
+   { 0x2441, "tdm_sink2_io"},    /* IO audio right                                    , */\
+   { 0x2461, "tdm_source0_io"},    /* IO gainout (not used in DSP)                      , */\
+   { 0x2481, "tdm_source1_io"},    /* IO voltage sense right                            , */\
+   { 0x24a1, "tdm_source2_io"},    /* IO current sense right                            , */\
+   { 0x24c1, "tdm_source3_io"},    /* IO voltage sense left                             , */\
+   { 0x24e1, "tdm_source4_io"},    /* IO current sense left                             , */\
+   { 0x2501, "tdm_source5_io"},    /* IO dspout right                                   , */\
+   { 0x2521, "tdm_source6_io"},    /* IO dspout left                                    , */\
+   { 0x2541, "tdm_source7_io"},    /* IO AEC ref left control                           , */\
+   { 0x2561, "tdm_source8_io"},    /* IO AEC ref right control                          , */\
+   { 0x2581, "tdm_source9_io"},    /* IO pdm1                                           , */\
+   { 0x25a1, "tdm_source10_io"},    /* IO pdm2                                           , */\
+   { 0x2603, "tdm_sink0_slot"},    /* Position gainin (not used in DSP)                 , */\
+   { 0x2643, "tdm_sink1_slot"},    /* Position audio left                               , */\
+   { 0x2683, "tdm_sink2_slot"},    /* Position audio right                              , */\
+   { 0x26c3, "tdm_source0_slot"},    /* Position gainout (not used in DSP)                , */\
+   { 0x2703, "tdm_source1_slot"},    /* Position voltage sense right                      , */\
+   { 0x2743, "tdm_source2_slot"},    /* Position current sense right                      , */\
+   { 0x2783, "tdm_source3_slot"},    /* Position voltage sense left                       , */\
+   { 0x27c3, "tdm_source4_slot"},    /* Position current sense left                       , */\
+   { 0x2803, "tdm_source5_slot"},    /* Position dspout right                             , */\
+   { 0x2843, "tdm_source6_slot"},    /* Position dspout left                              , */\
+   { 0x2883, "tdm_source7_slot"},    /* Position AEC ref left control                     , */\
+   { 0x28c3, "tdm_source8_slot"},    /* Position AEC ref right control                    , */\
+   { 0x2903, "tdm_source9_slot"},    /* Position pdm1                                     , */\
+   { 0x2943, "tdm_source10_slot"},    /* Position pdm2                                     , */\
+   { 0x3100, "pdm_mode"},    /* PDM control                                       , */\
+   { 0x3111, "pdm_side_tone_sel"},    /* Side tone input                                   , */\
+   { 0x3130, "pdm_left_sel"},    /* PDM data selection for left channel during PDM direct mode, */\
+   { 0x3140, "pdm_right_sel"},    /* PDM data selection for right channel during PDM direct mode, */\
+   { 0x3150, "enbl_micvdd"},    /* Enable MICVDD                                     , */\
+   { 0x3160, "bypass_micvdd_ocp"},    /* Bypass control for the MICVDD OCP flag processing , */\
+   { 0x3201, "pdm_nbck"},    /* PDM BCK/Fs ratio                                  , */\
+   { 0x3223, "pdm_gain"},    /* PDM gain                                          , */\
+   { 0x3263, "sel_pdm_out_data"},    /* PDM output selection - RE/FE data combination     , */\
+   { 0x32a0, "sel_cf_haptic_data"},    /* Select the source for haptic data output (not for customer), */\
+   { 0x3307, "haptic_duration"},    /* Duration (ms)                                     , */\
+   { 0x3387, "haptic_data"},    /* DC value (FFS)                                    , */\
+   { 0x3403, "gpio_datain"},    /* Receiving value                                   , */\
+   { 0x3500, "gpio_ctrl"},    /* GPIO master control over GPIO1/2 ports (not for customer), */\
+   { 0x3513, "gpio_dir"},    /* Configuration                                     , */\
+   { 0x3553, "gpio_dataout"},    /* Transmitting value                                , */\
+   { 0x4000, "int_out_flag_por"},    /* Status POR                                        , */\
+   { 0x4010, "int_out_flag_pll_lock"},    /* Status PLL lock                                   , */\
+   { 0x4020, "int_out_flag_otpok"},    /* Status OTP alarm                                  , */\
+   { 0x4030, "int_out_flag_ovpok"},    /* Status OVP alarm                                  , */\
+   { 0x4040, "int_out_flag_uvpok"},    /* Status UVP alarm                                  , */\
+   { 0x4050, "int_out_flag_clocks_stable"},    /* Status clocks stable                              , */\
+   { 0x4060, "int_out_flag_mtp_busy"},    /* Status MTP busy                                   , */\
+   { 0x4070, "int_out_flag_lost_clk"},    /* Status lost clock                                 , */\
+   { 0x4080, "int_out_flag_cf_speakererror"},    /* Status speaker error                              , */\
+   { 0x4090, "int_out_flag_cold_started"},    /* Status cold start                                 , */\
+   { 0x40a0, "int_out_flag_engage"},    /* Status amplifier engage                           , */\
+   { 0x40b0, "int_out_flag_watchdog_reset"},    /* Status watchdog                                   , */\
+   { 0x40c0, "int_out_flag_enbl_amp"},    /* Status amplifier enable                           , */\
+   { 0x40d0, "int_out_flag_enbl_ref"},    /* Status Ref enable                                 , */\
+   { 0x40e0, "int_out_flag_adc10_ready"},    /* Status Control ADC                                , */\
+   { 0x40f0, "int_out_flag_bod_vddd_nok"},    /* Status BOD                                        , */\
+   { 0x4100, "int_out_flag_bst_bstcur"},    /* Status DCDC current limiting                      , */\
+   { 0x4110, "int_out_flag_bst_hiz"},    /* Status DCDC active                                , */\
+   { 0x4120, "int_out_flag_bst_ocpok"},    /* Status DCDC OCP                                   , */\
+   { 0x4130, "int_out_flag_bst_peakcur"},    /* Status bst peakcur                                , */\
+   { 0x4140, "int_out_flag_bst_voutcomp"},    /* Status DCDC level 1x                              , */\
+   { 0x4150, "int_out_flag_bst_voutcomp86"},    /* Status DCDC level 1.14x                           , */\
+   { 0x4160, "int_out_flag_bst_voutcomp93"},    /* Status DCDC level 1.07x                           , */\
+   { 0x4170, "int_out_flag_rcvldop_ready"},    /* Status rcvldop ready                              , */\
+   { 0x4180, "int_out_flag_ocp_alarm_left"},    /* Status ocp alarm left                             , */\
+   { 0x4190, "int_out_flag_ocp_alarm_right"},    /* Status ocp alarm right                            , */\
+   { 0x41a0, "int_out_flag_man_wait_src_settings"},    /* Status Waits HW I2C settings                      , */\
+   { 0x41b0, "int_out_flag_man_wait_cf_config"},    /* Status waits CF config                            , */\
+   { 0x41c0, "int_out_flag_man_start_mute_audio"},    /* Status Audio mute sequence                        , */\
+   { 0x41d0, "int_out_flag_cfma_err"},    /* Status cfma error                                 , */\
+   { 0x41e0, "int_out_flag_cfma_ack"},    /* Status cfma ack                                   , */\
+   { 0x41f0, "int_out_flag_clk_out_of_range"},    /* Status flag_clk_out_of_range                      , */\
+   { 0x4200, "int_out_flag_tdm_error"},    /* Status tdm error                                  , */\
+   { 0x4210, "int_out_flag_clip_left"},    /* Status clip left                                  , */\
+   { 0x4220, "int_out_flag_clip_right"},    /* Status clip right                                 , */\
+   { 0x4230, "int_out_flag_mic_ocpok"},    /* Status mic ocpok                                  , */\
+   { 0x4400, "int_in_flag_por"},    /* Clear POR                                         , */\
+   { 0x4410, "int_in_flag_pll_lock"},    /* Clear PLL lock                                    , */\
+   { 0x4420, "int_in_flag_otpok"},    /* Clear OTP alarm                                   , */\
+   { 0x4430, "int_in_flag_ovpok"},    /* Clear OVP alarm                                   , */\
+   { 0x4440, "int_in_flag_uvpok"},    /* Clear UVP alarm                                   , */\
+   { 0x4450, "int_in_flag_clocks_stable"},    /* Clear clocks stable                               , */\
+   { 0x4460, "int_in_flag_mtp_busy"},    /* Clear mtp busy                                    , */\
+   { 0x4470, "int_in_flag_lost_clk"},    /* Clear lost clk                                    , */\
+   { 0x4480, "int_in_flag_cf_speakererror"},    /* Clear speaker error                               , */\
+   { 0x4490, "int_in_flag_cold_started"},    /* Clear cold started                                , */\
+   { 0x44a0, "int_in_flag_engage"},    /* Clear amplifier engage                            , */\
+   { 0x44b0, "int_in_flag_watchdog_reset"},    /* Clear watchdog                                    , */\
+   { 0x44c0, "int_in_flag_enbl_amp"},    /* Clear enbl amp                                    , */\
+   { 0x44d0, "int_in_flag_enbl_ref"},    /* Clear ref enable                                  , */\
+   { 0x44e0, "int_in_flag_adc10_ready"},    /* Clear control ADC                                 , */\
+   { 0x44f0, "int_in_flag_bod_vddd_nok"},    /* Clear BOD                                         , */\
+   { 0x4500, "int_in_flag_bst_bstcur"},    /* Clear DCDC current limiting                       , */\
+   { 0x4510, "int_in_flag_bst_hiz"},    /* Clear DCDC active                                 , */\
+   { 0x4520, "int_in_flag_bst_ocpok"},    /* Clear DCDC OCP                                    , */\
+   { 0x4530, "int_in_flag_bst_peakcur"},    /* Clear bst peakcur                                 , */\
+   { 0x4540, "int_in_flag_bst_voutcomp"},    /* Clear DCDC level 1x                               , */\
+   { 0x4550, "int_in_flag_bst_voutcomp86"},    /* Clear DCDC level 1.14x                            , */\
+   { 0x4560, "int_in_flag_bst_voutcomp93"},    /* Clear DCDC level 1.07x                            , */\
+   { 0x4570, "int_in_flag_rcvldop_ready"},    /* Clear rcvldop ready                               , */\
+   { 0x4580, "int_in_flag_ocp_alarm_left"},    /* Clear ocp alarm left                              , */\
+   { 0x4590, "int_in_flag_ocp_alarm_right"},    /* Clear ocp alarm right                             , */\
+   { 0x45a0, "int_in_flag_man_wait_src_settings"},    /* Clear wait HW I2C settings                        , */\
+   { 0x45b0, "int_in_flag_man_wait_cf_config"},    /* Clear wait cf config                              , */\
+   { 0x45c0, "int_in_flag_man_start_mute_audio"},    /* Clear audio mute sequence                         , */\
+   { 0x45d0, "int_in_flag_cfma_err"},    /* Clear cfma err                                    , */\
+   { 0x45e0, "int_in_flag_cfma_ack"},    /* Clear cfma ack                                    , */\
+   { 0x45f0, "int_in_flag_clk_out_of_range"},    /* Clear flag_clk_out_of_range                       , */\
+   { 0x4600, "int_in_flag_tdm_error"},    /* Clear tdm error                                   , */\
+   { 0x4610, "int_in_flag_clip_left"},    /* Clear clip left                                   , */\
+   { 0x4620, "int_in_flag_clip_right"},    /* Clear clip right                                  , */\
+   { 0x4630, "int_in_flag_mic_ocpok"},    /* Clear mic ocpok                                   , */\
+   { 0x4800, "int_enable_flag_por"},    /* Enable por                                        , */\
+   { 0x4810, "int_enable_flag_pll_lock"},    /* Enable pll lock                                   , */\
+   { 0x4820, "int_enable_flag_otpok"},    /* Enable OTP alarm                                  , */\
+   { 0x4830, "int_enable_flag_ovpok"},    /* Enable OVP alarm                                  , */\
+   { 0x4840, "int_enable_flag_uvpok"},    /* Enable UVP alarm                                  , */\
+   { 0x4850, "int_enable_flag_clocks_stable"},    /* Enable clocks stable                              , */\
+   { 0x4860, "int_enable_flag_mtp_busy"},    /* Enable mtp busy                                   , */\
+   { 0x4870, "int_enable_flag_lost_clk"},    /* Enable lost clk                                   , */\
+   { 0x4880, "int_enable_flag_cf_speakererror"},    /* Enable speaker error                              , */\
+   { 0x4890, "int_enable_flag_cold_started"},    /* Enable cold started                               , */\
+   { 0x48a0, "int_enable_flag_engage"},    /* Enable amplifier engage                           , */\
+   { 0x48b0, "int_enable_flag_watchdog_reset"},    /* Enable watchdog                                   , */\
+   { 0x48c0, "int_enable_flag_enbl_amp"},    /* Enable enbl amp                                   , */\
+   { 0x48d0, "int_enable_flag_enbl_ref"},    /* Enable ref enable                                 , */\
+   { 0x48e0, "int_enable_flag_adc10_ready"},    /* Enable Control ADC                                , */\
+   { 0x48f0, "int_enable_flag_bod_vddd_nok"},    /* Enable BOD                                        , */\
+   { 0x4900, "int_enable_flag_bst_bstcur"},    /* Enable DCDC current limiting                      , */\
+   { 0x4910, "int_enable_flag_bst_hiz"},    /* Enable DCDC active                                , */\
+   { 0x4920, "int_enable_flag_bst_ocpok"},    /* Enable DCDC OCP                                   , */\
+   { 0x4930, "int_enable_flag_bst_peakcur"},    /* Enable bst peakcur                                , */\
+   { 0x4940, "int_enable_flag_bst_voutcomp"},    /* Enable DCDC level 1x                              , */\
+   { 0x4950, "int_enable_flag_bst_voutcomp86"},    /* Enable DCDC level 1.14x                           , */\
+   { 0x4960, "int_enable_flag_bst_voutcomp93"},    /* Enable DCDC level 1.07x                           , */\
+   { 0x4970, "int_enable_flag_rcvldop_ready"},    /* Enable rcvldop ready                              , */\
+   { 0x4980, "int_enable_flag_ocp_alarm_left"},    /* Enable ocp alarm left                             , */\
+   { 0x4990, "int_enable_flag_ocp_alarm_right"},    /* Enable ocp alarm right                            , */\
+   { 0x49a0, "int_enable_flag_man_wait_src_settings"},    /* Enable waits HW I2C settings                      , */\
+   { 0x49b0, "int_enable_flag_man_wait_cf_config"},    /* Enable man wait cf config                         , */\
+   { 0x49c0, "int_enable_flag_man_start_mute_audio"},    /* Enable man Audio mute sequence                    , */\
+   { 0x49d0, "int_enable_flag_cfma_err"},    /* Enable cfma err                                   , */\
+   { 0x49e0, "int_enable_flag_cfma_ack"},    /* Enable cfma ack                                   , */\
+   { 0x49f0, "int_enable_flag_clk_out_of_range"},    /* Enable flag_clk_out_of_range                      , */\
+   { 0x4a00, "int_enable_flag_tdm_error"},    /* Enable tdm error                                  , */\
+   { 0x4a10, "int_enable_flag_clip_left"},    /* Enable clip left                                  , */\
+   { 0x4a20, "int_enable_flag_clip_right"},    /* Enable clip right                                 , */\
+   { 0x4a30, "int_enable_flag_mic_ocpok"},    /* Enable mic ocpok                                  , */\
+   { 0x4c00, "int_polarity_flag_por"},    /* Polarity por                                      , */\
+   { 0x4c10, "int_polarity_flag_pll_lock"},    /* Polarity pll lock                                 , */\
+   { 0x4c20, "int_polarity_flag_otpok"},    /* Polarity OTP alarm                                , */\
+   { 0x4c30, "int_polarity_flag_ovpok"},    /* Polarity OVP alarm                                , */\
+   { 0x4c40, "int_polarity_flag_uvpok"},    /* Polarity UVP alarm                                , */\
+   { 0x4c50, "int_polarity_flag_clocks_stable"},    /* Polarity clocks stable                            , */\
+   { 0x4c60, "int_polarity_flag_mtp_busy"},    /* Polarity mtp busy                                 , */\
+   { 0x4c70, "int_polarity_flag_lost_clk"},    /* Polarity lost clk                                 , */\
+   { 0x4c80, "int_polarity_flag_cf_speakererror"},    /* Polarity speaker error                            , */\
+   { 0x4c90, "int_polarity_flag_cold_started"},    /* Polarity cold started                             , */\
+   { 0x4ca0, "int_polarity_flag_engage"},    /* Polarity amplifier engage                         , */\
+   { 0x4cb0, "int_polarity_flag_watchdog_reset"},    /* Polarity watchdog                                 , */\
+   { 0x4cc0, "int_polarity_flag_enbl_amp"},    /* Polarity enbl amp                                 , */\
+   { 0x4cd0, "int_polarity_flag_enbl_ref"},    /* Polarity ref enable                               , */\
+   { 0x4ce0, "int_polarity_flag_adc10_ready"},    /* Polarity Control ADC                              , */\
+   { 0x4cf0, "int_polarity_flag_bod_vddd_nok"},    /* Polarity BOD                                      , */\
+   { 0x4d00, "int_polarity_flag_bst_bstcur"},    /* Polarity DCDC current limiting                    , */\
+   { 0x4d10, "int_polarity_flag_bst_hiz"},    /* Polarity DCDC active                              , */\
+   { 0x4d20, "int_polarity_flag_bst_ocpok"},    /* Polarity DCDC OCP                                 , */\
+   { 0x4d30, "int_polarity_flag_bst_peakcur"},    /* Polarity bst peakcur                              , */\
+   { 0x4d40, "int_polarity_flag_bst_voutcomp"},    /* Polarity DCDC level 1x                            , */\
+   { 0x4d50, "int_polarity_flag_bst_voutcomp86"},    /* Polarity DCDC level 1.14x                         , */\
+   { 0x4d60, "int_polarity_flag_bst_voutcomp93"},    /* Polarity DCDC level 1.07x                         , */\
+   { 0x4d70, "int_polarity_flag_rcvldop_ready"},    /* Polarity rcvldop ready                            , */\
+   { 0x4d80, "int_polarity_flag_ocp_alarm_left"},    /* Polarity ocp alarm left                           , */\
+   { 0x4d90, "int_polarity_flag_ocp_alarm_right"},    /* Polarity ocp alarm right                          , */\
+   { 0x4da0, "int_polarity_flag_man_wait_src_settings"},    /* Polarity waits HW I2C settings                    , */\
+   { 0x4db0, "int_polarity_flag_man_wait_cf_config"},    /* Polarity man wait cf config                       , */\
+   { 0x4dc0, "int_polarity_flag_man_start_mute_audio"},    /* Polarity man audio mute sequence                  , */\
+   { 0x4dd0, "int_polarity_flag_cfma_err"},    /* Polarity cfma err                                 , */\
+   { 0x4de0, "int_polarity_flag_cfma_ack"},    /* Polarity cfma ack                                 , */\
+   { 0x4df0, "int_polarity_flag_clk_out_of_range"},    /* Polarity flag_clk_out_of_range                    , */\
+   { 0x4e00, "int_polarity_flag_tdm_error"},    /* Polarity tdm error                                , */\
+   { 0x4e10, "int_polarity_flag_clip_left"},    /* Polarity clip left                                , */\
+   { 0x4e20, "int_polarity_flag_clip_right"},    /* Polarity clip right                               , */\
+   { 0x4e30, "int_polarity_flag_mic_ocpok"},    /* Polarity mic ocpok                                , */\
+   { 0x5001, "vbat_prot_attack_time"},    /* Battery protection attack Time                    , */\
+   { 0x5023, "vbat_prot_thlevel"},    /* Battery protection threshold voltage level        , */\
+   { 0x5061, "vbat_prot_max_reduct"},    /* Battery protection maximum reduction              , */\
+   { 0x5082, "vbat_prot_release_time"},    /* Battery protection release time                   , */\
+   { 0x50b1, "vbat_prot_hysterese"},    /* Battery protection hysteresis                     , */\
+   { 0x50d0, "rst_min_vbat"},    /* Reset clipper - Auto clear                        , */\
+   { 0x50e0, "sel_vbat"},    /* Battery voltage read out                          , */\
+   { 0x50f0, "bypass_clipper"},    /* Bypass HW clipper                                 , */\
+   { 0x5100, "batsense_steepness"},    /* Vbat prot steepness                               , */\
+   { 0x5110, "soft_mute"},    /* Soft mute HW                                      , */\
+   { 0x5120, "cf_mute_left"},    /* Soft mute FW left                                 , */\
+   { 0x5130, "cf_mute_right"},    /* Soft mute FW right                                , */\
+   { 0x5140, "bypass_hp_left"},    /* Bypass HPF left                                   , */\
+   { 0x5150, "bypass_hp_right"},    /* Bypass HPF right                                  , */\
+   { 0x5160, "enbl_dpsa_left"},    /* Enable DPSA left                                  , */\
+   { 0x5170, "enbl_dpsa_right"},    /* Enable DPSA right                                 , */\
+   { 0x5187, "cf_volume"},    /* FW volume control for primary audio channel       , */\
+   { 0x5200, "ctrl_rcv"},    /* Selection receiver                                , */\
+   { 0x5210, "ctrl_rcv_fb_100k"},    /* Selection of feedback resistor for receiver mode (not for customer), */\
+   { 0x5222, "ctrl_cc"},    /* Clip control setting                              , */\
+   { 0x5257, "gain"},    /* Amplifier gain                                    , */\
+   { 0x52d0, "ctrl_slopectrl"},    /* Enables slope control                             , */\
+   { 0x52e1, "ctrl_slope"},    /* Set slope                                         , */\
+   { 0x5301, "dpsa_level"},    /* DPSA threshold levels                             , */\
+   { 0x5321, "dpsa_release"},    /* DPSA Release time                                 , */\
+   { 0x5340, "clipfast"},    /* Clock selection for HW clipper for battery protection, */\
+   { 0x5350, "bypass_lp"},    /* Bypass the low power filter inside temperature sensor, */\
+   { 0x5360, "enbl_low_latency"},    /* CF low latency outputs for add module             , */\
+   { 0x5400, "first_order_mode"},    /* Overrule to 1st order mode of control stage when clipping, */\
+   { 0x5410, "bypass_ctrlloop"},    /* Switch amplifier into open loop configuration     , */\
+   { 0x5420, "fb_hz"},    /* Feedback resistor set to high ohmic               , */\
+   { 0x5430, "icomp_engage"},    /* Engage of icomp                                   , */\
+   { 0x5440, "ctrl_kickback"},    /* Prevent double pulses of output stage             , */\
+   { 0x5450, "icomp_engage_overrule"},    /* To overrule the functional icomp_engage signal during validation, */\
+   { 0x5503, "ctrl_dem"},    /* Enable DEM icomp and DEM one bit dac              , */\
+   { 0x5543, "ctrl_dem_mismatch"},    /* Enable DEM icomp mismatch for testing             , */\
+   { 0x5581, "dpsa_drive"},    /* Control of the number of power stage sections, total of 4 sections. Each section is 1/4 of the total power stages., */\
+   { 0x560a, "enbl_amp_left"},    /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually - Left channel, */\
+   { 0x56b0, "enbl_engage_left"},    /* Enables/engage power stage and control loop - left channel, */\
+   { 0x570a, "enbl_amp_right"},    /* Switch on the class-D power sections, each part of the analog sections can be switched on/off individually - Right channel, */\
+   { 0x57b0, "enbl_engage_right"},    /* Enables/engage power stage and control loop - right channel, */\
+   { 0x5800, "hard_mute_left"},    /* Hard mute - PWM module left                       , */\
+   { 0x5810, "hard_mute_right"},    /* Hard mute - PWM module right                      , */\
+   { 0x5820, "pwm_shape"},    /* PWM shape                                         , */\
+   { 0x5830, "pwm_bitlength"},    /* PWM bit length in noise shaper                    , */\
+   { 0x5844, "pwm_delay"},    /* PWM delay bits to set the delay, clockd is 1/(k*2048*fs), */\
+   { 0x5890, "reclock_pwm"},    /* Reclock the pwm signal inside analog              , */\
+   { 0x58a0, "reclock_voltsense"},    /* Reclock the voltage sense pwm signal              , */\
+   { 0x58b0, "enbl_pwm_phase_shift_left"},    /* Control for pwm phase shift, inverted function - left channel, */\
+   { 0x58c0, "enbl_pwm_phase_shift_right"},    /* Control for pwm phase shift - right channel       , */\
+   { 0x5900, "ctrl_rcvldop_pulldown"},    /* Pulldown of LDO (2.7V)                            , */\
+   { 0x5910, "ctrl_rcvldop_test_comp"},    /* Enable testing of LDO comparator                  , */\
+   { 0x5920, "ctrl_rcvldop_test_loadedldo"},    /* Load connected to rcvldo                          , */\
+   { 0x5930, "enbl_rcvldop"},    /* Enables the LDO (2.7)                             , */\
+   { 0x5a07, "cf_volume_sec"},    /* FW volume control for secondary audio channel     , */\
+   { 0x5a87, "sw_profile"},    /* Software profile data                             , */\
+   { 0x7002, "boost_volt"},    /* Boost voltage                                     , */\
+   { 0x7033, "boost_cur"},    /* Max coil current                                  , */\
+   { 0x7071, "bst_coil_value"},    /* Coil Value                                        , */\
+   { 0x7090, "boost_intel"},    /* Adaptive boost mode                               , */\
+   { 0x70a0, "boost_speed"},    /* Soft ramp up/down                                 , */\
+   { 0x70b2, "dcdc_synchronisation"},    /* DCDC synchronization off + 7 positions            , */\
+   { 0x70e0, "dcdcoff_mode"},    /* DCDC on/off                                       , */\
+   { 0x7104, "bst_drive"},    /* Binary coded drive setting for boost converter power stage, */\
+   { 0x7151, "bst_scalecur"},    /* For testing direct control scale current          , */\
+   { 0x7174, "bst_slopecur"},    /* For testing direct control slope current          , */\
+   { 0x71c1, "bst_slope"},    /* Boost slope speed                                 , */\
+   { 0x71e0, "bst_bypass_bstcur"},    /* Bypass control for boost current settings         , */\
+   { 0x71f0, "bst_bypass_bstfoldback"},    /* Bypass control for boost foldback                 , */\
+   { 0x7200, "enbl_bst_engage"},    /* Enable power stage dcdc controller                , */\
+   { 0x7210, "enbl_bst_hizcom"},    /* Enable hiz comparator                             , */\
+   { 0x7220, "enbl_bst_peak2avg"},    /* Enable boost peak2avg functionality               , */\
+   { 0x7230, "enbl_bst_peakcur"},    /* Enable peak current                               , */\
+   { 0x7240, "enbl_bst_power"},    /* Enable line of the powerstage                     , */\
+   { 0x7250, "enbl_bst_slopecur"},    /* Enable bit of max-current dac                     , */\
+   { 0x7260, "enbl_bst_voutcomp"},    /* Enable vout comparators                           , */\
+   { 0x7270, "enbl_bst_voutcomp86"},    /* Enable vout-86 comparators                        , */\
+   { 0x7280, "enbl_bst_voutcomp93"},    /* Enable vout-93 comparators                        , */\
+   { 0x7290, "enbl_bst_windac"},    /* Enable window dac                                 , */\
+   { 0x72a5, "bst_windac"},    /* for testing direct control windac                 , */\
+   { 0x7300, "boost_alg"},    /* Control for boost adaptive loop gain              , */\
+   { 0x7311, "boost_loopgain"},    /* DCDC boost loopgain setting                       , */\
+   { 0x7332, "bst_freq"},    /* DCDC bost frequency control                       , */\
+   { 0x8001, "sel_clk_cs"},    /* Current sense clock duty cycle control            , */\
+   { 0x8021, "micadc_speed"},    /* Current sense clock for MiCADC selection - 32/44.1/48 KHz Fs band only, */\
+   { 0x8040, "cs_dc_offset"},    /* Current sense decimator offset control            , */\
+   { 0x8050, "cs_gain_control"},    /* Current sense gain control                        , */\
+   { 0x8060, "cs_bypass_gc"},    /* Bypasses the CS gain correction                   , */\
+   { 0x8087, "cs_gain"},    /* Current sense gain                                , */\
+   { 0x8110, "invertpwm_left"},    /* Current sense common mode feedback pwm invert control for left channel, */\
+   { 0x8122, "cmfb_gain_left"},    /* Current sense common mode feedback control gain for left channel, */\
+   { 0x8154, "cmfb_offset_left"},    /* Current sense common mode feedback control offset for left channel, */\
+   { 0x8200, "enbl_cmfb_right"},    /* Current sense common mode feedback control for right channel, */\
+   { 0x8210, "invertpwm_right"},    /* Current sense common mode feedback pwm invert control for right channel, */\
+   { 0x8222, "cmfb_gain_right"},    /* Current sense common mode feedback control gain for right channel, */\
+   { 0x8254, "cmfb_offset_right"},    /* Current sense common mode feedback control offset for right channel, */\
+   { 0x8305, "cs_ktemp"},    /* Current sense temperature compensation trimming (1 - VALUE*TEMP)*signal, */\
+   { 0x8400, "cs_adc_bsoinv"},    /* Bitstream inversion for current sense ADC         , */\
+   { 0x8421, "cs_adc_hifreq"},    /* Frequency mode current sense ADC                  , */\
+   { 0x8440, "cs_adc_nortz"},    /* Return to zero for current sense ADC              , */\
+   { 0x8453, "cs_adc_offset"},    /* Micadc ADC offset setting                         , */\
+   { 0x8490, "cs_adc_slowdel"},    /* Select delay for current sense ADC (internal decision circuitry), */\
+   { 0x84a4, "cs_adc_gain"},    /* Gain setting for current sense ADC (two's complement), */\
+   { 0x8500, "cs_resonator_enable"},    /* Enable for resonator to improve SRN               , */\
+   { 0x8510, "cs_classd_tran_skip"},    /* Skip current sense connection during a classD amplifier transition, */\
+   { 0x8530, "cs_inn_short"},    /* Short current sense negative to common mode       , */\
+   { 0x8540, "cs_inp_short"},    /* Short current sense positive to common mode       , */\
+   { 0x8550, "cs_ldo_bypass"},    /* Bypass current sense LDO                          , */\
+   { 0x8560, "cs_ldo_pulldown"},    /* Pull down current sense LDO, only valid if left_enbl_cs_ldo is high, */\
+   { 0x8574, "cs_ldo_voset"},    /* Current sense LDO voltage level setting (two's complement), */\
+   { 0x8600, "enbl_cs_adc_left"},    /* Enable current sense ADC                          , */\
+   { 0x8610, "enbl_cs_inn1_left"},    /* Enable connection of current sense negative1      , */\
+   { 0x8630, "enbl_cs_inp1_left"},    /* Enable connection of current sense positive1      , */\
+   { 0x8650, "enbl_cs_ldo_left"},    /* Enable current sense LDO                          , */\
+   { 0x8660, "enbl_cs_nofloating_n_left"},    /* Connect current sense negative to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */\
+   { 0x8670, "enbl_cs_nofloating_p_left"},    /* Connect current sense positive to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */\
+   { 0x8680, "enbl_cs_vbatldo_left"},    /* Enable of current sense LDO                       , */\
+   { 0x8700, "enbl_cs_adc_right"},    /* Enable current sense ADC                          , */\
+   { 0x8710, "enbl_cs_inn1_right"},    /* Enable connection of current sense negative1      , */\
+   { 0x8730, "enbl_cs_inp1_right"},    /* Enable connection of current sense positive1      , */\
+   { 0x8750, "enbl_cs_ldo_right"},    /* Enable current sense LDO                          , */\
+   { 0x8760, "enbl_cs_nofloating_n_right"},    /* Connect current sense negative to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */\
+   { 0x8770, "enbl_cs_nofloating_p_right"},    /* Connect current sense positive to gnda at transitions of booster or classd amplifiers. Otherwise floating (0), */\
+   { 0x8780, "enbl_cs_vbatldo_right"},    /* Enable of current sense LDO                       , */\
+   { 0x8800, "volsense_pwm_sel"},    /* Voltage sense PWM source selection control        , */\
+   { 0x8810, "volsense_dc_offset"},    /* Voltage sense decimator offset control            , */\
+   { 0x9000, "cf_rst_dsp"},    /* Reset                                             , */\
+   { 0x9011, "cf_dmem"},    /* Target memory                                     , */\
+   { 0x9030, "cf_aif"},    /* Auto increment                                    , */\
+   { 0x9040, "cf_int"},    /* Interrupt - auto clear                            , */\
+   { 0x9050, "cf_cgate_off"},    /* Coolflux clock gating disabling control           , */\
+   { 0x9080, "cf_req_cmd"},    /* Firmware event request rpc command                , */\
+   { 0x9090, "cf_req_reset"},    /* Firmware event request reset restart              , */\
+   { 0x90a0, "cf_req_mips"},    /* Firmware event request short on mips              , */\
+   { 0x90b0, "cf_req_mute_ready"},    /* Firmware event request mute sequence ready        , */\
+   { 0x90c0, "cf_req_volume_ready"},    /* Firmware event request volume ready               , */\
+   { 0x90d0, "cf_req_damage"},    /* Firmware event request speaker damage detected    , */\
+   { 0x90e0, "cf_req_calibrate_ready"},    /* Firmware event request calibration completed      , */\
+   { 0x90f0, "cf_req_reserved"},    /* Firmware event request reserved                   , */\
+   { 0x910f, "cf_madd"},    /* Memory address                                    , */\
+   { 0x920f, "cf_mema"},    /* Activate memory access                            , */\
+   { 0x9307, "cf_err"},    /* Error flags                                       , */\
+   { 0x9387, "cf_ack"},    /* Acknowledge of requests                           , */\
+   { 0x9380, "cf_ack_cmd"},    /* Firmware event acknowledge rpc command            , */\
+   { 0x9390, "cf_ack_reset"},    /* Firmware event acknowledge reset restart          , */\
+   { 0x93a0, "cf_ack_mips"},    /* Firmware event acknowledge short on mips          , */\
+   { 0x93b0, "cf_ack_mute_ready"},    /* Firmware event acknowledge mute sequence ready    , */\
+   { 0x93c0, "cf_ack_volume_ready"},    /* Firmware event acknowledge volume ready           , */\
+   { 0x93d0, "cf_ack_damage"},    /* Firmware event acknowledge speaker damage detected, */\
+   { 0x93e0, "cf_ack_calibrate_ready"},    /* Firmware event acknowledge calibration completed  , */\
+   { 0x93f0, "cf_ack_reserved"},    /* Firmware event acknowledge reserved               , */\
+   { 0x980f, "ivt_addr0_msb"},    /* Coolflux interrupt vector table address0 MSB      , */\
+   { 0x990f, "ivt_addr0_lsb"},    /* Coolflux interrupt vector table address0 LSB      , */\
+   { 0x9a0f, "ivt_addr1_msb"},    /* Coolflux interrupt vector table address1 MSB      , */\
+   { 0x9b0f, "ivt_addr1_lsb"},    /* Coolflux interrupt vector table address1 LSB      , */\
+   { 0x9c0f, "ivt_addr2_msb"},    /* Coolflux interrupt vector table address2 MSB      , */\
+   { 0x9d0f, "ivt_addr2_lsb"},    /* Coolflux interrupt vector table address2 LSB      , */\
+   { 0x9e0f, "ivt_addr3_msb"},    /* Coolflux interrupt vector table address3 MSB      , */\
+   { 0x9f0f, "ivt_addr3_lsb"},    /* Coolflux interrupt vector table address3 LSB      , */\
+   { 0xa007, "mtpkey1"},    /* 5Ah, 90d To access KEY1_Protected registers (Default for engineering), */\
+   { 0xa107, "mtpkey2"},    /* MTP KEY2 register                                 , */\
+   { 0xa200, "key01_locked"},    /* Indicates KEY1 is locked                          , */\
+   { 0xa210, "key02_locked"},    /* Indicates KEY2 is locked                          , */\
+   { 0xa302, "mtp_man_address_in"},    /* MTP address from I2C register for read/writing mtp in manual single word mode, */\
+   { 0xa330, "man_copy_mtp_to_iic"},    /* Start copying single word from mtp to I2C mtp register, */\
+   { 0xa340, "man_copy_iic_to_mtp"},    /* Start copying single word from I2C mtp register to mtp, */\
+   { 0xa350, "auto_copy_mtp_to_iic"},    /* Start copying all the data from mtp to I2C mtp registers, */\
+   { 0xa360, "auto_copy_iic_to_mtp"},    /* Start copying data from I2C mtp registers to mtp  , */\
+   { 0xa400, "faim_set_clkws"},    /* Sets the faim controller clock wait state register, */\
+   { 0xa410, "faim_sel_evenrows"},    /* All even rows of the faim are selected, active high, */\
+   { 0xa420, "faim_sel_oddrows"},    /* All odd rows of the faim are selected, all rows in combination with sel_evenrows, */\
+   { 0xa430, "faim_program_only"},    /* Skip the erase access at wr_faim command (write-program-marginread), */\
+   { 0xa440, "faim_erase_only"},    /* Skip the program access at wr_faim command (write-erase-marginread), */\
+   { 0xa50f, "mtp_man_data_out_msb"},    /* MSB word of MTP manual read data                  , */\
+   { 0xa60f, "mtp_man_data_out_lsb"},    /* LSB word of MTP manual read data                  , */\
+   { 0xa70f, "mtp_man_data_in_msb"},    /* MSB word of write data for MTP manual write       , */\
+   { 0xa80f, "mtp_man_data_in_lsb"},    /* LSB word of write data for MTP manual write       , */\
+   { 0xb010, "bypass_ocpcounter"},    /* Bypass OCP Counter                                , */\
+   { 0xb020, "bypass_glitchfilter"},    /* Bypass glitch filter                              , */\
+   { 0xb030, "bypass_ovp"},    /* Bypass OVP                                        , */\
+   { 0xb040, "bypass_uvp"},    /* Bypass UVP                                        , */\
+   { 0xb050, "bypass_otp"},    /* Bypass OTP                                        , */\
+   { 0xb060, "bypass_lost_clk"},    /* Bypass lost clock detector                        , */\
+   { 0xb070, "ctrl_vpalarm"},    /* vpalarm (uvp ovp handling)                        , */\
+   { 0xb087, "ocp_threshold"},    /* OCP threshold level                               , */\
+   { 0xb108, "ext_temp"},    /* External temperature (C)                          , */\
+   { 0xb190, "ext_temp_sel"},    /* Select temp Speaker calibration                   , */\
+   { 0xc000, "use_direct_ctrls"},    /* Direct control to overrule several functions for testing, */\
+   { 0xc010, "rst_datapath"},    /* Direct control for datapath reset                 , */\
+   { 0xc020, "rst_cgu"},    /* Direct control for cgu reset                      , */\
+   { 0xc038, "enbl_ref"},    /* Switch on the analog references, each part of the references can be switched on/off individually, */\
+   { 0xc0d0, "enbl_ringo"},    /* Enable the ring oscillator for test purpose       , */\
+   { 0xc0e0, "use_direct_clk_ctrl"},    /* Direct clock control to overrule several functions for testing, */\
+   { 0xc0f0, "use_direct_pll_ctrl"},    /* Direct PLL control to overrule several functions for testing, */\
+   { 0xc100, "enbl_tsense"},    /* Temperature sensor enable control - I2C direct mode, */\
+   { 0xc110, "tsense_hibias"},    /* Bit to set the biasing in temp sensor to high     , */\
+   { 0xc120, "enbl_flag_vbg"},    /* Enable flagging of bandgap out of control         , */\
+   { 0xc20f, "abist_offset"},    /* Offset control for ABIST testing (two's complement), */\
+   { 0xc300, "bypasslatch"},    /* Bypass latch                                      , */\
+   { 0xc311, "sourcea"},    /* Set OUTA to                                       , */\
+   { 0xc331, "sourceb"},    /* Set OUTB to                                       , */\
+   { 0xc350, "inverta"},    /* Invert pwma test signal                           , */\
+   { 0xc360, "invertb"},    /* Invert pwmb test signal                           , */\
+   { 0xc374, "pulselength"},    /* Pulse length setting test input for amplifier (clock d - k*2048*fs), */\
+   { 0xc3c0, "tdm_enable_loopback"},    /* TDM loopback test                                 , */\
+   { 0xc3d0, "test_abistfft_enbl"},    /* FFT Coolflux                                      , */\
+   { 0xc3e0, "test_pwr_switch"},    /* Test mode for digital power switches  core sw/mem sw/micvdd sw, */\
+   { 0xc400, "bst_bypasslatch"},    /* Bypass latch in boost converter                   , */\
+   { 0xc411, "bst_source"},    /* Sets the source of the pwmbst output to boost converter input for testing, */\
+   { 0xc430, "bst_invertb"},    /* Invert pwmbst test signal                         , */\
+   { 0xc444, "bst_pulselength"},    /* Pulse length setting test input for boost converter , */\
+   { 0xc490, "test_bst_ctrlsthv"},    /* Test mode for boost control stage                 , */\
+   { 0xc4a0, "test_bst_iddq"},    /* IDDQ testing in power stage of boost converter    , */\
+   { 0xc4b0, "test_bst_rdson"},    /* RDSON testing - boost power stage                 , */\
+   { 0xc4c0, "test_bst_cvi"},    /* CVI testing - boost power stage                   , */\
+   { 0xc4d0, "test_bst_ocp"},    /* Boost OCP. For old ocp (ctrl_reversebst is 0), For new ocp (ctrl_reversebst is 1), */\
+   { 0xc4e0, "test_bst_sense"},    /* Test option for the sense NMOS in booster for current mode control., */\
+   { 0xc500, "test_cvi"},    /* Analog BIST, switch choose which transistor will be used as current source (also cross coupled sources possible), */\
+   { 0xc510, "test_discrete"},    /* Test function noise measurement                   , */\
+   { 0xc520, "test_iddq"},    /* Set the power stages in iddq mode for gate stress., */\
+   { 0xc540, "test_rdson"},    /* Analog BIST, switch to enable Rdson measurement   , */\
+   { 0xc550, "test_sdelta"},    /* Analog BIST, noise test                           , */\
+   { 0xc570, "test_enbl_cs"},    /* Enable for digimux mode of current sense          , */\
+   { 0xc600, "enbl_pwm_dcc"},    /* Enables direct control of pwm duty cycle for DCDC power stage, */\
+   { 0xc613, "pwm_dcc_cnt"},    /* Control pwm duty cycle when enbl_pwm_dcc is 1     , */\
+   { 0xc650, "enbl_ldo_stress"},    /* Enable stress of internal supply voltages powerstages, */\
+   { 0xc660, "bypass_diosw_ovp"},    /* Bypass ovp for memory switch diosw                , */\
+   { 0xc670, "enbl_powerswitch"},    /* Vddd core power switch control - overrules the manager control, */\
+   { 0xc707, "digimuxa_sel"},    /* DigimuxA input selection control routed to GPIO1 (see Digimux list for details), */\
+   { 0xc787, "digimuxb_sel"},    /* DigimuxB input selection control routed to GPIO2 (see Digimux list for details), */\
+   { 0xc807, "digimuxc_sel"},    /* DigimuxC input selection control routed to GPIO3 (see Digimux list for details), */\
+   { 0xc887, "digimuxd_sel"},    /* DigimuxD input selection control routed to GPIO4 (see Digimux list for details), */\
+   { 0xc901, "dio1_ehs"},    /* Speed/load setting for DIO1 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */\
+   { 0xc921, "dio2_ehs"},    /* Speed/load setting for DIO2 IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */\
+   { 0xc941, "gainio_ehs"},    /* Speed/load setting for GAINIO cell, clk or data mode range (see SLIMMF IO cell datasheet), */\
+   { 0xc961, "pdmo_ehs"},    /* Speed/load setting for PDMO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */\
+   { 0xc981, "int_ehs"},    /* Speed/load setting for INT IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */\
+   { 0xc9a1, "tdo_ehs"},    /* Speed/load setting for TDO IO cell, clk or data mode range (see SLIMMF IO cell datasheet), */\
+   { 0xc9c0, "hs_mode"},    /* I2C high speed mode control                       , */\
+   { 0xca00, "enbl_anamux1"},    /* Enable anamux1                                    , */\
+   { 0xca10, "enbl_anamux2"},    /* Enable anamux2                                    , */\
+   { 0xca20, "enbl_anamux3"},    /* Enable anamux3                                    , */\
+   { 0xca30, "enbl_anamux4"},    /* Enable anamux4                                    , */\
+   { 0xca40, "enbl_anamux5"},    /* Enable anamux5                                    , */\
+   { 0xca50, "enbl_anamux6"},    /* Enable anamux6                                    , */\
+   { 0xca60, "enbl_anamux7"},    /* Enable anamux7                                    , */\
+   { 0xca74, "anamux1"},    /* Anamux selection control - anamux on TEST1        , */\
+   { 0xcb04, "anamux2"},    /* Anamux selection control - anamux on TEST2        , */\
+   { 0xcb54, "anamux3"},    /* Anamux selection control - anamux on TEST3        , */\
+   { 0xcba4, "anamux4"},    /* Anamux selection control - anamux on TEST4        , */\
+   { 0xcc04, "anamux5"},    /* Anamux selection control - anamux on TEST5        , */\
+   { 0xcc54, "anamux6"},    /* Anamux selection control - anamux on TEST6        , */\
+   { 0xcca4, "anamux7"},    /* Anamux selection control - anamux on TEST7        , */\
+   { 0xcd05, "pll_seli"},    /* PLL SELI - I2C direct PLL control mode only       , */\
+   { 0xcd64, "pll_selp"},    /* PLL SELP - I2C direct PLL control mode only       , */\
+   { 0xcdb3, "pll_selr"},    /* PLL SELR - I2C direct PLL control mode only       , */\
+   { 0xcdf0, "pll_frm"},    /* PLL free running mode control; 1 in TCB direct control mode, else this control bit, */\
+   { 0xce09, "pll_ndec"},    /* PLL NDEC - I2C direct PLL control mode only       , */\
+   { 0xcea0, "pll_mdec_msb"},    /* MSB of pll_mdec - I2C direct PLL control mode only, */\
+   { 0xceb0, "enbl_pll"},    /* Enables PLL in I2C direct PLL control mode only   , */\
+   { 0xcec0, "enbl_osc"},    /* Enables OSC1M in I2C direct control mode only     , */\
+   { 0xced0, "pll_bypass"},    /* PLL bypass control in I2C direct PLL control mode only, */\
+   { 0xcee0, "pll_directi"},    /* PLL directi control in I2C direct PLL control mode only, */\
+   { 0xcef0, "pll_directo"},    /* PLL directo control in I2C direct PLL control mode only, */\
+   { 0xcf0f, "pll_mdec_lsb"},    /* Bits 15..0 of PLL MDEC are I2C direct PLL control mode only, */\
+   { 0xd006, "pll_pdec"},    /* PLL PDEC - I2C direct PLL control mode only       , */\
+   { 0xd10f, "tsig_freq_lsb"},    /* Internal sinus test generator frequency control   , */\
+   { 0xd202, "tsig_freq_msb"},    /* Select internal sinus test generator, frequency control msb bits, */\
+   { 0xd230, "inject_tsig"},    /* Control bit to switch to internal sinus test generator, */\
+   { 0xd243, "tsig_gain_left"},    /* Test signal gain for left channel                 , */\
+   { 0xd283, "tsig_gain_right"},    /* Test signal gain for right channel                , */\
+   { 0xd300, "adc10_reset"},    /* Reset for ADC10 - I2C direct control mode         , */\
+   { 0xd311, "adc10_test"},    /* Test mode selection signal for ADC10 - I2C direct control mode, */\
+   { 0xd332, "adc10_sel"},    /* Select the input to convert for ADC10 - I2C direct control mode, */\
+   { 0xd364, "adc10_prog_sample"},    /* ADC10 program sample setting - I2C direct control mode, */\
+   { 0xd3b0, "adc10_enbl"},    /* Enable ADC10 - I2C direct control mode            , */\
+   { 0xd3c0, "bypass_lp_vbat"},    /* Bypass control for Low pass filter in batt sensor , */\
+   { 0xd409, "data_adc10_tempbat"},    /* ADC 10 data output data for testing               , */\
+   { 0xd506, "ctrl_digtoana_hidden"},    /* Spare digital to analog control bits - Hidden     , */\
+   { 0xd570, "enbl_clk_out_of_range"},    /* Clock out of range                                , */\
+   { 0xf000, "calibration_onetime"},    /* Calibration schedule                              , */\
+   { 0xf010, "calibr_ron_done"},    /* Calibration Ron executed                          , */\
+   { 0xf020, "calibr_dcdc_api_calibrate"},    /* Calibration current limit DCDC                    , */\
+   { 0xf030, "calibr_dcdc_delta_sign"},    /* Sign bit for delta calibration current limit DCDC , */\
+   { 0xf042, "calibr_dcdc_delta"},    /* Calibration delta current limit DCDC              , */\
+   { 0xf078, "calibr_speaker_info"},    /* Reserved space for allowing customer to store speaker information, */\
+   { 0xf105, "calibr_vout_offset"},    /* DCDC offset calibration 2's complement (key1 protected), */\
+   { 0xf163, "calibr_gain_left"},    /* HW gain module - left channel (2's complement)    , */\
+   { 0xf1a5, "calibr_offset_left"},    /* Offset for amplifier, HW gain module - left channel (2's complement), */\
+   { 0xf203, "calibr_gain_right"},    /* HW gain module - right channel (2's complement)   , */\
+   { 0xf245, "calibr_offset_right"},    /* Offset for amplifier, HW gain module - right channel (2's complement), */\
+   { 0xf2a3, "calibr_rcvldop_trim"},    /* Trimming of LDO (2.7V)                            , */\
+   { 0xf307, "calibr_gain_cs_left"},    /* Current sense gain - left channel (signed two's complement format), */\
+   { 0xf387, "calibr_gain_cs_right"},    /* Current sense gain - right channel (signed two's complement format), */\
+   { 0xf40f, "calibr_R25C_L"},    /* Ron resistance of left channel speaker coil       , */\
+   { 0xf50f, "calibr_R25C_R"},    /* Ron resistance of right channel speaker coil      , */\
+   { 0xf606, "ctrl_offset_a_left"},    /* Offset of left amplifier level shifter A          , */\
+   { 0xf686, "ctrl_offset_b_left"},    /* Offset of left amplifier level shifter B          , */\
+   { 0xf706, "ctrl_offset_a_right"},    /* Offset of right amplifier level shifter A         , */\
+   { 0xf786, "ctrl_offset_b_right"},    /* Offset of right amplifier level shifter B         , */\
+   { 0xf806, "htol_iic_addr"},    /* 7-bit I2C address to be used during HTOL testing  , */\
+   { 0xf870, "htol_iic_addr_en"},    /* HTOL I2C address enable control                   , */\
+   { 0xf884, "calibr_temp_offset"},    /* Temperature offset 2's compliment (key1 protected), */\
+   { 0xf8d2, "calibr_temp_gain"},    /* Temperature gain 2's compliment (key1 protected)  , */\
+   { 0xf900, "mtp_lock_dcdcoff_mode"},    /* Disable function dcdcoff_mode                     , */\
+   { 0xf910, "mtp_lock_enbl_coolflux"},    /* Disable function enbl_coolflux                    , */\
+   { 0xf920, "mtp_lock_bypass_clipper"},    /* Disable function bypass_clipper                   , */\
+   { 0xf930, "mtp_lock_max_dcdc_voltage"},    /* Disable programming of max dcdc boost voltage     , */\
+   { 0xf943, "calibr_vbg_trim"},    /* Bandgap trimming control                          , */\
+   { 0xf987, "type_bits_fw"},    /* MTP-control FW - See Firmware I2C API document for details, */\
+   { 0xfa0f, "mtpdataA"},    /* MTPdataA (key1 protected)                         , */\
+   { 0xfb0f, "mtpdataB"},    /* MTPdataB (key1 protected)                         , */\
+   { 0xfc0f, "mtpdataC"},    /* MTPdataC (key1 protected)                         , */\
+   { 0xfd0f, "mtpdataD"},    /* MTPdataD (key1 protected)                         , */\
+   { 0xfe0f, "mtpdataE"},    /* MTPdataE (key1 protected)                         , */\
+   { 0xff05, "calibr_osc_delta_ndiv"},    /* Calibration data for OSC1M, signed number representation, */\
+   { 0xffff,"Unknown bitfield enum" }    /* not found */\
+};
+
+enum tfa2_irq {
+	tfa2_irq_stvdds = 0,
+	tfa2_irq_stplls = 1,
+	tfa2_irq_stotds = 2,
+	tfa2_irq_stovds = 3,
+	tfa2_irq_stuvds = 4,
+	tfa2_irq_stclks = 5,
+	tfa2_irq_stmtpb = 6,
+	tfa2_irq_stnoclk = 7,
+	tfa2_irq_stspks = 8,
+	tfa2_irq_stacs = 9,
+	tfa2_irq_stsws = 10,
+	tfa2_irq_stwds = 11,
+	tfa2_irq_stamps = 12,
+	tfa2_irq_starefs = 13,
+	tfa2_irq_stadccr = 14,
+	tfa2_irq_stbodnok = 15,
+	tfa2_irq_stbstcu = 16,
+	tfa2_irq_stbsthi = 17,
+	tfa2_irq_stbstoc = 18,
+	tfa2_irq_stbstpkcur = 19,
+	tfa2_irq_stbstvc = 20,
+	tfa2_irq_stbst86 = 21,
+	tfa2_irq_stbst93 = 22,
+	tfa2_irq_strcvld = 23,
+	tfa2_irq_stocpl = 24,
+	tfa2_irq_stocpr = 25,
+	tfa2_irq_stmwsrc = 26,
+	tfa2_irq_stmwcfc = 27,
+	tfa2_irq_stmwsmu = 28,
+	tfa2_irq_stcfmer = 29,
+	tfa2_irq_stcfmac = 30,
+	tfa2_irq_stclkoor = 31,
+	tfa2_irq_sttdmer = 32,
+	tfa2_irq_stclpl = 33,
+	tfa2_irq_stclpr = 34,
+	tfa2_irq_stocpm = 35,
+	tfa2_irq_max = 36,
+	tfa2_irq_all = -1 /* all irqs */};
+
+#define TFA2_IRQ_NAMETABLE static tfaIrqName_t Tfa2IrqNames[]= {\
+	{ 0, "STVDDS"},\
+	{ 1, "STPLLS"},\
+	{ 2, "STOTDS"},\
+	{ 3, "STOVDS"},\
+	{ 4, "STUVDS"},\
+	{ 5, "STCLKS"},\
+	{ 6, "STMTPB"},\
+	{ 7, "STNOCLK"},\
+	{ 8, "STSPKS"},\
+	{ 9, "STACS"},\
+	{ 10, "STSWS"},\
+	{ 11, "STWDS"},\
+	{ 12, "STAMPS"},\
+	{ 13, "STAREFS"},\
+	{ 14, "STADCCR"},\
+	{ 15, "STBODNOK"},\
+	{ 16, "STBSTCU"},\
+	{ 17, "STBSTHI"},\
+	{ 18, "STBSTOC"},\
+	{ 19, "STBSTPKCUR"},\
+	{ 20, "STBSTVC"},\
+	{ 21, "STBST86"},\
+	{ 22, "STBST93"},\
+	{ 23, "STRCVLD"},\
+	{ 24, "STOCPL"},\
+	{ 25, "STOCPR"},\
+	{ 26, "STMWSRC"},\
+	{ 27, "STMWCFC"},\
+	{ 28, "STMWSMU"},\
+	{ 29, "STCFMER"},\
+	{ 30, "STCFMAC"},\
+	{ 31, "STCLKOOR"},\
+	{ 32, "STTDMER"},\
+	{ 33, "STCLPL"},\
+	{ 34, "STCLPR"},\
+	{ 35, "STOCPM"},\
+	{ 36, "36"},\
+};
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9887B_init.c b/techpack/audio/asoc/codecs/tfa98xx/tfa9887B_init.c
new file mode 100644
index 0000000..52b03bc
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9887B_init.c
@@ -0,0 +1,76 @@
+/*
+ *Copyright 2014,2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *            
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *             
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+ 
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "tfa_internal.h"
+
+#include "tfa98xx_tfafieldnames.h"
+
+#ifdef TFA98XX_FULL
+/** clockless way to determine if this is the tfa9887
+ *  by testing if the PVP bit is writable 
+ */
+int tfa9887B_is87(Tfa98xx_handle_t handle)
+{
+        unsigned short save_value, check_value;
+		
+	tfa98xx_read_register16(handle, 0x08, &save_value);
+	if ( (save_value&0x0400) == 0 ) // if clear it's 87
+		return 1;	
+	/* try to clear pvp bit */
+	tfa98xx_write_register16(handle, 0x08, (save_value & ~0x0400));
+	tfa98xx_read_register16(handle, 0x08, &check_value);
+	/* restore */
+        tfa98xx_write_register16(handle, 0x08, save_value);
+	/* could we write the bit */
+	return (check_value!=save_value) ? 1 : 0; // if changed it's the 87
+}
+#endif
+
+static enum Tfa98xx_Error tfa9887B_specific(Tfa98xx_handle_t handle)
+{
+        enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+        int result;
+
+        if (!tfa98xx_handle_is_open(handle))
+                return Tfa98xx_Error_NotOpen;
+
+        /* all i2C registers are already set to default */
+
+        result = TFA_SET_BF(handle, AMPE, 1);
+        if (result < 0)
+        	return -result;
+
+        /* some other registers must be set for optimal amplifier behaviour */
+	tfa98xx_write_register16(handle, 0x05, 0x13AB);
+	tfa98xx_write_register16(handle, 0x06, 0x001F);
+	/* peak voltage protection is always on, but may be written */
+	tfa98xx_write_register16(handle, 0x08, 0x3C4E);
+	/*TFA98XX_SYSCTRL_DCA=0*/
+	tfa98xx_write_register16(handle, 0x09, 0x024D);
+	tfa98xx_write_register16(handle, 0x41, 0x0308);
+        error = tfa98xx_write_register16(handle, 0x49, 0x0E82);
+
+        return error;
+}
+
+/*
+ * register device specifics functions
+ */
+void tfa9887B_ops(struct tfa_device_ops *ops) {
+	ops->tfa_init=tfa9887B_specific;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9887_init.c b/techpack/audio/asoc/codecs/tfa98xx/tfa9887_init.c
new file mode 100644
index 0000000..e899ca8
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9887_init.c
@@ -0,0 +1,55 @@
+/*
+ *Copyright 2014,215 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *            
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *             
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+ 
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "tfa_internal.h"
+
+#include "tfa98xx_tfafieldnames.h"
+
+static enum Tfa98xx_Error tfa9887_specific(Tfa98xx_handle_t handle)
+{
+        enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+        int result;
+
+        if (!tfa98xx_handle_is_open(handle))
+                return Tfa98xx_Error_NotOpen;
+
+        /* all i2C registers are already set to default */
+
+        result = TFA_SET_BF(handle, AMPE, 1);
+        if (result < 0)
+        	return -result;
+
+        /* some other registers must be set for optimal amplifier behaviour */
+        tfa98xx_write_register16(handle, 0x05, 0x13AB);
+        tfa98xx_write_register16(handle, 0x06, 0x001F);
+        tfa98xx_write_register16(handle, 0x08, 0x3C4E);
+        /*TFA98XX_SYSCTRL_DCA=0*/
+        tfa98xx_write_register16(handle, 0x09, 0x024D);
+        tfa98xx_write_register16(handle, 0x0A, 0x3EC3);
+        tfa98xx_write_register16(handle, 0x41, 0x0308);
+        error = tfa98xx_write_register16(handle, 0x49, 0x0E82);
+
+        return error;
+}
+
+/*
+ * register device specifics functions
+ */
+void tfa9887_ops(struct tfa_device_ops *ops) {
+	ops->tfa_init=tfa9887_specific;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9887_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/tfa9887_tfafieldnames.h
new file mode 100644
index 0000000..912e331
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9887_tfafieldnames.h
@@ -0,0 +1,60 @@
+/** Filename: Tfa9887_TfaFieldnames.h
+ *  This file was generated automatically on 04/14/15 at 10:23:40. 
+ *  Source file: TFA9897N1B_I2C_list_URT_source_v34_87Only.xls
+ */
+
+#define TFA9887_NAMETABLE static tfaBfName_t Tfa9887DatasheetNames[]= {\
+   { 0x402, "I2SF"},    /* I2SFormat data 1 input:                           , */\
+   { 0x431, "CHS12"},    /* ChannelSelection data1 input  (In CoolFlux)       , */\
+   { 0x450, "CHS3"},    /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */\
+   { 0x461, "CHSA"},    /* Input selection for amplifier                     , */\
+   { 0x4b0, "I2SDOE"},    /* Enable data output                                , */\
+   { 0x4c3, "I2SSR"},    /* sample rate setting                               , */\
+   { 0x500, "BSSBY"},    /*                                                   , */\
+   { 0x511, "BSSCR"},    /* 00 = 0.56 dB/Sample                               , */\
+   { 0x532, "BSST"},    /* 000 = 2.92V                                       , */\
+   { 0x5f0, "I2SDOC"},    /* selection data out                                , */\
+   { 0xa02, "DOLS"},    /* Output selection dataout left channel             , */\
+   { 0xa32, "DORS"},    /* Output selection dataout right channel            , */\
+   { 0xa62, "SPKL"},    /* Selection speaker induction                       , */\
+   { 0xa91, "SPKR"},    /* Selection speaker impedance                       , */\
+   { 0xab3, "DCFG"},    /* DCDC speaker current compensation gain            , */\
+   { 0x4134, "PWMDEL"},    /* PWM DelayBits to set the delay                    , */\
+   { 0x4180, "PWMSH"},    /* PWM Shape                                         , */\
+   { 0x4190, "PWMRE"},    /* PWM Bitlength in noise shaper                     , */\
+   { 0x48e1, "TCC"},    /* sample & hold track time:                         , */\
+   { 0xffff,"Unknown bitfield enum" }   /* not found */\
+};
+
+#define TFA9887_BITNAMETABLE static tfaBfName_t Tfa9887BitNames[]= {\
+   { 0x402, "i2s_seti"},    /* I2SFormat data 1 input:                           , */\
+   { 0x431, "chan_sel1"},    /* ChannelSelection data1 input  (In CoolFlux)       , */\
+   { 0x450, "lr_sw_i2si2"},    /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */\
+   { 0x461, "input_sel"},    /* Input selection for amplifier                     , */\
+   { 0x4b0, "enbl_datao"},    /* Enable data output                                , */\
+   { 0x4c3, "i2s_fs"},    /* sample rate setting                               , */\
+   { 0x500, "bypass_clipper"},    /*                                                   , */\
+   { 0x511, "vbat_prot_attacktime[1:0]"},    /* 00 = 0.56 dB/Sample                               , */\
+   { 0x532, "vbat_prot_thlevel[2:0]"},    /* 000 = 2.92V                                       , */\
+   { 0x5d0, "reset_min_vbat"},    /* to reset the clipper via I2C in case the CF is bypassed, */\
+   { 0x5f0, "datao_sel"},    /* selection data out                                , */\
+   { 0xa02, "sel_i2so_l"},    /* Output selection dataout left channel             , */\
+   { 0xa32, "sel_i2so_r"},    /* Output selection dataout right channel            , */\
+   { 0xa62, "ctrl_spkr_coil"},    /* Selection speaker induction                       , */\
+   { 0xa91, "ctrl_spr_res"},    /* Selection speaker impedance                       , */\
+   { 0xab3, "ctrl_dcdc_spkr_i_comp_gain"},    /* DCDC speaker current compensation gain            , */\
+   { 0xaf0, "ctrl_dcdc_spkr_i_comp_sign"},    /* DCDC speaker current compensation sign            , */\
+   { 0x4100, "bypass_hp"},    /* bypass_hp, to bypass the hp filter byhind the CoolFlux, */\
+   { 0x4110, "hard_mute"},    /* hard mute setting in HW                           , */\
+   { 0x4120, "soft_mute"},    /* Soft mute setting in HW                           , */\
+   { 0x4134, "PWM_Delay[4:0]"},    /* PWM DelayBits to set the delay                    , */\
+   { 0x4180, "PWM_Shape"},    /* PWM Shape                                         , */\
+   { 0x4190, "PWM_BitLength"},    /* PWM Bitlength in noise shaper                     , */\
+   { 0x4800, "ctrl_negin"},    /*                                                   , */\
+   { 0x4810, "ctrl_cs_sein"},    /*                                                   , */\
+   { 0x4820, "ctrl_coincidencecs"},    /* HIGH => Prevent dcdc switching during clk_cs_clksh, */\
+   { 0x4876, "delay_se_neg[6:0]"},    /* delayshiftse2                                     , */\
+   { 0x48e1, "ctrl_cs_ttrack[1:0]"},    /* sample & hold track time:                         , */\
+   { 0xffff,"Unknown bitfield enum" }    /* not found */\
+};
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9888_init.c b/techpack/audio/asoc/codecs/tfa98xx/tfa9888_init.c
new file mode 100644
index 0000000..68f9e07
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9888_init.c
@@ -0,0 +1,177 @@
+/*
+ * initTfa9888.c
+ *
+ *  Created on: Jun 26, 2014
+ *      Author: wim
+ */
+
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "tfa_internal.h"
+
+#include "tfa98xx_tfafieldnames.h"
+
+
+static enum Tfa98xx_Error tfa9888_specific(Tfa98xx_handle_t handle) {
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned short value, xor;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	if ((handles_local[handle].rev & 0xff) != 0x88) {
+		pr_err("This code is not for this device type: %x\n", handles_local[handle].rev);
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	/* Unlock keys to write settings */
+	error = tfa98xx_write_register16(handle, 0x0F, 0x5A6B);
+	error = tfa98xx_read_register16(handle, 0xFB, &value);
+	xor = value ^ 0x005A;
+	error = tfa98xx_write_register16(handle, 0xA0, xor);
+
+	/* The optimal settings are different for 1c, 2c, 3b and 2b/1b */
+	if (handles_local[handle].rev == 0x2c88) {	
+		/* ----- generated code start ----- */
+		/* --------- Version v1 ---------- */
+		tfa98xx_write_register16(handle, 0x00, 0x164d); //POR=0x064d
+		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
+		tfa98xx_write_register16(handle, 0x02, 0x1dc8); //POR=0x1828
+		tfa98xx_write_register16(handle, 0x0e, 0x0080); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
+		tfa98xx_write_register16(handle, 0x22, 0x543c); //POR=0x545c
+		tfa98xx_write_register16(handle, 0x23, 0x0006); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
+		tfa98xx_write_register16(handle, 0x52, 0xfafe); //POR=0xbaf6
+		tfa98xx_write_register16(handle, 0x70, 0x3ee4); //POR=0x3ee6
+		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
+		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
+		/* ----- generated code end   ----- */
+	} else if (handles_local[handle].rev == 0x1c88) {
+		/* ----- generated code start ----- */
+		/* --------- Version v6 ---------- */
+		tfa98xx_write_register16(handle, 0x00, 0x164d); //POR=0x064d
+		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
+		tfa98xx_write_register16(handle, 0x02, 0x1dc8); //POR=0x1828
+		tfa98xx_write_register16(handle, 0x0e, 0x0080); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
+		tfa98xx_write_register16(handle, 0x22, 0x543c); //POR=0x545c
+		tfa98xx_write_register16(handle, 0x23, 0x0006); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
+		tfa98xx_write_register16(handle, 0x52, 0xfafe); //POR=0xbaf6
+		tfa98xx_write_register16(handle, 0x70, 0x3ee4); //POR=0x3ee6
+		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
+		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
+		/* ----- generated code end   ----- */
+	} else if (handles_local[handle].rev == 0x3b88) {
+		/* ----- generated code start ----- */
+		/* --------- Version v20 ---------- */
+		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
+		tfa98xx_write_register16(handle, 0x02, 0x1dc8); //POR=0x1828
+		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
+		tfa98xx_write_register16(handle, 0x22, 0x543c); //POR=0x545c
+		tfa98xx_write_register16(handle, 0x23, 0x0c06); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
+		tfa98xx_write_register16(handle, 0x52, 0xfafe); //POR=0xbaf6
+		tfa98xx_write_register16(handle, 0x58, 0x1e1c); //POR=0x161c
+		tfa98xx_write_register16(handle, 0x70, 0x3ee4); //POR=0x3ee6
+		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
+		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
+		/* ----- generated code end   ----- */
+	} else {
+		/* If not 1c or 3b assume older version */
+		/* ----- generated code start ----- */
+		/* --------- Version v19 ---------- */
+		tfa98xx_write_register16(handle, 0x00, 0x1e5d); //POR=0x064d
+		tfa98xx_write_register16(handle, 0x01, 0x828b); //POR=0x92cb
+		tfa98xx_write_register16(handle, 0x20, 0x089e); //POR=0x0890
+		tfa98xx_write_register16(handle, 0x23, 0x0c06); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x24, 0x0014); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x25, 0x000a); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x26, 0x0100); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x28, 0x1000); //POR=0x0000
+		tfa98xx_write_register16(handle, 0x51, 0x0000); //POR=0x00c0
+		tfa98xx_write_register16(handle, 0x52, 0x9ae2); //POR=0xbaf6
+		tfa98xx_write_register16(handle, 0x58, 0x1e1c); //POR=0x161c
+		tfa98xx_write_register16(handle, 0x70, 0x3ce6); //POR=0x3ee6
+		tfa98xx_write_register16(handle, 0x71, 0x1074); //POR=0x3074
+		tfa98xx_write_register16(handle, 0x83, 0x0014); //POR=0x0013
+		/* ----- generated code end   ----- */
+	}
+
+	return error;
+}
+
+static enum Tfa98xx_Error tfa9888_tfa_dsp_write_tables(Tfa98xx_handle_t handle, int sample_rate) 
+{
+	unsigned char buffer[15] = {0};
+	int size = 15 * sizeof(char);
+
+	/* Write the fractional delay in the hardware register 'cs_frac_delay' */
+	switch(sample_rate) {
+		case 0:	/* 8kHz */
+			TFA_SET_BF(handle, FRACTDEL, 40);
+			break;
+		case 1:	/* 11.025KHz */
+			TFA_SET_BF(handle, FRACTDEL, 38);
+			break;
+		case 2:	/* 12kHz */
+			TFA_SET_BF(handle, FRACTDEL, 37);
+			break;
+		case 3:	/* 16kHz */
+			TFA_SET_BF(handle, FRACTDEL, 59);
+			break;
+		case 4:	/* 22.05KHz */
+			TFA_SET_BF(handle, FRACTDEL, 56);
+			break;
+		case 5:	/* 24kHz */
+			TFA_SET_BF(handle, FRACTDEL, 56);
+			break;
+		case 6:	/* 32kHz */
+			TFA_SET_BF(handle, FRACTDEL, 52);
+			break;
+		case 7:	/* 44.1kHz */
+			TFA_SET_BF(handle, FRACTDEL, 48);
+			break;
+		case 8:
+		default:/* 48kHz */
+			TFA_SET_BF(handle, FRACTDEL, 46);
+			break;
+	}
+
+	/* First copy the msg_id to the buffer */
+        buffer[0] = (uint8_t) 0;
+        buffer[1] = (uint8_t) MODULE_FRAMEWORK + 128;
+        buffer[2] = (uint8_t) FW_PAR_ID_SET_SENSES_DELAY;
+
+        /* Required for all FS exept 8kHz (8kHz is all zero) */
+	if(sample_rate != 0) {
+		buffer[5] = 1;	/* Vdelay_P */
+		buffer[8] = 0;	/* Idelay_P */
+		buffer[11] = 1; /* Vdelay_S */
+		buffer[14] = 0; /* Idelay_S */
+	}
+
+	/* send SetSensesDelay msg */
+	return tfa_dsp_msg(handle, size, (char *)buffer);
+}
+
+/*
+ * register device specifics functions
+ */
+void tfa9888_ops(struct tfa_device_ops *ops) {
+	ops->tfa_init = tfa9888_specific;
+	ops->tfa_dsp_write_tables=tfa9888_tfa_dsp_write_tables;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9890_init.c b/techpack/audio/asoc/codecs/tfa98xx/tfa9890_init.c
new file mode 100644
index 0000000..595779a
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9890_init.c
@@ -0,0 +1,178 @@
+/*
+ *Copyright 2014,2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *            
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *             
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+ 
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "tfa_internal.h"
+
+#include "tfa98xx_tfafieldnames.h"
+
+static enum Tfa98xx_Error tfa9890_specific(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned short regRead = 0;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	/* all i2C registers are already set to default for N1C2 */
+
+	/* some PLL registers must be set optimal for amplifier behaviour
+	 */
+	error = tfa98xx_write_register16(handle, 0x40, 0x5a6b);
+	if (error)
+		return error;
+	tfa98xx_read_register16(handle, 0x59, &regRead);
+	regRead |= 0x3;
+	tfa98xx_write_register16(handle, 0x59, regRead);
+	error = tfa98xx_write_register16(handle, 0x40, 0x0000);
+
+	error = tfa98xx_write_register16(handle, 0x47, 0x7BE1);
+
+	return error;
+}
+
+/*
+ * Tfa9890_DspSystemStable will compensate for the wrong behavior of CLKS
+ * to determine if the DSP subsystem is ready for patch and config loading.
+ *
+ * A MTP calibration register is checked for non-zero.
+ *
+ * Note: This only works after i2c reset as this will clear the MTP contents.
+ * When we are configured then the DSP communication will synchronize access.
+ *
+ */
+static enum Tfa98xx_Error tfa9890_dsp_system_stable(Tfa98xx_handle_t handle, int *ready)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned short status, mtp0;
+	int result, tries;
+
+	/* check the contents of the STATUS register */
+	result = TFA_READ_REG(handle, AREFS);
+	if (result < 0) {
+		error = -result;
+		goto errorExit;
+	}
+	status = (unsigned short)result;
+
+	/* if AMPS is set then we were already configured and running
+	 *   no need to check further
+	 */
+	*ready = (TFA_GET_BF_VALUE(handle, AMPS, status) == 1);
+	if (*ready)		/* if  ready go back */
+		return error;	/* will be Tfa98xx_Error_Ok */
+
+	/* check AREFS and CLKS: not ready if either is clear */
+	*ready = !((TFA_GET_BF_VALUE(handle, AREFS, status) == 0)
+		   || (TFA_GET_BF_VALUE(handle, CLKS, status) == 0));
+	if (!*ready)		/* if not ready go back */
+		return error;	/* will be Tfa98xx_Error_Ok */
+
+	/* check MTPB
+	 *   mtpbusy will be active when the subsys copies MTP to I2C
+	 *   2 times retry avoids catching this short mtpbusy active period
+	 */
+	for (tries = 2; tries > 0; tries--) {
+		result = TFA_GET_BF(handle, MTPB);
+		if (result < 0) {
+			error = -result;
+			goto errorExit;
+		}
+		status = (unsigned short)result;
+
+		/* check the contents of the STATUS register */
+		*ready = (result == 0);
+		if (*ready)	/* if ready go on */
+			break;
+	}
+	if (tries == 0)		/* ready will be 0 if retries exausted */
+		return Tfa98xx_Error_Ok;
+
+	/* check the contents of  MTP register for non-zero,
+	 *  this indicates that the subsys is ready  */
+
+	error = tfa98xx_read_register16(handle, 0x84, &mtp0);
+	if (error)
+		goto errorExit;
+
+	*ready = (mtp0 != 0);	/* The MTP register written? */
+
+	return error;
+
+errorExit:
+	*ready = 0;
+	return error;
+}
+
+/*
+ * The CurrentSense4 register is not in the datasheet, define local
+ */
+#define TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF (1<<2)
+#define TFA98XX_CURRENTSENSE4 0x49
+/*
+ * Disable clock gating
+ */
+static enum Tfa98xx_Error tfa9890_clockgating(Tfa98xx_handle_t handle, int on)
+{
+	enum Tfa98xx_Error error;
+	unsigned short value;
+
+	/* for TFA9890 temporarily disable clock gating when dsp reset is used */
+	error = tfa98xx_read_register16(handle, TFA98XX_CURRENTSENSE4, &value);
+	if (error) return error;
+
+	if (Tfa98xx_Error_Ok == error) {
+		if (on)  /* clock gating on - clear the bit */
+			value &= ~TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF;
+		else  /* clock gating off - set the bit */
+			value |= TFA98XX_CURRENTSENSE4_CTRL_CLKGATECFOFF;
+
+		error = tfa98xx_write_register16(handle, TFA98XX_CURRENTSENSE4, value);
+	}
+
+	return error;
+}
+
+/*
+ * Tfa9890_DspReset will deal with clock gating control in order
+ * to reset the DSP for warm state restart
+ */
+static enum Tfa98xx_Error tfa9890_dsp_reset(Tfa98xx_handle_t handle, int state)
+{
+	enum Tfa98xx_Error error;
+
+	/* for TFA9890 temporarily disable clock gating
+	   when dsp reset is used */
+	tfa9890_clockgating(handle, 0);
+
+        TFA_SET_BF(handle, RST, (uint16_t)state);
+
+	/* clock gating restore */
+	error = tfa9890_clockgating(handle, 1);
+
+	return error;
+}
+
+/*
+ * register device specifics functions
+ */
+void tfa9890_ops(struct tfa_device_ops *ops) {
+	ops->tfa_init = tfa9890_specific;
+	ops->tfa_dsp_reset = tfa9890_dsp_reset;
+	ops->tfa_dsp_system_stable = tfa9890_dsp_system_stable;
+}
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9890_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/tfa9890_tfafieldnames.h
new file mode 100644
index 0000000..aec03ab
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9890_tfafieldnames.h
@@ -0,0 +1,76 @@
+/** Filename: Tfa9890_TfaFieldnames.h
+ *  This file was generated automatically on 04/07/15 at 14:46:37. 
+ *  Source file: TFA9897N1B_I2C_list_URT_source_v34_90Only.xls
+ */
+
+#define TFA9890_NAMETABLE static tfaBfName_t Tfa9890DatasheetNames[]= {\
+   { 0x402, "I2SF"},    /* I2SFormat data 1 input:                           , */\
+   { 0x431, "CHS12"},    /* ChannelSelection data1 input  (In CoolFlux)       , */\
+   { 0x450, "CHS3"},    /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */\
+   { 0x461, "CHSA"},    /* Input selection for amplifier                     , */\
+   { 0x481, "I2SDOC"},    /* selection data out                                , */\
+   { 0x4a0, "DISP"},    /* idp protection                                    , */\
+   { 0x4b0, "I2SDOE"},    /* Enable data output                                , */\
+   { 0x4c3, "I2SSR"},    /* sample rate setting                               , */\
+   { 0x732, "DCMCC"},   /* Max boost coil current - step of 500 mA           , */\
+   { 0x9c0, "CCFD"},    /* Selection CoolFlux Clock                          , */\
+   { 0x9d0, "ISEL"},    /* selection input 1 or 2                            , */\
+   { 0xa02, "DOLS"},    /* Output selection dataout left channel             , */\
+   { 0xa32, "DORS"},    /* Output selection dataout right channel            , */\
+   { 0xa62, "SPKL"},    /* Selection speaker induction                       , */\
+   { 0xa91, "SPKR"},    /* Selection speaker impedance                       , */\
+   { 0xab3, "DCFG"},    /* DCDC speaker current compensation gain            , */\
+   { 0xf00, "VDDD"},    /* mask flag_por for interupt generation             , */\
+   { 0xf10, "OTDD"},    /* mask flag_otpok for interupt generation           , */\
+   { 0xf20, "OVDD"},    /* mask flag_ovpok for interupt generation           , */\
+   { 0xf30, "UVDD"},    /* mask flag_uvpok for interupt generation           , */\
+   { 0xf40, "OCDD"},    /* mask flag_ocp_alarm for interupt generation       , */\
+   { 0xf50, "CLKD"},    /* mask flag_clocks_stable for interupt generation   , */\
+   { 0xf60, "DCCD"},    /* mask flag_pwrokbst for interupt generation        , */\
+   { 0xf70, "SPKD"},    /* mask flag_cf_speakererror for interupt generation , */\
+   { 0xf80, "WDD"},    /* mask flag_watchdog_reset for interupt generation  , */\
+   { 0xf90, "LCLK"},    /* mask flag_lost_clk for interupt generation        , */\
+   { 0xfe0, "INT"},    /* enabling interrupt                                , */\
+   { 0xff0, "INTP"},    /* Setting polarity interupt                         , */\
+   { 0x8f0f, "VERSION"},    /* (key1 protected)                                  , */\
+   { 0xffff,"Unknown bitfield enum" }   /* not found */\
+};
+
+#define TFA9890_BITNAMETABLE static tfaBfName_t Tfa9890BitNames[]= {\
+   { 0x402, "i2s_seti"},    /* I2SFormat data 1 input:                           , */\
+   { 0x431, "chan_sel1"},    /* ChannelSelection data1 input  (In CoolFlux)       , */\
+   { 0x450, "lr_sw_i2si2"},    /* ChannelSelection data 2 input (coolflux input, the DCDC converter gets the other signal), */\
+   { 0x461, "input_sel"},    /* Input selection for amplifier                     , */\
+   { 0x481, "datao_sel"},    /* selection data out                                , */\
+   { 0x4a0, "disable_idp"},    /* idp protection                                    , */\
+   { 0x4b0, "enbl_datao"},    /* Enable data output                                , */\
+   { 0x4c3, "i2s_fs"},    /* sample rate setting                               , */\
+   { 0x732, "ctrl_bstcur"},   /* Max boost coil current - step of 500 mA           , */\
+   { 0x9c0, "sel_cf_clk"},  /* Selection CoolFlux Clock                          , */\
+   { 0x9d0, "intf_sel"},    /* selection input 1 or 2                            , */\
+   { 0xa02, "sel_i2so_l"},    /* Output selection dataout left channel             , */\
+   { 0xa32, "sel_i2so_r"},    /* Output selection dataout right channel            , */\
+   { 0xa62, "ctrl_spkr_coil"},    /* Selection speaker induction                       , */\
+   { 0xa91, "ctrl_spr_res"},    /* Selection speaker impedance                       , */\
+   { 0xab3, "ctrl_dcdc_spkr_i_comp_gain"},    /* DCDC speaker current compensation gain            , */\
+   { 0xaf0, "ctrl_dcdc_spkr_i_comp_sign"},    /* DCDC speaker current compensation sign            , */\
+   { 0xf00, "flag_por_mask"},    /* mask flag_por for interupt generation             , */\
+   { 0xf10, "flag_otpok_mask"},    /* mask flag_otpok for interupt generation           , */\
+   { 0xf20, "flag_ovpok_mask"},    /* mask flag_ovpok for interupt generation           , */\
+   { 0xf30, "flag_uvpok_mask"},    /* mask flag_uvpok for interupt generation           , */\
+   { 0xf40, "flag_ocp_alarm_mask"},    /* mask flag_ocp_alarm for interupt generation       , */\
+   { 0xf50, "flag_clocks_stable_mask"},    /* mask flag_clocks_stable for interupt generation   , */\
+   { 0xf60, "flag_pwrokbst_mask"},    /* mask flag_pwrokbst for interupt generation        , */\
+   { 0xf70, "flag_cf_speakererror_mask"},    /* mask flag_cf_speakererror for interupt generation , */\
+   { 0xf80, "flag_watchdog_reset_mask"},    /* mask flag_watchdog_reset for interupt generation  , */\
+   { 0xf90, "flag_lost_clk_mask"},    /* mask flag_lost_clk for interupt generation        , */\
+   { 0xfe0, "enable_interrupt"},    /* enabling interrupt                                , */\
+   { 0xff0, "invert_int_polarity"},    /* Setting polarity interupt                         , */\
+   { 0x4700, "switch_fb"},    /* switch_fb                                         , */\
+   { 0x4713, "se_hyst"},    /* se_hyst                                           , */\
+   { 0x4754, "se_level"},    /* se_level                                          , */\
+   { 0x47a5, "ktemp"},    /* temperature compensation trimming                 , */\
+   { 0x8f0f, "production_data6"},    /* (key1 protected)                                  , */\
+   { 0xffff,"Unknown bitfield enum" }    /* not found */\
+};
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9891_genregs.h b/techpack/audio/asoc/codecs/tfa98xx/tfa9891_genregs.h
new file mode 100644
index 0000000..14f75af
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9891_genregs.h
@@ -0,0 +1,1125 @@
+/** Filename: Tfa98xx_genregs.h
+ *  This file was generated automatically on 07/01/15 at 10:25:08. 
+ *  Source file: TFA9891_I2C_list_V11.xls
+ */
+
+#ifndef TFA9891_GENREGS_H
+#define TFA9891_GENREGS_H
+
+
+#define TFA98XX_STATUSREG                  0x00
+#define TFA98XX_BATTERYVOLTAGE             0x01
+#define TFA9891_TEMPERATURE                0x02
+#define TFA98XX_REVISIONNUMBER             0x03
+#define TFA98XX_I2SREG                     0x04
+#define TFA98XX_BAT_PROT                   0x05
+#define TFA98XX_AUDIO_CTR                  0x06
+#define TFA98XX_DCDCBOOST                  0x07
+#define TFA98XX_SPKR_CALIBRATION           0x08
+#define TFA98XX_SYS_CTRL                   0x09
+#define TFA98XX_I2S_SEL_REG                0x0a
+#define TFA98XX_HIDDEN_MTP_KEY2            0x0b
+#define TFA98XX_INTERRUPT_REG              0x0f
+#define TFA98XX_PDM_CTRL                   0x10
+#define TFA98XX_PDM_OUT_CTRL               0x11
+#define TFA98XX_PDM_DS4_R                  0x12
+#define TFA98XX_PDM_DS4_L                  0x13
+#define TFA98XX_CTRL_SAAM_PGA              0x22
+#define TFA98XX_MISC_CTRL                  0x25
+#define TFA98XX_CURRENTSENSE1              0x46
+#define TFA98XX_CURRENTSENSE4              0x49
+#define TFA98XX_HIDDEN_MTP_CTRL_REG3       0x62
+#define TFA9891_CF_CONTROLS                0x70
+#define TFA9891_CF_MAD                     0x71
+#define TFA9891_CF_MEM                     0x72
+#define TFA9891_CF_STATUS                  0x73
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP 0x80
+
+/*
+ * (0x00)-StatusReg
+ */
+
+/*
+ * POR
+ */
+#define TFA98XX_STATUSREG_VDDS                              (0x1<<0)
+#define TFA98XX_STATUSREG_VDDS_POS                                 0
+#define TFA98XX_STATUSREG_VDDS_LEN                                 1
+#define TFA98XX_STATUSREG_VDDS_MAX                                 1
+#define TFA98XX_STATUSREG_VDDS_MSK                               0x1
+
+/*
+ * PLL_LOCK
+ */
+#define TFA98XX_STATUSREG_PLLS                              (0x1<<1)
+#define TFA98XX_STATUSREG_PLLS_POS                                 1
+#define TFA98XX_STATUSREG_PLLS_LEN                                 1
+#define TFA98XX_STATUSREG_PLLS_MAX                                 1
+#define TFA98XX_STATUSREG_PLLS_MSK                               0x2
+
+/*
+ * flag_otpok
+ */
+#define TFA98XX_STATUSREG_OTDS                              (0x1<<2)
+#define TFA98XX_STATUSREG_OTDS_POS                                 2
+#define TFA98XX_STATUSREG_OTDS_LEN                                 1
+#define TFA98XX_STATUSREG_OTDS_MAX                                 1
+#define TFA98XX_STATUSREG_OTDS_MSK                               0x4
+
+/*
+ * flag_ovpok
+ */
+#define TFA98XX_STATUSREG_OVDS                              (0x1<<3)
+#define TFA98XX_STATUSREG_OVDS_POS                                 3
+#define TFA98XX_STATUSREG_OVDS_LEN                                 1
+#define TFA98XX_STATUSREG_OVDS_MAX                                 1
+#define TFA98XX_STATUSREG_OVDS_MSK                               0x8
+
+/*
+ * flag_uvpok
+ */
+#define TFA98XX_STATUSREG_UVDS                              (0x1<<4)
+#define TFA98XX_STATUSREG_UVDS_POS                                 4
+#define TFA98XX_STATUSREG_UVDS_LEN                                 1
+#define TFA98XX_STATUSREG_UVDS_MAX                                 1
+#define TFA98XX_STATUSREG_UVDS_MSK                              0x10
+
+/*
+ * flag_OCP_alarm
+ */
+#define TFA98XX_STATUSREG_OCDS                              (0x1<<5)
+#define TFA98XX_STATUSREG_OCDS_POS                                 5
+#define TFA98XX_STATUSREG_OCDS_LEN                                 1
+#define TFA98XX_STATUSREG_OCDS_MAX                                 1
+#define TFA98XX_STATUSREG_OCDS_MSK                              0x20
+
+/*
+ * flag_clocks_stable
+ */
+#define TFA98XX_STATUSREG_CLKS                              (0x1<<6)
+#define TFA98XX_STATUSREG_CLKS_POS                                 6
+#define TFA98XX_STATUSREG_CLKS_LEN                                 1
+#define TFA98XX_STATUSREG_CLKS_MAX                                 1
+#define TFA98XX_STATUSREG_CLKS_MSK                              0x40
+
+/*
+ * CLIP
+ */
+#define TFA98XX_STATUSREG_CLIPS                             (0x1<<7)
+#define TFA98XX_STATUSREG_CLIPS_POS                                7
+#define TFA98XX_STATUSREG_CLIPS_LEN                                1
+#define TFA98XX_STATUSREG_CLIPS_MAX                                1
+#define TFA98XX_STATUSREG_CLIPS_MSK                             0x80
+
+/*
+ * mtp_busy
+ */
+#define TFA98XX_STATUSREG_MTPB                              (0x1<<8)
+#define TFA98XX_STATUSREG_MTPB_POS                                 8
+#define TFA98XX_STATUSREG_MTPB_LEN                                 1
+#define TFA98XX_STATUSREG_MTPB_MAX                                 1
+#define TFA98XX_STATUSREG_MTPB_MSK                             0x100
+
+/*
+ * flag_pwrokbst
+ */
+#define TFA98XX_STATUSREG_DCCS                              (0x1<<9)
+#define TFA98XX_STATUSREG_DCCS_POS                                 9
+#define TFA98XX_STATUSREG_DCCS_LEN                                 1
+#define TFA98XX_STATUSREG_DCCS_MAX                                 1
+#define TFA98XX_STATUSREG_DCCS_MSK                             0x200
+
+/*
+ * flag_cf_speakererror
+ */
+#define TFA98XX_STATUSREG_SPKS                             (0x1<<10)
+#define TFA98XX_STATUSREG_SPKS_POS                                10
+#define TFA98XX_STATUSREG_SPKS_LEN                                 1
+#define TFA98XX_STATUSREG_SPKS_MAX                                 1
+#define TFA98XX_STATUSREG_SPKS_MSK                             0x400
+
+/*
+ * flag_cold_started
+ */
+#define TFA98XX_STATUSREG_ACS                              (0x1<<11)
+#define TFA98XX_STATUSREG_ACS_POS                                 11
+#define TFA98XX_STATUSREG_ACS_LEN                                  1
+#define TFA98XX_STATUSREG_ACS_MAX                                  1
+#define TFA98XX_STATUSREG_ACS_MSK                              0x800
+
+/*
+ * flag_engage
+ */
+#define TFA98XX_STATUSREG_SWS                              (0x1<<12)
+#define TFA98XX_STATUSREG_SWS_POS                                 12
+#define TFA98XX_STATUSREG_SWS_LEN                                  1
+#define TFA98XX_STATUSREG_SWS_MAX                                  1
+#define TFA98XX_STATUSREG_SWS_MSK                             0x1000
+
+/*
+ * flag_watchdog_reset
+ */
+#define TFA98XX_STATUSREG_WDS                              (0x1<<13)
+#define TFA98XX_STATUSREG_WDS_POS                                 13
+#define TFA98XX_STATUSREG_WDS_LEN                                  1
+#define TFA98XX_STATUSREG_WDS_MAX                                  1
+#define TFA98XX_STATUSREG_WDS_MSK                             0x2000
+
+/*
+ * flag_enbl_amp
+ */
+#define TFA98XX_STATUSREG_AMPS                             (0x1<<14)
+#define TFA98XX_STATUSREG_AMPS_POS                                14
+#define TFA98XX_STATUSREG_AMPS_LEN                                 1
+#define TFA98XX_STATUSREG_AMPS_MAX                                 1
+#define TFA98XX_STATUSREG_AMPS_MSK                            0x4000
+
+/*
+ * flag_enbl_ref
+ */
+#define TFA98XX_STATUSREG_AREFS                            (0x1<<15)
+#define TFA98XX_STATUSREG_AREFS_POS                               15
+#define TFA98XX_STATUSREG_AREFS_LEN                                1
+#define TFA98XX_STATUSREG_AREFS_MAX                                1
+#define TFA98XX_STATUSREG_AREFS_MSK                           0x8000
+
+/*
+ * (0x01)-BatteryVoltage
+ */
+
+/*
+ * bat_adc
+ */
+#define TFA98XX_BATTERYVOLTAGE_BATS                       (0x3ff<<0)
+#define TFA98XX_BATTERYVOLTAGE_BATS_POS                            0
+#define TFA98XX_BATTERYVOLTAGE_BATS_LEN                           10
+#define TFA98XX_BATTERYVOLTAGE_BATS_MAX                         1023
+#define TFA98XX_BATTERYVOLTAGE_BATS_MSK                        0x3ff
+
+
+/*
+ * (0x02)-Temperature
+ */
+
+/*
+ * temp_adc
+ */
+#define TFA9891_TEMPERATURE_TEMPS                         (0x1ff<<0)
+#define TFA9891_TEMPERATURE_TEMPS_POS                              0
+#define TFA9891_TEMPERATURE_TEMPS_LEN                              9
+#define TFA9891_TEMPERATURE_TEMPS_MAX                            511
+#define TFA9891_TEMPERATURE_TEMPS_MSK                          0x1ff
+
+
+/*
+ * (0x03)-RevisionNumber
+ */
+
+/*
+ * rev_reg
+ */
+#define TFA98XX_REVISIONNUMBER_REV                         (0xff<<0)
+#define TFA98XX_REVISIONNUMBER_REV_POS                             0
+#define TFA98XX_REVISIONNUMBER_REV_LEN                             8
+#define TFA98XX_REVISIONNUMBER_REV_MAX                           255
+#define TFA98XX_REVISIONNUMBER_REV_MSK                          0xff
+
+
+/*
+ * (0x04)-I2SReg
+ */
+
+/*
+ * i2s_seti
+ */
+#define TFA98XX_I2SREG_I2SF                                 (0x7<<0)
+#define TFA98XX_I2SREG_I2SF_POS                                    0
+#define TFA98XX_I2SREG_I2SF_LEN                                    3
+#define TFA98XX_I2SREG_I2SF_MAX                                    7
+#define TFA98XX_I2SREG_I2SF_MSK                                  0x7
+
+/*
+ * chan_sel1
+ */
+#define TFA98XX_I2SREG_CHS12                                (0x3<<3)
+#define TFA98XX_I2SREG_CHS12_POS                                   3
+#define TFA98XX_I2SREG_CHS12_LEN                                   2
+#define TFA98XX_I2SREG_CHS12_MAX                                   3
+#define TFA98XX_I2SREG_CHS12_MSK                                0x18
+
+/*
+ * lr_sw_i2si2
+ */
+#define TFA98XX_I2SREG_CHS3                                 (0x1<<5)
+#define TFA98XX_I2SREG_CHS3_POS                                    5
+#define TFA98XX_I2SREG_CHS3_LEN                                    1
+#define TFA98XX_I2SREG_CHS3_MAX                                    1
+#define TFA98XX_I2SREG_CHS3_MSK                                 0x20
+
+/*
+ * input_sel
+ */
+#define TFA98XX_I2SREG_CHSA                                 (0x3<<6)
+#define TFA98XX_I2SREG_CHSA_POS                                    6
+#define TFA98XX_I2SREG_CHSA_LEN                                    2
+#define TFA98XX_I2SREG_CHSA_MAX                                    3
+#define TFA98XX_I2SREG_CHSA_MSK                                 0xc0
+
+/*
+ * datao_sel
+ */
+#define TFA98XX_I2SREG_I2SDOC                               (0x3<<8)
+#define TFA98XX_I2SREG_I2SDOC_POS                                  8
+#define TFA98XX_I2SREG_I2SDOC_LEN                                  2
+#define TFA98XX_I2SREG_I2SDOC_MAX                                  3
+#define TFA98XX_I2SREG_I2SDOC_MSK                              0x300
+
+/*
+ * disable_idp
+ */
+#define TFA98XX_I2SREG_DISP                                (0x1<<10)
+#define TFA98XX_I2SREG_DISP_POS                                   10
+#define TFA98XX_I2SREG_DISP_LEN                                    1
+#define TFA98XX_I2SREG_DISP_MAX                                    1
+#define TFA98XX_I2SREG_DISP_MSK                                0x400
+
+/*
+ * enbl_datao
+ */
+#define TFA98XX_I2SREG_I2SDOE                              (0x1<<11)
+#define TFA98XX_I2SREG_I2SDOE_POS                                 11
+#define TFA98XX_I2SREG_I2SDOE_LEN                                  1
+#define TFA98XX_I2SREG_I2SDOE_MAX                                  1
+#define TFA98XX_I2SREG_I2SDOE_MSK                              0x800
+
+/*
+ * i2s_fs
+ */
+#define TFA98XX_I2SREG_I2SSR                               (0xf<<12)
+#define TFA98XX_I2SREG_I2SSR_POS                                  12
+#define TFA98XX_I2SREG_I2SSR_LEN                                   4
+#define TFA98XX_I2SREG_I2SSR_MAX                                  15
+#define TFA98XX_I2SREG_I2SSR_MSK                              0xf000
+
+
+/*
+ * (0x05)-bat_prot
+ */
+
+/*
+ * vbat_prot_attacktime
+ */
+#define TFA98XX_BAT_PROT_BSSCR                              (0x3<<0)
+#define TFA98XX_BAT_PROT_BSSCR_POS                                 0
+#define TFA98XX_BAT_PROT_BSSCR_LEN                                 2
+#define TFA98XX_BAT_PROT_BSSCR_MAX                                 3
+#define TFA98XX_BAT_PROT_BSSCR_MSK                               0x3
+
+/*
+ * vbat_prot_thlevel
+ */
+#define TFA98XX_BAT_PROT_BSST                               (0xf<<2)
+#define TFA98XX_BAT_PROT_BSST_POS                                  2
+#define TFA98XX_BAT_PROT_BSST_LEN                                  4
+#define TFA98XX_BAT_PROT_BSST_MAX                                 15
+#define TFA98XX_BAT_PROT_BSST_MSK                               0x3c
+
+/*
+ * vbat_prot_max_reduct
+ */
+#define TFA98XX_BAT_PROT_BSSRL                              (0x3<<6)
+#define TFA98XX_BAT_PROT_BSSRL_POS                                 6
+#define TFA98XX_BAT_PROT_BSSRL_LEN                                 2
+#define TFA98XX_BAT_PROT_BSSRL_MAX                                 3
+#define TFA98XX_BAT_PROT_BSSRL_MSK                              0xc0
+
+/*
+ * vbat_prot_release_t
+ */
+#define TFA98XX_BAT_PROT_BSSRR                              (0x7<<8)
+#define TFA98XX_BAT_PROT_BSSRR_POS                                 8
+#define TFA98XX_BAT_PROT_BSSRR_LEN                                 3
+#define TFA98XX_BAT_PROT_BSSRR_MAX                                 7
+#define TFA98XX_BAT_PROT_BSSRR_MSK                             0x700
+
+/*
+ * vbat_prot_hysterese
+ */
+#define TFA98XX_BAT_PROT_BSSHY                             (0x3<<11)
+#define TFA98XX_BAT_PROT_BSSHY_POS                                11
+#define TFA98XX_BAT_PROT_BSSHY_LEN                                 2
+#define TFA98XX_BAT_PROT_BSSHY_MAX                                 3
+#define TFA98XX_BAT_PROT_BSSHY_MSK                            0x1800
+
+/*
+ * sel_vbat
+ */
+#define TFA98XX_BAT_PROT_BSSR                              (0x1<<14)
+#define TFA98XX_BAT_PROT_BSSR_POS                                 14
+#define TFA98XX_BAT_PROT_BSSR_LEN                                  1
+#define TFA98XX_BAT_PROT_BSSR_MAX                                  1
+#define TFA98XX_BAT_PROT_BSSR_MSK                             0x4000
+
+/*
+ * bypass_clipper
+ */
+#define TFA98XX_BAT_PROT_BSSBY                             (0x1<<15)
+#define TFA98XX_BAT_PROT_BSSBY_POS                                15
+#define TFA98XX_BAT_PROT_BSSBY_LEN                                 1
+#define TFA98XX_BAT_PROT_BSSBY_MAX                                 1
+#define TFA98XX_BAT_PROT_BSSBY_MSK                            0x8000
+
+
+/*
+ * (0x06)-audio_ctr
+ */
+
+/*
+ * dpsa
+ */
+#define TFA98XX_AUDIO_CTR_DPSA                              (0x1<<0)
+#define TFA98XX_AUDIO_CTR_DPSA_POS                                 0
+#define TFA98XX_AUDIO_CTR_DPSA_LEN                                 1
+#define TFA98XX_AUDIO_CTR_DPSA_MAX                                 1
+#define TFA98XX_AUDIO_CTR_DPSA_MSK                               0x1
+
+/*
+ * ctrl_slope
+ */
+#define TFA98XX_AUDIO_CTR_AMPSL                             (0xf<<1)
+#define TFA98XX_AUDIO_CTR_AMPSL_POS                                1
+#define TFA98XX_AUDIO_CTR_AMPSL_LEN                                4
+#define TFA98XX_AUDIO_CTR_AMPSL_MAX                               15
+#define TFA98XX_AUDIO_CTR_AMPSL_MSK                             0x1e
+
+/*
+ * cf_mute
+ */
+#define TFA98XX_AUDIO_CTR_CFSM                              (0x1<<5)
+#define TFA98XX_AUDIO_CTR_CFSM_POS                                 5
+#define TFA98XX_AUDIO_CTR_CFSM_LEN                                 1
+#define TFA98XX_AUDIO_CTR_CFSM_MAX                                 1
+#define TFA98XX_AUDIO_CTR_CFSM_MSK                              0x20
+
+/*
+ * ctrl_batsensesteepness
+ */
+#define TFA98XX_AUDIO_CTR_BSSS                              (0x1<<7)
+#define TFA98XX_AUDIO_CTR_BSSS_POS                                 7
+#define TFA98XX_AUDIO_CTR_BSSS_LEN                                 1
+#define TFA98XX_AUDIO_CTR_BSSS_MAX                                 1
+#define TFA98XX_AUDIO_CTR_BSSS_MSK                              0x80
+
+/*
+ * vol
+ */
+#define TFA98XX_AUDIO_CTR_VOL                              (0xff<<8)
+#define TFA98XX_AUDIO_CTR_VOL_POS                                  8
+#define TFA98XX_AUDIO_CTR_VOL_LEN                                  8
+#define TFA98XX_AUDIO_CTR_VOL_MAX                                255
+#define TFA98XX_AUDIO_CTR_VOL_MSK                             0xff00
+
+
+/*
+ * (0x07)-DCDCboost
+ */
+
+/*
+ * ctrl_bstvolt
+ */
+#define TFA98XX_DCDCBOOST_DCVO                              (0x7<<0)
+#define TFA98XX_DCDCBOOST_DCVO_POS                                 0
+#define TFA98XX_DCDCBOOST_DCVO_LEN                                 3
+#define TFA98XX_DCDCBOOST_DCVO_MAX                                 7
+#define TFA98XX_DCDCBOOST_DCVO_MSK                               0x7
+
+/*
+ * ctrl_bstcur
+ */
+#define TFA98XX_DCDCBOOST_DCMCC                             (0x7<<3)
+#define TFA98XX_DCDCBOOST_DCMCC_POS                                3
+#define TFA98XX_DCDCBOOST_DCMCC_LEN                                3
+#define TFA98XX_DCDCBOOST_DCMCC_MAX                                7
+#define TFA98XX_DCDCBOOST_DCMCC_MSK                             0x38
+
+/*
+ * boost_intel
+ */
+#define TFA98XX_DCDCBOOST_DCIE                             (0x1<<10)
+#define TFA98XX_DCDCBOOST_DCIE_POS                                10
+#define TFA98XX_DCDCBOOST_DCIE_LEN                                 1
+#define TFA98XX_DCDCBOOST_DCIE_MAX                                 1
+#define TFA98XX_DCDCBOOST_DCIE_MSK                             0x400
+
+/*
+ * boost_speed
+ */
+#define TFA98XX_DCDCBOOST_DCSR                             (0x1<<11)
+#define TFA98XX_DCDCBOOST_DCSR_POS                                11
+#define TFA98XX_DCDCBOOST_DCSR_LEN                                 1
+#define TFA98XX_DCDCBOOST_DCSR_MAX                                 1
+#define TFA98XX_DCDCBOOST_DCSR_MSK                             0x800
+
+
+/*
+ * (0x08)-spkr_calibration
+ */
+
+/*
+ * ext_temp_sel
+ */
+#define TFA98XX_SPKR_CALIBRATION_TROS                       (0x1<<0)
+#define TFA98XX_SPKR_CALIBRATION_TROS_POS                          0
+#define TFA98XX_SPKR_CALIBRATION_TROS_LEN                          1
+#define TFA98XX_SPKR_CALIBRATION_TROS_MAX                          1
+#define TFA98XX_SPKR_CALIBRATION_TROS_MSK                        0x1
+
+/*
+ * ext_temp
+ */
+#define TFA98XX_SPKR_CALIBRATION_EXTTS                    (0x1ff<<1)
+#define TFA98XX_SPKR_CALIBRATION_EXTTS_POS                         1
+#define TFA98XX_SPKR_CALIBRATION_EXTTS_LEN                         9
+#define TFA98XX_SPKR_CALIBRATION_EXTTS_MAX                       511
+#define TFA98XX_SPKR_CALIBRATION_EXTTS_MSK                     0x3fe
+
+
+/*
+ * (0x09)-sys_ctrl
+ */
+
+/*
+ * PowerDown
+ */
+#define TFA98XX_SYS_CTRL_PWDN                               (0x1<<0)
+#define TFA98XX_SYS_CTRL_PWDN_POS                                  0
+#define TFA98XX_SYS_CTRL_PWDN_LEN                                  1
+#define TFA98XX_SYS_CTRL_PWDN_MAX                                  1
+#define TFA98XX_SYS_CTRL_PWDN_MSK                                0x1
+
+/*
+ * reset
+ */
+#define TFA98XX_SYS_CTRL_I2CR                               (0x1<<1)
+#define TFA98XX_SYS_CTRL_I2CR_POS                                  1
+#define TFA98XX_SYS_CTRL_I2CR_LEN                                  1
+#define TFA98XX_SYS_CTRL_I2CR_MAX                                  1
+#define TFA98XX_SYS_CTRL_I2CR_MSK                                0x2
+
+/*
+ * enbl_coolflux
+ */
+#define TFA98XX_SYS_CTRL_CFE                                (0x1<<2)
+#define TFA98XX_SYS_CTRL_CFE_POS                                   2
+#define TFA98XX_SYS_CTRL_CFE_LEN                                   1
+#define TFA98XX_SYS_CTRL_CFE_MAX                                   1
+#define TFA98XX_SYS_CTRL_CFE_MSK                                 0x4
+
+/*
+ * enbl_amplifier
+ */
+#define TFA98XX_SYS_CTRL_AMPE                               (0x1<<3)
+#define TFA98XX_SYS_CTRL_AMPE_POS                                  3
+#define TFA98XX_SYS_CTRL_AMPE_LEN                                  1
+#define TFA98XX_SYS_CTRL_AMPE_MAX                                  1
+#define TFA98XX_SYS_CTRL_AMPE_MSK                                0x8
+
+/*
+ * enbl_boost
+ */
+#define TFA98XX_SYS_CTRL_DCA                                (0x1<<4)
+#define TFA98XX_SYS_CTRL_DCA_POS                                   4
+#define TFA98XX_SYS_CTRL_DCA_LEN                                   1
+#define TFA98XX_SYS_CTRL_DCA_MAX                                   1
+#define TFA98XX_SYS_CTRL_DCA_MSK                                0x10
+
+/*
+ * cf_configured
+ */
+#define TFA98XX_SYS_CTRL_SBSL                               (0x1<<5)
+#define TFA98XX_SYS_CTRL_SBSL_POS                                  5
+#define TFA98XX_SYS_CTRL_SBSL_LEN                                  1
+#define TFA98XX_SYS_CTRL_SBSL_MAX                                  1
+#define TFA98XX_SYS_CTRL_SBSL_MSK                               0x20
+
+/*
+ * sel_enbl_amplifier
+ */
+#define TFA98XX_SYS_CTRL_AMPC                               (0x1<<6)
+#define TFA98XX_SYS_CTRL_AMPC_POS                                  6
+#define TFA98XX_SYS_CTRL_AMPC_LEN                                  1
+#define TFA98XX_SYS_CTRL_AMPC_MAX                                  1
+#define TFA98XX_SYS_CTRL_AMPC_MSK                               0x40
+
+/*
+ * dcdcoff_mode
+ */
+#define TFA98XX_SYS_CTRL_DCDIS                              (0x1<<7)
+#define TFA98XX_SYS_CTRL_DCDIS_POS                                 7
+#define TFA98XX_SYS_CTRL_DCDIS_LEN                                 1
+#define TFA98XX_SYS_CTRL_DCDIS_MAX                                 1
+#define TFA98XX_SYS_CTRL_DCDIS_MSK                              0x80
+
+/*
+ * cttr_iddqtest
+ */
+#define TFA98XX_SYS_CTRL_PSDR                               (0x1<<8)
+#define TFA98XX_SYS_CTRL_PSDR_POS                                  8
+#define TFA98XX_SYS_CTRL_PSDR_LEN                                  1
+#define TFA98XX_SYS_CTRL_PSDR_MAX                                  1
+#define TFA98XX_SYS_CTRL_PSDR_MSK                              0x100
+
+/*
+ * ctrl_coil_value
+ */
+#define TFA98XX_SYS_CTRL_DCCV                               (0x3<<9)
+#define TFA98XX_SYS_CTRL_DCCV_POS                                  9
+#define TFA98XX_SYS_CTRL_DCCV_LEN                                  2
+#define TFA98XX_SYS_CTRL_DCCV_MAX                                  3
+#define TFA98XX_SYS_CTRL_DCCV_MSK                              0x600
+
+/*
+ * ctrl_sel_cf_clock
+ */
+#define TFA98XX_SYS_CTRL_CCFD                              (0x3<<11)
+#define TFA98XX_SYS_CTRL_CCFD_POS                                 11
+#define TFA98XX_SYS_CTRL_CCFD_LEN                                  2
+#define TFA98XX_SYS_CTRL_CCFD_MAX                                  3
+#define TFA98XX_SYS_CTRL_CCFD_MSK                             0x1800
+
+/*
+ * intf_sel
+ */
+#define TFA98XX_SYS_CTRL_ISEL                              (0x1<<13)
+#define TFA98XX_SYS_CTRL_ISEL_POS                                 13
+#define TFA98XX_SYS_CTRL_ISEL_LEN                                  1
+#define TFA98XX_SYS_CTRL_ISEL_MAX                                  1
+#define TFA98XX_SYS_CTRL_ISEL_MSK                             0x2000
+
+/*
+ * sel_ws_bck
+ */
+#define TFA98XX_SYS_CTRL_IPLL                              (0x1<<14)
+#define TFA98XX_SYS_CTRL_IPLL_POS                                 14
+#define TFA98XX_SYS_CTRL_IPLL_LEN                                  1
+#define TFA98XX_SYS_CTRL_IPLL_MAX                                  1
+#define TFA98XX_SYS_CTRL_IPLL_MSK                             0x4000
+
+
+/*
+ * (0x0a)-I2S_sel_reg
+ */
+
+/*
+ * sel_i2so_l
+ */
+#define TFA98XX_I2S_SEL_REG_DOLS                            (0x7<<0)
+#define TFA98XX_I2S_SEL_REG_DOLS_POS                               0
+#define TFA98XX_I2S_SEL_REG_DOLS_LEN                               3
+#define TFA98XX_I2S_SEL_REG_DOLS_MAX                               7
+#define TFA98XX_I2S_SEL_REG_DOLS_MSK                             0x7
+
+/*
+ * sel_i2so_r
+ */
+#define TFA98XX_I2S_SEL_REG_DORS                            (0x7<<3)
+#define TFA98XX_I2S_SEL_REG_DORS_POS                               3
+#define TFA98XX_I2S_SEL_REG_DORS_LEN                               3
+#define TFA98XX_I2S_SEL_REG_DORS_MAX                               7
+#define TFA98XX_I2S_SEL_REG_DORS_MSK                            0x38
+
+/*
+ * ctrl_spkr_coil
+ */
+#define TFA98XX_I2S_SEL_REG_SPKL                            (0x7<<6)
+#define TFA98XX_I2S_SEL_REG_SPKL_POS                               6
+#define TFA98XX_I2S_SEL_REG_SPKL_LEN                               3
+#define TFA98XX_I2S_SEL_REG_SPKL_MAX                               7
+#define TFA98XX_I2S_SEL_REG_SPKL_MSK                           0x1c0
+
+/*
+ * ctrl_spr_res
+ */
+#define TFA98XX_I2S_SEL_REG_SPKR                            (0x3<<9)
+#define TFA98XX_I2S_SEL_REG_SPKR_POS                               9
+#define TFA98XX_I2S_SEL_REG_SPKR_LEN                               2
+#define TFA98XX_I2S_SEL_REG_SPKR_MAX                               3
+#define TFA98XX_I2S_SEL_REG_SPKR_MSK                           0x600
+
+/*
+ * ctrl_dcdc_spkr_i_comp_gain
+ */
+#define TFA98XX_I2S_SEL_REG_DCFG                           (0xf<<11)
+#define TFA98XX_I2S_SEL_REG_DCFG_POS                              11
+#define TFA98XX_I2S_SEL_REG_DCFG_LEN                               4
+#define TFA98XX_I2S_SEL_REG_DCFG_MAX                              15
+#define TFA98XX_I2S_SEL_REG_DCFG_MSK                          0x7800
+
+
+/*
+ * (0x0b)-Hidden_mtp_key2
+ */
+
+/*
+ * MTP_key2
+ */
+#define TFA98XX_HIDDEN_MTP_KEY2_MTPK                       (0xff<<0)
+#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_POS                           0
+#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_LEN                           8
+#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_MAX                         255
+#define TFA98XX_HIDDEN_MTP_KEY2_MTPK_MSK                        0xff
+
+
+/*
+ * (0x0f)-interrupt_reg
+ */
+
+/*
+ * flag_por_mask
+ */
+#define TFA98XX_INTERRUPT_REG_VDDD                          (0x1<<0)
+#define TFA98XX_INTERRUPT_REG_VDDD_POS                             0
+#define TFA98XX_INTERRUPT_REG_VDDD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_VDDD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_VDDD_MSK                           0x1
+
+/*
+ * flag_otpok_mask
+ */
+#define TFA98XX_INTERRUPT_REG_OTDD                          (0x1<<1)
+#define TFA98XX_INTERRUPT_REG_OTDD_POS                             1
+#define TFA98XX_INTERRUPT_REG_OTDD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_OTDD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_OTDD_MSK                           0x2
+
+/*
+ * flag_ovpok_mask
+ */
+#define TFA98XX_INTERRUPT_REG_OVDD                          (0x1<<2)
+#define TFA98XX_INTERRUPT_REG_OVDD_POS                             2
+#define TFA98XX_INTERRUPT_REG_OVDD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_OVDD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_OVDD_MSK                           0x4
+
+/*
+ * flag_uvpok_mask
+ */
+#define TFA98XX_INTERRUPT_REG_UVDD                          (0x1<<3)
+#define TFA98XX_INTERRUPT_REG_UVDD_POS                             3
+#define TFA98XX_INTERRUPT_REG_UVDD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_UVDD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_UVDD_MSK                           0x8
+
+/*
+ * flag_ocp_alarm_mask
+ */
+#define TFA98XX_INTERRUPT_REG_OCDD                          (0x1<<4)
+#define TFA98XX_INTERRUPT_REG_OCDD_POS                             4
+#define TFA98XX_INTERRUPT_REG_OCDD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_OCDD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_OCDD_MSK                          0x10
+
+/*
+ * flag_clocks_stable_mask
+ */
+#define TFA98XX_INTERRUPT_REG_CLKD                          (0x1<<5)
+#define TFA98XX_INTERRUPT_REG_CLKD_POS                             5
+#define TFA98XX_INTERRUPT_REG_CLKD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_CLKD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_CLKD_MSK                          0x20
+
+/*
+ * flag_pwrokbst_mask
+ */
+#define TFA98XX_INTERRUPT_REG_DCCD                          (0x1<<6)
+#define TFA98XX_INTERRUPT_REG_DCCD_POS                             6
+#define TFA98XX_INTERRUPT_REG_DCCD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_DCCD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_DCCD_MSK                          0x40
+
+/*
+ * flag_cf_speakererror_mask
+ */
+#define TFA98XX_INTERRUPT_REG_SPKD                          (0x1<<7)
+#define TFA98XX_INTERRUPT_REG_SPKD_POS                             7
+#define TFA98XX_INTERRUPT_REG_SPKD_LEN                             1
+#define TFA98XX_INTERRUPT_REG_SPKD_MAX                             1
+#define TFA98XX_INTERRUPT_REG_SPKD_MSK                          0x80
+
+/*
+ * flag_watchdog_reset_mask
+ */
+#define TFA98XX_INTERRUPT_REG_WDD                           (0x1<<8)
+#define TFA98XX_INTERRUPT_REG_WDD_POS                              8
+#define TFA98XX_INTERRUPT_REG_WDD_LEN                              1
+#define TFA98XX_INTERRUPT_REG_WDD_MAX                              1
+#define TFA98XX_INTERRUPT_REG_WDD_MSK                          0x100
+
+/*
+ * enable_interrupt
+ */
+#define TFA98XX_INTERRUPT_REG_INT                          (0x1<<14)
+#define TFA98XX_INTERRUPT_REG_INT_POS                             14
+#define TFA98XX_INTERRUPT_REG_INT_LEN                              1
+#define TFA98XX_INTERRUPT_REG_INT_MAX                              1
+#define TFA98XX_INTERRUPT_REG_INT_MSK                         0x4000
+
+/*
+ * invert_int_polarity
+ */
+#define TFA98XX_INTERRUPT_REG_INTP                         (0x1<<15)
+#define TFA98XX_INTERRUPT_REG_INTP_POS                            15
+#define TFA98XX_INTERRUPT_REG_INTP_LEN                             1
+#define TFA98XX_INTERRUPT_REG_INTP_MAX                             1
+#define TFA98XX_INTERRUPT_REG_INTP_MSK                        0x8000
+
+
+/*
+ * (0x10)-pdm_ctrl
+ */
+
+/*
+ * pdm_i2s_input
+ */
+#define TFA98XX_PDM_CTRL_PDMSEL                             (0x1<<0)
+#define TFA98XX_PDM_CTRL_PDMSEL_POS                                0
+#define TFA98XX_PDM_CTRL_PDMSEL_LEN                                1
+#define TFA98XX_PDM_CTRL_PDMSEL_MAX                                1
+#define TFA98XX_PDM_CTRL_PDMSEL_MSK                              0x1
+
+/*
+ * I2S_master_ena
+ */
+#define TFA98XX_PDM_CTRL_I2SMOUTEN                          (0x1<<1)
+#define TFA98XX_PDM_CTRL_I2SMOUTEN_POS                             1
+#define TFA98XX_PDM_CTRL_I2SMOUTEN_LEN                             1
+#define TFA98XX_PDM_CTRL_I2SMOUTEN_MAX                             1
+#define TFA98XX_PDM_CTRL_I2SMOUTEN_MSK                           0x2
+
+/*
+ * pdm_out_sel_r
+ */
+#define TFA98XX_PDM_CTRL_PDMORSEL                           (0x3<<2)
+#define TFA98XX_PDM_CTRL_PDMORSEL_POS                              2
+#define TFA98XX_PDM_CTRL_PDMORSEL_LEN                              2
+#define TFA98XX_PDM_CTRL_PDMORSEL_MAX                              3
+#define TFA98XX_PDM_CTRL_PDMORSEL_MSK                            0xc
+
+/*
+ * pdm_out_sel_l
+ */
+#define TFA98XX_PDM_CTRL_PDMOLSEL                           (0x3<<4)
+#define TFA98XX_PDM_CTRL_PDMOLSEL_POS                              4
+#define TFA98XX_PDM_CTRL_PDMOLSEL_LEN                              2
+#define TFA98XX_PDM_CTRL_PDMOLSEL_MAX                              3
+#define TFA98XX_PDM_CTRL_PDMOLSEL_MSK                           0x30
+
+/*
+ * micdat_out_sel
+ */
+#define TFA98XX_PDM_CTRL_PADSEL                             (0x3<<6)
+#define TFA98XX_PDM_CTRL_PADSEL_POS                                6
+#define TFA98XX_PDM_CTRL_PADSEL_LEN                                2
+#define TFA98XX_PDM_CTRL_PADSEL_MAX                                3
+#define TFA98XX_PDM_CTRL_PADSEL_MSK                             0xc0
+
+
+/*
+ * (0x11)-pdm_out_ctrl
+ */
+
+/*
+ * secure_dly
+ */
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN                       (0x1<<0)
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_POS                          0
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_LEN                          1
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_MAX                          1
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDEN_MSK                        0x1
+
+/*
+ * d_out_valid_rf_mux
+ */
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF                       (0x1<<1)
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_POS                          1
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_LEN                          1
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_MAX                          1
+#define TFA98XX_PDM_OUT_CTRL_PDMOSDCF_MSK                        0x2
+
+/*
+ * Speak_As_Mic_en
+ */
+#define TFA98XX_PDM_OUT_CTRL_SAAMEN                         (0x1<<4)
+#define TFA98XX_PDM_OUT_CTRL_SAAMEN_POS                            4
+#define TFA98XX_PDM_OUT_CTRL_SAAMEN_LEN                            1
+#define TFA98XX_PDM_OUT_CTRL_SAAMEN_MAX                            1
+#define TFA98XX_PDM_OUT_CTRL_SAAMEN_MSK                         0x10
+
+/*
+ * speak_as_mic_lp_mode
+ */
+#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN                       (0x1<<5)
+#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_POS                          5
+#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_LEN                          1
+#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_MAX                          1
+#define TFA98XX_PDM_OUT_CTRL_SAAMLPEN_MSK                       0x20
+
+/*
+ * pdm_out_rate
+ */
+#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN                      (0x1<<6)
+#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_POS                         6
+#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_LEN                         1
+#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_MAX                         1
+#define TFA98XX_PDM_OUT_CTRL_PDMOINTEN_MSK                      0x40
+
+
+/*
+ * (0x12)-pdm_ds4_r
+ */
+
+/*
+ * ds4_g1_r
+ */
+#define TFA98XX_PDM_DS4_R_PDMORG1                           (0xf<<0)
+#define TFA98XX_PDM_DS4_R_PDMORG1_POS                              0
+#define TFA98XX_PDM_DS4_R_PDMORG1_LEN                              4
+#define TFA98XX_PDM_DS4_R_PDMORG1_MAX                             15
+#define TFA98XX_PDM_DS4_R_PDMORG1_MSK                            0xf
+
+/*
+ * ds4_g2_r
+ */
+#define TFA98XX_PDM_DS4_R_PDMORG2                           (0xf<<4)
+#define TFA98XX_PDM_DS4_R_PDMORG2_POS                              4
+#define TFA98XX_PDM_DS4_R_PDMORG2_LEN                              4
+#define TFA98XX_PDM_DS4_R_PDMORG2_MAX                             15
+#define TFA98XX_PDM_DS4_R_PDMORG2_MSK                           0xf0
+
+
+/*
+ * (0x13)-pdm_ds4_l
+ */
+
+/*
+ * ds4_g1_l
+ */
+#define TFA98XX_PDM_DS4_L_PDMOLG1                           (0xf<<0)
+#define TFA98XX_PDM_DS4_L_PDMOLG1_POS                              0
+#define TFA98XX_PDM_DS4_L_PDMOLG1_LEN                              4
+#define TFA98XX_PDM_DS4_L_PDMOLG1_MAX                             15
+#define TFA98XX_PDM_DS4_L_PDMOLG1_MSK                            0xf
+
+/*
+ * ds4_g2_l
+ */
+#define TFA98XX_PDM_DS4_L_PDMOLG2                           (0xf<<4)
+#define TFA98XX_PDM_DS4_L_PDMOLG2_POS                              4
+#define TFA98XX_PDM_DS4_L_PDMOLG2_LEN                              4
+#define TFA98XX_PDM_DS4_L_PDMOLG2_MAX                             15
+#define TFA98XX_PDM_DS4_L_PDMOLG2_MSK                           0xf0
+
+
+/*
+ * (0x22)-ctrl_saam_pga
+ */
+
+/*
+ * Ctrl_saam_pga_gain
+ */
+#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN                      (0x7<<0)
+#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_POS                         0
+#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_LEN                         3
+#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_MAX                         7
+#define TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_MSK                       0x7
+
+/*
+ * ctrl_saam_pga_src
+ */
+#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL                   (0x1<<5)
+#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_POS                      5
+#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_LEN                      1
+#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_MAX                      1
+#define TFA98XX_CTRL_SAAM_PGA_SAAMPGACTRL_MSK                   0x20
+
+
+/*
+ * (0x25)-misc_ctrl
+ */
+
+/*
+ * pll_fcco
+ */
+#define TFA98XX_MISC_CTRL_PLLCCOSEL                         (0x1<<0)
+#define TFA98XX_MISC_CTRL_PLLCCOSEL_POS                            0
+#define TFA98XX_MISC_CTRL_PLLCCOSEL_LEN                            1
+#define TFA98XX_MISC_CTRL_PLLCCOSEL_MAX                            1
+#define TFA98XX_MISC_CTRL_PLLCCOSEL_MSK                          0x1
+
+
+/*
+ * (0x46)-CurrentSense1
+ */
+
+/*
+ * bypass_gc
+ */
+#define TFA98XX_CURRENTSENSE1_CSBYPGC                       (0x1<<0)
+#define TFA98XX_CURRENTSENSE1_CSBYPGC_POS                          0
+#define TFA98XX_CURRENTSENSE1_CSBYPGC_LEN                          1
+#define TFA98XX_CURRENTSENSE1_CSBYPGC_MAX                          1
+#define TFA98XX_CURRENTSENSE1_CSBYPGC_MSK                        0x1
+
+
+/*
+ * (0x49)-CurrentSense4
+ */
+
+/*
+ * ctrl_bypassclip
+ */
+#define TFA98XX_CURRENTSENSE4_CLIP                          (0x1<<0)
+#define TFA98XX_CURRENTSENSE4_CLIP_POS                             0
+#define TFA98XX_CURRENTSENSE4_CLIP_LEN                             1
+#define TFA98XX_CURRENTSENSE4_CLIP_MAX                             1
+#define TFA98XX_CURRENTSENSE4_CLIP_MSK                           0x1
+
+/*
+ * ctrl_bypassclip2
+ */
+#define TFA98XX_CURRENTSENSE4_CLIP2                         (0x1<<1)
+#define TFA98XX_CURRENTSENSE4_CLIP2_POS                            1
+#define TFA98XX_CURRENTSENSE4_CLIP2_LEN                            1
+#define TFA98XX_CURRENTSENSE4_CLIP2_MAX                            1
+#define TFA98XX_CURRENTSENSE4_CLIP2_MSK                          0x2
+
+
+/*
+ * (0x62)-Hidden_mtp_ctrl_reg3
+ */
+
+
+/*
+ * (0x70)-cf_controls
+ */
+
+/*
+ * cf_rst_dsp
+ */
+#define TFA98XX_CF_CONTROLS_RST                             (0x1<<0)
+#define TFA98XX_CF_CONTROLS_RST_POS                                0
+#define TFA98XX_CF_CONTROLS_RST_LEN                                1
+#define TFA98XX_CF_CONTROLS_RST_MAX                                1
+#define TFA98XX_CF_CONTROLS_RST_MSK                              0x1
+
+/*
+ * cf_dmem
+ */
+#define TFA98XX_CF_CONTROLS_DMEM                            (0x3<<1)
+#define TFA98XX_CF_CONTROLS_DMEM_POS                               1
+#define TFA98XX_CF_CONTROLS_DMEM_LEN                               2
+#define TFA98XX_CF_CONTROLS_DMEM_MAX                               3
+#define TFA98XX_CF_CONTROLS_DMEM_MSK                             0x6
+
+/*
+ * cf_aif
+ */
+#define TFA98XX_CF_CONTROLS_AIF                             (0x1<<3)
+#define TFA98XX_CF_CONTROLS_AIF_POS                                3
+#define TFA98XX_CF_CONTROLS_AIF_LEN                                1
+#define TFA98XX_CF_CONTROLS_AIF_MAX                                1
+#define TFA98XX_CF_CONTROLS_AIF_MSK                              0x8
+
+/*
+ * cf_int
+ */
+#define TFA98XX_CF_CONTROLS_CFINT                           (0x1<<4)
+#define TFA98XX_CF_CONTROLS_CFINT_POS                              4
+#define TFA98XX_CF_CONTROLS_CFINT_LEN                              1
+#define TFA98XX_CF_CONTROLS_CFINT_MAX                              1
+#define TFA98XX_CF_CONTROLS_CFINT_MSK                           0x10
+
+/*
+ * cf_req
+ */
+#define TFA98XX_CF_CONTROLS_REQ                            (0xff<<8)
+#define TFA98XX_CF_CONTROLS_REQ_POS                                8
+#define TFA98XX_CF_CONTROLS_REQ_LEN                                8
+#define TFA98XX_CF_CONTROLS_REQ_MAX                              255
+#define TFA98XX_CF_CONTROLS_REQ_MSK                           0xff00
+
+
+/*
+ * (0x71)-cf_mad
+ */
+
+/*
+ * cf_madd
+ */
+#define TFA9891_CF_MAD_MADD                              (0xffff<<0)
+#define TFA9891_CF_MAD_MADD_POS                                    0
+#define TFA9891_CF_MAD_MADD_LEN                                   16
+#define TFA9891_CF_MAD_MADD_MAX                                65535
+#define TFA9891_CF_MAD_MADD_MSK                               0xffff
+
+
+/*
+ * (0x72)-cf_mem
+ */
+
+/*
+ * cf_mema
+ */
+#define TFA9891_CF_MEM_MEMA                              (0xffff<<0)
+#define TFA9891_CF_MEM_MEMA_POS                                    0
+#define TFA9891_CF_MEM_MEMA_LEN                                   16
+#define TFA9891_CF_MEM_MEMA_MAX                                65535
+#define TFA9891_CF_MEM_MEMA_MSK                               0xffff
+
+
+/*
+ * (0x73)-cf_status
+ */
+
+/*
+ * cf_err
+ */
+#define TFA9891_CF_STATUS_ERR                              (0xff<<0)
+#define TFA9891_CF_STATUS_ERR_POS                                  0
+#define TFA9891_CF_STATUS_ERR_LEN                                  8
+#define TFA9891_CF_STATUS_ERR_MAX                                255
+#define TFA9891_CF_STATUS_ERR_MSK                               0xff
+
+/*
+ * cf_ack
+ */
+#define TFA9891_CF_STATUS_ACK                              (0xff<<8)
+#define TFA9891_CF_STATUS_ACK_POS                                  8
+#define TFA9891_CF_STATUS_ACK_LEN                                  8
+#define TFA9891_CF_STATUS_ACK_MAX                                255
+#define TFA9891_CF_STATUS_ACK_MSK                             0xff00
+
+
+/*
+ * (0x80)-Key2Protected_spkr_cal_mtp
+ */
+
+/*
+ * calibration_onetime
+ */
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC           (0x1<<0)
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_POS              0
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_LEN              1
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_MAX              1
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPOTC_MSK            0x1
+
+/*
+ * calibr_ron_done
+ */
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX            (0x1<<1)
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_POS               1
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_LEN               1
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_MAX               1
+#define TFA98XX_KEY2PROTECTED_SPKR_CAL_MTP_MTPEX_MSK             0x2
+
+#endif /* TFA9891_GENREGS_H */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9891_init.c b/techpack/audio/asoc/codecs/tfa98xx/tfa9891_init.c
new file mode 100644
index 0000000..bce1db9
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9891_init.c
@@ -0,0 +1,51 @@
+/*
+ *Copyright 2014,2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *            
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *             
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+ 
+
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "tfa_internal.h"
+
+#include "tfa98xx_tfafieldnames.h"
+
+static enum Tfa98xx_Error tfa9891_specific(Tfa98xx_handle_t handle)
+{
+        enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+        if (!tfa98xx_handle_is_open(handle))
+                return Tfa98xx_Error_NotOpen;
+
+	/* ----- generated code start ----- */
+	/* -----  version 18.0 ----- */
+	tfa98xx_write_register16(handle, 0x09, 0x025d); //POR=0x024d
+	tfa98xx_write_register16(handle, 0x10, 0x0018); //POR=0x0024
+	tfa98xx_write_register16(handle, 0x22, 0x0003); //POR=0x0023
+	tfa98xx_write_register16(handle, 0x25, 0x0001); //POR=0x0000
+	tfa98xx_write_register16(handle, 0x46, 0x0000); //POR=0x4000
+	tfa98xx_write_register16(handle, 0x55, 0x3ffb); //POR=0x7fff
+	/* ----- generated code end   ----- */
+
+        return error;
+}
+
+
+/*
+ * register device specifics functions
+ */
+void tfa9891_ops(struct tfa_device_ops *ops) {
+	ops->tfa_init=tfa9891_specific;
+
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9891_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/tfa9891_tfafieldnames.h
new file mode 100644
index 0000000..987db1b
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9891_tfafieldnames.h
@@ -0,0 +1,515 @@
+/*
+ * tfa9891_tfafieldnames.h
+ *
+ *  Created on: Jul 16, 2015
+ *      Author: wim
+ */
+
+#ifndef TFA_INC_TFA9891_TFAFIELDNAMES_H_
+#define TFA_INC_TFA9891_TFAFIELDNAMES_H_
+
+/** Filename: Tfa9891_TfaFieldnames.h
+ *  This file was generated automatically on 07/16/15 at 15:00:02.
+ *  Source file: TFA9891_I2C_list_V13.xls
+ */
+
+#define TFA9891_I2CVERSION    13.0
+
+
+#define TFA9891_NAMETABLE static tfaBfName_t Tfa9891DatasheetNames[]= {\
+   { 0x0, "VDDS"},    /* POR                                               , */\
+   { 0x10, "PLLS"},    /* PLL                                               , */\
+   { 0x20, "OTDS"},    /* OTP                                               , */\
+   { 0x30, "OVDS"},    /* OVP                                               , */\
+   { 0x40, "UVDS"},    /* UVP                                               , */\
+   { 0x50, "OCDS"},    /* OCP                                               , */\
+   { 0x60, "CLKS"},    /* Clocks                                            , */\
+   { 0x70, "CLIPS"},    /* CLIP                                              , */\
+   { 0x80, "MTPB"},    /* MTP                                               , */\
+   { 0x90, "DCCS"},    /* BOOST                                             , */\
+   { 0xa0, "SPKS"},    /* Speaker                                           , */\
+   { 0xb0, "ACS"},    /* cold start flag                                   , */\
+   { 0xc0, "SWS"},    /* flag engage                                       , */\
+   { 0xd0, "WDS"},    /* flag watchdog reset                               , */\
+   { 0xe0, "AMPS"},    /* amplifier is enabled by manager                   , */\
+   { 0xf0, "AREFS"},    /* references are enabled by manager                 , */\
+   { 0x109, "BATS"},    /* Battery voltage readout; 0[V]..5.5[V]             , */\
+   { 0x208, "TEMPS"},    /* Temperature readout                               , */\
+   { 0x307, "REV"},    /* Device Revision                                   , */\
+   { 0x402, "I2SF"},    /* I2SFormat data 1 input                            , */\
+   { 0x431, "CHS12"},    /* ChannelSelection data1 input  (In CoolFlux)       , */\
+   { 0x450, "CHS3"},    /* Channel Selection data 2 input (coolflux input, the DCDC converter gets the other signal), */\
+   { 0x461, "CHSA"},    /* Input selection for amplifier                     , */\
+   { 0x481, "I2SDOC"},    /* Selection for I2S data out                        , */\
+   { 0x4a0, "DISP"},    /* idp protection                                    , */\
+   { 0x4b0, "I2SDOE"},    /* Enable data output                                , */\
+   { 0x4c3, "I2SSR"},    /* sample rate setting                               , */\
+   { 0x501, "BSSCR"},    /* ProtectionAttackTime                              , */\
+   { 0x523, "BSST"},    /* ProtectionThreshold                               , */\
+   { 0x561, "BSSRL"},    /* ProtectionMaximumReduction                        , */\
+   { 0x582, "BSSRR"},    /* Protection Release Timer                          , */\
+   { 0x5b1, "BSSHY"},    /* ProtectionHysterese                               , */\
+   { 0x5e0, "BSSR"},    /* battery voltage for I2C read out only             , */\
+   { 0x5f0, "BSSBY"},    /* bypass clipper battery protection                 , */\
+   { 0x600, "DPSA"},    /* Enable dynamic powerstage activation              , */\
+   { 0x613, "AMPSL"},    /* control slope                                     , */\
+   { 0x650, "CFSM"},    /* Soft mute in CoolFlux                             , */\
+   { 0x670, "BSSS"},    /* batsensesteepness                                 , */\
+   { 0x687, "VOL"},    /* volume control (in CoolFlux)                      , */\
+   { 0x702, "DCVO"},    /* Boost voltage                                     , */\
+   { 0x732, "DCMCC"},    /* Max boost coil current                            , */\
+   { 0x7a0, "DCIE"},    /* Adaptive boost mode                               , */\
+   { 0x7b0, "DCSR"},    /* Soft RampUp/Down mode for DCDC controller         , */\
+   { 0x800, "TROS"},    /* select external temperature also the ext_temp will be put on the temp read out , */\
+   { 0x818, "EXTTS"},    /* external temperature setting to be given by host  , */\
+   { 0x900, "PWDN"},    /* ON/OFF                                            , */\
+   { 0x910, "I2CR"},    /* I2CReset                                          , */\
+   { 0x920, "CFE"},    /* EnableCoolFlux                                    , */\
+   { 0x930, "AMPE"},    /* EnableAmplifier                                   , */\
+   { 0x940, "DCA"},    /* EnableBoost                                       , */\
+   { 0x950, "SBSL"},    /* Coolflux configured                               , */\
+   { 0x960, "AMPC"},    /* Selection on how AmplifierEnabling                , */\
+   { 0x970, "DCDIS"},    /* DCDC not connected                                , */\
+   { 0x980, "PSDR"},    /* Iddq test amplifier                               , */\
+   { 0x991, "DCCV"},    /* Coil Value                                        , */\
+   { 0x9b1, "CCFD"},    /* Selection CoolFluxClock                           , */\
+   { 0x9d0, "ISEL"},    /* Interface Selection                               , */\
+   { 0x9e0, "IPLL"},    /* selection input PLL for lock                      , */\
+   { 0xa02, "DOLS"},    /* Output selection dataout left channel             , */\
+   { 0xa32, "DORS"},    /* Output selection dataout right channel            , */\
+   { 0xa62, "SPKL"},    /* Selection speaker induction                       , */\
+   { 0xa91, "SPKR"},    /* Selection speaker impedance                       , */\
+   { 0xab3, "DCFG"},    /* DCDC speaker current compensation gain            , */\
+   { 0xb07, "MTPK"},    /* MTP KEY2 register                                 , */\
+   { 0xf00, "VDDD"},    /* mask flag_por for interupt generation             , */\
+   { 0xf10, "OTDD"},    /* mask flag_otpok for interupt generation           , */\
+   { 0xf20, "OVDD"},    /* mask flag_ovpok for interupt generation           , */\
+   { 0xf30, "UVDD"},    /* mask flag_uvpok for interupt generation           , */\
+   { 0xf40, "OCDD"},    /* mask flag_ocp_alarm for interupt generation       , */\
+   { 0xf50, "CLKD"},    /* mask flag_clocks_stable for interupt generation   , */\
+   { 0xf60, "DCCD"},    /* mask flag_pwrokbst for interupt generation        , */\
+   { 0xf70, "SPKD"},    /* mask flag_cf_speakererror for interupt generation , */\
+   { 0xf80, "WDD"},    /* mask flag_watchdog_reset for interupt generation  , */\
+   { 0xfe0, "INT"},    /* enabling interrupt                                , */\
+   { 0xff0, "INTP"},    /* Setting polarity interupt                         , */\
+   { 0x1000, "PDMSEL"},    /* Audio input interface mode                        , */\
+   { 0x1010, "I2SMOUTEN"},    /* I2S Master enable (CLK and WS pads)               , */\
+   { 0x1021, "PDMORSEL"},    /* PDM Output right channel source selection         , */\
+   { 0x1041, "PDMOLSEL"},    /* PDM Output Left/Mono channel source selection     , */\
+   { 0x1061, "PADSEL"},    /* Output interface mode and ball selection          , */\
+   { 0x1100, "PDMOSDEN"},    /* Secure delay Cell                                 , */\
+   { 0x1110, "PDMOSDCF"},    /* Rising Falling Resync control Mux                 , */\
+   { 0x1140, "SAAMEN"},    /* Speaker As a Mic feature ON/OFF                   , */\
+   { 0x1150, "SAAMLPEN"},    /* speaker_as_mic low power mode (only in PDM_out mode), */\
+   { 0x1160, "PDMOINTEN"},    /* PDM output interpolation ratio                    , */\
+   { 0x1203, "PDMORG1"},    /* PDM Interpolator Right Channel DS4 G1 Gain Value  , */\
+   { 0x1243, "PDMORG2"},    /* PDM Interpolator Right Channel DS4 G2 Gain Value  , */\
+   { 0x1303, "PDMOLG1"},    /* PDM Interpolator Left Channel DS4 G1 Gain Value   , */\
+   { 0x1343, "PDMOLG2"},    /* PDM Interpolator Left Channel DS4 G2 Gain Value   , */\
+   { 0x2202, "SAAMGAIN"},    /* pga gain                                          , */\
+   { 0x2250, "SAAMPGACTRL"},    /* 0 = active input common mode voltage source at the attenuator/PGA level, */\
+   { 0x2500, "PLLCCOSEL"},    /* pll cco frequency                                 , */\
+   { 0x4600, "CSBYPGC"},    /* bypass_gc, bypasses the CS gain correction        , */\
+   { 0x4900, "CLIP"},    /* Bypass clip control (function depending on digimux clip_x), */\
+   { 0x4910, "CLIP2"},    /* Bypass clip control (function depending on digimux clip_x), */\
+   { 0x62b0, "CIMTP"},    /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */\
+   { 0x7000, "RST"},    /* Reset CoolFlux DSP                                , */\
+   { 0x7011, "DMEM"},    /* Target memory for access                          , */\
+   { 0x7030, "AIF"},    /* Autoincrement-flag for memory-address             , */\
+   { 0x7040, "CFINT"},    /* Interrupt CoolFlux DSP                            , */\
+   { 0x7087, "REQ"},    /* request for access (8 channels)                   , */\
+   { 0x710f, "MADD"},    /* memory-address to be accessed                     , */\
+   { 0x720f, "MEMA"},    /* activate memory access (24- or 32-bits data is written/read to/from memory, */\
+   { 0x7307, "ERR"},    /* cf error Flags                                    , */\
+   { 0x7387, "ACK"},    /* acknowledge of requests (8 channels")"            , */\
+   { 0x8000, "MTPOTC"},    /* Calibration schedule (key2 protected)             , */\
+   { 0x8010, "MTPEX"},    /* (key2 protected) calibration of Ron has been executed, */\
+   { 0x8045, "SWPROFIL" },\
+   { 0x80a5, "SWVSTEP" },\
+   { 0xffff,"Unknown bitfield enum" }   /* not found */\
+};
+
+#define TFA9891_BITNAMETABLE static tfaBfName_t Tfa9891BitNames[]= {\
+   { 0x0, "POR"},    /* POR                                               , */\
+   { 0x10, "PLL_LOCK"},    /* PLL                                               , */\
+   { 0x20, "flag_otpok"},    /* OTP                                               , */\
+   { 0x30, "flag_ovpok"},    /* OVP                                               , */\
+   { 0x40, "flag_uvpok"},    /* UVP                                               , */\
+   { 0x50, "flag_OCP_alarm"},    /* OCP                                               , */\
+   { 0x60, "flag_clocks_stable"},    /* Clocks                                            , */\
+   { 0x70, "CLIP"},    /* CLIP                                              , */\
+   { 0x80, "mtp_busy"},    /* MTP                                               , */\
+   { 0x90, "flag_pwrokbst"},    /* BOOST                                             , */\
+   { 0xa0, "flag_cf_speakererror"},    /* Speaker                                           , */\
+   { 0xb0, "flag_cold_started"},    /* cold start flag                                   , */\
+   { 0xc0, "flag_engage"},    /* flag engage                                       , */\
+   { 0xd0, "flag_watchdog_reset"},    /* flag watchdog reset                               , */\
+   { 0xe0, "flag_enbl_amp"},    /* amplifier is enabled by manager                   , */\
+   { 0xf0, "flag_enbl_ref"},    /* references are enabled by manager                 , */\
+   { 0x109, "bat_adc"},    /* Battery voltage readout; 0[V]..5.5[V]             , */\
+   { 0x208, "temp_adc"},    /* Temperature readout                               , */\
+   { 0x307, "rev_reg"},    /* Device Revision                                   , */\
+   { 0x402, "i2s_seti"},    /* I2SFormat data 1 input                            , */\
+   { 0x431, "chan_sel1"},    /* ChannelSelection data1 input  (In CoolFlux)       , */\
+   { 0x450, "lr_sw_i2si2"},    /* Channel Selection data 2 input (coolflux input, the DCDC converter gets the other signal), */\
+   { 0x461, "input_sel"},    /* Input selection for amplifier                     , */\
+   { 0x481, "datao_sel"},    /* Selection for I2S data out                        , */\
+   { 0x4a0, "disable_idp"},    /* idp protection                                    , */\
+   { 0x4b0, "enbl_datao"},    /* Enable data output                                , */\
+   { 0x4c3, "i2s_fs"},    /* sample rate setting                               , */\
+   { 0x501, "vbat_prot_attacktime"},    /* ProtectionAttackTime                              , */\
+   { 0x523, "vbat_prot_thlevel"},    /* ProtectionThreshold                               , */\
+   { 0x561, "vbat_prot_max_reduct"},    /* ProtectionMaximumReduction                        , */\
+   { 0x582, "vbat_prot_release_t"},    /* Protection Release Timer                          , */\
+   { 0x5b1, "vbat_prot_hysterese"},    /* ProtectionHysterese                               , */\
+   { 0x5d0, "reset_min_vbat"},    /* reset clipper                                     , */\
+   { 0x5e0, "sel_vbat"},    /* battery voltage for I2C read out only             , */\
+   { 0x5f0, "bypass_clipper"},    /* bypass clipper battery protection                 , */\
+   { 0x600, "dpsa"},    /* Enable dynamic powerstage activation              , */\
+   { 0x613, "ctrl_slope"},    /* control slope                                     , */\
+   { 0x650, "cf_mute"},    /* Soft mute in CoolFlux                             , */\
+   { 0x660, "sel_other_vamp"},    /* Input selection for the second channel of the DCDC inteligent mode detector, */\
+   { 0x670, "ctrl_batsensesteepness"},    /* batsensesteepness                                 , */\
+   { 0x687, "vol"},    /* volume control (in CoolFlux)                      , */\
+   { 0x702, "ctrl_bstvolt"},    /* Boost voltage                                     , */\
+   { 0x732, "ctrl_bstcur"},    /* Max boost coil current                            , */\
+   { 0x761, "ctrl_slopebst_1_0"},    /* Setting for the slope of the boost converter power stage, */\
+   { 0x781, "ctrl_slopebst_3_2"},    /* Setting for the part of the power transistor voltage to be used in peak current mode control, */\
+   { 0x7a0, "boost_intel"},    /* Adaptive boost mode                               , */\
+   { 0x7b0, "boost_speed"},    /* Soft RampUp/Down mode for DCDC controller         , */\
+   { 0x7c1, "ctrl_delay_comp_dcdc"},    /* delay compensation in current patg compared to delay in the audio path (relative) , */\
+   { 0x7e0, "boost_input"},    /* Selection intelligent boost detector input        , */\
+   { 0x7f0, "ctrl_supplysense"},    /* ADC10 input selection                             , */\
+   { 0x800, "ext_temp_sel"},    /* select external temperature also the ext_temp will be put on the temp read out , */\
+   { 0x818, "ext_temp"},    /* external temperature setting to be given by host  , */\
+   { 0x8a0, "ctrl_spk_coilpvp_bst"},    /* Peak voltage protection boost converter           , */\
+   { 0x8b2, "ctrl_dcdc_synchronisation"},    /* DCDC synchronisation off + 7 positions            , */\
+   { 0x8e0, "ctrl_cs_samplevalid"},    /* sample valid moment for CS in single sample moment mode, */\
+   { 0x900, "PowerDown"},    /* ON/OFF                                            , */\
+   { 0x910, "reset"},    /* I2CReset                                          , */\
+   { 0x920, "enbl_coolflux"},    /* EnableCoolFlux                                    , */\
+   { 0x930, "enbl_amplifier"},    /* EnableAmplifier                                   , */\
+   { 0x940, "enbl_boost"},    /* EnableBoost                                       , */\
+   { 0x950, "cf_configured"},    /* Coolflux configured                               , */\
+   { 0x960, "sel_enbl_amplifier"},    /* Selection on how AmplifierEnabling                , */\
+   { 0x970, "dcdcoff_mode"},    /* DCDC not connected                                , */\
+   { 0x980, "cttr_iddqtest"},    /* Iddq test amplifier                               , */\
+   { 0x991, "ctrl_coil_value"},    /* Coil Value                                        , */\
+   { 0x9b1, "ctrl_sel_cf_clock"},    /* Selection CoolFluxClock                           , */\
+   { 0x9d0, "intf_sel"},    /* Interface Selection                               , */\
+   { 0x9e0, "sel_ws_bck"},    /* selection input PLL for lock                      , */\
+   { 0xa02, "sel_i2so_l"},    /* Output selection dataout left channel             , */\
+   { 0xa32, "sel_i2so_r"},    /* Output selection dataout right channel            , */\
+   { 0xa62, "ctrl_spkr_coil"},    /* Selection speaker induction                       , */\
+   { 0xa91, "ctrl_spr_res"},    /* Selection speaker impedance                       , */\
+   { 0xab3, "ctrl_dcdc_spkr_i_comp_gain"},    /* DCDC speaker current compensation gain            , */\
+   { 0xaf0, "ctrl_dcdc_spkr_i_comp_sign"},    /* DCDC speaker current compensation sign            , */\
+   { 0xb07, "MTP_key2"},    /* MTP KEY2 register                                 , */\
+   { 0xc0c, "clk_sync_delay"},    /* Delay count for clock synchronisation             , */\
+   { 0xcf0, "enbl_clk_sync"},    /* Enable CGU clock synchronisation                  , */\
+   { 0xd0c, "adc_sync_delay"},    /* Delay count for ADC synchronisation               , */\
+   { 0xdf0, "enable_adc_sync"},    /* Enable ADC synchronisation                        , */\
+   { 0xe00, "bypass_dcdc_curr_prot"},    /* to switch off dcdc reduction with bat prot        , */\
+   { 0xe24, "ctrl_digtoana6_2"},    /* for extra connections digital to analog           , */\
+   { 0xe70, "switch_on_icomp"},    /* icomp dem switch                                  , */\
+   { 0xe87, "reserve_reg_1_7_0"},    /* reserved                                          , */\
+   { 0xf00, "flag_por_mask"},    /* mask flag_por for interupt generation             , */\
+   { 0xf10, "flag_otpok_mask"},    /* mask flag_otpok for interupt generation           , */\
+   { 0xf20, "flag_ovpok_mask"},    /* mask flag_ovpok for interupt generation           , */\
+   { 0xf30, "flag_uvpok_mask"},    /* mask flag_uvpok for interupt generation           , */\
+   { 0xf40, "flag_ocp_alarm_mask"},    /* mask flag_ocp_alarm for interupt generation       , */\
+   { 0xf50, "flag_clocks_stable_mask"},    /* mask flag_clocks_stable for interupt generation   , */\
+   { 0xf60, "flag_pwrokbst_mask"},    /* mask flag_pwrokbst for interupt generation        , */\
+   { 0xf70, "flag_cf_speakererror_mask"},    /* mask flag_cf_speakererror for interupt generation , */\
+   { 0xf80, "flag_watchdog_reset_mask"},    /* mask flag_watchdog_reset for interupt generation  , */\
+   { 0xf90, "flag_lost_clk_mask"},    /* mask flag_lost_clk for interupt generation        , */\
+   { 0xfe0, "enable_interrupt"},    /* enabling interrupt                                , */\
+   { 0xff0, "invert_int_polarity"},    /* Setting polarity interupt                         , */\
+   { 0x1000, "pdm_i2s_input"},    /* Audio input interface mode                        , */\
+   { 0x1010, "I2S_master_ena"},    /* I2S Master enable (CLK and WS pads)               , */\
+   { 0x1021, "pdm_out_sel_r"},    /* PDM Output right channel source selection         , */\
+   { 0x1041, "pdm_out_sel_l"},    /* PDM Output Left/Mono channel source selection     , */\
+   { 0x1061, "micdat_out_sel"},    /* Output interface mode and ball selection          , */\
+   { 0x1100, "secure_dly"},    /* Secure delay Cell                                 , */\
+   { 0x1110, "d_out_valid_rf_mux"},    /* Rising Falling Resync control Mux                 , */\
+   { 0x1140, "Speak_As_Mic_en"},    /* Speaker As a Mic feature ON/OFF                   , */\
+   { 0x1150, "speak_as_mic_lp_mode"},    /* speaker_as_mic low power mode (only in PDM_out mode), */\
+   { 0x1160, "pdm_out_rate"},    /* PDM output interpolation ratio                    , */\
+   { 0x1203, "ds4_g1_r"},    /* PDM Interpolator Right Channel DS4 G1 Gain Value  , */\
+   { 0x1243, "ds4_g2_r"},    /* PDM Interpolator Right Channel DS4 G2 Gain Value  , */\
+   { 0x1303, "ds4_g1_l"},    /* PDM Interpolator Left Channel DS4 G1 Gain Value   , */\
+   { 0x1343, "ds4_g2_l"},    /* PDM Interpolator Left Channel DS4 G2 Gain Value   , */\
+   { 0x1400, "clk_secure_dly"},    /* Secure delay Cell  on clock path                  , */\
+   { 0x1410, "data_secure_dly"},    /* Secure delay Cell  enable on PDM data path        , */\
+   { 0x2202, "Ctrl_saam_pga_gain"},    /* pga gain                                          , */\
+   { 0x2250, "ctrl_saam_pga_src"},    /* 0 = active input common mode voltage source at the attenuator/PGA level, */\
+   { 0x2300, "flag_saam_spare"},    /* spare flag                                        , */\
+   { 0x2400, "ctrl_saam_pga_tm"},    /* enables PGA test mode                             , */\
+   { 0x2500, "pll_fcco"},    /* pll cco frequency                                 , */\
+   { 0x3000, "flag_hi_small"},    /* positive small window dcdc converter              , */\
+   { 0x3010, "flag_hi_large"},    /* positive large window dcdc converter              , */\
+   { 0x3020, "flag_lo_small"},    /* negative small window dcdc converter              , */\
+   { 0x3030, "flag_lo_large"},    /* negative large window dcdc converter              , */\
+   { 0x3040, "flag_voutcomp"},    /* flag_voutcomp, indication Vset is larger than Vbat, */\
+   { 0x3050, "flag_voutcomp93"},    /* flag_voutcomp93, indication Vset is larger than 1.07* Vbat , */\
+   { 0x3060, "flag_voutcomp86"},    /* flag_voutcomp86, indication Vset is larger than 1.14* Vbat , */\
+   { 0x3070, "flag_hiz"},    /* flag_hiz, indication Vbst is larger than  Vbat    , */\
+   { 0x3080, "flag_hi_peak"},    /* flag_hi_peak, indication hi_peak                  , */\
+   { 0x3090, "flag_ocpokbst"},    /* flag_ocpokbst, indication no over current in boost converter pmos switch, */\
+   { 0x30a0, "flag_peakcur"},    /* flag_peakcur, indication current is max in dcdc converter, */\
+   { 0x30b0, "flag_ocpokap"},    /* flag_ocpokap, indication no over current in amplifier "a" pmos output stage, */\
+   { 0x30c0, "flag_ocpokan"},    /* flag_ocpokan, indication no over current in amplifier "a" nmos output stage, */\
+   { 0x30d0, "flag_ocpokbp"},    /* flag_ocpokbp, indication no over current in amplifier "b" pmos output stage, */\
+   { 0x30e0, "flag_ocpokbn"},    /* flag_ocpokbn, indication no over current in amplifier"b" nmos output stage, */\
+   { 0x30f0, "lost_clk"},    /* lost_clk, lost clock indication CGU               , */\
+   { 0x310f, "mtp_man_data_out"},    /* single word read from MTP (manual copy)           , */\
+   { 0x3200, "key01_locked"},    /* key01_locked, indication key 1 is locked          , */\
+   { 0x3210, "key02_locked"},    /* key02_locked, indication key 2 is locked          , */\
+   { 0x3225, "mtp_ecc_tcout"},    /* mtp_ecc_tcout                                     , */\
+   { 0x3280, "mtpctrl_valid_test_rd"},    /* mtp test readout for read                         , */\
+   { 0x3290, "mtpctrl_valid_test_wr"},    /* mtp test readout for write                        , */\
+   { 0x32a0, "flag_in_alarm_state"},    /* alarm state                                       , */\
+   { 0x32b0, "mtp_ecc_err2"},    /* two or more bit errors detected in MTP, can not reconstruct value, */\
+   { 0x32c0, "mtp_ecc_err1"},    /* one bit error detected in MTP, reconstructed value, */\
+   { 0x32d0, "mtp_mtp_hvf"},    /* high voltage ready flag for MTP                   , */\
+   { 0x32f0, "mtp_zero_check_fail"},    /* zero check failed (tbd) for MTP                   , */\
+   { 0x3300, "flag_adc10_ready"},    /* flag_adc10_ready, indication adc10 is ready       , */\
+   { 0x3310, "flag_clipa_high"},    /* flag_clipa_high, indication pmos amplifier "a" is clipping, */\
+   { 0x3320, "flag_clipa_low"},    /* flag_clipa_low, indication nmos amplifier "a" is clipping, */\
+   { 0x3330, "flag_clipb_high"},    /* flag_clipb_high, indication pmos amplifier "b" is clipping, */\
+   { 0x3340, "flag_clipb_low"},    /* flag_clipb_low, indication nmos amplifier "b" is clipping, */\
+   { 0x3359, "data_adc10_tempbat"},    /* adc 10 data output for testing                    , */\
+   { 0x33f0, "flag_vddd_comp_nok"},    /* power switch flag 2 for testing                   , */\
+   { 0x400f, "hid_code"},    /* hidden code                                       , */\
+   { 0x4100, "bypass_hp"},    /* Bypass_High Pass Filter                           , */\
+   { 0x4110, "hard_mute"},    /* Hard Mute                                         , */\
+   { 0x4120, "soft_mute"},    /* Soft Mute                                         , */\
+   { 0x4134, "PWM_Delay"},    /* PWM DelayBits to set the delay                    , */\
+   { 0x4180, "PWM_Shape"},    /* PWM Shape                                         , */\
+   { 0x4190, "PWM_BitLength"},    /* PWM Bitlength in noise shaper                     , */\
+   { 0x4207, "ctrl_drive"},    /* drive bits to select amount of power stages amplifier, */\
+   { 0x4281, "dpsalevel"},    /* DPSA Threshold level                              , */\
+   { 0x42a1, "dpsa_release"},    /* DPSA Release time                                 , */\
+   { 0x42c0, "ctrl_coincidence"},    /* Prevent simultaneously switching of output stage  , */\
+   { 0x42d0, "ctrl_kickback"},    /* Prevent double pulses of output stage             , */\
+   { 0x42e0, "ctrl_test_sdeltaoffset"},    /* ctrl_test_sdeltaoffset                            , */\
+   { 0x42f0, "ctrl_test_sdeltaclk"},    /* ctrl_test_sdeltaclk                               , */\
+   { 0x4309, "ctrl_drivebst"},    /* Drive bits to select the powertransistor sections boost converter, */\
+   { 0x43a0, "ctrl_ocptestbst"},    /* Boost OCP.                                        , */\
+   { 0x43c0, "enbl_hi_peak"},    /* enable for high peak comparator                   , */\
+   { 0x43d0, "test_abistfft_enbl"},    /* FFT coolflux                                      , */\
+   { 0x43e0, "ctrl_sensetest_amp"},    /* sensetest amplifier                               , */\
+   { 0x43f0, "test_bcontrol"},    /* test _bcontrol                                    , */\
+   { 0x4400, "ctrl_reversebst"},    /* OverCurrent Protection selection of power stage boost converter, */\
+   { 0x4410, "ctrl_sensetest"},    /* Test option for the sense NMOS in booster for current mode control., */\
+   { 0x4420, "enbl_engagebst"},    /* Enable power stage dcdc controller                , */\
+   { 0x4430, "enbl_hi_small"},    /* Enable bit of hi (small) comparator               , */\
+   { 0x4440, "enbl_hi_large"},    /* Enable bit of hi (large) comparator               , */\
+   { 0x4450, "enbl_lo_small"},    /* Enable bit of lo (small) comparator               , */\
+   { 0x4460, "enbl_lo_large"},    /* Enable bit of lo (large) comparator               , */\
+   { 0x4470, "enbl_slopecur"},    /* Enable bit of max-current dac                     , */\
+   { 0x4480, "enbl_voutcomp"},    /* Enable vout comparators                           , */\
+   { 0x4490, "enbl_voutcomp93"},    /* Enable vout-93 comparators                        , */\
+   { 0x44a0, "enbl_voutcomp86"},    /* Enable vout-86 comparators                        , */\
+   { 0x44b0, "enbl_hizcom"},    /* Enable hiz comparator                             , */\
+   { 0x44c0, "enbl_pcdac"},    /* Enable peak current dac                           , */\
+   { 0x44d0, "enbl_pccomp"},    /* Enable peak current comparator                    , */\
+   { 0x44e0, "enbl_windac"},    /* Enable window dac                                 , */\
+   { 0x44f0, "enbl_powerbst"},    /* Enable line of the powerstage                     , */\
+   { 0x4507, "ocp_thr"},    /* ocp_thr threshold level for OCP                   , */\
+   { 0x4580, "bypass_glitchfilter"},    /* Bypass glitchfilter                               , */\
+   { 0x4590, "bypass_ovp"},    /* Bypass OVP                                        , */\
+   { 0x45a0, "bypass_uvp"},    /* Bypass UVP                                        , */\
+   { 0x45b0, "bypass_otp"},    /* Bypass OTP                                        , */\
+   { 0x45c0, "bypass_ocp"},    /* Bypass OCP                                        , */\
+   { 0x45d0, "bypass_ocpcounter"},    /* BypassOCPCounter                                  , */\
+   { 0x45e0, "bypass_lost_clk"},    /* Bypasslost_clk detector                           , */\
+   { 0x45f0, "vpalarm"},    /* vpalarm (uvp ovp handling)                        , */\
+   { 0x4600, "bypass_gc"},    /* bypass_gc, bypasses the CS gain correction        , */\
+   { 0x4610, "cs_gain_control"},    /* gain control by means of MTP or i2c               , */\
+   { 0x4627, "cs_gain"},    /* + / - 128 steps in steps of 1/4 %  2's compliment , */\
+   { 0x46a0, "bypass_lp"},    /* bypass Low-Pass filter in temperature sensor      , */\
+   { 0x46b0, "bypass_pwmcounter"},    /* bypass_pwmcounter                                 , */\
+   { 0x46c0, "ctrl_cs_negfixed"},    /* does not switch to neg                            , */\
+   { 0x46d2, "ctrl_cs_neghyst"},    /* switches to neg depending on level                , */\
+   { 0x4700, "switch_fb"},    /* switch_fb                                         , */\
+   { 0x4713, "se_hyst"},    /* se_hyst                                           , */\
+   { 0x4754, "se_level"},    /* se_level                                          , */\
+   { 0x47a5, "ktemp"},    /* temperature compensation trimming                 , */\
+   { 0x4800, "ctrl_negin"},    /* negin                                             , */\
+   { 0x4810, "ctrl_cs_sein"},    /* cs_sein                                           , */\
+   { 0x4820, "ctrl_coincidencecs"},    /* Coincidence current sense                         , */\
+   { 0x4830, "ctrl_iddqtestbst"},    /* for iddq testing in powerstage of boost convertor , */\
+   { 0x4840, "ctrl_coincidencebst"},    /* Switch protection on to prevent simultaniously switching power stages bst and amp, */\
+   { 0x4851, "clock_sh_sel"},    /* Clock SH selection                                , */\
+   { 0x4876, "delay_se_neg"},    /* delay of se and neg                               , */\
+   { 0x48e1, "ctrl_cs_ttrack"},    /* sample & hold track time                          , */\
+   { 0x4900, "ctrl_bypassclip"},    /* Bypass clip control (function depending on digimux clip_x), */\
+   { 0x4910, "ctrl_bypassclip2"},    /* Bypass clip control (function depending on digimux clip_x), */\
+   { 0x4920, "ctrl_clkgateCFoff"},    /* to disable clock gating in the coolflux           , */\
+   { 0x4930, "ctrl_testabst"},    /* testabst                                          , */\
+   { 0x4940, "ctrl_clipfast"},    /* clock switch for battery protection clipper, it switches back to old frequency, */\
+   { 0x4950, "ctrl_cs_8ohm"},    /* 8 ohm mode for current sense (gain mode)          , */\
+   { 0x4960, "reserved"},    /* reserved                                          , */\
+   { 0x4974, "delay_clock_sh"},    /* delay_sh, tunes S7H delay                         , */\
+   { 0x49c0, "inv_clksh"},    /* Invert the sample/hold clock for current sense ADC, */\
+   { 0x49d0, "inv_neg"},    /* Invert neg signal                                 , */\
+   { 0x49e0, "inv_se"},    /* Invert se signal                                  , */\
+   { 0x49f0, "setse"},    /* switches between Single Ende and differentail mode, */\
+   { 0x4a12, "ctrl_adc10_sel"},    /* select the input to convert the 10b ADC           , */\
+   { 0x4a60, "ctrl_adc10_reset"},    /* Global asynchronous reset (active HIGH) 10 bit ADC, */\
+   { 0x4a81, "ctrl_adc10_test"},    /* Test mode selection signal 10 bit ADC             , */\
+   { 0x4aa0, "ctrl_bypass_lp_vbat"},    /* lp filter in batt sensor                          , */\
+   { 0x4ae0, "ctrl_dc_offset"},    /* switch offset control on/off, is decimator offset control, */\
+   { 0x4af0, "ctrl_tsense_hibias"},    /* bit to set the biasing in temp sensor to high     , */\
+   { 0x4b00, "ctrl_adc13_iset"},    /* Micadc Setting of current consumption. Debug use only, */\
+   { 0x4b14, "ctrl_adc13_gain"},    /* Micadc gain setting (2-compl)                     , */\
+   { 0x4b61, "ctrl_adc13_slowdel"},    /* Micadc Delay setting for internal clock. Debug use only, */\
+   { 0x4b83, "ctrl_adc13_offset"},    /* Micadc ADC offset setting                         , */\
+   { 0x4bc0, "ctrl_adc13_bsoinv"},    /* Micadc bit stream output invert mode for test     , */\
+   { 0x4bd0, "ctrl_adc13_resonator_enable"},    /* Micadc Give extra SNR with less stability. Debug use only, */\
+   { 0x4be0, "ctrl_testmicadc"},    /* Mux at input of MICADC for test purpose           , */\
+   { 0x4c0f, "ctrl_offset"},    /* offset control for ABIST testing                  , */\
+   { 0x4d05, "ctrl_windac"},    /* for testing direct control windac                 , */\
+   { 0x4d65, "ctrl_peakcur"},    /* Control peakcur                                   , */\
+   { 0x4dc3, "pwm_dcc_cnt"},    /* control pwm duty cycle when enbl_pwm_dcc is 1     , */\
+   { 0x4e04, "ctrl_slopecur"},    /* for testing direct control slopecur               , */\
+   { 0x4e53, "ctrl_dem"},    /* dyn element matching control, rest of codes are optional, */\
+   { 0x4e93, "ctrl_demmismatch"},    /* dyn element matching add offset                   , */\
+   { 0x4ed0, "enbl_pwm_dcc"},    /* to enable direct control of pwm duty cycle        , */\
+   { 0x5007, "gain"},    /* gain setting of the gain multiplier gain need to increase with factor 1.41 (3dB), */\
+   { 0x5081, "ctrl_sourceb"},    /* Set OUTB to                                       , */\
+   { 0x50a1, "ctrl_sourcea"},    /* Set OUTA to                                       , */\
+   { 0x50c1, "ctrl_sourcebst"},    /* Sets the source of the pwmbst output to boost converter input for testing, */\
+   { 0x50e1, "ctrl_test_mono"},    /* ABIST mode to add both amplifier halfs as stereo or one amplifier half as mono, */\
+   { 0x5104, "pulselengthbst"},    /* pulselength setting test input for boost converter , */\
+   { 0x5150, "ctrl_bypasslatchbst"},    /* bypass_latch in boost converter                   , */\
+   { 0x5160, "invertbst"},    /* invert pwmbst test signal                         , */\
+   { 0x5174, "pulselength"},    /* pulselength setting test input for amplifier      , */\
+   { 0x51c0, "ctrl_bypasslatch"},    /* bypass_latch in boost convert                     , */\
+   { 0x51d0, "invertb"},    /* invert pwmb test signal                           , */\
+   { 0x51e0, "inverta"},    /* invert pwma test signal                           , */\
+   { 0x51f0, "ctrl_bypass_ctrlloop"},    /* bypass_ctrlloop bypasses the control loop of the amplifier, */\
+   { 0x5200, "ctrl_test_discrete"},    /* tbd for rdson testing                             , */\
+   { 0x5210, "ctrl_test_rdsona"},    /* tbd for rdson testing                             , */\
+   { 0x5220, "ctrl_test_rdsonb"},    /* tbd for rdson testing                             , */\
+   { 0x5230, "ctrl_test_rdsonbst"},    /* tbd for rdson testing                             , */\
+   { 0x5240, "ctrl_test_cvia"},    /* tbd for rdson testing                             , */\
+   { 0x5250, "ctrl_test_cvib"},    /* tbd for rdson testing                             , */\
+   { 0x5260, "ctrl_test_cvibst"},    /* tbd for rdson testing                             , */\
+   { 0x5290, "test_bypass_pwmdiscretea"},    /* for testing ( ABIST)                              , */\
+   { 0x52a0, "test_bypass_pwmdiscreteb"},    /* for testing ( ABIST)                              , */\
+   { 0x52b0, "ctrl_clipc_forcehigh"},    /* test signal for clipcontrol                       , */\
+   { 0x52c0, "ctrl_clipc_forcelow"},    /* test signal for clipcontrol                       , */\
+   { 0x52d0, "ctrl_test_sdelta"},    /* for testing ( ABIST)                              , */\
+   { 0x52e0, "ctrl_test_swhvp"},    /* for testing ( ABIST)                              , */\
+   { 0x52f0, "test_gain_reduction"},    /* test gain reduction                               , */\
+   { 0x5303, "ctrl_digimux_out_test1"},    /* Digimux TEST1 out                                 , */\
+   { 0x5343, "ctrl_digimux_out_test2"},    /* Digimux TEST2 out. output flag_clipa_low depending on cntr_bypassclip setting, */\
+   { 0x5383, "ctrl_digimux_out_data1"},    /* Digimux DATA1 out (output flag_clipb_high depending on cntr_bypassclip setting), */\
+   { 0x53c3, "ctrl_digimux_out_data3"},    /* Digimux DATA3 out  (output flag_clipx_x depending on cntr_bypassclip setting), */\
+   { 0x5400, "hs_mode"},    /* hs_mode, high speed mode I2C bus                  , */\
+   { 0x5412, "test_parametric_io"},    /* test_parametric_io for testing pads               , */\
+   { 0x5440, "enbl_ringo"},    /* enbl_ringo, for test purpose to check with ringo  , */\
+   { 0x5480, "ctrl_cliplevel"},    /* Clip level                                        , */\
+   { 0x5491, "ctrl_anamux_sel"},    /* anamux selection                                  , */\
+   { 0x54b0, "test_vdddsw_dio"},    /* to overrule the power switches for memory         , */\
+   { 0x54c0, "ctrl_bypass_diosw_ovp"},    /* To disable the overvoltage protection of vddd_dio_sw, */\
+   { 0x54d0, "test_vddd_sw"},    /* test vdd sw                                       , */\
+   { 0x54e0, "test_vddd_sw_comp"},    /* test vdd sw comp                                  , */\
+   { 0x550e, "enbl_amp"},    /* enbl_amp for testing to enable all analoge blocks in amplifier, */\
+   { 0x55f0, "fr_fsp"},    /* extr free running clock mode for testing          , */\
+   { 0x5600, "use_direct_ctrls"},    /* use_direct_ctrls, to overrule several functions direct for testing, */\
+   { 0x5610, "rst_datapath"},    /* rst_datapath, datapath reset                      , */\
+   { 0x5620, "rst_cgu"},    /* rst_cgu, cgu reset                                , */\
+   { 0x5637, "enbl_ref"},    /* for testing to enable all analoge blocks in references, */\
+   { 0x56b0, "enbl_engage"},    /* Enable output stage amplifier                     , */\
+   { 0x56c0, "use_direct_clk_ctrl"},    /* use_direct_clk_ctrl, to overrule several functions direct for testing, */\
+   { 0x56d0, "use_direct_pll_ctrl"},    /* use_direct_pll_ctrl, to overrule several functions direct for test, */\
+   { 0x56e0, "use_direct_ctrls_2"},    /* use_direct_sourseamp_ctrls, to overrule several functions direct for testing, */\
+   { 0x5707, "ctrl_anamux_out_test1"},    /* Anamux control                                    , */\
+   { 0x5782, "ctrl_zero"},    /* Bandwith control feedbackloop                     , */\
+   { 0x57b0, "enbl_ldo_stress"},    /* LDO stress function frinch capacitors             , */\
+   { 0x57c0, "ctrl_ocptest"},    /* ctrl_ocptest, deactivates the over current protection in the power stages of the amplifier. The ocp flag signals stay active., */\
+   { 0x57e0, "ctrl_otptest"},    /* otptest, test mode otp amplifier                  , */\
+   { 0x57f0, "ctrl_reverse"},    /* CTRL revers                                       , */\
+   { 0x5802, "pll_mdec_msb"},    /* most significant bits pll_mdec                    , */\
+   { 0x5833, "pll_selr"},    /* pll_selr                                          , */\
+   { 0x5874, "pll_selp"},    /* pll_selp                                          , */\
+   { 0x58c3, "pll_seli"},    /* pll_seli                                          , */\
+   { 0x5900, "pll_psel"},    /* pll_psel                                          , */\
+   { 0x5910, "use_direct_pll_psel"},    /* use_direct_pll_psel                               , */\
+   { 0x5923, "nbck"},    /* NBCK                                              , */\
+   { 0x5960, "auto_nbck"},    /* AUTO_NBCK                                         , */\
+   { 0x5970, "pll_frm"},    /* pll_frm                                           , */\
+   { 0x5980, "pll_directi"},    /* pll_directi                                       , */\
+   { 0x5990, "pll_directo"},    /* pll_directo                                       , */\
+   { 0x59a0, "enbl_PLL"},    /* enbl_PLL                                          , */\
+   { 0x59b0, "sel_clkout"},    /* SEL_CLKOUT                                        , */\
+   { 0x59e0, "fr_lost_clk"},    /* fr_lost_clk                                       , */\
+   { 0x59f0, "pll_bypass"},    /* pll_bypass                                        , */\
+   { 0x5a0f, "tsig_freq"},    /* tsig_freq, internal sinus test generator, frequency control, */\
+   { 0x5b02, "tsig_freq_msb"},    /* select internal sinus test generator, frequency control msb bits, */\
+   { 0x5b30, "inject_tsig"},    /* inject_tsig, control bit to switch to internal sinus test generator, */\
+   { 0x5b44, "ctrl_adc10_prog_sample"},    /* control ADC10                                     , */\
+   { 0x5c01, "pll_ndec_msb"},    /* most significant bits of pll_ndec                 , */\
+   { 0x5c2d, "pll_mdec"},    /* bits 13..0 of pll_mdec                            , */\
+   { 0x5d06, "pll_pdec"},    /* pll_pdec                                          , */\
+   { 0x5d87, "pll_ndec"},    /* bits 7..0 of pll_ndec                             , */\
+   { 0x5e00, "pdm_ch_sel_reg"},    /* PDM channel selection                             , */\
+   { 0x5e10, "pdm_iis_rst_reg"},    /* PDM Interface reset                               , */\
+   { 0x5e20, "clk_src_sel_reg"},    /* WS  Source Selection                              , */\
+   { 0x5e70, "pdm_resync_bypass"},    /* PDM resynchronization bypass                      , */\
+   { 0x6007, "MTP_key1"},    /* MTP Key1                                          , */\
+   { 0x6185, "mtp_ecc_tcin"},    /* Mtp_ecc_tcin                                      , */\
+   { 0x6203, "mtp_man_address_in"},    /* address from i2cregs for writing one word single mtp, */\
+   { 0x6260, "mtp_ecc_eeb"},    /* enable code bit generation (active low!)          , */\
+   { 0x6270, "mtp_ecc_ecb"},    /* enable correction signal (active low!)            , */\
+   { 0x6280, "man_copy_mtp_to_iic"},    /* start copying single word from mtp to i2cregs_mtp , */\
+   { 0x6290, "man_copy_iic_to_mtp"},    /* start copying single word from i2cregs_mtp to mtp [Key 1 protected], */\
+   { 0x62a0, "auto_copy_mtp_to_iic"},    /* start copying all the data from mtp to i2cregs_mtp, */\
+   { 0x62b0, "auto_copy_iic_to_mtp"},    /* start copying all the data from i2cregs_mtp to mtp [Key 2 protected], */\
+   { 0x62d2, "mtp_speed_mode"},    /* Speed mode                                        , */\
+   { 0x6340, "mtp_dircet_enable"},    /* mtp_direct_enable (key1 protected)                , */\
+   { 0x6350, "mtp_direct_wr"},    /* mtp_direct_wr (key1 protected) direct value for mtp pin wr. To be enabled via iic2mtp_mtp_direct_enable, */\
+   { 0x6360, "mtp_direct_rd"},    /* mtp_direct_rd  (key1 protected) direct value for mtp pin rd. To be enabled via iic2mtp_mtp_direct_enable, */\
+   { 0x6370, "mtp_direct_rst"},    /* mtp_direct_rst  (key1 protected) direct value for mtp pin rst. To be enabled via iic2mtp_mtp_direct_enable, */\
+   { 0x6380, "mtp_direct_ers"},    /* mtp_direct_ers  (key1 protected) direct value for mtp pin ers. To be enabled via iic2mtp_mtp_direct_enable, */\
+   { 0x6390, "mtp_direct_prg"},    /* mtp_direct_prg  (key1 protected) direct value for mtp pin prg. To be enabled via iic2mtp_mtp_direct_enable, */\
+   { 0x63a0, "mtp_direct_epp"},    /* mtp_direct_epp  (key1 protected) direct value for mtp pin epp. To be enabled via iic2mtp_mtp_direct_enable, */\
+   { 0x63b4, "mtp_direct_test"},    /* mtp_direct_test  (key1 protected)                 , */\
+   { 0x640f, "mtp_man_data_in"},    /* single wordt be written to MTP (manual copy)      , */\
+   { 0x7000, "cf_rst_dsp"},    /* Reset CoolFlux DSP                                , */\
+   { 0x7011, "cf_dmem"},    /* Target memory for access                          , */\
+   { 0x7030, "cf_aif"},    /* Autoincrement-flag for memory-address             , */\
+   { 0x7040, "cf_int"},    /* Interrupt CoolFlux DSP                            , */\
+   { 0x7087, "cf_req"},    /* request for access (8 channels)                   , */\
+   { 0x710f, "cf_madd"},    /* memory-address to be accessed                     , */\
+   { 0x720f, "cf_mema"},    /* activate memory access (24- or 32-bits data is written/read to/from memory, */\
+   { 0x7307, "cf_err"},    /* cf error Flags                                    , */\
+   { 0x7387, "cf_ack"},    /* acknowledge of requests (8 channels")"            , */\
+   { 0x8000, "calibration_onetime"},    /* Calibration schedule (key2 protected)             , */\
+   { 0x8010, "calibr_ron_done"},    /* (key2 protected) calibration of Ron has been executed, */\
+   { 0x8105, "calibr_vout_offset"},    /* calibr_vout_offset (DCDCoffset) 2's compliment (key1 protected), */\
+   { 0x8163, "calibr_delta_gain"},    /* delta gain for vamp (alpha) 2's compliment (key1 protected), */\
+   { 0x81a5, "calibr_offs_amp"},    /* offset for vamp (Ampoffset) 2's compliment (key1 protected), */\
+   { 0x8207, "calibr_gain_cs"},    /* gain current sense (Imeasalpha) 2's compliment (key1 protected), */\
+   { 0x8284, "calibr_temp_offset"},    /* temperature offset 2's compliment (key1 protected), */\
+   { 0x82d2, "calibr_temp_gain"},    /* temperature gain 2's compliment (key1 protected)  , */\
+   { 0x830f, "calibr_ron"},    /* Ron resistance of coil (key1 protected)           , */\
+   { 0x8406, "ctrl_offset_a"},    /* Offset of amplifier level shifter                 , */\
+   { 0x8486, "ctrl_offset_b"},    /* Offset of amplifier level shifter                 , */\
+   { 0x850f, "type_bits_HW"},    /* HW Bits                                           , */\
+   { 0x860f, "type_bits1_SW"},    /* MTP-control SW1                                   , */\
+   { 0x870f, "type_bits2_SW"},    /* MTP-control SW2                                   , */\
+   { 0x8a0f, "production_data1"},    /* (key1 protected)                                  , */\
+   { 0x8b0f, "production_data2"},    /* (key1 protected)                                  , */\
+   { 0x8c0f, "production_data3"},    /* (key1 protected)                                  , */\
+   { 0x8d0f, "production_data4"},    /* (key1 protected)                                  , */\
+   { 0x8e0f, "production_data5"},    /* (key1 protected)                                  , */\
+   { 0x8f0f, "production_data6"},    /* (key1 protected)                                  , */\
+   { 0xffff,"Unknown bitfield enum" }    /* not found */\
+};
+
+
+#endif /* TFA_INC_TFA9891_TFAFIELDNAMES_H_ */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa9897_init.c b/techpack/audio/asoc/codecs/tfa98xx/tfa9897_init.c
new file mode 100644
index 0000000..3d5e78d
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa9897_init.c
@@ -0,0 +1,129 @@
+/*
+ *Copyright 2014,2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *            
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *             
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+ 
+
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "tfa_internal.h"
+
+#include "tfa98xx_tfafieldnames.h"
+
+static enum Tfa98xx_Error tfa9897_specific(Tfa98xx_handle_t handle)
+{
+        enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+        unsigned short check_value;
+
+        if (!tfa98xx_handle_is_open(handle))
+                return Tfa98xx_Error_NotOpen;
+
+        /* all i2C registers must already set to default POR value */
+
+        /* $48:[3] - 1 ==> 0; iddqtestbst - default value changed.
+         * When Iddqtestbst is set to "0", the slewrate is reduced.
+         * This will lower the overshoot on IN-B to avoid NMOS damage of booster.
+         */
+        error = tfa98xx_write_register16(handle, 0x48, 0x0300); /* POR value = 0x308 */
+
+        /* $49:[0] - 1 ==> 0; CLIP - default value changed. 0 means CLIPPER on
+         */
+        error = tfa98xx_read_register16(handle, 0x49, &check_value);
+        check_value &= ~0x1;
+        error = tfa98xx_write_register16(handle, 0x49, check_value);
+
+        return error;
+}
+
+/*
+ * the int24 values for the vsfw delay table
+ */
+static unsigned char vsfwdelay_table[] = {
+        0,0,2, /*Index 0 - Current/Volt Fractional Delay for 8KHz  */
+        0,0,0, /*Index 1 - Current/Volt Fractional Delay for 11KHz */
+        0,0,0, /*Index 2 - Current/Volt Fractional Delay for 12KHz */
+        0,0,2, /*Index 3 - Current/Volt Fractional Delay for 16KHz */
+        0,0,2, /*Index 4 - Current/Volt Fractional Delay for 22KHz */
+        0,0,2, /*Index 5 - Current/Volt Fractional Delay for 24KHz */
+        0,0,2, /*Index 6 - Current/Volt Fractional Delay for 32KHz */
+        0,0,2, /*Index 7 - Current/Volt Fractional Delay for 44KHz */
+        0,0,3 /*Index 8 - Current/Volt Fractional Delay for 48KHz */
+};
+
+/*
+ * TODO make this tfa98xx
+ *  Note that the former products write this table via the patch
+ *  so moving this to the tfa98xx API requires also updating all patches
+ */
+static enum Tfa98xx_Error tfa9897_dsp_write_vsfwdelay_table(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error error;
+        error = tfa_dsp_cmd_id_write(handle, MODULE_FRAMEWORK,
+        		             TFA1_FW_PAR_ID_SET_CURRENT_DELAY,
+        		             sizeof(vsfwdelay_table),
+		    		     vsfwdelay_table);
+        return error;
+}
+
+/*
+ * The int24 values for the fracdelay table
+ * For now applicable only for 8 and 48 kHz
+ */
+static unsigned char cvfracdelay_table[] ={
+        0,0,51, /*Index 0 - Current/Volt Fractional Delay for 8KHz  */
+        0,0, 0, /*Index 1 - Current/Volt Fractional Delay for 11KHz */
+        0,0, 0, /*Index 2 - Current/Volt Fractional Delay for 12KHz */
+        0,0,38, /*Index 3 - Current/Volt Fractional Delay for 16KHz */
+        0,0,34, /*Index 4 - Current/Volt Fractional Delay for 22KHz */
+        0,0,33, /*Index 5 - Current/Volt Fractional Delay for 24KHz */
+        0,0,11, /*Index 6 - Current/Volt Fractional Delay for 32KHz */
+        0,0,2, /*Index 7 - Current/Volt Fractional Delay for 44KHz */
+        0,0,62 /*Index 8 - Current/Volt Fractional Delay for 48KHz */
+};
+
+enum Tfa98xx_Error tfa9897_dsp_write_cvfracdelay_table(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error error;
+        error = tfa_dsp_cmd_id_write(handle, MODULE_FRAMEWORK,
+        		             TFA1_FW_PAR_ID_SET_CURFRAC_DELAY,
+        		             sizeof(cvfracdelay_table),
+		    		     cvfracdelay_table);
+        return error;
+}
+
+static enum Tfa98xx_Error tfa9897_tfa_dsp_write_tables(Tfa98xx_handle_t dev_idx, int sample_rate)
+{
+	enum Tfa98xx_Error error;
+
+	/* Not used for max1! */
+	sample_rate=sample_rate;
+
+	error = tfa9897_dsp_write_vsfwdelay_table(dev_idx);
+	if (error == Tfa98xx_Error_Ok) {
+		error = tfa9897_dsp_write_cvfracdelay_table(dev_idx);
+	}
+
+	tfa98xx_dsp_reset(dev_idx, 1);
+	tfa98xx_dsp_reset(dev_idx, 0);
+
+	return error;
+}
+
+/*
+ * register device specifics functions
+ */
+void tfa9897_ops(struct tfa_device_ops *ops) {
+	ops->tfa_init=tfa9897_specific;
+	ops->tfa_dsp_write_tables=tfa9897_tfa_dsp_write_tables;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa98xx.c b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx.c
new file mode 100644
index 0000000..92202cf
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx.c
@@ -0,0 +1,3327 @@
+/*
+ * tfa98xx.c   tfa98xx codec module
+ *
+ * Copyright (c) 2015 NXP Semiconductors
+ *
+ *  Author: Sebastien Jan <sjan@baylibre.com>
+ *
+ * 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;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#define pr_fmt(fmt) "%s(): " fmt, __func__
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <linux/of_gpio.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <linux/debugfs.h>
+#include <linux/version.h>
+#include <linux/input.h>
+
+#include "config.h"
+
+#define I2C_RETRIES 50
+#define I2C_RETRY_DELAY 5 /* ms */
+/* TODO: remove genregs usage? */
+#ifdef N1A
+#include "tfa98xx_genregs_N1A12.h"
+#else
+#include "tfa98xx_genregs_N1C.h"
+#endif
+#include "tfa9891_genregs.h"
+
+#include "tfa98xx_tfafieldnames.h"
+#include "tfa_internal.h"
+#include "tfa.h"
+#include "tfa_service.h"
+#include "tfa_container.h"
+#include "tfa98xx_parameters.h"
+
+#define TFA98XX_VERSION		"2.10.2"
+
+/* Change volume selection behavior:
+ * Uncomment following line to generate a profile change when updating
+ * a volume control (also changes to the profile of the modified  volume
+ * control)
+ */
+/*#define TFA98XX_ALSA_CTRL_PROF_CHG_ON_VOL	1
+*/
+
+/* Supported rates and data formats */
+#define TFA98XX_RATES SNDRV_PCM_RATE_8000_48000
+
+/*#define TFA98XX_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) */
+#define TFA98XX_FORMATS	SNDRV_PCM_FMTBIT_S16_LE
+
+#define TF98XX_MAX_DSP_START_TRY_COUNT	10
+
+#define XMEM_TAP_ACK  0x0122
+#define XMEM_TAP_READ 0x010f
+
+static LIST_HEAD(profile_list); /* list of user selectable profiles */
+
+static int tfa98xx_kmsg_regs = 0;
+static int tfa98xx_ftrace_regs = 0;
+
+static struct tfa98xx *tfa98xx_devices[4] = {NULL, NULL, NULL, NULL};
+static int tfa98xx_registered_handles = 0;
+static int tfa98xx_vsteps[4]={0,0,0,0};
+static int tfa98xx_profile = 0; /* store profile */
+static int tfa98xx_prof_vsteps[10] = {0}; /* store vstep per profile (single device) */
+static int tfa98xx_mixer_profiles = 0; /* number of user selectable profiles */
+static int tfa98xx_mixer_profile = 0; /* current mixer profile */
+
+static char *dflt_prof_name = "";
+module_param(dflt_prof_name, charp, S_IRUGO);
+
+static int no_start = 0;
+module_param(no_start, int, S_IRUGO);
+MODULE_PARM_DESC(no_start, "do not start the work queue; for debugging via user\n");
+
+static void tfa98xx_tapdet_check_update(struct tfa98xx *tfa98xx);
+static void tfa98xx_interrupt_restore(struct tfa98xx *tfa98xx);
+static int tfa98xx_get_fssel(unsigned int rate);
+
+static int get_profile_from_list(char *buf, int id);
+static int get_profile_id_for_sr(int id, unsigned int rate);
+
+struct tfa98xx_rate {
+	unsigned int rate;
+	unsigned int fssel;
+};
+
+static struct tfa98xx_rate rate_to_fssel[] = {
+	{ 8000, 0 },
+	{ 11025, 1 },
+	{ 12000, 2 },
+	{ 16000, 3 },
+	{ 22050, 4 },
+	{ 24000, 5 },
+	{ 32000, 6 },
+	{ 44100, 7 },
+	{ 48000, 8 },
+};
+
+/* Wrapper for tfa start */
+static enum tfa_error tfa98xx_tfa_start(struct tfa98xx *tfa98xx, int next_profile, int *vstep)
+{
+	enum tfa_error err;
+
+	err = tfa_start(next_profile, vstep);
+
+	/* Check and update tap-detection state (in case of profile change) */
+	tfa98xx_tapdet_check_update(tfa98xx);
+
+	/* A cold start erases the configuration, including interrupts setting.
+	 * Restore it if required
+	 */
+	tfa98xx_interrupt_restore(tfa98xx);
+
+	return err;
+}
+
+static int tfa98xx_input_open(struct input_dev *dev)
+{
+	struct tfa98xx *tfa98xx = input_get_drvdata(dev);
+	dev_dbg(tfa98xx->codec->dev, "opening device file\n");
+
+	/* note: open function is called only once by the framework.
+	 * No need to count number of open file instances.
+	 */
+	if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) {
+		dev_dbg(&tfa98xx->i2c->dev,
+			"DSP not loaded, cannot start tap-detection\n");
+		return -EIO;
+	}
+
+	/* enable tap-detection service */
+	tfa98xx->tapdet_open = true;
+	tfa98xx_tapdet_check_update(tfa98xx);
+
+    return 0;
+}
+
+static void tfa98xx_input_close(struct input_dev *dev)
+{
+	struct tfa98xx *tfa98xx = input_get_drvdata(dev);
+
+	dev_dbg(tfa98xx->codec->dev, "closing device file\n");
+
+	/* Note: close function is called if the device is unregistered */
+
+	/* disable tap-detection service */
+	tfa98xx->tapdet_open = false;
+	tfa98xx_tapdet_check_update(tfa98xx);
+}
+
+static int tfa98xx_register_inputdev(struct tfa98xx *tfa98xx)
+{
+	int err;
+	struct input_dev *input;
+	input = input_allocate_device();
+
+	if (!input) {
+		dev_err(tfa98xx->codec->dev, "Unable to allocate input device\n");
+		return -ENOMEM;
+	}
+
+	input->evbit[0] = BIT_MASK(EV_KEY);
+	input->keybit[BIT_WORD(BTN_0)] |= BIT_MASK(BTN_0);
+	input->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1);
+	input->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2);
+	input->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3);
+	input->keybit[BIT_WORD(BTN_4)] |= BIT_MASK(BTN_4);
+	input->keybit[BIT_WORD(BTN_5)] |= BIT_MASK(BTN_5);
+	input->keybit[BIT_WORD(BTN_6)] |= BIT_MASK(BTN_6);
+	input->keybit[BIT_WORD(BTN_7)] |= BIT_MASK(BTN_7);
+	input->keybit[BIT_WORD(BTN_8)] |= BIT_MASK(BTN_8);
+	input->keybit[BIT_WORD(BTN_9)] |= BIT_MASK(BTN_9);
+
+	input->open = tfa98xx_input_open;
+	input->close = tfa98xx_input_close;
+
+	input->name = "tfa98xx-tapdetect";
+
+	input->id.bustype = BUS_I2C;
+	input_set_drvdata(input, tfa98xx);
+
+	err = input_register_device(input);
+	if (err) {
+		dev_err(tfa98xx->codec->dev, "Unable to register input device\n");
+		goto err_free_dev;
+	}
+
+	dev_dbg(tfa98xx->codec->dev, "Input device for tap-detection registered: %s\n",
+		input->name);
+	tfa98xx->input = input;
+	return 0;
+
+err_free_dev:
+	input_free_device(input);
+	return err;
+}
+
+/*
+ * Check if an input device for tap-detection can and shall be registered.
+ * Register it if appropriate.
+ * If already registered, check if still relevant and remove it if necessary.
+ * unregister: true to request inputdev unregistration.
+ */
+static void __tfa98xx_inputdev_check_register(struct tfa98xx *tfa98xx, bool unregister)
+{
+	bool tap_profile = false;
+	unsigned int i;
+	for (i = 0; i < tfaContMaxProfile(tfa98xx->handle); i++) {
+		if (strstr(tfaContProfileName(tfa98xx->handle, i), ".tap")) {
+			tap_profile = true;
+			tfa98xx->tapdet_profiles |= 1 << i;
+			dev_info(tfa98xx->codec->dev,
+				"found a tap-detection profile (%d - %s)\n",
+				i, tfaContProfileName(tfa98xx->handle, i));
+		}
+	}
+
+	/* Check for device support:
+	 *  - at device level
+	 *  - at container (profile) level
+	 */
+	if (!(tfa98xx->flags & TFA98XX_FLAG_TAPDET_AVAILABLE) ||
+		!tap_profile ||
+		unregister) {
+		/* No input device supported or required */
+		if (tfa98xx->input) {
+			input_unregister_device(tfa98xx->input);
+			tfa98xx->input = NULL;
+		}
+		return;
+	}
+
+	/* input device required */
+	if (tfa98xx->input)
+		dev_info(tfa98xx->codec->dev, "Input device already registered, skipping\n");
+	else
+		tfa98xx_register_inputdev(tfa98xx);
+}
+
+static void tfa98xx_inputdev_check_register(struct tfa98xx *tfa98xx)
+{
+	__tfa98xx_inputdev_check_register(tfa98xx, false);
+}
+
+static void tfa98xx_inputdev_unregister(struct tfa98xx *tfa98xx)
+{
+	__tfa98xx_inputdev_check_register(tfa98xx, true);
+}
+
+#ifdef CONFIG_DEBUG_FS
+/* OTC reporting
+ * Returns the MTP0 OTC bit value
+ */
+static int tfa98xx_dbgfs_otc_get(void *data, u64 *val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	struct tfa98xx_control *otc = &(handles_local[tfa98xx->handle].dev_ops.controls.otc);
+	enum Tfa98xx_Error err, status;
+	unsigned short value;
+
+	mutex_lock(&tfa98xx->dsp_lock);
+	status = tfa98xx_open(tfa98xx->handle);
+	if (status) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+
+	err = tfa98xx_get_mtp(tfa98xx->handle, &value);
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	if (otc->deferrable) {
+		if (err != Tfa98xx_Error_Ok && err != Tfa98xx_Error_NoClock) {
+			pr_err("Unable to check DSP access: %d\n", err);
+			return -EIO;
+		} else if (err == Tfa98xx_Error_NoClock) {
+			if (otc->rd_valid) {
+				/* read cached value */
+				*val = otc->rd_value;
+				pr_debug("Returning cached value of OTC: %llu\n", *val);
+			} else {
+				pr_info("OTC value never read!\n");
+				return -EIO;
+			}
+			return 0;
+		}
+	}
+
+	*val = (value & TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK)
+			 >> TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS;
+	pr_debug("OTC : %d\n", value&1);
+
+	if (otc->deferrable) {
+		otc->rd_value = *val;
+		otc->rd_valid = true;
+	}
+
+	return 0;
+}
+
+static int tfa98xx_dbgfs_otc_set(void *data, u64 val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	struct tfa98xx_control *otc = &(handles_local[tfa98xx->handle].dev_ops.controls.otc);
+	enum Tfa98xx_Error err, status;
+
+	if (val != 0 && val != 1) {
+		pr_err("Unexpected value %llu\n\n", val);
+		return -EINVAL;
+	}
+	mutex_lock(&tfa98xx->dsp_lock);
+	status = tfa98xx_open(tfa98xx->handle);
+	if (status) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+	err = tfa98xx_set_mtp(tfa98xx->handle,
+			(val << TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS)
+			& TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK,
+			TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK);
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	if (otc->deferrable) {
+		if (err != Tfa98xx_Error_Ok && err != Tfa98xx_Error_NoClock) {
+			pr_err("Unable to check DSP access: %d\n", err);
+			return -EIO;
+		} else if (err == Tfa98xx_Error_NoClock) {
+			/* defer OTC */
+			otc->wr_value = val;
+			otc->triggered = true;
+			pr_debug("Deferring write to OTC (%d)\n", otc->wr_value);
+			return 0;
+		}
+	}
+
+	/* deferrable: cache the value for subsequent offline read */
+	if (otc->deferrable) {
+		otc->rd_value = val;
+		otc->rd_valid = true;
+	}
+
+	pr_debug("otc < %llu\n", val);
+
+	return 0;
+}
+
+static int tfa98xx_dbgfs_mtpex_get(void *data, u64 *val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	enum Tfa98xx_Error err, status;
+	unsigned short value;
+
+	mutex_lock(&tfa98xx->dsp_lock);
+	status = tfa98xx_open(tfa98xx->handle);
+	if (status) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+	err = tfa98xx_get_mtp(tfa98xx->handle, &value);
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	if (err != Tfa98xx_Error_Ok) {
+		pr_err("Unable to check DSP access: %d\n", err);
+		return -EIO;
+	}
+
+	*val = (value & TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK)
+				>> TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS;
+	pr_debug("MTPEX : %d\n", value & 2 >> 1);
+
+	return 0;
+}
+
+static int tfa98xx_dbgfs_mtpex_set(void *data, u64 val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	struct tfa98xx_control *mtpex = &(handles_local[tfa98xx->handle].dev_ops.controls.mtpex);
+	enum Tfa98xx_Error err, status;
+
+	if (val != 0) {
+		pr_err("Can only clear MTPEX (0 value expected)\n");
+		return -EINVAL;
+	}
+
+	mutex_lock(&tfa98xx->dsp_lock);
+	status = tfa98xx_open(tfa98xx->handle);
+	if (status) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+	err = tfa98xx_set_mtp(tfa98xx->handle, 0,
+					TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK);
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	if (mtpex->deferrable) {
+		if (err != Tfa98xx_Error_Ok && err != Tfa98xx_Error_NoClock) {
+			pr_err("Unable to check DSP access: %d\n", err);
+			return -EIO;
+		} else if (err == Tfa98xx_Error_NoClock) {
+			/* defer OTC */
+			mtpex->wr_value = 0;
+			mtpex->triggered = true;
+			pr_debug("Deferring write to MTPEX (%d)\n", mtpex->wr_value);
+			return 0;
+		}
+	}
+
+	pr_debug("mtpex < 0\n");
+
+	return 0;
+}
+
+static int tfa98xx_dbgfs_temp_get(void *data, u64 *val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	enum Tfa98xx_Error status;
+
+	mutex_lock(&tfa98xx->dsp_lock);
+	status = tfa98xx_open(tfa98xx->handle);
+	if (status) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+	*val = tfa98xx_get_exttemp(tfa98xx->handle);
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	return 0;
+}
+
+static int tfa98xx_dbgfs_temp_set(void *data, u64 val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	enum Tfa98xx_Error status;
+
+	mutex_lock(&tfa98xx->dsp_lock);
+	status = tfa98xx_open(tfa98xx->handle);
+	if (status) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+	tfa98xx_set_exttemp(tfa98xx->handle, (short)val);
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	return 0;
+}
+
+/*
+ * calibration:
+ * write key phrase to the 'calibration' file to trigger a new calibration
+ * read the calibration file once to get the calibration result
+ */
+/* tfa98xx_deferred_calibration_status - called from tfaRunWaitCalibration */
+void tfa98xx_deferred_calibration_status(Tfa98xx_handle_t handle, int calibrateDone)
+{
+	struct tfa98xx *tfa98xx = tfa98xx_devices[handle];
+	struct tfa98xx_control *calib = &(handles_local[handle].dev_ops.controls.calib);
+
+	if (calib->wr_value) {
+		/* a calibration was programmed from the calibration file
+		 * interface
+		 */
+		switch (calibrateDone) {
+		case 1:
+			/* calibration complete ! */
+			calib->wr_value = false; /* calibration over */
+			calib->rd_valid = true;  /* result available */
+			calib->rd_value = true;  /* result valid */
+			tfa_dsp_get_calibration_impedance(tfa98xx->handle);
+			wake_up_interruptible(&tfa98xx->wq);
+			break;
+		case 0:
+			pr_info("Calibration not complete, still waiting...\n");
+			break;
+		case -1:
+			pr_info("Calibration failed\n");
+			calib->wr_value = false; /* calibration over */
+			calib->rd_valid = true;  /* result available */
+			calib->rd_value = false; /* result not valid */
+			wake_up_interruptible(&tfa98xx->wq);
+			break;
+		default:
+			pr_info("Unknown calibration status: %d\n",
+							calibrateDone);
+		}
+	}
+}
+
+static ssize_t tfa98xx_dbgfs_start_get(struct file *file,
+				     char __user *user_buf, size_t count,
+				     loff_t *ppos)
+{
+	struct i2c_client *i2c = file->private_data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	struct tfa98xx_control *calib = &(handles_local[tfa98xx->handle].dev_ops.controls.calib);
+	char *str;
+	int ret;
+
+	ret = wait_event_interruptible(tfa98xx->wq, calib->wr_value == false);
+
+	if (ret == -ERESTARTSYS) {
+		/* interrupted by signal */
+		return ret;
+	}
+
+	if (!calib->rd_valid)
+		/* no calibration result available - skip */
+		return 0;
+
+	if (calib->rd_value) {
+		/* Calibration already complete, return result */
+		str = kmalloc(PAGE_SIZE, GFP_KERNEL);
+		if (!str)
+			return -ENOMEM;
+		ret = print_calibration(tfa98xx->handle, str, PAGE_SIZE);
+		if (ret < 0) {
+			kfree(str);
+			return ret;
+		}
+		ret = simple_read_from_buffer(user_buf, count, ppos, str, ret);
+
+		pr_debug("%s", str);
+		kfree(str);
+		calib->rd_value = false;
+	} else {
+		/* Calibration failed, return the error code */
+		const char estr[] = "-1\n";
+		ret = copy_to_user(user_buf, estr, sizeof(estr));
+		if (ret)
+			return -EFAULT;
+		ret =  sizeof(estr);
+	}
+	calib->rd_valid = false;
+	return ret;
+}
+
+static ssize_t tfa98xx_dbgfs_start_set(struct file *file,
+				     const char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct i2c_client *i2c = file->private_data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	struct tfa98xx_control *calib = &(handles_local[tfa98xx->handle].dev_ops.controls.calib);
+	enum Tfa98xx_Error ret;
+	char buf[32];
+	const char ref[] = "please calibrate now";
+	int buf_size;
+
+	/* check string length, and account for eol */
+	if (count > sizeof(ref) + 1 || count < (sizeof(ref) - 1))
+		return -EINVAL;
+
+	buf_size = min(count, (size_t)(sizeof(buf)-1));
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	buf[buf_size] = 0;
+
+	/* Compare string, excluding the trailing \0 and the potentials eol */
+	if (strncmp(buf, ref, sizeof(ref) - 1))
+		return -EINVAL;
+
+	/* Do not open/close tfa98xx: not required by tfa_clibrate */
+	mutex_lock(&tfa98xx->dsp_lock);
+	ret = tfa_calibrate(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	if(ret) {
+		pr_info("Calibration start failed (%d), deferring...\n", ret);
+		calib->triggered = true;
+	} else {
+		pr_info("Calibration started\n");
+	}
+	calib->wr_value = true;  /* request was triggered from here */
+	calib->rd_valid = false; /* result not available */
+	calib->rd_value = false; /* result not valid (dafault) */
+
+	return count;
+}
+
+static ssize_t tfa98xx_dbgfs_r_read(struct file *file,
+				     char __user *user_buf, size_t count,
+				     loff_t *ppos)
+{
+	struct i2c_client *i2c = file->private_data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	char *str;
+	uint16_t status;
+	int ret, calibrate_done;
+
+	mutex_lock(&tfa98xx->dsp_lock);
+	ret = tfa98xx_open(tfa98xx->handle);
+	if (ret) {
+		mutex_unlock(&tfa98xx->dsp_lock);
+		return -EBUSY;
+	}
+
+	/* Need to ensure DSP is access-able, use mtp read access for this
+	 * purpose
+	 */
+	ret = tfa98xx_get_mtp(tfa98xx->handle, &status);
+	if (ret) {
+		ret = -EIO;
+		goto r_c_err;
+	}
+
+	ret = tfaRunWaitCalibration(tfa98xx->handle, &calibrate_done);
+	if (ret) {
+		ret = -EIO;
+		goto r_c_err;
+	}
+
+	str = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!str) {
+		ret = -ENOMEM;
+		goto r_c_err;
+	}
+
+	switch (calibrate_done) {
+	case 1:
+		/* calibration complete ! */
+		tfa_dsp_get_calibration_impedance(tfa98xx->handle);
+		ret = print_calibration(tfa98xx->handle, str, PAGE_SIZE);
+		break;
+	case 0:
+	case -1:
+		ret = scnprintf(str, PAGE_SIZE, "%d\n", calibrate_done);
+		break;
+	default:
+		pr_err("Unknown calibration status: %d\n", calibrate_done);
+		ret = -EINVAL;
+	}
+	pr_debug("calib_done: %d - ret = %d - %s", calibrate_done, ret, str);
+
+	if (ret < 0)
+		goto r_err;
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, str, ret);
+
+r_err:
+	kfree(str);
+r_c_err:
+	tfa98xx_close(tfa98xx->handle);
+	mutex_unlock(&tfa98xx->dsp_lock);
+	return ret;
+}
+
+static ssize_t tfa98xx_dbgfs_version_read(struct file *file,
+				     char __user *user_buf, size_t count,
+				     loff_t *ppos)
+{
+	char str[] = TFA98XX_VERSION "\n";
+	int ret;
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, str, sizeof(str));
+
+	return ret;
+}
+
+static ssize_t tfa98xx_dbgfs_dsp_state_get(struct file *file,
+				     char __user *user_buf, size_t count,
+				     loff_t *ppos)
+{
+	struct i2c_client *i2c = file->private_data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	int ret = 0;
+	char *str;
+
+	switch (tfa98xx->dsp_init) {
+	case TFA98XX_DSP_INIT_STOPPED:
+		str = "Stopped\n";
+		break;
+	case TFA98XX_DSP_INIT_RECOVER:
+		str = "Recover requested\n";
+		break;
+	case TFA98XX_DSP_INIT_FAIL:
+		str = "Failed init\n";
+		break;
+	case TFA98XX_DSP_INIT_PENDING:
+		str =  "Pending init\n";
+		break;
+	case TFA98XX_DSP_INIT_DONE:
+		str = "Init complete\n";
+		break;
+	default:
+		str = "Invalid\n";
+	}
+	ret = simple_read_from_buffer(user_buf, count, ppos, str, strlen(str));
+	return ret;
+}
+
+static ssize_t tfa98xx_dbgfs_dsp_state_set(struct file *file,
+				     const char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct i2c_client *i2c = file->private_data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	enum tfa_error ret;
+	char buf[32];
+	const char start_cmd[] = "start";
+	const char stop_cmd[] = "stop";
+	const char mon_start_cmd[] = "monitor start";
+	const char mon_stop_cmd[] = "monitor stop";
+	int buf_size;
+
+	buf_size = min(count, (size_t)(sizeof(buf)-1));
+	if (copy_from_user(buf, user_buf, buf_size))
+		return -EFAULT;
+	buf[buf_size] = 0;
+
+	/* Compare strings, excluding the trailing \0 */
+	if (!strncmp(buf, start_cmd, sizeof(start_cmd) - 1)) {
+		pr_info("Manual triggering of dsp start...\n");
+		mutex_lock(&tfa98xx->dsp_lock);
+		ret = tfa98xx_tfa_start(tfa98xx, tfa98xx_profile, tfa98xx_vsteps);
+		mutex_unlock(&tfa98xx->dsp_lock);
+		pr_debug("tfa_start complete: %d\n", ret);
+	} else if (!strncmp(buf, stop_cmd, sizeof(stop_cmd) - 1)) {
+		pr_info("Manual triggering of dsp stop...\n");
+		mutex_lock(&tfa98xx->dsp_lock);
+		ret = tfa_stop();
+		mutex_unlock(&tfa98xx->dsp_lock);
+		pr_debug("tfa_stop complete: %d\n", ret);
+	} else if (!strncmp(buf, mon_start_cmd, sizeof(mon_start_cmd) - 1)) {
+		pr_info("Manual start of monitor thread...\n");
+		queue_delayed_work(tfa98xx->tfa98xx_wq,
+					&tfa98xx->monitor_work, HZ);
+	} else if (!strncmp(buf, mon_stop_cmd, sizeof(mon_stop_cmd) - 1)) {
+		pr_info("Manual stop of monitor thread...\n");
+		cancel_delayed_work_sync(&tfa98xx->monitor_work);
+	} else {
+		return -EINVAL;
+	}
+
+	return count;
+}
+
+static ssize_t tfa98xx_dbgfs_accounting_get(struct file *file,
+				     char __user *user_buf, size_t count,
+				     loff_t *ppos)
+{
+	struct i2c_client *i2c = file->private_data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	char str[255];
+	int ret;
+	int n = 0;
+
+	n += snprintf(&str[n], sizeof(str)-1-n, "Wait4Src\t= %d\n",  tfa98xx->count_wait_for_source_state);
+	n += snprintf(&str[n], sizeof(str)-1-n, "NOCLK\t\t= %d\n",  tfa98xx->count_noclk);
+
+	str[n+1] = '\0'; /* in case str is not large enough */
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, str, n+1);
+
+	return ret;
+}
+
+static int tfa98xx_dbgfs_pga_gain_get(void *data, u64 *val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	int err;
+	unsigned int value;
+
+/*	*val = TFA_GET_BF(tfa98xx->handle, SAAMGAIN);*/
+	err = regmap_read(tfa98xx->regmap, TFA98XX_CTRL_SAAM_PGA, &value);
+	*val = (value & TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_MSK) >>
+				TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_POS;
+	return 0;
+}
+
+static int tfa98xx_dbgfs_pga_gain_set(void *data, u64 val)
+{
+	struct i2c_client *i2c = (struct i2c_client *)data;
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+	int err;
+	unsigned int value;
+
+	value = val & 0xffff;
+	if (value > 7)
+		return -EINVAL;
+/*	TFA_SET_BF(tfa98xx->handle, SAAMGAIN, value);*/
+	err = regmap_update_bits(tfa98xx->regmap, TFA98XX_CTRL_SAAM_PGA,
+				TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_MSK,
+				value << TFA98XX_CTRL_SAAM_PGA_SAAMGAIN_POS);
+	return err;
+}
+
+/* Direct registers access - provide register address in hex */
+#define TFA98XX_DEBUGFS_REG_SET(__reg)					\
+static int tfa98xx_dbgfs_reg_##__reg##_set(void *data, u64 val)		\
+{									\
+	struct i2c_client *i2c = (struct i2c_client *)data;		\
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);		\
+	unsigned int ret, value;					\
+									\
+	ret = regmap_write(tfa98xx->regmap, 0x##__reg, (val & 0xffff));	\
+	value = val & 0xffff;						\
+	return 0;							\
+}									\
+static int tfa98xx_dbgfs_reg_##__reg##_get(void *data, u64 *val)	\
+{									\
+	struct i2c_client *i2c = (struct i2c_client *)data;		\
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);		\
+	unsigned int value;						\
+	int ret;							\
+	ret = regmap_read(tfa98xx->regmap, 0x##__reg, &value);		\
+	*val = value;							\
+	return 0;							\
+}									\
+DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_reg_##__reg##_fops, tfa98xx_dbgfs_reg_##__reg##_get,	\
+						tfa98xx_dbgfs_reg_##__reg##_set, "0x%llx\n");
+
+#define VAL(str) #str
+#define TOSTRING(str) VAL(str)
+#define TFA98XX_DEBUGFS_REG_CREATE_FILE(__reg, __name)				\
+	debugfs_create_file(TOSTRING(__reg) "-" TOSTRING(__name), S_IRUGO|S_IWUGO, dbg_reg_dir,\
+					i2c, &tfa98xx_dbgfs_reg_##__reg##_fops);
+
+
+TFA98XX_DEBUGFS_REG_SET(00);
+TFA98XX_DEBUGFS_REG_SET(01);
+TFA98XX_DEBUGFS_REG_SET(02);
+TFA98XX_DEBUGFS_REG_SET(03);
+TFA98XX_DEBUGFS_REG_SET(04);
+TFA98XX_DEBUGFS_REG_SET(05);
+TFA98XX_DEBUGFS_REG_SET(06);
+TFA98XX_DEBUGFS_REG_SET(07);
+TFA98XX_DEBUGFS_REG_SET(08);
+TFA98XX_DEBUGFS_REG_SET(09);
+TFA98XX_DEBUGFS_REG_SET(0A);
+TFA98XX_DEBUGFS_REG_SET(0B);
+TFA98XX_DEBUGFS_REG_SET(0F);
+TFA98XX_DEBUGFS_REG_SET(10);
+TFA98XX_DEBUGFS_REG_SET(11);
+TFA98XX_DEBUGFS_REG_SET(12);
+TFA98XX_DEBUGFS_REG_SET(13);
+TFA98XX_DEBUGFS_REG_SET(22);
+TFA98XX_DEBUGFS_REG_SET(25);
+
+DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_calib_otc_fops, tfa98xx_dbgfs_otc_get,
+						tfa98xx_dbgfs_otc_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_calib_mtpex_fops, tfa98xx_dbgfs_mtpex_get,
+						tfa98xx_dbgfs_mtpex_set, "%llu\n");
+DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_calib_temp_fops, tfa98xx_dbgfs_temp_get,
+						tfa98xx_dbgfs_temp_set, "%llu\n");
+
+DEFINE_SIMPLE_ATTRIBUTE(tfa98xx_dbgfs_pga_gain_fops, tfa98xx_dbgfs_pga_gain_get,
+						tfa98xx_dbgfs_pga_gain_set, "%llu\n");
+
+static const struct file_operations tfa98xx_dbgfs_calib_start_fops = {
+	.open = simple_open,
+	.read = tfa98xx_dbgfs_start_get,
+	.write = tfa98xx_dbgfs_start_set,
+	.llseek = default_llseek,
+};
+
+static const struct file_operations tfa98xx_dbgfs_r_fops = {
+	.open = simple_open,
+	.read = tfa98xx_dbgfs_r_read,
+	.llseek = default_llseek,
+};
+
+static const struct file_operations tfa98xx_dbgfs_version_fops = {
+	.open = simple_open,
+	.read = tfa98xx_dbgfs_version_read,
+	.llseek = default_llseek,
+};
+
+static const struct file_operations tfa98xx_dbgfs_dsp_state_fops = {
+	.open = simple_open,
+	.read = tfa98xx_dbgfs_dsp_state_get,
+	.write = tfa98xx_dbgfs_dsp_state_set,
+	.llseek = default_llseek,
+};
+
+static const struct file_operations tfa98xx_dbgfs_accounting_fops = {
+	.open = simple_open,
+	.read = tfa98xx_dbgfs_accounting_get,
+	.llseek = default_llseek,
+};
+
+
+static void tfa98xx_debug_init(struct tfa98xx *tfa98xx, struct i2c_client *i2c)
+{
+	char name[50];
+	struct dentry *dbg_reg_dir;
+
+	scnprintf(name, MAX_CONTROL_NAME, "%s-%x", i2c->name, i2c->addr);
+	tfa98xx->dbg_dir = debugfs_create_dir(name, NULL);
+	debugfs_create_file("OTC", S_IRUGO|S_IWUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_calib_otc_fops);
+	debugfs_create_file("MTPEX", S_IRUGO|S_IWUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_calib_mtpex_fops);
+	debugfs_create_file("TEMP", S_IRUGO|S_IWUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_calib_temp_fops);
+	debugfs_create_file("calibrate", S_IRUGO|S_IWUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_calib_start_fops);
+	debugfs_create_file("R", S_IRUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_r_fops);
+	debugfs_create_file("version", S_IRUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_version_fops);
+	debugfs_create_file("dsp-state", S_IRUGO|S_IWUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_dsp_state_fops);
+	debugfs_create_file("accounting", S_IRUGO, tfa98xx->dbg_dir,
+						i2c, &tfa98xx_dbgfs_accounting_fops);
+
+	/* Direct registers access */
+	if (tfa98xx->flags & TFA98XX_FLAG_TFA9890_FAM_DEV) {
+		dbg_reg_dir = debugfs_create_dir("regs", tfa98xx->dbg_dir);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(00, STATUS);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(01, BATTERYVOLTAGE);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(02, TEMPERATURE);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(03, REVISIONNUMBER);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(04, I2SREG);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(05, BAT_PROT);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(06, AUDIO_CTR);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(07, DCDCBOOST);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(08, SPKR_CALIBRATION);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(09, SYS_CTRL);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(0A, I2S_SEL_REG);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(0B, HIDDEN_MTP_KEY2);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(0F, INTERRUPT_REG);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(10, PDM_CTRL);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(11, PDM_OUT_CTRL);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(12, PDM_DS4_R);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(13, PDM_DS4_L);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(22, CTRL_SAAM_PGA);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(25, MISC_CTRL);
+	}
+
+	if (tfa98xx->flags & TFA98XX_FLAG_TFA9897_FAM_DEV) {
+		dbg_reg_dir = debugfs_create_dir("regs", tfa98xx->dbg_dir);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(00, STATUS);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(01, BATTERYVOLTAGE);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(02, TEMPERATURE);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(03, REVISIONNUMBER);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(04, I2SREG);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(05, BAT_PROT);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(06, AUDIO_CTR);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(07, DCDCBOOST);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(08, SPKR_CALIBRATION);
+		TFA98XX_DEBUGFS_REG_CREATE_FILE(09, SYS_CTRL);
+	}
+
+	if (tfa98xx->flags & TFA98XX_FLAG_SAAM_AVAILABLE) {
+		dev_dbg(tfa98xx->dev, "Adding pga_gain debug interface\n");
+		debugfs_create_file("pga_gain", S_IRUGO, tfa98xx->dbg_dir,
+						tfa98xx->i2c,
+						&tfa98xx_dbgfs_pga_gain_fops);
+	}
+}
+
+static void tfa98xx_debug_remove(struct tfa98xx *tfa98xx)
+{
+	if (tfa98xx->dbg_dir)
+		debugfs_remove_recursive(tfa98xx->dbg_dir);
+}
+#endif
+
+static int tfa98xx_get_vstep(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+#else
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	int mixer_profile = kcontrol->private_value;
+	int profile = get_profile_id_for_sr(mixer_profile, tfa98xx->rate);
+	int vstep = tfa98xx_prof_vsteps[profile];
+	ucontrol->value.integer.value[0] =
+				tfacont_get_max_vstep(tfa98xx->handle, profile)
+				- vstep - 1;
+	return 0;
+}
+
+static int tfa98xx_set_vstep(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+#else
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	int mixer_profile = kcontrol->private_value;
+	int profile = get_profile_id_for_sr(mixer_profile, tfa98xx->rate);
+	int value = ucontrol->value.integer.value[0];
+	int vstep = tfa98xx_prof_vsteps[profile];
+	int vsteps = tfacont_get_max_vstep(tfa98xx->handle, profile);
+	int new_vstep, err = 0;
+	int ready = 0;
+	unsigned int base_addr_inten = TFA_FAM(tfa98xx->handle,INTENVDDS) >> 8;
+
+	if (no_start != 0)
+		return 0;
+
+	if (vstep == vsteps - value - 1)
+		return 0;
+
+	new_vstep = vsteps - value - 1;
+
+	if (new_vstep < 0)
+		new_vstep = 0;
+
+	tfa98xx_prof_vsteps[profile] = new_vstep;
+
+#ifndef TFA98XX_ALSA_CTRL_PROF_CHG_ON_VOL
+	if (profile == tfa98xx_profile) {
+#endif
+		/* this is the active profile, program the new vstep */
+		tfa98xx_vsteps[0] = new_vstep;
+		tfa98xx_vsteps[1] = new_vstep;
+		mutex_lock(&tfa98xx->dsp_lock);
+		tfa98xx_open(tfa98xx->handle);
+		tfa98xx_dsp_system_stable(tfa98xx->handle, &ready);
+		tfa98xx_close(tfa98xx->handle);
+
+		/* Enable internal clk (osc1m) to switch profile */
+		if ((tfa98xx_dev_family(tfa98xx->handle) == 2) && (ready == 0)) {
+			/* Disable interrupts (Enabled again in the wrapper function: tfa98xx_tfa_start) */
+			regmap_write(tfa98xx->regmap, base_addr_inten + 1, 0);
+			/* Set polarity to high */
+			TFA_SET_BF(tfa98xx->handle, IPOMWSRC, 1);
+
+			TFA_SET_BF(tfa98xx->handle, RST, 1);
+			TFA_SET_BF(tfa98xx->handle, SBSL, 0);
+			TFA_SET_BF(tfa98xx->handle, AMPC, 0);
+			TFA_SET_BF(tfa98xx->handle, AMPE, 0);
+			TFA_SET_BF(tfa98xx->handle, REFCKSEL, 1);
+			ready = 1;
+		}
+
+		if (ready) {
+			err = tfa98xx_tfa_start(tfa98xx, profile, tfa98xx_vsteps);
+			if (err) {
+				pr_err("Write vstep error: %d\n", err);
+			} else {
+				pr_debug("Succesfully changed vstep index!\n");
+			}
+		}
+
+		if (tfa98xx_dev_family(tfa98xx->handle) == 2) {
+			/* Set back to external clock */
+			TFA_SET_BF(tfa98xx->handle, REFCKSEL, 0);
+			TFA_SET_BF(tfa98xx->handle, SBSL, 1);
+		}
+
+		mutex_unlock(&tfa98xx->dsp_lock);
+#ifndef TFA98XX_ALSA_CTRL_PROF_CHG_ON_VOL
+	}
+#endif
+
+	pr_debug("vstep:%d, (control value: %d) - profile %d\n", new_vstep,
+								 value, profile);
+	return (err == 0);
+}
+
+static int tfa98xx_info_vstep(struct snd_kcontrol *kcontrol,
+		       struct snd_ctl_elem_info *uinfo)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+#else
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	int mixer_profile = kcontrol->private_value;
+	int profile = get_profile_id_for_sr(mixer_profile, tfa98xx->rate);
+
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;// TODO handles_local[dev_idx].spkr_count
+	uinfo->value.integer.min = 0;
+	uinfo->value.integer.max = tfacont_get_max_vstep(tfa98xx->handle, profile) - 1;
+	pr_debug("vsteps count: %d [prof=%d]\n", tfacont_get_max_vstep(tfa98xx->handle, profile),
+			profile);
+	return 0;
+}
+
+static int tfa98xx_get_profile(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+    ucontrol->value.integer.value[0] = tfa98xx_mixer_profile;
+	return 0;
+}
+
+static int tfa98xx_set_profile(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+#else
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+
+	unsigned int base_addr_inten = TFA_FAM(tfa98xx->handle,INTENVDDS) >> 8;
+	int profile_count = tfa98xx_mixer_profiles;
+	int profile = tfa98xx_mixer_profile;
+	int new_profile = ucontrol->value.integer.value[0];
+	int err;
+	int ready = 0;
+	int prof_idx;
+
+
+	if (no_start != 0)
+		return 0;
+
+	if (new_profile == profile)
+		return 0;
+
+	if (new_profile >= profile_count)
+		return 0;
+    
+	/* get the container profile for the requested sample rate */
+	prof_idx = get_profile_id_for_sr(new_profile, tfa98xx->rate);
+	if (prof_idx < 0) {
+		pr_err("tfa98xx: sample rate [%d] not supported for this mixer profile [%d].\n", tfa98xx->rate, new_profile);
+		return 0;
+	}
+	pr_debug("selected container profile [%d]\n", prof_idx);
+    
+	/* update mixer profile */
+	tfa98xx_mixer_profile = new_profile;
+    
+	/* update 'real' profile (container profile) */
+	tfa98xx_profile = prof_idx;
+	tfa98xx_vsteps[0] = tfa98xx_prof_vsteps[prof_idx];
+	tfa98xx_vsteps[1] = tfa98xx_prof_vsteps[prof_idx];
+
+	/*
+	 * Don't call tfa_start() on TFA1 if there is no clock.
+	 * For TFA2 is able to load the profile without clock.
+	 */
+	
+	mutex_lock(&tfa98xx->dsp_lock);
+	tfa98xx_open(tfa98xx->handle);
+	tfa98xx_dsp_system_stable(tfa98xx->handle, &ready);
+	tfa98xx_close(tfa98xx->handle);
+	
+	/* Enable internal clk (osc1m) to switch profile */
+	if (tfa98xx_dev_family(tfa98xx->handle) == 2 && ready == 0) {
+		/* Disable interrupts (Enabled again in the wrapper function: tfa98xx_tfa_start) */
+		regmap_write(tfa98xx->regmap, base_addr_inten + 1, 0);
+		/* Set polarity to high */
+		TFA_SET_BF(tfa98xx->handle, IPOMWSRC, 1);
+
+		TFA_SET_BF(tfa98xx->handle, RST, 1);
+		TFA_SET_BF_VOLATILE(tfa98xx->handle, SBSL, 0);
+		TFA_SET_BF(tfa98xx->handle, AMPC, 0);
+		TFA_SET_BF(tfa98xx->handle, AMPE, 0);
+		TFA_SET_BF(tfa98xx->handle, REFCKSEL, 1);
+		ready = 1;
+	}
+
+	if (ready) {
+		/* Also re-enables the interrupts */
+		err = tfa98xx_tfa_start(tfa98xx, prof_idx, tfa98xx_vsteps);
+		if (err) {
+			pr_info("Write profile error: %d\n", err);
+		} else {
+			pr_debug("Changed to profile %d (vstep = %d)\n", prof_idx,
+							tfa98xx_vsteps[0]);
+		}
+	}
+
+	if (tfa98xx_dev_family(tfa98xx->handle) == 2) {
+		/* Set back to external clock */
+		TFA_SET_BF(tfa98xx->handle, REFCKSEL, 0);
+		TFA_SET_BF_VOLATILE(tfa98xx->handle, SBSL, 1);
+	}
+	
+	mutex_unlock(&tfa98xx->dsp_lock);
+
+	/* Flag DSP as invalidated as the profile change may invalidate the
+	 * current DSP configuration. That way, further stream start can
+	 * trigger a tfa_start.
+	 */
+	tfa98xx->dsp_init = TFA98XX_DSP_INIT_INVALIDATED;
+
+	return 1;
+}
+
+static struct snd_kcontrol_new *tfa98xx_controls;
+
+/* copies the profile basename (i.e. part until .) into buf */
+static void get_profile_basename(char* buf, char* profile) 
+{
+	int cp_len = 0, idx = 0;
+	char *pch;
+
+	pch = strchr(profile, '.');
+	idx = pch - profile;
+	cp_len = (pch != NULL) ? idx : (int) strlen(profile);
+	memcpy(buf, profile, cp_len);
+	buf[cp_len] = 0;
+}
+
+/* return the profile name accociated with id from the profile list */
+static int get_profile_from_list(char *buf, int id)
+{
+	struct tfa98xx_baseprofile *bprof;
+
+	list_for_each_entry(bprof, &profile_list, list) {
+		if (bprof->item_id == id) {
+			strcpy(buf, bprof->basename);
+			return 0;
+		}
+	}
+
+	return -1;
+}
+
+/* search for the profile in the profile list */
+static int is_profile_in_list(char *profile, int len) 
+{
+	struct tfa98xx_baseprofile *bprof;
+
+	list_for_each_entry(bprof, &profile_list, list) {
+		if (0 == strncmp(bprof->basename, profile, len))
+			return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * for the profile with id, look if the requested samplerate is
+ * supported, if found return the (container)profile for this
+ * samplerate, on error or if not found return -1
+ */
+static int get_profile_id_for_sr(int id, unsigned int rate)
+{
+	int idx = 0;
+	struct tfa98xx_baseprofile *bprof;
+
+	list_for_each_entry(bprof, &profile_list, list) {
+		if (id == bprof->item_id) {
+			idx = tfa98xx_get_fssel(rate);
+			if (idx < 0) {
+				/* samplerate not supported */
+				return -1;
+			}
+
+			return bprof->sr_rate_sup[idx];
+		}
+	}
+
+	/* profile not found */
+	return -1;
+}
+
+/* check if this profile is a calibration profile */
+static int is_calibration_profile(char *profile)
+{
+	if (strstr(profile, ".cal") != NULL)
+		return 1;
+	return 0;
+}
+
+/*
+ * adds the (container)profile index of the samplerate found in
+ * the (container)profile to a fixed samplerate table in the (mixer)profile
+ */
+static int add_sr_to_profile(struct tfa98xx *tfa98xx, char *basename, int len, int profile)
+{
+	struct tfa98xx_baseprofile *bprof;
+	int idx = 0;
+	unsigned int sr = 0;
+
+	list_for_each_entry(bprof, &profile_list, list) {
+		if (0 == strncmp(bprof->basename, basename, len)) {
+			/* add supported samplerate for this profile */
+			sr = tfa98xx_get_profile_sr(tfa98xx->handle, profile);
+			if (!sr) {
+				pr_err("unable to identify supported sample rate for %s\n", bprof->basename);
+				return -1;
+			}
+
+			/* get the index for this samplerate */
+			idx = tfa98xx_get_fssel(sr);
+			if (idx < 0 || idx >= TFA98XX_NUM_RATES) {
+				pr_err("invalid index for samplerate %d\n", idx);
+				return -1;
+			}
+
+			/* enter the (container)profile for this samplerate at the corresponding index */
+			bprof->sr_rate_sup[idx] = profile;
+
+			pr_debug("added profile:samplerate = [%d:%d] for mixer profile: %s\n", profile, sr, bprof->basename);    
+		}
+	}
+
+	return 0;
+}
+
+static int tfa98xx_info_profile(struct snd_kcontrol *kcontrol,
+			 struct snd_ctl_elem_info *uinfo)
+{
+	char profile_name[MAX_CONTROL_NAME] = {0};
+	int count = tfa98xx_mixer_profiles, err = -1;
+       
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->count = 1;
+	uinfo->value.enumerated.items = count;
+
+	if (uinfo->value.enumerated.item >= count)
+		uinfo->value.enumerated.item = count - 1;
+        
+	err = get_profile_from_list(profile_name, uinfo->value.enumerated.item);
+	if (err != 0)
+		return -EINVAL;
+
+	strcpy(uinfo->value.enumerated.name, profile_name);
+ 
+	return 0;
+}
+
+static int tfa98xx_get_stop_ctl(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+	ucontrol->value.integer.value[0] = 0;
+	return 0;
+}
+
+static int tfa98xx_set_stop_ctl(struct snd_kcontrol *kcontrol,
+			     struct snd_ctl_elem_value *ucontrol)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+	struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
+#else
+	struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
+#endif
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	int ready = 0;
+
+	pr_debug("%ld\n", ucontrol->value.integer.value[0]);
+
+	tfa98xx_open(tfa98xx->handle);
+	tfa98xx_dsp_system_stable(tfa98xx->handle, &ready);
+	tfa98xx_close(tfa98xx->handle);
+
+	if ((ucontrol->value.integer.value[0] != 0) && ready) {
+		cancel_delayed_work_sync(&tfa98xx->monitor_work);
+
+		cancel_delayed_work_sync(&tfa98xx->init_work);
+		if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK)
+			return 0;
+		mutex_lock(&tfa98xx->dsp_lock);
+		tfa_stop();
+		tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED;
+		mutex_unlock(&tfa98xx->dsp_lock);
+	}
+
+	ucontrol->value.integer.value[0] = 0;
+	return 1;
+}
+
+static int tfa98xx_create_controls(struct tfa98xx *tfa98xx)
+{
+	int prof, nprof, mix_index = 0;
+	int  nr_controls = 0, id = 0;
+	char *name;
+	struct tfa98xx_baseprofile *bprofile;
+
+	/* Create the following controls:
+	 *  - enum control to select the active profile
+	 *  - one volume control for each profile hosting a vstep
+	 *  - Stop control on TFA1 devices
+	 */
+
+	nr_controls = 1; 	 /* Profile control */
+	if (tfa98xx_dev_family(tfa98xx->handle) == 1)
+		nr_controls += 1; /* Stop control */
+
+	/* allocate the tfa98xx_controls base on the nr of profiles */
+	nprof = tfaContMaxProfile(tfa98xx->handle);
+
+	for (prof = 0; prof < nprof; prof++) {
+		if (tfacont_get_max_vstep(tfa98xx->handle, prof))
+			nr_controls++; /* Playback Volume control */
+	}
+
+	tfa98xx_controls = devm_kzalloc(tfa98xx->codec->dev,
+			nr_controls * sizeof(tfa98xx_controls[0]), GFP_KERNEL);
+	if(!tfa98xx_controls)
+		return -ENOMEM;
+
+	/* Create a mixer item for selecting the active profile */
+	name = devm_kzalloc(tfa98xx->codec->dev, MAX_CONTROL_NAME, GFP_KERNEL);
+	if (!name)
+		return -ENOMEM;
+	scnprintf(name, MAX_CONTROL_NAME, "%s Profile", tfa98xx->fw.name);
+	tfa98xx_controls[mix_index].name = name;
+	tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+	tfa98xx_controls[mix_index].info = tfa98xx_info_profile;
+	tfa98xx_controls[mix_index].get = tfa98xx_get_profile;
+	tfa98xx_controls[mix_index].put = tfa98xx_set_profile;
+	// tfa98xx_controls[mix_index].private_value = profs; /* save number of profiles */
+	mix_index++;
+
+	/* create mixer items for each profile that has volume */
+	for (prof = 0; prof < nprof; prof++) {
+		/* create an new empty profile */
+		bprofile = devm_kzalloc(tfa98xx->codec->dev, sizeof(*bprofile), GFP_KERNEL);
+		if (!bprofile)
+			return -ENOMEM;
+
+		bprofile->len = 0;
+		bprofile->item_id = -1;
+		INIT_LIST_HEAD(&bprofile->list);
+
+		/* copy profile name into basename until the . */
+		get_profile_basename(bprofile->basename, tfaContProfileName(tfa98xx->handle, prof));
+		bprofile->len = strlen(bprofile->basename);
+
+		/*
+		 * search the profile list for a profile with basename, if it is not found then
+		 * add it to the list and add a new mixer control (if it has vsteps)
+		 * also, if it is a calibration profile, do not add it to the list
+		 */
+		if (is_profile_in_list(bprofile->basename, bprofile->len) == 0 &&
+			 is_calibration_profile(tfaContProfileName(tfa98xx->handle, prof)) == 0) {
+			/* the profile is not present, add it to the list */
+			list_add(&bprofile->list, &profile_list);
+			bprofile->item_id = id++;
+
+			pr_debug("profile added [%d]: %s\n", bprofile->item_id, bprofile->basename);
+
+			if (tfacont_get_max_vstep(tfa98xx->handle, prof)) {
+				name = devm_kzalloc(tfa98xx->codec->dev, MAX_CONTROL_NAME, GFP_KERNEL);
+				if (!name)
+					return -ENOMEM;
+
+				scnprintf(name, MAX_CONTROL_NAME, "%s %s Playback Volume",
+				tfa98xx->fw.name, bprofile->basename);
+
+				tfa98xx_controls[mix_index].name = name;
+				tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+				tfa98xx_controls[mix_index].info = tfa98xx_info_vstep;
+				tfa98xx_controls[mix_index].get = tfa98xx_get_vstep;
+				tfa98xx_controls[mix_index].put = tfa98xx_set_vstep;
+				tfa98xx_controls[mix_index].private_value = prof; /* save profile index */
+				mix_index++;
+			}
+		}
+
+		/* look for the basename profile in the list of mixer profiles and add the
+		   container profile index to the supported samplerates of this mixer profile */
+		add_sr_to_profile(tfa98xx, bprofile->basename, bprofile->len, prof);
+	}
+
+
+	if (tfa98xx_dev_family(tfa98xx->handle) == 1) {
+		/* Create a mixer item for stop control on TFA1 */
+		name = devm_kzalloc(tfa98xx->codec->dev, MAX_CONTROL_NAME, GFP_KERNEL);
+		if (!name)
+			return -ENOMEM;
+
+		scnprintf(name, MAX_CONTROL_NAME, "%s Stop", tfa98xx->fw.name);
+		tfa98xx_controls[mix_index].name = name;
+		tfa98xx_controls[mix_index].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+		tfa98xx_controls[mix_index].info = snd_soc_info_bool_ext;
+		tfa98xx_controls[mix_index].get = tfa98xx_get_stop_ctl;
+		tfa98xx_controls[mix_index].put = tfa98xx_set_stop_ctl;
+		mix_index++;
+	}
+
+	/* set the number of user selectable profiles in the mixer */
+	tfa98xx_mixer_profiles = id;
+
+	return snd_soc_add_codec_controls(tfa98xx->codec,
+		tfa98xx_controls, mix_index);
+}
+
+static void *tfa98xx_devm_kstrdup(struct device *dev, char *buf)
+{
+	char *str = devm_kzalloc(dev, strlen(buf) + 1, GFP_KERNEL);
+	if (!str)
+		return str;
+	memcpy(str, buf, strlen(buf));
+	return str;
+}
+
+static int tfa98xx_append_i2c_address(struct device *dev,
+				struct i2c_client *i2c,
+				struct snd_soc_dapm_widget *widgets,
+				int num_widgets,
+				struct snd_soc_dai_driver *dai_drv,
+				int num_dai)
+{
+	char buf[50];
+	int i;
+	int i2cbus = i2c->adapter->nr;
+	int addr = i2c->addr;
+	if (dai_drv && num_dai > 0)
+		for(i = 0; i < num_dai; i++) {
+			snprintf(buf, 50, "%s-%x-%x",dai_drv[i].name, i2cbus,
+				addr);
+			dai_drv[i].name = tfa98xx_devm_kstrdup(dev, buf);
+
+			snprintf(buf, 50, "%s-%x-%x",
+						dai_drv[i].playback.stream_name,
+						i2cbus, addr);
+			dai_drv[i].playback.stream_name = tfa98xx_devm_kstrdup(dev, buf);
+
+			snprintf(buf, 50, "%s-%x-%x",
+						dai_drv[i].capture.stream_name,
+						i2cbus, addr);
+			dai_drv[i].capture.stream_name = tfa98xx_devm_kstrdup(dev, buf);
+		}
+
+	/* the idea behind this is convert:
+	 * SND_SOC_DAPM_AIF_IN("AIF IN", "AIF Playback", 0, SND_SOC_NOPM, 0, 0),
+	 * into:
+	 * SND_SOC_DAPM_AIF_IN("AIF IN", "AIF Playback-2-36", 0, SND_SOC_NOPM, 0, 0),
+	 */
+	if (widgets && num_widgets > 0)
+		for(i = 0; i < num_widgets; i++) {
+			if(!widgets[i].sname)
+				continue;
+			if((widgets[i].id == snd_soc_dapm_aif_in)
+				|| (widgets[i].id == snd_soc_dapm_aif_out)) {
+				snprintf(buf, 50, "%s-%x-%x", widgets[i].sname,
+					i2cbus, addr);
+				widgets[i].sname = tfa98xx_devm_kstrdup(dev, buf);
+			}
+		}
+
+	return 0;
+}
+
+static struct snd_soc_dapm_widget tfa98xx_dapm_widgets_common[] = {
+	/* Stream widgets */
+	SND_SOC_DAPM_AIF_IN("AIF IN", "AIF Playback", 0, SND_SOC_NOPM, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("AIF OUT", "AIF Capture", 0, SND_SOC_NOPM, 0, 0),
+
+	SND_SOC_DAPM_OUTPUT("OUTL"),
+	SND_SOC_DAPM_INPUT("AEC Loopback"),
+};
+
+static struct snd_soc_dapm_widget tfa98xx_dapm_widgets_stereo[] = {
+	SND_SOC_DAPM_OUTPUT("OUTR"),
+};
+
+static struct snd_soc_dapm_widget tfa98xx_dapm_widgets_saam[] = {
+	SND_SOC_DAPM_INPUT("SAAM MIC"),
+};
+
+static struct snd_soc_dapm_widget tfa9888_dapm_inputs[] = {
+	SND_SOC_DAPM_INPUT("DMIC1"),
+	SND_SOC_DAPM_INPUT("DMIC2"),
+	SND_SOC_DAPM_INPUT("DMIC3"),
+	SND_SOC_DAPM_INPUT("DMIC4"),
+};
+
+static const struct snd_soc_dapm_route tfa98xx_dapm_routes_common[] = {
+	{ "OUTL", NULL, "AIF IN" },
+	{ "AIF OUT", NULL, "AEC Loopback" },
+};
+
+static const struct snd_soc_dapm_route tfa98xx_dapm_routes_saam[] = {
+	{ "AIF OUT", NULL, "SAAM MIC" },
+};
+
+static const struct snd_soc_dapm_route tfa98xx_dapm_routes_stereo[] = {
+	{ "OUTR", NULL, "AIF IN" },
+};
+
+static const struct snd_soc_dapm_route tfa9888_input_dapm_routes[] = {
+	{ "AIF OUT", NULL, "DMIC1" },
+	{ "AIF OUT", NULL, "DMIC2" },
+	{ "AIF OUT", NULL, "DMIC3" },
+	{ "AIF OUT", NULL, "DMIC4" },
+};
+
+static void tfa98xx_add_widgets(struct tfa98xx *tfa98xx)
+{
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,2,0)
+	struct snd_soc_dapm_context *dapm = &tfa98xx->codec->dapm;
+#else
+    struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(tfa98xx->codec);
+#endif
+	struct snd_soc_dapm_widget *widgets;
+	unsigned int num_dapm_widgets = ARRAY_SIZE(tfa98xx_dapm_widgets_common);
+
+	widgets = devm_kzalloc(&tfa98xx->i2c->dev,
+			sizeof(struct snd_soc_dapm_widget) *
+				ARRAY_SIZE(tfa98xx_dapm_widgets_common),
+			GFP_KERNEL);
+	if (!widgets)
+		return;
+	memcpy(widgets, tfa98xx_dapm_widgets_common,
+			sizeof(struct snd_soc_dapm_widget) *
+				ARRAY_SIZE(tfa98xx_dapm_widgets_common));
+
+	tfa98xx_append_i2c_address(&tfa98xx->i2c->dev,
+				tfa98xx->i2c,
+				widgets,
+				num_dapm_widgets,
+				NULL,
+				0);
+
+	snd_soc_dapm_new_controls(dapm, widgets,
+				  ARRAY_SIZE(tfa98xx_dapm_widgets_common));
+	snd_soc_dapm_add_routes(dapm, tfa98xx_dapm_routes_common,
+				ARRAY_SIZE(tfa98xx_dapm_routes_common));
+
+	if (tfa98xx->flags & TFA98XX_FLAG_STEREO_DEVICE) {
+		snd_soc_dapm_new_controls(dapm, tfa98xx_dapm_widgets_stereo,
+					  ARRAY_SIZE(tfa98xx_dapm_widgets_stereo));
+		snd_soc_dapm_add_routes(dapm, tfa98xx_dapm_routes_stereo,
+					ARRAY_SIZE(tfa98xx_dapm_routes_stereo));
+	}
+
+	if (tfa98xx->flags & TFA98XX_FLAG_MULTI_MIC_INPUTS) {
+		snd_soc_dapm_new_controls(dapm, tfa9888_dapm_inputs,
+					  ARRAY_SIZE(tfa9888_dapm_inputs));
+		snd_soc_dapm_add_routes(dapm, tfa9888_input_dapm_routes,
+					ARRAY_SIZE(tfa9888_input_dapm_routes));
+	}
+
+	if (tfa98xx->flags & TFA98XX_FLAG_SAAM_AVAILABLE) {
+		snd_soc_dapm_new_controls(dapm, tfa98xx_dapm_widgets_saam,
+					  ARRAY_SIZE(tfa98xx_dapm_widgets_saam));
+		snd_soc_dapm_add_routes(dapm, tfa98xx_dapm_routes_saam,
+					ARRAY_SIZE(tfa98xx_dapm_routes_saam));
+	}
+}
+
+
+/* Match tfa98xx device structure with a valid DSP handle */
+/* TODO  can be removed once we pass the device struct in stead of handles
+	The check in tfa98xx_register_dsp() is implicitly done in tfa_probe() /tfa98xx_cnt_slave2idx(_)
+*/
+static int tfa98xx_register_dsp(struct tfa98xx *tfa98xx)
+{
+	int i, handle = -1;
+	u8 slave;
+
+	for (i = 0; i < tfa98xx_cnt_max_device(); i++) {
+		if (tfaContGetSlave(i, &slave) != Tfa98xx_Error_Ok)
+			goto reg_err;
+		pr_debug("%s: i=%d - dev = 0x%x\n", __func__, i, slave);
+		if (slave == tfa98xx->i2c->addr) {
+			handle = i;
+			break;
+		}
+	}
+	if (handle != -1) {
+		tfa98xx_devices[handle] = tfa98xx;
+		dev_info(&tfa98xx->i2c->dev,
+				"Registered DSP instance with handle %d\n",
+								handle);
+		tfa98xx_registered_handles++;
+		return handle;
+	}
+reg_err:
+	dev_err(&tfa98xx->i2c->dev,
+		"Unable to match I2C address 0x%x with a container device\n",
+							tfa98xx->i2c->addr);
+	return -EINVAL;
+}
+
+static void tfa98xx_unregister_dsp(struct tfa98xx *tfa98xx)
+{
+	tfa98xx_registered_handles--;
+
+	tfa98xx_devices[tfa98xx->handle] = NULL;
+	dev_info(&tfa98xx->i2c->dev, "Un-registered DSP instance with handle %d\n",
+							tfa98xx->handle);
+}
+
+
+/* I2C wrapper functions */
+enum Tfa98xx_Error tfa98xx_write_register16(Tfa98xx_handle_t handle,
+					unsigned char subaddress,
+					unsigned short value)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	struct tfa98xx *tfa98xx;
+	int ret;
+	int retries = I2C_RETRIES;
+
+	if (tfa98xx_devices[handle]) {
+		tfa98xx = tfa98xx_devices[handle];
+		if (!tfa98xx || !tfa98xx->regmap) {
+			pr_err("No tfa98xx regmap available\n");
+			return Tfa98xx_Error_Bad_Parameter;
+		}
+retry:
+		ret = regmap_write(tfa98xx->regmap, subaddress, value);
+		if (ret < 0) {
+			pr_warn("i2c error, retries left: %d\n", retries);
+			if (retries) {
+				retries--;
+				msleep(I2C_RETRY_DELAY);
+				goto retry;
+			}
+			return Tfa98xx_Error_Fail;
+		}
+		if (tfa98xx_kmsg_regs)
+			dev_dbg(&tfa98xx->i2c->dev, "  WR reg=0x%02x, val=0x%04x %s\n",
+								subaddress, value,
+								ret<0? "Error!!" : "");
+
+		if(tfa98xx_ftrace_regs)
+			tfa98xx_trace_printk("\tWR     reg=0x%02x, val=0x%04x %s\n",
+								subaddress, value,
+								ret<0? "Error!!" : "");
+	} else {
+		pr_err("No device available\n");
+		error = Tfa98xx_Error_Fail;
+	}
+	return error;
+}
+
+enum Tfa98xx_Error tfa98xx_read_register16(Tfa98xx_handle_t handle,
+					unsigned char subaddress,
+					unsigned short *val)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	struct tfa98xx *tfa98xx;
+	unsigned int value;
+	int retries = I2C_RETRIES;
+	int ret;
+
+	if (tfa98xx_devices[handle]) {
+		tfa98xx = tfa98xx_devices[handle];
+		if (!tfa98xx || !tfa98xx->regmap) {
+			pr_err("No tfa98xx regmap available\n");
+			return Tfa98xx_Error_Bad_Parameter;
+		}
+retry:
+		ret = regmap_read(tfa98xx->regmap, subaddress, &value);
+		if (ret < 0) {
+			pr_warn("i2c error at subaddress 0x%x, retries left: %d\n", subaddress, retries);
+			if (retries) {
+				retries--;
+				msleep(I2C_RETRY_DELAY);
+				goto retry;
+			}
+			return Tfa98xx_Error_Fail;
+		}
+		*val = value & 0xffff;
+
+		if (tfa98xx_kmsg_regs)
+			dev_dbg(&tfa98xx->i2c->dev, "RD   reg=0x%02x, val=0x%04x %s\n",
+								subaddress, *val,
+								ret<0? "Error!!" : "");
+		if (tfa98xx_ftrace_regs)
+			tfa98xx_trace_printk("\tRD     reg=0x%02x, val=0x%04x %s\n",
+								subaddress, *val,
+								ret<0? "Error!!" : "");
+	} else {
+		pr_err("No device available\n");
+		error = Tfa98xx_Error_Fail;
+	}
+	return error;
+}
+
+enum Tfa98xx_Error tfa98xx_read_data(Tfa98xx_handle_t handle,
+				unsigned char reg,
+				int len, unsigned char value[])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	struct tfa98xx *tfa98xx;
+	struct i2c_client *tfa98xx_client;
+	int err;
+	int tries = 0;
+	struct i2c_msg msgs[] = {
+		{
+			.flags = 0,
+			.len = 1,
+			.buf = &reg,
+		}, {
+			.flags = I2C_M_RD,
+			.len = len,
+			.buf = value,
+		},
+	};
+
+	if (tfa98xx_devices[handle] && tfa98xx_devices[handle]->i2c) {
+		tfa98xx = tfa98xx_devices[handle];
+		tfa98xx_client = tfa98xx->i2c;
+		msgs[0].addr = tfa98xx_client->addr;
+		msgs[1].addr = tfa98xx_client->addr;
+
+		do {
+			err = i2c_transfer(tfa98xx_client->adapter, msgs,
+							ARRAY_SIZE(msgs));
+			if (err != ARRAY_SIZE(msgs))
+				msleep_interruptible(I2C_RETRY_DELAY);
+		} while ((err != ARRAY_SIZE(msgs)) && (++tries < I2C_RETRIES));
+
+		if (err != ARRAY_SIZE(msgs)) {
+			dev_err(&tfa98xx_client->dev, "read transfer error %d\n",
+									err);
+			error = Tfa98xx_Error_Fail;
+		}
+
+		if (tfa98xx_kmsg_regs)
+			dev_dbg(&tfa98xx_client->dev, "RD-DAT reg=0x%02x, len=%d\n",
+								reg, len);
+		if (tfa98xx_ftrace_regs)
+			tfa98xx_trace_printk("\t\tRD-DAT reg=0x%02x, len=%d\n",
+					reg, len);
+	} else {
+		pr_err("No device available\n");
+		error = Tfa98xx_Error_Fail;
+	}
+	return error;
+}
+
+enum Tfa98xx_Error tfa98xx_write_raw(Tfa98xx_handle_t handle,
+				int len,
+				const unsigned char data[])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	struct tfa98xx *tfa98xx;
+	int ret;
+	int retries = I2C_RETRIES;
+
+	if (tfa98xx_devices[handle]) {
+		tfa98xx = tfa98xx_devices[handle];
+retry:
+		ret = i2c_master_send(tfa98xx->i2c, data, len);
+		if (ret < 0) {
+			pr_warn("i2c error, retries left: %d\n", retries);
+			if (retries) {
+				retries--;
+				msleep(I2C_RETRY_DELAY);
+				goto retry;
+			}
+		}
+
+		if (ret == len) {
+			if (tfa98xx_kmsg_regs)
+				dev_dbg(&tfa98xx->i2c->dev, "  WR-RAW len=%d\n", len);
+			if (tfa98xx_ftrace_regs)
+				tfa98xx_trace_printk("\t\tWR-RAW len=%d\n", len);
+			return Tfa98xx_Error_Ok;
+		}
+		pr_err("  WR-RAW (len=%d) Error I2C send size mismatch %d\n", len, ret);
+		error = Tfa98xx_Error_Fail;
+	} else {
+		pr_err("No device available\n");
+		error = Tfa98xx_Error_Fail;
+	}
+	return error;
+}
+
+/* Read and return status_reg content, and intercept (interrupt related)
+ * events if any.
+ * mask can be used to ask to ignore some status bits.
+ */
+static unsigned int tfa98xx_read_status_reg(struct tfa98xx *tfa98xx,
+							unsigned int mask)
+{
+	unsigned int reg;
+	/* interrupt bits to check */
+	unsigned int errs =	TFA98XX_STATUSREG_WDS |
+				TFA98XX_STATUSREG_SPKS;
+
+	regmap_read(tfa98xx->regmap, TFA98XX_STATUSREG, &reg);
+
+	if (reg & errs & ~mask) {
+		/* interesting status bits to handle. Just trace for now. */
+		dev_info(tfa98xx->codec->dev, "status_reg events: 0x%x\n", reg);
+	}
+
+	return reg;
+}
+
+/* Interrupts management */
+
+static void tfa98xx_interrupt_restore_tfa2(struct tfa98xx *tfa98xx)
+{
+	unsigned int base_addr_inten = TFA_FAM(tfa98xx->handle,INTENVDDS) >> 8;
+
+	/* Write interrupt enable registers */
+	regmap_write(tfa98xx->regmap, base_addr_inten + 0,
+			handles_local[tfa98xx->handle].interrupt_enable[0]);
+	regmap_write(tfa98xx->regmap, base_addr_inten + 1,
+			handles_local[tfa98xx->handle].interrupt_enable[1]);
+	regmap_write(tfa98xx->regmap, base_addr_inten + 2,
+			handles_local[tfa98xx->handle].interrupt_enable[2]);
+}
+
+static void tfa98xx_interrupt_enable_tfa2(struct tfa98xx *tfa98xx, bool enable)
+{
+	unsigned int base_addr_inten = TFA_FAM(tfa98xx->handle,INTENVDDS) >> 8;
+
+	if (enable) {
+		tfa98xx_interrupt_restore_tfa2(tfa98xx);
+	} else {
+		regmap_write(tfa98xx->regmap, base_addr_inten + 0, 0);
+		regmap_write(tfa98xx->regmap, base_addr_inten + 1, 0);
+		regmap_write(tfa98xx->regmap, base_addr_inten + 2, 0);
+	}
+}
+
+/* Check if tap-detection can and shall be enabled.
+ * Configure SPK interrupt accordingly or setup polling mode
+ * Tap-detection shall be active if:
+ *  - the service is enabled (tapdet_open), AND
+ *  - the current profile is a tap-detection profile
+ * On TFA1 familiy of devices, activating tap-detection means enabling the SPK
+ * interrupt if available.
+ * We also update the tapdet_enabled and tapdet_poll variables.
+ */
+static void tfa98xx_tapdet_check_update(struct tfa98xx *tfa98xx)
+{
+	unsigned int spkerr, enable = false;
+	unsigned int err;
+	int val, count = 0;
+
+	/* Support tap-detection on TFA1 family of devices */
+	if (!(tfa98xx->flags & TFA98XX_FLAG_TAPDET_AVAILABLE) ||
+		(tfa98xx_dev_family(tfa98xx->handle)) != 1)
+		return;
+
+	if (tfa98xx->tapdet_open &&
+		(tfa98xx->tapdet_profiles & (1 << tfa98xx_profile)))
+		enable = true;
+
+	spkerr = enable ? 0 : 1;
+
+	if (!gpio_is_valid(tfa98xx->irq_gpio)) {
+		/* interrupt not available, setup polling mode */
+		tfa98xx->tapdet_poll = true;
+		if (enable)
+			queue_delayed_work(tfa98xx->tfa98xx_wq,
+						&tfa98xx->tapdet_work, HZ/10);
+		else
+			cancel_delayed_work_sync(&tfa98xx->tapdet_work);
+		dev_dbg(tfa98xx->codec->dev,
+			"Polling for tap-detection: %s (%d; 0x%x, %d)\n",
+			enable? "enabled":"disabled",
+			tfa98xx->tapdet_open, tfa98xx->tapdet_profiles,
+			tfa98xx_profile);
+
+	} else {
+		dev_dbg(tfa98xx->codec->dev,
+			"SPK interrupt for tap-detection: %s (%d; 0x%x, %d)\n",
+				enable? "enabled":"disabled",
+				tfa98xx->tapdet_open, tfa98xx->tapdet_profiles,
+				tfa98xx_profile);
+
+		/* update status_reg mask to match enabled interrupts */
+		handles_local[tfa98xx->handle].interrupt_status[0] &=
+					~TFA98XX_STATUSREG_SPKS;
+		handles_local[tfa98xx->handle].interrupt_status[0] |=
+					enable << TFA98XX_STATUSREG_SPKS_POS;
+
+		/* update interrupt_reg to match enabled interrupts */
+		handles_local[tfa98xx->handle].interrupt_enable[0] &=
+					~TFA98XX_INTERRUPT_REG_SPKD;
+		handles_local[tfa98xx->handle].interrupt_enable[0] |=
+					spkerr << TFA98XX_INTERRUPT_REG_SPKD_POS;
+	}
+
+	/* check disabled => enabled transition to clear pending events */
+	if (!tfa98xx->tapdet_enabled && enable) {
+		/* clear pending event if any */
+		err = tfa98xx_dsp_write_mem_word(tfa98xx->handle, XMEM_TAP_ACK, 0,
+							Tfa98xx_DMEM_XMEM);
+		if (err)
+			pr_info("Unable to write to XMEM\n");
+
+		val = tfa98xx_read_status_reg(tfa98xx, TFA98XX_STATUSREG_SPKS);
+		while ((TFA98XX_STATUSREG_SPKS & val) && (count < 50)) {
+			val = tfa98xx_read_status_reg(tfa98xx,
+							TFA98XX_STATUSREG_SPKS);
+			count++;
+		}
+		if (count > 1)
+			pr_info("Had to run %d times to ack SPKS at init\n", count);
+	}
+
+	tfa98xx->tapdet_enabled = enable;
+
+	if (!tfa98xx->tapdet_poll)
+		tfa98xx_interrupt_restore(tfa98xx);
+}
+
+/* Initial configuration of interrupt masks of devices for TFA1 family
+ * Disable all interrupts by default.
+ */
+static void tfa98xx_interrupt_setup_tfa1(struct tfa98xx *tfa98xx)
+{
+	uint16_t ie_reg = 0;
+
+	/* disable all interrupt sources */
+	ie_reg = TFA98XX_INTERRUPT_REG_VDDD |
+		TFA98XX_INTERRUPT_REG_OTDD |
+		TFA98XX_INTERRUPT_REG_OVDD |
+		TFA98XX_INTERRUPT_REG_UVDD |
+		TFA98XX_INTERRUPT_REG_OCDD |
+		TFA98XX_INTERRUPT_REG_CLKD |
+		TFA98XX_INTERRUPT_REG_DCCD |
+		TFA98XX_INTERRUPT_REG_SPKD |
+		TFA98XX_INTERRUPT_REG_WDD;
+	/* preserve reserved value */
+	ie_reg |= 1 << 9;
+
+	/* Store requested setup */
+	handles_local[tfa98xx->handle].interrupt_enable[0] = ie_reg;
+	handles_local[tfa98xx->handle].interrupt_status[0] = 0;
+
+	dev_dbg(&tfa98xx->i2c->dev, "Initial interrupts setup: ICR = 0x%04x\n", ie_reg);
+}
+
+/* Restore for 1st generation of devices */
+static void tfa98xx_interrupt_restore_tfa1(struct tfa98xx *tfa98xx)
+{
+	unsigned int ie_reg = 0;
+
+	regmap_read(tfa98xx->regmap, TFA98XX_INTERRUPT_REG, &ie_reg);
+
+	if (ie_reg != handles_local[tfa98xx->handle].interrupt_enable[0]) {
+		ie_reg = handles_local[tfa98xx->handle].interrupt_enable[0];
+
+		/* Write interrupt enable registers */
+		regmap_write(tfa98xx->regmap, TFA98XX_INTERRUPT_REG, ie_reg);
+
+		dev_dbg(&tfa98xx->i2c->dev, "Restored interrupts: ICR = 0x%04x\n",
+									ie_reg);
+	} else {
+		dev_dbg(&tfa98xx->i2c->dev, "No interrupt restore needed\n");
+	}
+
+}
+
+/* Enable for 1st generation of devices */
+static void tfa98xx_interrupt_enable_tfa1(struct tfa98xx *tfa98xx, bool enable)
+{
+	handles_local[tfa98xx->handle].interrupt_enable[0] &= ~TFA98XX_INTERRUPT_REG_INT;
+	handles_local[tfa98xx->handle].interrupt_enable[0] |= enable << TFA98XX_INTERRUPT_REG_INT_POS;
+
+	tfa98xx_interrupt_restore_tfa1(tfa98xx);
+}
+
+static void tfa98xx_interrupt_setup_tfa2(struct tfa98xx *tfa98xx)
+{
+	uint16_t ie_reg;
+
+	handles_local[tfa98xx->handle].interrupt_enable[0] = 0;
+	ie_reg = 0;
+	TFA_SET_BF_VALUE(tfa98xx->handle, IEMWSRC, 1, &ie_reg);
+	handles_local[tfa98xx->handle].interrupt_enable[1] = ie_reg;
+	handles_local[tfa98xx->handle].interrupt_enable[2] = 0;
+}
+
+/* Initial SW configuration for interrupts. Does not enable HW interrupts. */
+static void tfa98xx_interrupt_setup(struct tfa98xx *tfa98xx)
+{
+	if (tfa98xx->flags & TFA98XX_FLAG_SKIP_INTERRUPTS)
+		return;
+
+	if (tfa98xx->flags & TFA98XX_FLAG_TFA9890_FAM_DEV)
+		tfa98xx_interrupt_setup_tfa1(tfa98xx);
+	else
+		tfa98xx_interrupt_setup_tfa2(tfa98xx);
+}
+
+/* Restore interrupt setup in case it would be lost (at device cold-start) */
+static void tfa98xx_interrupt_restore(struct tfa98xx *tfa98xx)
+{
+	if (tfa98xx->flags & TFA98XX_FLAG_SKIP_INTERRUPTS)
+		return;
+
+	if (tfa98xx_dev_family(tfa98xx->handle) == 2)
+		tfa98xx_interrupt_restore_tfa2(tfa98xx);
+	else
+		tfa98xx_interrupt_restore_tfa1(tfa98xx);
+}
+
+/* global enable / disable interrupts */
+static void tfa98xx_interrupt_enable(struct tfa98xx *tfa98xx, bool enable)
+{
+	if (tfa98xx->flags & TFA98XX_FLAG_SKIP_INTERRUPTS)
+		return;
+
+	if (tfa98xx_dev_family(tfa98xx->handle) == 2)
+		tfa98xx_interrupt_enable_tfa2(tfa98xx, enable);
+	else
+		tfa98xx_interrupt_enable_tfa1(tfa98xx, enable);
+}
+
+/* Firmware management
+ * Downloaded once only at module init
+ * FIXME: may need to review that (one per instance of codec device?)
+ */
+static char *fw_name = "tfa98xx.cnt";
+module_param(fw_name, charp, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(fw_name, "TFA98xx DSP firmware (container file) name.");
+
+static nxpTfaContainer_t *container;
+
+static void tfa98xx_container_loaded(const struct firmware *cont, void *context)
+{
+	struct tfa98xx *tfa98xx = context;
+	enum tfa_error tfa_err;
+	int container_size;
+	int handle;
+	int ret;
+
+	tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_FAIL;
+
+	if (!cont) {
+		pr_err("Failed to read %s\n", fw_name);
+		return;
+	}
+
+	pr_debug("loaded %s - size: %zu\n", fw_name,
+					cont ? cont->size : 0);
+
+	container = kzalloc(cont->size, GFP_KERNEL);
+	if (!container) {
+		release_firmware(cont);
+		pr_err("Error allocating memory\n");
+		return;
+	}
+
+	container_size = cont->size;
+	memcpy(container, cont->data, container_size);
+	release_firmware(cont);
+
+	pr_debug("%.2s%.2s\n", container->version, container->subversion);
+	pr_debug("%.8s\n", container->customer);
+	pr_debug("%.8s\n", container->application);
+	pr_debug("%.8s\n", container->type);
+	pr_debug("%d ndev\n", container->ndev);
+	pr_debug("%d nprof\n", container->nprof);
+
+	tfa_err = tfa_load_cnt(container, container_size);
+	if (tfa_err != tfa_error_ok) {
+		dev_err(tfa98xx->dev, "Cannot load container file, aborting\n");
+		return;
+	}
+
+	/* register codec with dsp */
+	tfa98xx->handle = tfa98xx_register_dsp(tfa98xx);
+	if (tfa98xx->handle < 0) {
+		dev_err(tfa98xx->dev, "Cannot register with DSP, aborting\n");
+		return;
+	}
+
+	if (tfa_probe(tfa98xx->i2c->addr << 1, &handle) != Tfa98xx_Error_Ok) {
+		dev_err(tfa98xx->dev, "Failed to probe TFA98xx @ 0x%.2x\n", tfa98xx->i2c->addr);
+		return;
+	}
+
+	/* prefix is the application name from the cnt */
+	tfa_cnt_get_app_name(tfa98xx->fw.name);
+
+	/* Override default profile if requested */
+	if (strcmp(dflt_prof_name, "")) {
+		unsigned int i;
+		for (i = 0; i < tfaContMaxProfile(tfa98xx->handle); i++) {
+			if (strcmp(tfaContProfileName(tfa98xx->handle, i),
+							dflt_prof_name) == 0) {
+				tfa98xx_profile = i;
+				dev_info(tfa98xx->dev,
+					"changing default profile to %s (%d)\n",
+					dflt_prof_name, tfa98xx_profile);
+				break;
+			}
+		}
+		if (i >= tfaContMaxProfile(tfa98xx->handle))
+			dev_info(tfa98xx->dev,
+				"Default profile override failed (%s profile not found)\n",
+				dflt_prof_name);
+	}
+
+
+	tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_OK;
+	pr_debug("Firmware init complete\n");
+
+	if (no_start != 0)
+		return;
+
+	/* Only controls for master device */
+	if (tfa98xx->handle == 0)
+		tfa98xx_create_controls(tfa98xx);
+
+
+	tfa98xx_inputdev_check_register(tfa98xx);
+
+	if (tfa98xx->flags & TFA98XX_FLAG_DSP_START_ON_MUTE) {
+		tfa98xx_interrupt_enable(tfa98xx, true);
+		return;
+	}
+
+	mutex_lock(&tfa98xx->dsp_lock);
+
+	ret = tfa98xx_tfa_start(tfa98xx, tfa98xx_profile, tfa98xx_vsteps);
+	if (ret == Tfa98xx_Error_Ok)
+		tfa98xx->dsp_init = TFA98XX_DSP_INIT_DONE;
+	mutex_unlock(&tfa98xx->dsp_lock);
+	tfa98xx_interrupt_enable(tfa98xx, true);
+}
+
+static int tfa98xx_load_container(struct tfa98xx *tfa98xx)
+{
+	tfa98xx->dsp_fw_state = TFA98XX_DSP_FW_PENDING;
+
+	return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG,
+	                               fw_name, tfa98xx->dev, GFP_KERNEL,
+	                               tfa98xx, tfa98xx_container_loaded);
+}
+
+
+static void tfa98xx_tapdet(struct tfa98xx *tfa98xx)
+{
+	unsigned int mem;
+	int err, btn, count = 0;
+	uint16_t val;
+
+	/* check tap pattern (BTN_0 is "error" wrong tap indication */
+	tfa98xx_dsp_read_mem(tfa98xx->handle, XMEM_TAP_READ, 1, &mem);
+	switch (mem) {
+	case 0xffffffff:
+		pr_info("More than 4 taps detected! (flagTapPattern = -1)\n");
+		btn = BTN_0;
+		break;
+	case 0xfffffffe:
+		pr_info("Single tap detected! (flagTapPattern = -2)\n");
+		btn = BTN_0;
+		break;
+	case 0:
+		pr_info("Unrecognized pattern! (flagTapPattern = 0)\n");
+		btn = BTN_0;
+		break;
+	default:
+		pr_info("Detected pattern: %d\n", mem);
+		btn = BTN_0 + mem;
+		break;
+	}
+
+	input_report_key(tfa98xx->input, btn, 1);
+	input_report_key(tfa98xx->input, btn, 0);
+	input_sync(tfa98xx->input);
+
+	/* acknowledge event */
+	err = tfa98xx_dsp_write_mem_word(tfa98xx->handle, XMEM_TAP_ACK, 0, Tfa98xx_DMEM_XMEM);
+	if (err)
+		pr_info("Unable to write to XMEM\n");
+
+	val = tfa98xx_read_status_reg(tfa98xx, TFA98XX_STATUSREG_SPKS);
+	while ((TFA98XX_STATUSREG_SPKS & val) && (count < 50)) {
+		val = tfa98xx_read_status_reg(tfa98xx, TFA98XX_STATUSREG_SPKS);
+		count++;
+	}
+	if (count > 1)
+		pr_info("Had to run %d times to ack SPKS\n", count);
+
+}
+
+static void tfa98xx_tapdet_work(struct work_struct *work)
+{
+	struct tfa98xx *tfa98xx;
+	u16 val;
+
+	tfa98xx = container_of(work, struct tfa98xx, tapdet_work.work);
+
+	/* Check for SPKS bit*/
+	val = snd_soc_read(tfa98xx->codec, TFA98XX_STATUSREG);
+
+	if (val & TFA98XX_STATUSREG_SPKS)
+		tfa98xx_tapdet(tfa98xx);
+
+	queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->tapdet_work, HZ/10);
+}
+
+static void tfa98xx_monitor(struct work_struct *work)
+{
+	struct tfa98xx *tfa98xx;
+	u16 val;
+
+	tfa98xx = container_of(work, struct tfa98xx, monitor_work.work);
+
+	/* Check for tap-detection - bypass monitor if it is active */
+	if (!tfa98xx->input) {
+		/*
+		 * check IC status bits: cold start
+		 * and DSP watch dog bit to re init
+		 */
+		val = snd_soc_read(tfa98xx->codec, TFA98XX_STATUSREG);
+		pr_debug("SYS_STATUS0: 0x%04x\n", val);
+		if ((TFA98XX_STATUSREG_ACS & val) ||
+		    (TFA98XX_STATUSREG_WDS & val)) {
+			tfa98xx->dsp_init = TFA98XX_DSP_INIT_RECOVER;
+
+			if (TFA98XX_STATUSREG_ACS & val)
+				pr_err("ERROR: ACS\n");
+			if (TFA98XX_STATUSREG_WDS & val)
+				pr_err("ERROR: WDS\n");
+
+			queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->init_work, 0);
+		}
+
+		if (TFA98XX_STATUSREG_SPKS & val)
+			pr_err("ERROR: SPKS\n");
+		if (!(TFA98XX_STATUSREG_SWS & val))
+			pr_err("ERROR: SWS\n");
+
+		/* Check secondary errors */
+		if (	!(val & TFA98XX_STATUSREG_CLKS) ||
+			!(val & TFA98XX_STATUSREG_UVDS) ||
+			!(val & TFA98XX_STATUSREG_OVDS) ||
+			!(val & TFA98XX_STATUSREG_OTDS) ||
+			!(val & TFA98XX_STATUSREG_PLLS) ||
+			!(val & TFA98XX_STATUSREG_VDDS))
+			pr_err("Misc errors detected: STATUS_FLAG0 = 0x%x\n", val);
+
+		if (tfa98xx_dev_family(tfa98xx->handle) == 2) {
+			val = snd_soc_read(tfa98xx->codec, TFA98XX_STATUS_FLAGS1);
+			if ((val & TFA98XX_STATUS_FLAGS1_TDMERR) |
+				(val & (0x6 << TFA98XX_STATUS_FLAGS1_TDMSTAT_POS)) |
+				(val & TFA98XX_STATUS_FLAGS1_TDMLUTER))
+				pr_err("TDM related errors: STATUS_FLAG1 = 0x%x\n", val);
+		}
+	}
+
+	/* reschedule */
+	queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->monitor_work, 5*HZ);
+}
+
+static void tfa98xx_dsp_init(struct tfa98xx *tfa98xx)
+{
+	int ret;
+	bool failed = false;
+	bool reschedule = false;
+
+	if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK) {
+		pr_debug("Skipping tfa_start (no FW: %d)\n", tfa98xx->dsp_fw_state);
+		return;
+	}
+
+	if(tfa98xx->dsp_init == TFA98XX_DSP_INIT_DONE) {
+		pr_debug("Stream already started, skipping DSP power-on\n");
+		return;
+	}
+
+	mutex_lock(&tfa98xx->dsp_lock);
+
+	tfa98xx->dsp_init = TFA98XX_DSP_INIT_PENDING;
+
+	if (tfa98xx->init_count < TF98XX_MAX_DSP_START_TRY_COUNT) {
+		/* directly try to start DSP */
+		ret = tfa98xx_tfa_start(tfa98xx, tfa98xx_profile, tfa98xx_vsteps);
+		if (ret != Tfa98xx_Error_Ok) {
+			/* It may fail as we may not have a valid clock at that
+			 * time, so re-schedule and re-try later.
+			 */
+			dev_err(&tfa98xx->i2c->dev,
+					"tfa_start failed! (err %d) - %d\n",
+					ret, tfa98xx->init_count);
+			reschedule = true;
+		} else {
+			/* Subsystem ready, tfa init complete */
+			dev_dbg(&tfa98xx->i2c->dev,
+						"tfa_start success (%d)\n",
+						tfa98xx->init_count);
+			/* cancel other pending init works */
+			cancel_delayed_work(&tfa98xx->init_work);
+			tfa98xx->init_count = 0;
+			/*
+			 * start monitor thread to check IC status bit
+			 * periodically, and re-init IC to recover if
+			 * needed.
+			 */
+			queue_delayed_work(tfa98xx->tfa98xx_wq,
+						&tfa98xx->monitor_work,
+						1*HZ);
+		}
+	} else {
+		/* exceeded max number ot start tentatives, cancel start */
+		dev_err(&tfa98xx->i2c->dev,
+			"Failed starting device (%d)\n",
+			tfa98xx->init_count);
+			failed = true;
+	}
+	if (reschedule) {
+		/* reschedule this init work for later */
+		queue_delayed_work(tfa98xx->tfa98xx_wq,
+						&tfa98xx->init_work,
+						msecs_to_jiffies(5));
+		tfa98xx->init_count++;
+	}
+	if (failed) {
+		tfa98xx->dsp_init = TFA98XX_DSP_INIT_FAIL;
+		/* cancel other pending init works */
+		cancel_delayed_work(&tfa98xx->init_work);
+		tfa98xx->init_count = 0;
+	}
+	mutex_unlock(&tfa98xx->dsp_lock);
+	return;
+}
+
+
+static void tfa98xx_dsp_init_work(struct work_struct *work)
+{
+	struct tfa98xx *tfa98xx = container_of(work, struct tfa98xx, init_work.work);
+
+	/* Only do dsp init for master device */
+	if (tfa98xx->handle != 0)
+		return;
+
+	tfa98xx_dsp_init(tfa98xx);
+}
+
+static void tfa98xx_interrupt(struct work_struct *work)
+{
+	struct tfa98xx *tfa98xx = container_of(work, struct tfa98xx, interrupt_work.work);
+	unsigned int base_addr_inten = TFA_FAM(tfa98xx->handle,INTENVDDS) >> 8;
+	unsigned int base_addr_ist   = TFA_FAM(tfa98xx->handle,ISTVDDS) >> 8;
+	unsigned int base_addr_icl   = TFA_FAM(tfa98xx->handle,ICLVDDS) >> 8;
+	//unsigned int base_addr_ipo   = TFA_FAM(tfa98xx->handle,IPOVDDS) >> 8;
+
+	u32 out1, out2, out3;
+
+	pr_info("\n");
+
+	regmap_read(tfa98xx->regmap, base_addr_ist + 0, &out1);
+	regmap_read(tfa98xx->regmap, base_addr_ist + 1, &out2);
+	regmap_read(tfa98xx->regmap, base_addr_ist + 2, &out3);
+
+	out1 &= handles_local[tfa98xx->handle].interrupt_enable[0];
+	out2 &= handles_local[tfa98xx->handle].interrupt_enable[1];
+	out3 &= handles_local[tfa98xx->handle].interrupt_enable[2];
+
+	if (out1) {
+		/* clear and enable interrupt(s) again */
+		regmap_write(tfa98xx->regmap, base_addr_icl + 0, out1);
+		regmap_write(tfa98xx->regmap, base_addr_inten + 0,
+			handles_local[tfa98xx->handle].interrupt_enable[0]);
+	}
+
+	if (out2) {
+		/* manager wait for source state */
+		if (TFA_GET_BF_VALUE(tfa98xx->handle, ISTMWSRC, out2) > 0) {
+			int manwait1 = TFA_GET_BF(tfa98xx->handle, MANWAIT1);
+
+			if (manwait1 > 0) {
+				pr_info("entering wait for source state\n");
+				tfa98xx->count_wait_for_source_state++;
+				
+				/* set AMPC and AMPE to make sure the amp is enabled */
+				pr_info("setting AMPC and AMPE to 1 (default) \n");	
+				TFA_SET_BF(tfa98xx->handle, AMPC, 1);
+				TFA_SET_BF(tfa98xx->handle, AMPE, 1);
+
+				/* set MANSCONF here, the manager will continue if clock is there */
+				TFA_SET_BF(tfa98xx->handle, MANSCONF, 1);
+			} else {
+				/* Now we can switch profile with internal clock it is not required to call tfa_start */
+				 
+				pr_info("leaving wait for source state\n");
+
+				TFA_SET_BF(tfa98xx->handle, MANSCONF, 0);
+			}
+
+			if (manwait1 > 0)
+				TFA_SET_BF(tfa98xx->handle, IPOMWSRC, 0);
+			else
+				TFA_SET_BF(tfa98xx->handle, IPOMWSRC, 1);
+		}
+
+		/* clear and enable interrupt(s) again */
+		regmap_write(tfa98xx->regmap, base_addr_icl + 1, out2);
+		regmap_write(tfa98xx->regmap, base_addr_inten + 1,
+			handles_local[tfa98xx->handle].interrupt_enable[1]);
+	}
+
+	if (out3) {
+		/* clear and enable interrupt(s) again */
+		regmap_write(tfa98xx->regmap, base_addr_icl + 2, out3);
+		regmap_write(tfa98xx->regmap, base_addr_inten + 2,
+			handles_local[tfa98xx->handle].interrupt_enable[2]);
+	}
+
+}
+
+static int tfa98xx_startup(struct snd_pcm_substream *substream,
+						struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	unsigned int sr;
+	int len, prof, nprof = tfaContMaxProfile(tfa98xx->handle), idx = 0;
+	char *basename;
+
+	/*
+	 * Support CODEC to CODEC links,
+	 * these are called with a NULL runtime pointer.
+	 */
+	if (!substream->runtime)
+		return 0;
+
+	if (no_start != 0)
+		return 0;
+
+	basename = kzalloc(MAX_CONTROL_NAME, GFP_KERNEL);
+	if (!basename)
+		return -ENOMEM;
+    
+	/* copy profile name into basename until the . */
+	get_profile_basename(basename, tfaContProfileName(tfa98xx->handle, tfa98xx_profile));  
+	len = strlen(basename);
+    
+	/* loop over all profiles and get the supported samples rate(s) from
+	 * the profiles with the same basename
+	 */
+	for (prof = 0; prof < nprof; prof++) {
+		if (0 == strncmp(basename, tfaContProfileName(tfa98xx->handle, prof), len)) {   
+			/* Check which sample rate is supported with current profile,
+			 * and enforce this.
+			 */
+			sr = tfa98xx_get_profile_sr(tfa98xx->handle, prof);
+			if (!sr)
+				dev_info(codec->dev, "Unable to identify supported sample rate\n");
+			tfa98xx->rate_constraint_list[idx++] = sr;
+			tfa98xx->rate_constraint.count += 1;
+		}
+	}
+    
+    kfree((void*)basename);
+	
+/* as QUALCOMM FAE suggested, we don't need call 'snd_pcm_hw_constraint_list' on QUALCOMM platform. */
+#ifdef CONFIG_ARCH_MSM
+	return 0;		
+#else
+	return snd_pcm_hw_constraint_list(substream->runtime, 0,
+				   SNDRV_PCM_HW_PARAM_RATE,
+				   &tfa98xx->rate_constraint);
+#endif
+}
+
+static int tfa98xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
+				  int clk_id, unsigned int freq, int dir)
+{
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec_dai->codec);
+
+	tfa98xx->sysclk = freq;
+	return 0;
+}
+
+static int tfa98xx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(dai->codec);
+	struct snd_soc_codec *codec = dai->codec;
+
+	pr_debug("fmt=0x%x\n", fmt);
+
+	/* Supported mode: regular I2S, slave, or PDM */
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
+			dev_err(codec->dev, "Invalid Codec master mode\n");
+			return -EINVAL;
+		}
+		break;
+	case SND_SOC_DAIFMT_PDM:
+		break;
+	default:
+		dev_err(codec->dev, "Unsupported DAI format %d\n",
+					fmt & SND_SOC_DAIFMT_FORMAT_MASK);
+		return -EINVAL;
+	}
+
+	tfa98xx->audio_mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+
+	return 0;
+}
+
+static int tfa98xx_get_fssel(unsigned int rate)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(rate_to_fssel); i++) {
+		if (rate_to_fssel[i].rate == rate) {
+			return rate_to_fssel[i].fssel;
+		}
+	}
+	return -EINVAL;
+}
+
+static int tfa98xx_hw_params(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params,
+			     struct snd_soc_dai *dai)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	unsigned int rate;
+	int prof_idx;
+
+	/* Supported */
+	rate = params_rate(params);
+	pr_debug("Requested rate: %d, sample size: %d, physical size: %d\n",
+			rate, snd_pcm_format_width(params_format(params)),
+			snd_pcm_format_physical_width(params_format(params)));
+
+	if (params_channels(params) > 2) {
+		pr_warn("Unusual number of channels: %d\n", params_channels(params));
+	}
+
+	if (no_start != 0)
+		return 0;
+
+	/* check if samplerate is supported for this mixer profile */
+	prof_idx = get_profile_id_for_sr(tfa98xx_mixer_profile, rate);
+	if (prof_idx < 0) {
+		pr_err("tfa98xx: invalid sample rate %d.\n", rate);
+		return -EINVAL;
+	}
+	pr_debug("mixer profile:container profile = [%d:%d]\n", tfa98xx_mixer_profile, prof_idx);
+
+
+	/* update 'real' profile (container profile) */
+	tfa98xx_profile = prof_idx;
+    
+	/* update to new rate */
+	tfa98xx->rate = rate;
+
+	return 0;
+}
+
+static int tfa98xx_mute(struct snd_soc_dai *dai, int mute, int stream)
+{
+	struct snd_soc_codec *codec = dai->codec;
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+
+	dev_dbg(&tfa98xx->i2c->dev, "state: %d\n", mute);
+
+	if (!(tfa98xx->flags & TFA98XX_FLAG_DSP_START_ON_MUTE))
+		return 0;
+
+	if (no_start) {
+		pr_debug("no_start parameter set no tfa_start or tfa_stop, returning\n");
+		return 0;
+	}
+
+	if (mute) {
+		/* stop DSP only when both playback and capture streams
+		 * are deactivated
+		 */
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			tfa98xx->pstream = 0;
+		else
+			tfa98xx->cstream = 0;
+		if (tfa98xx->pstream != 0 || tfa98xx->cstream != 0)
+			return 0;
+
+		cancel_delayed_work_sync(&tfa98xx->monitor_work);
+
+		cancel_delayed_work_sync(&tfa98xx->init_work);
+		if (tfa98xx->dsp_fw_state != TFA98XX_DSP_FW_OK)
+			return 0;
+		mutex_lock(&tfa98xx->dsp_lock);
+		tfa_stop();
+		tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED;
+		mutex_unlock(&tfa98xx->dsp_lock);
+	} else {
+		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
+			tfa98xx->pstream = 1;
+		else
+			tfa98xx->cstream = 1;
+
+		/* Start DSP */
+		if (tfa98xx->dsp_init != TFA98XX_DSP_INIT_PENDING)
+			queue_delayed_work(tfa98xx->tfa98xx_wq,
+							&tfa98xx->init_work,
+							0);
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops tfa98xx_dai_ops = {
+	.startup = tfa98xx_startup,
+	.set_fmt = tfa98xx_set_fmt,
+	.set_sysclk = tfa98xx_set_dai_sysclk,
+	.hw_params = tfa98xx_hw_params,
+	.mute_stream = tfa98xx_mute,
+};
+
+static struct snd_soc_dai_driver tfa98xx_dai[] = {
+	{
+		.name = "tfa98xx-aif",
+		.base = TFA98XX_TDM_CONFIG0 - 1,
+		.id = 1,
+		.playback = {
+			.stream_name = "AIF Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = TFA98XX_RATES,
+			.formats = TFA98XX_FORMATS,
+		},
+		.capture = {
+			 .stream_name = "AIF Capture",
+			 .channels_min = 1,
+			 .channels_max = 2,
+			 .rates = TFA98XX_RATES,
+			 .formats = TFA98XX_FORMATS,
+		 },
+		.ops = &tfa98xx_dai_ops,
+		.symmetric_rates = 1,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0)
+		.symmetric_channels = 1,
+		.symmetric_samplebits = 1,
+#endif
+	},
+};
+
+static int tfa98xx_probe(struct snd_soc_codec *codec)
+{
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	int ret;
+
+	pr_debug("\n");
+
+	tfa98xx->rate_constraint.list = &tfa98xx->rate_constraint_list[0];
+	tfa98xx->rate_constraint.count =
+		ARRAY_SIZE(tfa98xx->rate_constraint_list);
+
+	/* setup work queue, will be used to initial DSP on first boot up */
+	tfa98xx->tfa98xx_wq = create_singlethread_workqueue("tfa98xx");
+	if (!tfa98xx->tfa98xx_wq)
+		return -ENOMEM;
+
+	INIT_DELAYED_WORK(&tfa98xx->init_work, tfa98xx_dsp_init_work);
+	INIT_DELAYED_WORK(&tfa98xx->monitor_work, tfa98xx_monitor);
+	INIT_DELAYED_WORK(&tfa98xx->interrupt_work, tfa98xx_interrupt);
+	INIT_DELAYED_WORK(&tfa98xx->tapdet_work, tfa98xx_tapdet_work);
+
+	tfa98xx->codec = codec;
+
+	ret = tfa98xx_load_container(tfa98xx);
+	pr_debug("Container loading requested: %d\n", ret);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,16,0)
+	codec->control_data = tfa98xx->regmap;
+	ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
+	if (ret != 0) {
+		dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
+		return ret;
+	}
+#endif
+	tfa98xx_add_widgets(tfa98xx);
+
+	dev_info(codec->dev, "tfa98xx codec registered (%s)",
+							tfa98xx->fw.name);
+
+	return ret;
+}
+
+static int tfa98xx_remove(struct snd_soc_codec *codec)
+{
+	struct tfa98xx *tfa98xx = snd_soc_codec_get_drvdata(codec);
+	pr_debug("\n");
+
+	tfa98xx_inputdev_unregister(tfa98xx);
+
+	cancel_delayed_work_sync(&tfa98xx->interrupt_work);
+	cancel_delayed_work_sync(&tfa98xx->monitor_work);
+	cancel_delayed_work_sync(&tfa98xx->init_work);
+	cancel_delayed_work_sync(&tfa98xx->tapdet_work);
+
+	if (tfa98xx->tfa98xx_wq)
+		destroy_workqueue(tfa98xx->tfa98xx_wq);
+
+	return 0;
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)
+struct regmap *tfa98xx_get_regmap(struct device *dev)
+{
+	struct tfa98xx *tfa98xx = dev_get_drvdata(dev);
+
+	return tfa98xx->regmap;
+}
+#endif
+static struct snd_soc_codec_driver soc_codec_dev_tfa98xx = {
+	.probe =	tfa98xx_probe,
+	.remove =	tfa98xx_remove,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0)
+	.get_regmap = tfa98xx_get_regmap,
+#endif
+};
+
+
+static bool tfa98xx_writeable_register(struct device *dev, unsigned int reg)
+{
+	/* enable read access for all registers */
+	return 1;
+}
+
+static bool tfa98xx_readable_register(struct device *dev, unsigned int reg)
+{
+	/* enable read access for all registers */
+	return 1;
+}
+
+static bool tfa98xx_volatile_register(struct device *dev, unsigned int reg)
+{
+	/* enable read access for all registers */
+	return 1;
+}
+
+static const struct regmap_config tfa98xx_regmap = {
+	.reg_bits = 8,
+	.val_bits = 16,
+
+	.max_register = TFA98XX_MAX_REGISTER,
+	.writeable_reg = tfa98xx_writeable_register,
+	.readable_reg = tfa98xx_readable_register,
+	.volatile_reg = tfa98xx_volatile_register,
+	.cache_type = REGCACHE_NONE,
+};
+
+
+static void tfa98xx_irq_tfa2(struct tfa98xx *tfa98xx)
+{
+	unsigned int base_addr_inten = TFA_FAM(tfa98xx->handle,INTENVDDS) >> 8;
+	unsigned int base_addr_ist   = TFA_FAM(tfa98xx->handle,ISTVDDS) >> 8;
+	u32 en1, en2, en3;
+	u32 out1 = 0, out2 = 0, out3 = 0;
+
+	pr_info("\n");
+
+	regmap_read(tfa98xx->regmap, base_addr_inten + 0, &en1);
+	regmap_read(tfa98xx->regmap, base_addr_inten + 1, &en2);
+	regmap_read(tfa98xx->regmap, base_addr_inten + 2, &en3);
+
+	regmap_read(tfa98xx->regmap, base_addr_ist + 0, &out1);
+	regmap_read(tfa98xx->regmap, base_addr_ist + 1, &out2);
+	regmap_read(tfa98xx->regmap, base_addr_ist + 2, &out3);
+
+	pr_info("interrupt1: 0x%.4x (enabled: 0x%.4x)\n", out1, en1);
+	pr_info("interrupt2: 0x%.4x (enabled: 0x%.4x)\n", out2, en2);
+	pr_info("interrupt3: 0x%.4x (enabled: 0x%.4x)\n", out3, en3);
+
+	out1 &= en1;
+	out2 &= en2;
+	out3 &= en3;
+
+	en1 = handles_local[tfa98xx->handle].interrupt_enable[0] ^ out1;
+	en2 = handles_local[tfa98xx->handle].interrupt_enable[1] ^ out2;
+	en3 = handles_local[tfa98xx->handle].interrupt_enable[2] ^ out3;
+
+	regmap_write(tfa98xx->regmap, base_addr_inten + 0, en1);
+	regmap_write(tfa98xx->regmap, base_addr_inten + 1, en2);
+	regmap_write(tfa98xx->regmap, base_addr_inten + 2, en3);
+
+	if (out1 || out2 || out3)
+		queue_delayed_work(tfa98xx->tfa98xx_wq, &tfa98xx->interrupt_work, 0);
+}
+
+static void __tfa98xx_irq(struct tfa98xx *tfa98xx)
+{
+	uint16_t val;
+	uint16_t ie = handles_local[tfa98xx->handle].interrupt_status[0];
+
+	val = snd_soc_read(tfa98xx->codec, TFA98XX_STATUSREG);
+
+	dev_info(&tfa98xx->i2c->dev, "interrupt: 0x%04x (enabled: 0x%04x)\n", val, ie);
+#ifdef DEBUG
+	if (!(val & ie)) {
+		unsigned int ireg;
+		/* interrupt triggered while all interrupt sources supposedly
+		 * disabled
+		 */
+		ireg = snd_soc_read(tfa98xx->codec, TFA98XX_INTERRUPT_REG);
+		dev_dbg(&tfa98xx->i2c->dev, "ICR: 0x%04x\n", ireg);
+	}
+#endif
+
+	val &= ie;
+
+	/* Check for SPKS bit */
+	if (val & TFA98XX_STATUSREG_SPKS)
+		tfa98xx_tapdet(tfa98xx);
+}
+
+static irqreturn_t tfa98xx_irq(int irq, void *data)
+{
+	struct tfa98xx *tfa98xx = data;
+
+	if (tfa98xx_dev_family(tfa98xx->handle) == 2)
+		tfa98xx_irq_tfa2(tfa98xx);
+	else
+		__tfa98xx_irq(tfa98xx);
+
+	return IRQ_HANDLED;
+}
+
+static int tfa98xx_ext_reset(struct tfa98xx *tfa98xx)
+{
+	if (tfa98xx && gpio_is_valid(tfa98xx->reset_gpio)) {
+		gpio_set_value_cansleep(tfa98xx->reset_gpio, 1);
+		gpio_set_value_cansleep(tfa98xx->reset_gpio, 0);
+	}
+	return 0;
+}
+
+static int tfa98xx_parse_dt(struct device *dev, struct tfa98xx *tfa98xx,
+		struct device_node *np) {
+	tfa98xx->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0);
+	if (tfa98xx->reset_gpio < 0)
+		dev_dbg(dev, "No reset GPIO provided, will not HW reset device\n");
+
+	tfa98xx->irq_gpio =  of_get_named_gpio(np, "irq-gpio", 0);
+	if (tfa98xx->irq_gpio < 0)
+		dev_dbg(dev, "No IRQ GPIO provided.\n");
+
+	return 0;
+}
+
+static ssize_t tfa98xx_reg_write(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct tfa98xx *tfa98xx = dev_get_drvdata(dev);
+
+	if (count != 1) {
+		pr_debug("invalid register address");
+		return -EINVAL;
+	}
+
+	tfa98xx->reg = buf[0];
+
+	return 1;
+}
+
+static ssize_t tfa98xx_rw_write(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct tfa98xx *tfa98xx = dev_get_drvdata(dev);
+	u8 *data;
+	int ret;
+	int retries = I2C_RETRIES;
+
+	data = kmalloc(count+1, GFP_KERNEL);
+	if (data == NULL) {
+		pr_debug("can not allocate memory\n");
+		return  -ENOMEM;
+	}
+
+	data[0] = tfa98xx->reg;
+	memcpy(&data[1], buf, count);
+
+retry:
+	ret = i2c_master_send(tfa98xx->i2c, data, count+1);
+	if (ret < 0) {
+		pr_warn("i2c error, retries left: %d\n", retries);
+		if (retries) {
+			retries--;
+			msleep(I2C_RETRY_DELAY);
+			goto retry;
+		}
+	}
+
+	kfree(data);
+	return ret;
+}
+
+static ssize_t tfa98xx_rw_read(struct file *filp, struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct tfa98xx *tfa98xx = dev_get_drvdata(dev);
+	struct i2c_msg msgs[] = {
+		{
+			.addr = tfa98xx->i2c->addr,
+			.flags = 0,
+			.len = 1,
+			.buf = &tfa98xx->reg,
+		},
+		{
+			.addr = tfa98xx->i2c->addr,
+			.flags = I2C_M_RD,
+			.len = count,
+			.buf = buf,
+		},
+	};
+	int ret;
+	int retries = I2C_RETRIES;
+retry:
+	ret = i2c_transfer(tfa98xx->i2c->adapter, msgs, ARRAY_SIZE(msgs));
+	if (ret < 0) {
+		pr_warn("i2c error, retries left: %d\n", retries);
+		if (retries) {
+			retries--;
+			msleep(I2C_RETRY_DELAY);
+			goto retry;
+		}
+		return ret;
+	}
+	/* ret contains the number of i2c messages send */
+	return 1 + ((ret > 1) ? count : 0);
+}
+
+static struct bin_attribute dev_attr_rw = {
+	.attr = {
+		.name = "rw",
+		.mode = S_IRUSR | S_IWUSR,
+	},
+	.size = 0,
+	.read = tfa98xx_rw_read,
+	.write = tfa98xx_rw_write,
+};
+
+static struct bin_attribute dev_attr_reg = {
+	.attr = {
+		.name = "reg",
+		.mode = S_IWUSR,
+	},
+	.size = 0,
+	.read = NULL,
+	.write = tfa98xx_reg_write,
+};
+
+static int tfa98xx_i2c_probe(struct i2c_client *i2c,
+			     const struct i2c_device_id *id)
+{
+	struct snd_soc_dai_driver *dai;
+	struct tfa98xx *tfa98xx;
+	struct device_node *np = i2c->dev.of_node;
+	int irq_flags;
+	unsigned int reg;
+	int ret;
+
+	pr_info("%s\n", __func__);
+
+	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) {
+		dev_err(&i2c->dev, "check_functionality failed\n");
+		return -EIO;
+	}
+
+	tfa98xx = devm_kzalloc(&i2c->dev, sizeof(struct tfa98xx),
+		      GFP_KERNEL);
+	if (tfa98xx == NULL)
+		return -ENOMEM;
+
+	tfa98xx->dev = &i2c->dev;
+	tfa98xx->i2c = i2c;
+	tfa98xx->dsp_init = TFA98XX_DSP_INIT_STOPPED;
+	tfa98xx->rate = 48000; /* init to the default sample rate (48kHz) */
+
+	tfa98xx->regmap = devm_regmap_init_i2c(i2c, &tfa98xx_regmap);
+	if (IS_ERR(tfa98xx->regmap)) {
+		ret = PTR_ERR(tfa98xx->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		goto err;
+	}
+
+	i2c_set_clientdata(i2c, tfa98xx);
+	mutex_init(&tfa98xx->dsp_lock);
+	init_waitqueue_head(&tfa98xx->wq);
+
+	if (np) {
+		ret = tfa98xx_parse_dt(&i2c->dev, tfa98xx, np);
+		if (ret) {
+			dev_err(&i2c->dev, "Failed to parse DT node\n");
+			goto err;
+		}
+		if (no_start)
+			tfa98xx->irq_gpio = -1;
+	} else {
+		tfa98xx->reset_gpio = -1;
+		tfa98xx->irq_gpio = -1;
+	}
+
+	if (gpio_is_valid(tfa98xx->reset_gpio)) {
+		ret = devm_gpio_request_one(&i2c->dev, tfa98xx->reset_gpio,
+			GPIOF_OUT_INIT_LOW, "TFA98XX_RST");
+		if (ret)
+			goto err;
+	}
+
+	if (gpio_is_valid(tfa98xx->irq_gpio)) {
+		ret = devm_gpio_request_one(&i2c->dev, tfa98xx->irq_gpio,
+			GPIOF_DIR_IN, "TFA98XX_INT");
+		if (ret)
+			goto err;
+	}
+
+	/* Power up! */
+	tfa98xx_ext_reset(tfa98xx);
+
+	if (no_start == 0) {
+		ret = regmap_read(tfa98xx->regmap, 0x03, &reg);
+		if (ret < 0) {
+			dev_err(&i2c->dev, "Failed to read Revision register: %d\n",
+				ret);
+			return -EIO;
+		}
+		switch (reg & 0xff) {
+		case 0x88: /* tfa9888 */
+			pr_info("TFA9888 detected\n");
+			tfa98xx->flags |= TFA98XX_FLAG_STEREO_DEVICE;
+			tfa98xx->flags |= TFA98XX_FLAG_MULTI_MIC_INPUTS;
+			break;
+		case 0x80: /* tfa9890 */
+		case 0x81: /* tfa9890 */
+			pr_info("TFA9890 detected\n");
+			tfa98xx->flags |= TFA98XX_FLAG_DSP_START_ON_MUTE;
+			tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS;
+			tfa98xx->flags |= TFA98XX_FLAG_TFA9890_FAM_DEV;
+			break;
+		case 0x92: /* tfa9891 */
+			pr_info("TFA9891 detected\n");
+			tfa98xx->flags |= TFA98XX_FLAG_DSP_START_ON_MUTE;
+			tfa98xx->flags |= TFA98XX_FLAG_SAAM_AVAILABLE;
+			tfa98xx->flags |= TFA98XX_FLAG_TAPDET_AVAILABLE;
+			tfa98xx->flags |= TFA98XX_FLAG_TFA9890_FAM_DEV;
+			break;
+		case 0x97:
+			pr_info("TFA9897 detected\n");
+			tfa98xx->flags |= TFA98XX_FLAG_DSP_START_ON_MUTE;
+            tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS;
+			tfa98xx->flags |= TFA98XX_FLAG_TFA9897_FAM_DEV;
+			break;
+		case 0x12:
+			pr_info("TFA9895 detected\n");
+			tfa98xx->flags |= TFA98XX_FLAG_DSP_START_ON_MUTE;
+			tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS;
+			tfa98xx->flags |= TFA98XX_FLAG_TFA9890_FAM_DEV;
+			break;
+		default:
+			pr_info("Unsupported device revision (0x%x)\n", reg & 0xff);
+			return -EINVAL;
+		}
+	}
+
+	/* Modify the stream names, by appending the i2c device address.
+	 * This is used with multicodec, in order to discriminate the devices.
+	 * Stream names appear in the dai definition and in the stream  	 .
+	 * We create copies of original structures because each device will
+	 * have its own instance of this structure, with its own address.
+	 */
+	dai = devm_kzalloc(&i2c->dev, sizeof(tfa98xx_dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+	memcpy(dai, tfa98xx_dai, sizeof(tfa98xx_dai));
+
+	tfa98xx_append_i2c_address(&i2c->dev,
+				i2c,
+				NULL,
+				0,
+				dai,
+				ARRAY_SIZE(tfa98xx_dai));
+
+	ret = snd_soc_register_codec(&i2c->dev,
+				&soc_codec_dev_tfa98xx, dai,
+				ARRAY_SIZE(tfa98xx_dai));
+
+	if (ret < 0) {
+		dev_err(&i2c->dev, "Failed to register TFA98xx: %d\n", ret);
+		goto err_off;
+	}
+
+	if (gpio_is_valid(tfa98xx->irq_gpio) &&
+		!(tfa98xx->flags & TFA98XX_FLAG_SKIP_INTERRUPTS)) {
+		/* register irq handler */
+		irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
+		ret = devm_request_threaded_irq(&i2c->dev,
+					gpio_to_irq(tfa98xx->irq_gpio),
+					NULL, tfa98xx_irq, irq_flags,
+					"tfa98xx", tfa98xx);
+		if (ret != 0) {
+			dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
+					gpio_to_irq(tfa98xx->irq_gpio), ret);
+			goto err_off;
+		}
+		tfa98xx_interrupt_setup(tfa98xx);
+	} else {
+		dev_info(&i2c->dev, "Skipping IRQ registration\n");
+		/* disable feature support if gpio was invalid */
+		tfa98xx->flags |= TFA98XX_FLAG_SKIP_INTERRUPTS;
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	tfa98xx_debug_init(tfa98xx, i2c);
+#endif
+	/* Register the sysfs files for climax backdoor access */
+	ret = device_create_bin_file(&i2c->dev, &dev_attr_rw);
+	if (ret)
+		dev_info(&i2c->dev, "error creating sysfs files\n");
+	ret = device_create_bin_file(&i2c->dev, &dev_attr_reg);
+	if (ret)
+		dev_info(&i2c->dev, "error creating sysfs files\n");
+
+	pr_info("%s Probe completed successfully!\n", __func__);
+
+	return 0;
+
+err_off:
+	tfa98xx_unregister_dsp(tfa98xx);
+err:
+	return ret;
+}
+
+static int tfa98xx_i2c_remove(struct i2c_client *i2c)
+{
+	struct tfa98xx *tfa98xx = i2c_get_clientdata(i2c);
+
+	pr_debug("\n");
+
+	cancel_delayed_work_sync(&tfa98xx->interrupt_work);
+	cancel_delayed_work_sync(&tfa98xx->monitor_work);
+	cancel_delayed_work_sync(&tfa98xx->init_work);
+	cancel_delayed_work_sync(&tfa98xx->tapdet_work);
+
+	device_remove_bin_file(&i2c->dev, &dev_attr_reg);
+	device_remove_bin_file(&i2c->dev, &dev_attr_rw);
+#ifdef CONFIG_DEBUG_FS
+	tfa98xx_debug_remove(tfa98xx);
+#endif
+
+	tfa98xx_unregister_dsp(tfa98xx);
+
+	snd_soc_unregister_codec(&i2c->dev);
+
+	if (gpio_is_valid(tfa98xx->irq_gpio))
+		devm_gpio_free(&i2c->dev, tfa98xx->irq_gpio);
+	if (gpio_is_valid(tfa98xx->reset_gpio))
+		devm_gpio_free(&i2c->dev, tfa98xx->reset_gpio);
+
+	return 0;
+}
+
+static const struct i2c_device_id tfa98xx_i2c_id[] = {
+	{ "tfa98xx", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tfa98xx_i2c_id);
+
+#ifdef CONFIG_OF
+static struct of_device_id tfa98xx_dt_match[] = {
+	{ .compatible = "nxp,tfa98xx" },
+	{ .compatible = "nxp,tfa9890" },
+	{ .compatible = "nxp,tfa9891" },
+	{ .compatible = "nxp,tfa9888" },
+	{ },
+};
+#endif
+
+static struct i2c_driver tfa98xx_i2c_driver = {
+	.driver = {
+		.name = "tfa98xx",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(tfa98xx_dt_match),
+	},
+	.probe =    tfa98xx_i2c_probe,
+	.remove =   tfa98xx_i2c_remove,
+	.id_table = tfa98xx_i2c_id,
+};
+
+static int trace_level = 0;
+module_param(trace_level, int, S_IRUGO);
+MODULE_PARM_DESC(trace_level, "TFA98xx debug trace level (0=off, bits:1=verbose,2=regdmesg,3=regftrace).");
+static int __init tfa98xx_i2c_init(void)
+{
+	int ret = 0;
+
+	pr_info("TFA98XX driver version %s\n", TFA98XX_VERSION);
+
+	/* Enable debug traces */
+	tfa_verbose(trace_level);
+	tfa98xx_kmsg_regs = trace_level & 2;
+	tfa98xx_ftrace_regs = trace_level & 4;
+
+	ret = i2c_add_driver(&tfa98xx_i2c_driver);
+
+	return ret;
+}
+module_init(tfa98xx_i2c_init);
+
+
+static void __exit tfa98xx_i2c_exit(void)
+{
+	i2c_del_driver(&tfa98xx_i2c_driver);
+
+	kfree(container);
+}
+module_exit(tfa98xx_i2c_exit);
+
+MODULE_DESCRIPTION("ASoC TFA98XX driver");
+MODULE_LICENSE("GPL");
+
+
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_genregs_N1C.h b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_genregs_N1C.h
new file mode 100644
index 0000000..0064137
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_genregs_N1C.h
@@ -0,0 +1,3853 @@
+/** Filename: Tfa98xx_genregs.h
+ *  This file was generated automatically on 09/01/15 at 09:40:23. 
+ *  Source file: TFA9888_N1C_I2C_regmap_V1.xlsx
+ */
+
+#ifndef TFA2_GENREGS_H
+#define TFA2_GENREGS_H
+
+
+#define TFA98XX_SYS_CONTROL0              0x00
+#define TFA98XX_SYS_CONTROL1              0x01
+#define TFA98XX_SYS_CONTROL2              0x02
+#define TFA98XX_DEVICE_REVISION           0x03
+#define TFA98XX_CLOCK_CONTROL             0x04
+#define TFA98XX_CLOCK_GATING_CONTROL      0x05
+#define TFA98XX_SIDE_TONE_CONFIG          0x0d
+#define TFA98XX_CTRL_DIGTOANA_REG         0x0e
+#define TFA98XX_STATUS_FLAGS0             0x10
+#define TFA98XX_STATUS_FLAGS1             0x11
+#define TFA98XX_STATUS_FLAGS2             0x12
+#define TFA98XX_STATUS_FLAGS3             0x13
+#define TFA98XX_STATUS_FLAGS4             0x14
+#define TFA98XX_BATTERY_VOLTAGE           0x15
+#define TFA98XX_TEMPERATURE               0x16
+#define TFA98XX_TDM_CONFIG0               0x20
+#define TFA98XX_TDM_CONFIG1               0x21
+#define TFA98XX_TDM_CONFIG2               0x22
+#define TFA98XX_TDM_CONFIG3               0x23
+#define TFA98XX_TDM_CONFIG4               0x24
+#define TFA98XX_TDM_CONFIG5               0x25
+#define TFA98XX_TDM_CONFIG6               0x26
+#define TFA98XX_TDM_CONFIG7               0x27
+#define TFA98XX_TDM_CONFIG8               0x28
+#define TFA98XX_TDM_CONFIG9               0x29
+#define TFA98XX_PDM_CONFIG0               0x31
+#define TFA98XX_PDM_CONFIG1               0x32
+#define TFA98XX_HAPTIC_DRIVER_CONFIG      0x33
+#define TFA98XX_GPIO_DATAIN_REG           0x34
+#define TFA98XX_GPIO_CONFIG               0x35
+#define TFA98XX_INTERRUPT_OUT_REG1        0x40
+#define TFA98XX_INTERRUPT_OUT_REG2        0x41
+#define TFA98XX_INTERRUPT_OUT_REG3        0x42
+#define TFA98XX_INTERRUPT_IN_REG1         0x44
+#define TFA98XX_INTERRUPT_IN_REG2         0x45
+#define TFA98XX_INTERRUPT_IN_REG3         0x46
+#define TFA98XX_INTERRUPT_ENABLE_REG1     0x48
+#define TFA98XX_INTERRUPT_ENABLE_REG2     0x49
+#define TFA98XX_INTERRUPT_ENABLE_REG3     0x4a
+#define TFA98XX_STATUS_POLARITY_REG1      0x4c
+#define TFA98XX_STATUS_POLARITY_REG2      0x4d
+#define TFA98XX_STATUS_POLARITY_REG3      0x4e
+#define TFA98XX_BAT_PROT_CONFIG           0x50
+#define TFA98XX_AUDIO_CONTROL             0x51
+#define TFA98XX_AMPLIFIER_CONFIG          0x52
+#define TFA98XX_AUDIO_CONTROL2            0x5a
+#define TFA98XX_DCDC_CONTROL0             0x70
+#define TFA98XX_CF_CONTROLS               0x90
+#define TFA98XX_CF_MAD                    0x91
+#define TFA98XX_CF_MEM                    0x92
+#define TFA98XX_CF_STATUS                 0x93
+#define TFA98XX_MTPKEY2_REG               0xa1
+#define TFA98XX_MTP_STATUS                0xa2
+#define TFA98XX_KEY_PROTECTED_MTP_CONTROL 0xa3
+#define TFA98XX_MTP_DATA_OUT_MSB          0xa5
+#define TFA98XX_MTP_DATA_OUT_LSB          0xa6
+#define TFA98XX_TEMP_SENSOR_CONFIG        0xb1
+#define TFA98XX_KEY2_PROTECTED_MTP0       0xf0
+#define TFA98XX_KEY1_PROTECTED_MTP4       0xf4
+#define TFA98XX_KEY1_PROTECTED_MTP5       0xf5
+
+/*
+ * (0x00)-sys_control0
+ */
+
+/*
+ * powerdown
+ */
+#define TFA98XX_SYS_CONTROL0_PWDN                         (0x1<<0)
+#define TFA98XX_SYS_CONTROL0_PWDN_POS                            0
+#define TFA98XX_SYS_CONTROL0_PWDN_LEN                            1
+#define TFA98XX_SYS_CONTROL0_PWDN_MAX                            1
+#define TFA98XX_SYS_CONTROL0_PWDN_MSK                          0x1
+
+/*
+ * reset
+ */
+#define TFA98XX_SYS_CONTROL0_I2CR                         (0x1<<1)
+#define TFA98XX_SYS_CONTROL0_I2CR_POS                            1
+#define TFA98XX_SYS_CONTROL0_I2CR_LEN                            1
+#define TFA98XX_SYS_CONTROL0_I2CR_MAX                            1
+#define TFA98XX_SYS_CONTROL0_I2CR_MSK                          0x2
+
+/*
+ * enbl_coolflux
+ */
+#define TFA98XX_SYS_CONTROL0_CFE                          (0x1<<2)
+#define TFA98XX_SYS_CONTROL0_CFE_POS                             2
+#define TFA98XX_SYS_CONTROL0_CFE_LEN                             1
+#define TFA98XX_SYS_CONTROL0_CFE_MAX                             1
+#define TFA98XX_SYS_CONTROL0_CFE_MSK                           0x4
+
+/*
+ * enbl_amplifier
+ */
+#define TFA98XX_SYS_CONTROL0_AMPE                         (0x1<<3)
+#define TFA98XX_SYS_CONTROL0_AMPE_POS                            3
+#define TFA98XX_SYS_CONTROL0_AMPE_LEN                            1
+#define TFA98XX_SYS_CONTROL0_AMPE_MAX                            1
+#define TFA98XX_SYS_CONTROL0_AMPE_MSK                          0x8
+
+/*
+ * enbl_boost
+ */
+#define TFA98XX_SYS_CONTROL0_DCA                          (0x1<<4)
+#define TFA98XX_SYS_CONTROL0_DCA_POS                             4
+#define TFA98XX_SYS_CONTROL0_DCA_LEN                             1
+#define TFA98XX_SYS_CONTROL0_DCA_MAX                             1
+#define TFA98XX_SYS_CONTROL0_DCA_MSK                          0x10
+
+/*
+ * coolflux_configured
+ */
+#define TFA98XX_SYS_CONTROL0_SBSL                         (0x1<<5)
+#define TFA98XX_SYS_CONTROL0_SBSL_POS                            5
+#define TFA98XX_SYS_CONTROL0_SBSL_LEN                            1
+#define TFA98XX_SYS_CONTROL0_SBSL_MAX                            1
+#define TFA98XX_SYS_CONTROL0_SBSL_MSK                         0x20
+
+/*
+ * sel_enbl_amplifier
+ */
+#define TFA98XX_SYS_CONTROL0_AMPC                         (0x1<<6)
+#define TFA98XX_SYS_CONTROL0_AMPC_POS                            6
+#define TFA98XX_SYS_CONTROL0_AMPC_LEN                            1
+#define TFA98XX_SYS_CONTROL0_AMPC_MAX                            1
+#define TFA98XX_SYS_CONTROL0_AMPC_MSK                         0x40
+
+/*
+ * int_pad_io
+ */
+#define TFA98XX_SYS_CONTROL0_INTP                         (0x3<<7)
+#define TFA98XX_SYS_CONTROL0_INTP_POS                            7
+#define TFA98XX_SYS_CONTROL0_INTP_LEN                            2
+#define TFA98XX_SYS_CONTROL0_INTP_MAX                            3
+#define TFA98XX_SYS_CONTROL0_INTP_MSK                        0x180
+
+/*
+ * fs_pulse_sel
+ */
+#define TFA98XX_SYS_CONTROL0_FSSSEL                       (0x3<<9)
+#define TFA98XX_SYS_CONTROL0_FSSSEL_POS                          9
+#define TFA98XX_SYS_CONTROL0_FSSSEL_LEN                          2
+#define TFA98XX_SYS_CONTROL0_FSSSEL_MAX                          3
+#define TFA98XX_SYS_CONTROL0_FSSSEL_MSK                      0x600
+
+/*
+ * bypass_ocp
+ */
+#define TFA98XX_SYS_CONTROL0_BYPOCP                      (0x1<<11)
+#define TFA98XX_SYS_CONTROL0_BYPOCP_POS                         11
+#define TFA98XX_SYS_CONTROL0_BYPOCP_LEN                          1
+#define TFA98XX_SYS_CONTROL0_BYPOCP_MAX                          1
+#define TFA98XX_SYS_CONTROL0_BYPOCP_MSK                      0x800
+
+/*
+ * test_ocp
+ */
+#define TFA98XX_SYS_CONTROL0_TSTOCP                      (0x1<<12)
+#define TFA98XX_SYS_CONTROL0_TSTOCP_POS                         12
+#define TFA98XX_SYS_CONTROL0_TSTOCP_LEN                          1
+#define TFA98XX_SYS_CONTROL0_TSTOCP_MAX                          1
+#define TFA98XX_SYS_CONTROL0_TSTOCP_MSK                     0x1000
+
+
+/*
+ * (0x01)-sys_control1
+ */
+
+/*
+ * vamp_sel
+ */
+#define TFA98XX_SYS_CONTROL1_AMPINSEL                     (0x3<<0)
+#define TFA98XX_SYS_CONTROL1_AMPINSEL_POS                        0
+#define TFA98XX_SYS_CONTROL1_AMPINSEL_LEN                        2
+#define TFA98XX_SYS_CONTROL1_AMPINSEL_MAX                        3
+#define TFA98XX_SYS_CONTROL1_AMPINSEL_MSK                      0x3
+
+/*
+ * src_set_configured
+ */
+#define TFA98XX_SYS_CONTROL1_MANSCONF                     (0x1<<2)
+#define TFA98XX_SYS_CONTROL1_MANSCONF_POS                        2
+#define TFA98XX_SYS_CONTROL1_MANSCONF_LEN                        1
+#define TFA98XX_SYS_CONTROL1_MANSCONF_MAX                        1
+#define TFA98XX_SYS_CONTROL1_MANSCONF_MSK                      0x4
+
+/*
+ * execute_cold_start
+ */
+#define TFA98XX_SYS_CONTROL1_MANCOLD                      (0x1<<3)
+#define TFA98XX_SYS_CONTROL1_MANCOLD_POS                         3
+#define TFA98XX_SYS_CONTROL1_MANCOLD_LEN                         1
+#define TFA98XX_SYS_CONTROL1_MANCOLD_MAX                         1
+#define TFA98XX_SYS_CONTROL1_MANCOLD_MSK                       0x8
+
+/*
+ * enbl_osc1m_auto_off
+ */
+#define TFA98XX_SYS_CONTROL1_MANAOOSC                     (0x1<<4)
+#define TFA98XX_SYS_CONTROL1_MANAOOSC_POS                        4
+#define TFA98XX_SYS_CONTROL1_MANAOOSC_LEN                        1
+#define TFA98XX_SYS_CONTROL1_MANAOOSC_MAX                        1
+#define TFA98XX_SYS_CONTROL1_MANAOOSC_MSK                     0x10
+
+/*
+ * man_enbl_brown_out
+ */
+#define TFA98XX_SYS_CONTROL1_MANROBOD                     (0x1<<5)
+#define TFA98XX_SYS_CONTROL1_MANROBOD_POS                        5
+#define TFA98XX_SYS_CONTROL1_MANROBOD_LEN                        1
+#define TFA98XX_SYS_CONTROL1_MANROBOD_MAX                        1
+#define TFA98XX_SYS_CONTROL1_MANROBOD_MSK                     0x20
+
+/*
+ * enbl_bod
+ */
+#define TFA98XX_SYS_CONTROL1_BODE                         (0x1<<6)
+#define TFA98XX_SYS_CONTROL1_BODE_POS                            6
+#define TFA98XX_SYS_CONTROL1_BODE_LEN                            1
+#define TFA98XX_SYS_CONTROL1_BODE_MAX                            1
+#define TFA98XX_SYS_CONTROL1_BODE_MSK                         0x40
+
+/*
+ * enbl_bod_hyst
+ */
+#define TFA98XX_SYS_CONTROL1_BODHYS                       (0x1<<7)
+#define TFA98XX_SYS_CONTROL1_BODHYS_POS                          7
+#define TFA98XX_SYS_CONTROL1_BODHYS_LEN                          1
+#define TFA98XX_SYS_CONTROL1_BODHYS_MAX                          1
+#define TFA98XX_SYS_CONTROL1_BODHYS_MSK                       0x80
+
+/*
+ * bod_delay
+ */
+#define TFA98XX_SYS_CONTROL1_BODFILT                      (0x3<<8)
+#define TFA98XX_SYS_CONTROL1_BODFILT_POS                         8
+#define TFA98XX_SYS_CONTROL1_BODFILT_LEN                         2
+#define TFA98XX_SYS_CONTROL1_BODFILT_MAX                         3
+#define TFA98XX_SYS_CONTROL1_BODFILT_MSK                     0x300
+
+/*
+ * bod_lvlsel
+ */
+#define TFA98XX_SYS_CONTROL1_BODTHLVL                    (0x3<<10)
+#define TFA98XX_SYS_CONTROL1_BODTHLVL_POS                       10
+#define TFA98XX_SYS_CONTROL1_BODTHLVL_LEN                        2
+#define TFA98XX_SYS_CONTROL1_BODTHLVL_MAX                        3
+#define TFA98XX_SYS_CONTROL1_BODTHLVL_MSK                    0xc00
+
+/*
+ * disable_mute_time_out
+ */
+#define TFA98XX_SYS_CONTROL1_MUTETO                      (0x1<<13)
+#define TFA98XX_SYS_CONTROL1_MUTETO_POS                         13
+#define TFA98XX_SYS_CONTROL1_MUTETO_LEN                          1
+#define TFA98XX_SYS_CONTROL1_MUTETO_MAX                          1
+#define TFA98XX_SYS_CONTROL1_MUTETO_MSK                     0x2000
+
+/*
+ * pwm_sel_rcv_ns
+ */
+#define TFA98XX_SYS_CONTROL1_RCVNS                       (0x1<<14)
+#define TFA98XX_SYS_CONTROL1_RCVNS_POS                          14
+#define TFA98XX_SYS_CONTROL1_RCVNS_LEN                           1
+#define TFA98XX_SYS_CONTROL1_RCVNS_MAX                           1
+#define TFA98XX_SYS_CONTROL1_RCVNS_MSK                      0x4000
+
+/*
+ * man_enbl_watchdog
+ */
+#define TFA98XX_SYS_CONTROL1_MANWDE                      (0x1<<15)
+#define TFA98XX_SYS_CONTROL1_MANWDE_POS                         15
+#define TFA98XX_SYS_CONTROL1_MANWDE_LEN                          1
+#define TFA98XX_SYS_CONTROL1_MANWDE_MAX                          1
+#define TFA98XX_SYS_CONTROL1_MANWDE_MSK                     0x8000
+
+
+/*
+ * (0x02)-sys_control2
+ */
+
+/*
+ * audio_fs
+ */
+#define TFA98XX_SYS_CONTROL2_AUDFS                        (0xf<<0)
+#define TFA98XX_SYS_CONTROL2_AUDFS_POS                           0
+#define TFA98XX_SYS_CONTROL2_AUDFS_LEN                           4
+#define TFA98XX_SYS_CONTROL2_AUDFS_MAX                          15
+#define TFA98XX_SYS_CONTROL2_AUDFS_MSK                         0xf
+
+/*
+ * input_level
+ */
+#define TFA98XX_SYS_CONTROL2_INPLEV                       (0x1<<4)
+#define TFA98XX_SYS_CONTROL2_INPLEV_POS                          4
+#define TFA98XX_SYS_CONTROL2_INPLEV_LEN                          1
+#define TFA98XX_SYS_CONTROL2_INPLEV_MAX                          1
+#define TFA98XX_SYS_CONTROL2_INPLEV_MSK                       0x10
+
+/*
+ * cs_frac_delay
+ */
+#define TFA98XX_SYS_CONTROL2_FRACTDEL                    (0x3f<<5)
+#define TFA98XX_SYS_CONTROL2_FRACTDEL_POS                        5
+#define TFA98XX_SYS_CONTROL2_FRACTDEL_LEN                        6
+#define TFA98XX_SYS_CONTROL2_FRACTDEL_MAX                       63
+#define TFA98XX_SYS_CONTROL2_FRACTDEL_MSK                    0x7e0
+
+/*
+ * bypass_hvbat_filter
+ */
+#define TFA98XX_SYS_CONTROL2_BYPHVBF                     (0x1<<11)
+#define TFA98XX_SYS_CONTROL2_BYPHVBF_POS                        11
+#define TFA98XX_SYS_CONTROL2_BYPHVBF_LEN                         1
+#define TFA98XX_SYS_CONTROL2_BYPHVBF_MAX                         1
+#define TFA98XX_SYS_CONTROL2_BYPHVBF_MSK                     0x800
+
+/*
+ * ctrl_rcvldop_bypass
+ */
+#define TFA98XX_SYS_CONTROL2_LDOBYP                      (0x1<<12)
+#define TFA98XX_SYS_CONTROL2_LDOBYP_POS                         12
+#define TFA98XX_SYS_CONTROL2_LDOBYP_LEN                          1
+#define TFA98XX_SYS_CONTROL2_LDOBYP_MAX                          1
+#define TFA98XX_SYS_CONTROL2_LDOBYP_MSK                     0x1000
+
+
+/*
+ * (0x03)-device_revision
+ */
+
+/*
+ * device_rev
+ */
+#define TFA98XX_DEVICE_REVISION_REV                    (0xffff<<0)
+#define TFA98XX_DEVICE_REVISION_REV_POS                          0
+#define TFA98XX_DEVICE_REVISION_REV_LEN                         16
+#define TFA98XX_DEVICE_REVISION_REV_MAX                      65535
+#define TFA98XX_DEVICE_REVISION_REV_MSK                     0xffff
+
+
+/*
+ * (0x04)-clock_control
+ */
+
+/*
+ * pll_clkin_sel
+ */
+#define TFA98XX_CLOCK_CONTROL_REFCKEXT                    (0x3<<0)
+#define TFA98XX_CLOCK_CONTROL_REFCKEXT_POS                       0
+#define TFA98XX_CLOCK_CONTROL_REFCKEXT_LEN                       2
+#define TFA98XX_CLOCK_CONTROL_REFCKEXT_MAX                       3
+#define TFA98XX_CLOCK_CONTROL_REFCKEXT_MSK                     0x3
+
+/*
+ * pll_clkin_sel_osc
+ */
+#define TFA98XX_CLOCK_CONTROL_REFCKSEL                    (0x1<<2)
+#define TFA98XX_CLOCK_CONTROL_REFCKSEL_POS                       2
+#define TFA98XX_CLOCK_CONTROL_REFCKSEL_LEN                       1
+#define TFA98XX_CLOCK_CONTROL_REFCKSEL_MAX                       1
+#define TFA98XX_CLOCK_CONTROL_REFCKSEL_MSK                     0x4
+
+
+/*
+ * (0x05)-clock_gating_control
+ */
+
+/*
+ * enbl_spkr_ss_left
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE              (0x1<<0)
+#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_POS                 0
+#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_LEN                 1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_MAX                 1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSLEFTE_MSK               0x1
+
+/*
+ * enbl_spkr_ss_right
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE             (0x1<<1)
+#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_POS                1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_LEN                1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_MAX                1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSRIGHTE_MSK              0x2
+
+/*
+ * enbl_volsense_left
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE              (0x1<<2)
+#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_POS                 2
+#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_LEN                 1
+#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_MAX                 1
+#define TFA98XX_CLOCK_GATING_CONTROL_VSLEFTE_MSK               0x4
+
+/*
+ * enbl_volsense_right
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE             (0x1<<3)
+#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_POS                3
+#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_LEN                1
+#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_MAX                1
+#define TFA98XX_CLOCK_GATING_CONTROL_VSRIGHTE_MSK              0x8
+
+/*
+ * enbl_cursense_left
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE              (0x1<<4)
+#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_POS                 4
+#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_LEN                 1
+#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_MAX                 1
+#define TFA98XX_CLOCK_GATING_CONTROL_CSLEFTE_MSK              0x10
+
+/*
+ * enbl_cursense_right
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE             (0x1<<5)
+#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_POS                5
+#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_LEN                1
+#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_MAX                1
+#define TFA98XX_CLOCK_GATING_CONTROL_CSRIGHTE_MSK             0x20
+
+/*
+ * enbl_pdm_ss
+ */
+#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME               (0x1<<6)
+#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_POS                  6
+#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_LEN                  1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_MAX                  1
+#define TFA98XX_CLOCK_GATING_CONTROL_SSPDME_MSK               0x40
+
+
+/*
+ * (0x0d)-side_tone_config
+ */
+
+/*
+ * side_tone_gain
+ */
+#define TFA98XX_SIDE_TONE_CONFIG_STGAIN                 (0x1ff<<1)
+#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_POS                      1
+#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_LEN                      9
+#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_MAX                    511
+#define TFA98XX_SIDE_TONE_CONFIG_STGAIN_MSK                  0x3fe
+
+/*
+ * mute_side_tone
+ */
+#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE                (0x1<<10)
+#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_POS                   10
+#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_LEN                    1
+#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_MAX                    1
+#define TFA98XX_SIDE_TONE_CONFIG_PDMSMUTE_MSK                0x400
+
+
+/*
+ * (0x0e)-ctrl_digtoana_reg
+ */
+
+/*
+ * ctrl_digtoana
+ */
+#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP                (0x7f<<0)
+#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_POS                    0
+#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_LEN                    7
+#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_MAX                  127
+#define TFA98XX_CTRL_DIGTOANA_REG_SWVSTEP_MSK                 0x7f
+
+
+/*
+ * (0x10)-status_flags0
+ */
+
+/*
+ * flag_por
+ */
+#define TFA98XX_STATUS_FLAGS0_VDDS                        (0x1<<0)
+#define TFA98XX_STATUS_FLAGS0_VDDS_POS                           0
+#define TFA98XX_STATUS_FLAGS0_VDDS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_VDDS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_VDDS_MSK                         0x1
+
+/*
+ * flag_pll_lock
+ */
+#define TFA98XX_STATUS_FLAGS0_PLLS                        (0x1<<1)
+#define TFA98XX_STATUS_FLAGS0_PLLS_POS                           1
+#define TFA98XX_STATUS_FLAGS0_PLLS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_PLLS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_PLLS_MSK                         0x2
+
+/*
+ * flag_otpok
+ */
+#define TFA98XX_STATUS_FLAGS0_OTDS                        (0x1<<2)
+#define TFA98XX_STATUS_FLAGS0_OTDS_POS                           2
+#define TFA98XX_STATUS_FLAGS0_OTDS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_OTDS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_OTDS_MSK                         0x4
+
+/*
+ * flag_ovpok
+ */
+#define TFA98XX_STATUS_FLAGS0_OVDS                        (0x1<<3)
+#define TFA98XX_STATUS_FLAGS0_OVDS_POS                           3
+#define TFA98XX_STATUS_FLAGS0_OVDS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_OVDS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_OVDS_MSK                         0x8
+
+/*
+ * flag_uvpok
+ */
+#define TFA98XX_STATUS_FLAGS0_UVDS                        (0x1<<4)
+#define TFA98XX_STATUS_FLAGS0_UVDS_POS                           4
+#define TFA98XX_STATUS_FLAGS0_UVDS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_UVDS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_UVDS_MSK                        0x10
+
+/*
+ * flag_clocks_stable
+ */
+#define TFA98XX_STATUS_FLAGS0_CLKS                        (0x1<<5)
+#define TFA98XX_STATUS_FLAGS0_CLKS_POS                           5
+#define TFA98XX_STATUS_FLAGS0_CLKS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_CLKS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_CLKS_MSK                        0x20
+
+/*
+ * flag_mtp_busy
+ */
+#define TFA98XX_STATUS_FLAGS0_MTPB                        (0x1<<6)
+#define TFA98XX_STATUS_FLAGS0_MTPB_POS                           6
+#define TFA98XX_STATUS_FLAGS0_MTPB_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_MTPB_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_MTPB_MSK                        0x40
+
+/*
+ * flag_lost_clk
+ */
+#define TFA98XX_STATUS_FLAGS0_NOCLK                       (0x1<<7)
+#define TFA98XX_STATUS_FLAGS0_NOCLK_POS                          7
+#define TFA98XX_STATUS_FLAGS0_NOCLK_LEN                          1
+#define TFA98XX_STATUS_FLAGS0_NOCLK_MAX                          1
+#define TFA98XX_STATUS_FLAGS0_NOCLK_MSK                       0x80
+
+/*
+ * flag_cf_speakererror
+ */
+#define TFA98XX_STATUS_FLAGS0_SPKS                        (0x1<<8)
+#define TFA98XX_STATUS_FLAGS0_SPKS_POS                           8
+#define TFA98XX_STATUS_FLAGS0_SPKS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_SPKS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_SPKS_MSK                       0x100
+
+/*
+ * flag_cold_started
+ */
+#define TFA98XX_STATUS_FLAGS0_ACS                         (0x1<<9)
+#define TFA98XX_STATUS_FLAGS0_ACS_POS                            9
+#define TFA98XX_STATUS_FLAGS0_ACS_LEN                            1
+#define TFA98XX_STATUS_FLAGS0_ACS_MAX                            1
+#define TFA98XX_STATUS_FLAGS0_ACS_MSK                        0x200
+
+/*
+ * flag_engage
+ */
+#define TFA98XX_STATUS_FLAGS0_SWS                        (0x1<<10)
+#define TFA98XX_STATUS_FLAGS0_SWS_POS                           10
+#define TFA98XX_STATUS_FLAGS0_SWS_LEN                            1
+#define TFA98XX_STATUS_FLAGS0_SWS_MAX                            1
+#define TFA98XX_STATUS_FLAGS0_SWS_MSK                        0x400
+
+/*
+ * flag_watchdog_reset
+ */
+#define TFA98XX_STATUS_FLAGS0_WDS                        (0x1<<11)
+#define TFA98XX_STATUS_FLAGS0_WDS_POS                           11
+#define TFA98XX_STATUS_FLAGS0_WDS_LEN                            1
+#define TFA98XX_STATUS_FLAGS0_WDS_MAX                            1
+#define TFA98XX_STATUS_FLAGS0_WDS_MSK                        0x800
+
+/*
+ * flag_enbl_amp
+ */
+#define TFA98XX_STATUS_FLAGS0_AMPS                       (0x1<<12)
+#define TFA98XX_STATUS_FLAGS0_AMPS_POS                          12
+#define TFA98XX_STATUS_FLAGS0_AMPS_LEN                           1
+#define TFA98XX_STATUS_FLAGS0_AMPS_MAX                           1
+#define TFA98XX_STATUS_FLAGS0_AMPS_MSK                      0x1000
+
+/*
+ * flag_enbl_ref
+ */
+#define TFA98XX_STATUS_FLAGS0_AREFS                      (0x1<<13)
+#define TFA98XX_STATUS_FLAGS0_AREFS_POS                         13
+#define TFA98XX_STATUS_FLAGS0_AREFS_LEN                          1
+#define TFA98XX_STATUS_FLAGS0_AREFS_MAX                          1
+#define TFA98XX_STATUS_FLAGS0_AREFS_MSK                     0x2000
+
+/*
+ * flag_adc10_ready
+ */
+#define TFA98XX_STATUS_FLAGS0_ADCCR                      (0x1<<14)
+#define TFA98XX_STATUS_FLAGS0_ADCCR_POS                         14
+#define TFA98XX_STATUS_FLAGS0_ADCCR_LEN                          1
+#define TFA98XX_STATUS_FLAGS0_ADCCR_MAX                          1
+#define TFA98XX_STATUS_FLAGS0_ADCCR_MSK                     0x4000
+
+/*
+ * flag_bod_vddd_nok
+ */
+#define TFA98XX_STATUS_FLAGS0_BODNOK                     (0x1<<15)
+#define TFA98XX_STATUS_FLAGS0_BODNOK_POS                        15
+#define TFA98XX_STATUS_FLAGS0_BODNOK_LEN                         1
+#define TFA98XX_STATUS_FLAGS0_BODNOK_MAX                         1
+#define TFA98XX_STATUS_FLAGS0_BODNOK_MSK                    0x8000
+
+
+/*
+ * (0x11)-status_flags1
+ */
+
+/*
+ * flag_bst_bstcur
+ */
+#define TFA98XX_STATUS_FLAGS1_DCIL                        (0x1<<0)
+#define TFA98XX_STATUS_FLAGS1_DCIL_POS                           0
+#define TFA98XX_STATUS_FLAGS1_DCIL_LEN                           1
+#define TFA98XX_STATUS_FLAGS1_DCIL_MAX                           1
+#define TFA98XX_STATUS_FLAGS1_DCIL_MSK                         0x1
+
+/*
+ * flag_bst_hiz
+ */
+#define TFA98XX_STATUS_FLAGS1_DCDCA                       (0x1<<1)
+#define TFA98XX_STATUS_FLAGS1_DCDCA_POS                          1
+#define TFA98XX_STATUS_FLAGS1_DCDCA_LEN                          1
+#define TFA98XX_STATUS_FLAGS1_DCDCA_MAX                          1
+#define TFA98XX_STATUS_FLAGS1_DCDCA_MSK                        0x2
+
+/*
+ * flag_bst_ocpok
+ */
+#define TFA98XX_STATUS_FLAGS1_DCOCPOK                     (0x1<<2)
+#define TFA98XX_STATUS_FLAGS1_DCOCPOK_POS                        2
+#define TFA98XX_STATUS_FLAGS1_DCOCPOK_LEN                        1
+#define TFA98XX_STATUS_FLAGS1_DCOCPOK_MAX                        1
+#define TFA98XX_STATUS_FLAGS1_DCOCPOK_MSK                      0x4
+
+/*
+ * flag_bst_voutcomp
+ */
+#define TFA98XX_STATUS_FLAGS1_DCHVBAT                     (0x1<<4)
+#define TFA98XX_STATUS_FLAGS1_DCHVBAT_POS                        4
+#define TFA98XX_STATUS_FLAGS1_DCHVBAT_LEN                        1
+#define TFA98XX_STATUS_FLAGS1_DCHVBAT_MAX                        1
+#define TFA98XX_STATUS_FLAGS1_DCHVBAT_MSK                     0x10
+
+/*
+ * flag_bst_voutcomp86
+ */
+#define TFA98XX_STATUS_FLAGS1_DCH114                      (0x1<<5)
+#define TFA98XX_STATUS_FLAGS1_DCH114_POS                         5
+#define TFA98XX_STATUS_FLAGS1_DCH114_LEN                         1
+#define TFA98XX_STATUS_FLAGS1_DCH114_MAX                         1
+#define TFA98XX_STATUS_FLAGS1_DCH114_MSK                      0x20
+
+/*
+ * flag_bst_voutcomp93
+ */
+#define TFA98XX_STATUS_FLAGS1_DCH107                      (0x1<<6)
+#define TFA98XX_STATUS_FLAGS1_DCH107_POS                         6
+#define TFA98XX_STATUS_FLAGS1_DCH107_LEN                         1
+#define TFA98XX_STATUS_FLAGS1_DCH107_MAX                         1
+#define TFA98XX_STATUS_FLAGS1_DCH107_MSK                      0x40
+
+/*
+ * flag_soft_mute_busy
+ */
+#define TFA98XX_STATUS_FLAGS1_STMUTEB                     (0x1<<7)
+#define TFA98XX_STATUS_FLAGS1_STMUTEB_POS                        7
+#define TFA98XX_STATUS_FLAGS1_STMUTEB_LEN                        1
+#define TFA98XX_STATUS_FLAGS1_STMUTEB_MAX                        1
+#define TFA98XX_STATUS_FLAGS1_STMUTEB_MSK                     0x80
+
+/*
+ * flag_soft_mute_state
+ */
+#define TFA98XX_STATUS_FLAGS1_STMUTE                      (0x1<<8)
+#define TFA98XX_STATUS_FLAGS1_STMUTE_POS                         8
+#define TFA98XX_STATUS_FLAGS1_STMUTE_LEN                         1
+#define TFA98XX_STATUS_FLAGS1_STMUTE_MAX                         1
+#define TFA98XX_STATUS_FLAGS1_STMUTE_MSK                     0x100
+
+/*
+ * flag_tdm_lut_error
+ */
+#define TFA98XX_STATUS_FLAGS1_TDMLUTER                    (0x1<<9)
+#define TFA98XX_STATUS_FLAGS1_TDMLUTER_POS                       9
+#define TFA98XX_STATUS_FLAGS1_TDMLUTER_LEN                       1
+#define TFA98XX_STATUS_FLAGS1_TDMLUTER_MAX                       1
+#define TFA98XX_STATUS_FLAGS1_TDMLUTER_MSK                   0x200
+
+/*
+ * flag_tdm_status
+ */
+#define TFA98XX_STATUS_FLAGS1_TDMSTAT                    (0x7<<10)
+#define TFA98XX_STATUS_FLAGS1_TDMSTAT_POS                       10
+#define TFA98XX_STATUS_FLAGS1_TDMSTAT_LEN                        3
+#define TFA98XX_STATUS_FLAGS1_TDMSTAT_MAX                        7
+#define TFA98XX_STATUS_FLAGS1_TDMSTAT_MSK                   0x1c00
+
+/*
+ * flag_tdm_error
+ */
+#define TFA98XX_STATUS_FLAGS1_TDMERR                     (0x1<<13)
+#define TFA98XX_STATUS_FLAGS1_TDMERR_POS                        13
+#define TFA98XX_STATUS_FLAGS1_TDMERR_LEN                         1
+#define TFA98XX_STATUS_FLAGS1_TDMERR_MAX                         1
+#define TFA98XX_STATUS_FLAGS1_TDMERR_MSK                    0x2000
+
+/*
+ * flag_haptic_busy
+ */
+#define TFA98XX_STATUS_FLAGS1_HAPTIC                     (0x1<<14)
+#define TFA98XX_STATUS_FLAGS1_HAPTIC_POS                        14
+#define TFA98XX_STATUS_FLAGS1_HAPTIC_LEN                         1
+#define TFA98XX_STATUS_FLAGS1_HAPTIC_MAX                         1
+#define TFA98XX_STATUS_FLAGS1_HAPTIC_MSK                    0x4000
+
+
+/*
+ * (0x12)-status_flags2
+ */
+
+/*
+ * flag_ocpokap_left
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOAPL                     (0x1<<0)
+#define TFA98XX_STATUS_FLAGS2_OCPOAPL_POS                        0
+#define TFA98XX_STATUS_FLAGS2_OCPOAPL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOAPL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOAPL_MSK                      0x1
+
+/*
+ * flag_ocpokan_left
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOANL                     (0x1<<1)
+#define TFA98XX_STATUS_FLAGS2_OCPOANL_POS                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOANL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOANL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOANL_MSK                      0x2
+
+/*
+ * flag_ocpokbp_left
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOBPL                     (0x1<<2)
+#define TFA98XX_STATUS_FLAGS2_OCPOBPL_POS                        2
+#define TFA98XX_STATUS_FLAGS2_OCPOBPL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOBPL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOBPL_MSK                      0x4
+
+/*
+ * flag_ocpokbn_left
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOBNL                     (0x1<<3)
+#define TFA98XX_STATUS_FLAGS2_OCPOBNL_POS                        3
+#define TFA98XX_STATUS_FLAGS2_OCPOBNL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOBNL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_OCPOBNL_MSK                      0x8
+
+/*
+ * flag_clipa_high_left
+ */
+#define TFA98XX_STATUS_FLAGS2_CLIPAHL                     (0x1<<4)
+#define TFA98XX_STATUS_FLAGS2_CLIPAHL_POS                        4
+#define TFA98XX_STATUS_FLAGS2_CLIPAHL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPAHL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPAHL_MSK                     0x10
+
+/*
+ * flag_clipa_low_left
+ */
+#define TFA98XX_STATUS_FLAGS2_CLIPALL                     (0x1<<5)
+#define TFA98XX_STATUS_FLAGS2_CLIPALL_POS                        5
+#define TFA98XX_STATUS_FLAGS2_CLIPALL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPALL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPALL_MSK                     0x20
+
+/*
+ * flag_clipb_high_left
+ */
+#define TFA98XX_STATUS_FLAGS2_CLIPBHL                     (0x1<<6)
+#define TFA98XX_STATUS_FLAGS2_CLIPBHL_POS                        6
+#define TFA98XX_STATUS_FLAGS2_CLIPBHL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPBHL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPBHL_MSK                     0x40
+
+/*
+ * flag_clipb_low_left
+ */
+#define TFA98XX_STATUS_FLAGS2_CLIPBLL                     (0x1<<7)
+#define TFA98XX_STATUS_FLAGS2_CLIPBLL_POS                        7
+#define TFA98XX_STATUS_FLAGS2_CLIPBLL_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPBLL_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_CLIPBLL_MSK                     0x80
+
+/*
+ * flag_ocpokap_rcv
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOAPRC                    (0x1<<8)
+#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_POS                       8
+#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_LEN                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_MAX                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOAPRC_MSK                   0x100
+
+/*
+ * flag_ocpokan_rcv
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOANRC                    (0x1<<9)
+#define TFA98XX_STATUS_FLAGS2_OCPOANRC_POS                       9
+#define TFA98XX_STATUS_FLAGS2_OCPOANRC_LEN                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOANRC_MAX                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOANRC_MSK                   0x200
+
+/*
+ * flag_ocpokbp_rcv
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOBPRC                   (0x1<<10)
+#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_POS                      10
+#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_LEN                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_MAX                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOBPRC_MSK                   0x400
+
+/*
+ * flag_ocpokbn_rcv
+ */
+#define TFA98XX_STATUS_FLAGS2_OCPOBNRC                   (0x1<<11)
+#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_POS                      11
+#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_LEN                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_MAX                       1
+#define TFA98XX_STATUS_FLAGS2_OCPOBNRC_MSK                   0x800
+
+/*
+ * flag_rcvldop_ready
+ */
+#define TFA98XX_STATUS_FLAGS2_RCVLDOR                    (0x1<<12)
+#define TFA98XX_STATUS_FLAGS2_RCVLDOR_POS                       12
+#define TFA98XX_STATUS_FLAGS2_RCVLDOR_LEN                        1
+#define TFA98XX_STATUS_FLAGS2_RCVLDOR_MAX                        1
+#define TFA98XX_STATUS_FLAGS2_RCVLDOR_MSK                   0x1000
+
+/*
+ * flag_rcvldop_bypassready
+ */
+#define TFA98XX_STATUS_FLAGS2_RCVLDOBR                   (0x1<<13)
+#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_POS                      13
+#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_LEN                       1
+#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_MAX                       1
+#define TFA98XX_STATUS_FLAGS2_RCVLDOBR_MSK                  0x2000
+
+/*
+ * flag_ocp_alarm_left
+ */
+#define TFA98XX_STATUS_FLAGS2_OCDSL                      (0x1<<14)
+#define TFA98XX_STATUS_FLAGS2_OCDSL_POS                         14
+#define TFA98XX_STATUS_FLAGS2_OCDSL_LEN                          1
+#define TFA98XX_STATUS_FLAGS2_OCDSL_MAX                          1
+#define TFA98XX_STATUS_FLAGS2_OCDSL_MSK                     0x4000
+
+/*
+ * flag_clip_left
+ */
+#define TFA98XX_STATUS_FLAGS2_CLIPSL                     (0x1<<15)
+#define TFA98XX_STATUS_FLAGS2_CLIPSL_POS                        15
+#define TFA98XX_STATUS_FLAGS2_CLIPSL_LEN                         1
+#define TFA98XX_STATUS_FLAGS2_CLIPSL_MAX                         1
+#define TFA98XX_STATUS_FLAGS2_CLIPSL_MSK                    0x8000
+
+
+/*
+ * (0x13)-status_flags3
+ */
+
+/*
+ * flag_ocpokap_right
+ */
+#define TFA98XX_STATUS_FLAGS3_OCPOAPR                     (0x1<<0)
+#define TFA98XX_STATUS_FLAGS3_OCPOAPR_POS                        0
+#define TFA98XX_STATUS_FLAGS3_OCPOAPR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOAPR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOAPR_MSK                      0x1
+
+/*
+ * flag_ocpokan_right
+ */
+#define TFA98XX_STATUS_FLAGS3_OCPOANR                     (0x1<<1)
+#define TFA98XX_STATUS_FLAGS3_OCPOANR_POS                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOANR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOANR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOANR_MSK                      0x2
+
+/*
+ * flag_ocpokbp_right
+ */
+#define TFA98XX_STATUS_FLAGS3_OCPOBPR                     (0x1<<2)
+#define TFA98XX_STATUS_FLAGS3_OCPOBPR_POS                        2
+#define TFA98XX_STATUS_FLAGS3_OCPOBPR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOBPR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOBPR_MSK                      0x4
+
+/*
+ * flag_ocpokbn_right
+ */
+#define TFA98XX_STATUS_FLAGS3_OCPOBNR                     (0x1<<3)
+#define TFA98XX_STATUS_FLAGS3_OCPOBNR_POS                        3
+#define TFA98XX_STATUS_FLAGS3_OCPOBNR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOBNR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOBNR_MSK                      0x8
+
+/*
+ * flag_clipa_high_right
+ */
+#define TFA98XX_STATUS_FLAGS3_CLIPAHR                     (0x1<<4)
+#define TFA98XX_STATUS_FLAGS3_CLIPAHR_POS                        4
+#define TFA98XX_STATUS_FLAGS3_CLIPAHR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPAHR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPAHR_MSK                     0x10
+
+/*
+ * flag_clipa_low_right
+ */
+#define TFA98XX_STATUS_FLAGS3_CLIPALR                     (0x1<<5)
+#define TFA98XX_STATUS_FLAGS3_CLIPALR_POS                        5
+#define TFA98XX_STATUS_FLAGS3_CLIPALR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPALR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPALR_MSK                     0x20
+
+/*
+ * flag_clipb_high_right
+ */
+#define TFA98XX_STATUS_FLAGS3_CLIPBHR                     (0x1<<6)
+#define TFA98XX_STATUS_FLAGS3_CLIPBHR_POS                        6
+#define TFA98XX_STATUS_FLAGS3_CLIPBHR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPBHR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPBHR_MSK                     0x40
+
+/*
+ * flag_clipb_low_right
+ */
+#define TFA98XX_STATUS_FLAGS3_CLIPBLR                     (0x1<<7)
+#define TFA98XX_STATUS_FLAGS3_CLIPBLR_POS                        7
+#define TFA98XX_STATUS_FLAGS3_CLIPBLR_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPBLR_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_CLIPBLR_MSK                     0x80
+
+/*
+ * flag_ocp_alarm_right
+ */
+#define TFA98XX_STATUS_FLAGS3_OCDSR                       (0x1<<8)
+#define TFA98XX_STATUS_FLAGS3_OCDSR_POS                          8
+#define TFA98XX_STATUS_FLAGS3_OCDSR_LEN                          1
+#define TFA98XX_STATUS_FLAGS3_OCDSR_MAX                          1
+#define TFA98XX_STATUS_FLAGS3_OCDSR_MSK                      0x100
+
+/*
+ * flag_clip_right
+ */
+#define TFA98XX_STATUS_FLAGS3_CLIPSR                      (0x1<<9)
+#define TFA98XX_STATUS_FLAGS3_CLIPSR_POS                         9
+#define TFA98XX_STATUS_FLAGS3_CLIPSR_LEN                         1
+#define TFA98XX_STATUS_FLAGS3_CLIPSR_MAX                         1
+#define TFA98XX_STATUS_FLAGS3_CLIPSR_MSK                     0x200
+
+/*
+ * flag_mic_ocpok
+ */
+#define TFA98XX_STATUS_FLAGS3_OCPOKMC                    (0x1<<10)
+#define TFA98XX_STATUS_FLAGS3_OCPOKMC_POS                       10
+#define TFA98XX_STATUS_FLAGS3_OCPOKMC_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOKMC_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_OCPOKMC_MSK                    0x400
+
+/*
+ * flag_man_alarm_state
+ */
+#define TFA98XX_STATUS_FLAGS3_MANALARM                   (0x1<<11)
+#define TFA98XX_STATUS_FLAGS3_MANALARM_POS                      11
+#define TFA98XX_STATUS_FLAGS3_MANALARM_LEN                       1
+#define TFA98XX_STATUS_FLAGS3_MANALARM_MAX                       1
+#define TFA98XX_STATUS_FLAGS3_MANALARM_MSK                   0x800
+
+/*
+ * flag_man_wait_src_settings
+ */
+#define TFA98XX_STATUS_FLAGS3_MANWAIT1                   (0x1<<12)
+#define TFA98XX_STATUS_FLAGS3_MANWAIT1_POS                      12
+#define TFA98XX_STATUS_FLAGS3_MANWAIT1_LEN                       1
+#define TFA98XX_STATUS_FLAGS3_MANWAIT1_MAX                       1
+#define TFA98XX_STATUS_FLAGS3_MANWAIT1_MSK                  0x1000
+
+/*
+ * flag_man_wait_cf_config
+ */
+#define TFA98XX_STATUS_FLAGS3_MANWAIT2                   (0x1<<13)
+#define TFA98XX_STATUS_FLAGS3_MANWAIT2_POS                      13
+#define TFA98XX_STATUS_FLAGS3_MANWAIT2_LEN                       1
+#define TFA98XX_STATUS_FLAGS3_MANWAIT2_MAX                       1
+#define TFA98XX_STATUS_FLAGS3_MANWAIT2_MSK                  0x2000
+
+/*
+ * flag_man_start_mute_audio
+ */
+#define TFA98XX_STATUS_FLAGS3_MANMUTE                    (0x1<<14)
+#define TFA98XX_STATUS_FLAGS3_MANMUTE_POS                       14
+#define TFA98XX_STATUS_FLAGS3_MANMUTE_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_MANMUTE_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_MANMUTE_MSK                   0x4000
+
+/*
+ * flag_man_operating_state
+ */
+#define TFA98XX_STATUS_FLAGS3_MANOPER                    (0x1<<15)
+#define TFA98XX_STATUS_FLAGS3_MANOPER_POS                       15
+#define TFA98XX_STATUS_FLAGS3_MANOPER_LEN                        1
+#define TFA98XX_STATUS_FLAGS3_MANOPER_MAX                        1
+#define TFA98XX_STATUS_FLAGS3_MANOPER_MSK                   0x8000
+
+
+/*
+ * (0x14)-status_flags4
+ */
+
+/*
+ * flag_cf_speakererror_left
+ */
+#define TFA98XX_STATUS_FLAGS4_SPKSL                       (0x1<<0)
+#define TFA98XX_STATUS_FLAGS4_SPKSL_POS                          0
+#define TFA98XX_STATUS_FLAGS4_SPKSL_LEN                          1
+#define TFA98XX_STATUS_FLAGS4_SPKSL_MAX                          1
+#define TFA98XX_STATUS_FLAGS4_SPKSL_MSK                        0x1
+
+/*
+ * flag_cf_speakererror_right
+ */
+#define TFA98XX_STATUS_FLAGS4_SPKSR                       (0x1<<1)
+#define TFA98XX_STATUS_FLAGS4_SPKSR_POS                          1
+#define TFA98XX_STATUS_FLAGS4_SPKSR_LEN                          1
+#define TFA98XX_STATUS_FLAGS4_SPKSR_MAX                          1
+#define TFA98XX_STATUS_FLAGS4_SPKSR_MSK                        0x2
+
+/*
+ * flag_clk_out_of_range
+ */
+#define TFA98XX_STATUS_FLAGS4_CLKOOR                      (0x1<<2)
+#define TFA98XX_STATUS_FLAGS4_CLKOOR_POS                         2
+#define TFA98XX_STATUS_FLAGS4_CLKOOR_LEN                         1
+#define TFA98XX_STATUS_FLAGS4_CLKOOR_MAX                         1
+#define TFA98XX_STATUS_FLAGS4_CLKOOR_MSK                       0x4
+
+/*
+ * man_state
+ */
+#define TFA98XX_STATUS_FLAGS4_MANSTATE                    (0xf<<3)
+#define TFA98XX_STATUS_FLAGS4_MANSTATE_POS                       3
+#define TFA98XX_STATUS_FLAGS4_MANSTATE_LEN                       4
+#define TFA98XX_STATUS_FLAGS4_MANSTATE_MAX                      15
+#define TFA98XX_STATUS_FLAGS4_MANSTATE_MSK                    0x78
+
+
+/*
+ * (0x15)-battery_voltage
+ */
+
+/*
+ * bat_adc
+ */
+#define TFA98XX_BATTERY_VOLTAGE_BATS                    (0x3ff<<0)
+#define TFA98XX_BATTERY_VOLTAGE_BATS_POS                         0
+#define TFA98XX_BATTERY_VOLTAGE_BATS_LEN                        10
+#define TFA98XX_BATTERY_VOLTAGE_BATS_MAX                      1023
+#define TFA98XX_BATTERY_VOLTAGE_BATS_MSK                     0x3ff
+
+
+/*
+ * (0x16)-temperature
+ */
+
+/*
+ * temp_adc
+ */
+#define TFA98XX_TEMPERATURE_TEMPS                       (0x1ff<<0)
+#define TFA98XX_TEMPERATURE_TEMPS_POS                            0
+#define TFA98XX_TEMPERATURE_TEMPS_LEN                            9
+#define TFA98XX_TEMPERATURE_TEMPS_MAX                          511
+#define TFA98XX_TEMPERATURE_TEMPS_MSK                        0x1ff
+
+
+/*
+ * (0x20)-tdm_config0
+ */
+
+/*
+ * tdm_usecase
+ */
+#define TFA98XX_TDM_CONFIG0_TDMUC                         (0xf<<0)
+#define TFA98XX_TDM_CONFIG0_TDMUC_POS                            0
+#define TFA98XX_TDM_CONFIG0_TDMUC_LEN                            4
+#define TFA98XX_TDM_CONFIG0_TDMUC_MAX                           15
+#define TFA98XX_TDM_CONFIG0_TDMUC_MSK                          0xf
+
+/*
+ * tdm_enable
+ */
+#define TFA98XX_TDM_CONFIG0_TDME                          (0x1<<4)
+#define TFA98XX_TDM_CONFIG0_TDME_POS                             4
+#define TFA98XX_TDM_CONFIG0_TDME_LEN                             1
+#define TFA98XX_TDM_CONFIG0_TDME_MAX                             1
+#define TFA98XX_TDM_CONFIG0_TDME_MSK                          0x10
+
+/*
+ * tdm_mode
+ */
+#define TFA98XX_TDM_CONFIG0_TDMMODE                       (0x1<<5)
+#define TFA98XX_TDM_CONFIG0_TDMMODE_POS                          5
+#define TFA98XX_TDM_CONFIG0_TDMMODE_LEN                          1
+#define TFA98XX_TDM_CONFIG0_TDMMODE_MAX                          1
+#define TFA98XX_TDM_CONFIG0_TDMMODE_MSK                       0x20
+
+/*
+ * tdm_clk_inversion
+ */
+#define TFA98XX_TDM_CONFIG0_TDMCLINV                      (0x1<<6)
+#define TFA98XX_TDM_CONFIG0_TDMCLINV_POS                         6
+#define TFA98XX_TDM_CONFIG0_TDMCLINV_LEN                         1
+#define TFA98XX_TDM_CONFIG0_TDMCLINV_MAX                         1
+#define TFA98XX_TDM_CONFIG0_TDMCLINV_MSK                      0x40
+
+/*
+ * tdm_fs_ws_length
+ */
+#define TFA98XX_TDM_CONFIG0_TDMFSLN                       (0xf<<7)
+#define TFA98XX_TDM_CONFIG0_TDMFSLN_POS                          7
+#define TFA98XX_TDM_CONFIG0_TDMFSLN_LEN                          4
+#define TFA98XX_TDM_CONFIG0_TDMFSLN_MAX                         15
+#define TFA98XX_TDM_CONFIG0_TDMFSLN_MSK                      0x780
+
+/*
+ * tdm_fs_ws_polarity
+ */
+#define TFA98XX_TDM_CONFIG0_TDMFSPOL                     (0x1<<11)
+#define TFA98XX_TDM_CONFIG0_TDMFSPOL_POS                        11
+#define TFA98XX_TDM_CONFIG0_TDMFSPOL_LEN                         1
+#define TFA98XX_TDM_CONFIG0_TDMFSPOL_MAX                         1
+#define TFA98XX_TDM_CONFIG0_TDMFSPOL_MSK                     0x800
+
+/*
+ * tdm_nbck
+ */
+#define TFA98XX_TDM_CONFIG0_TDMNBCK                      (0xf<<12)
+#define TFA98XX_TDM_CONFIG0_TDMNBCK_POS                         12
+#define TFA98XX_TDM_CONFIG0_TDMNBCK_LEN                          4
+#define TFA98XX_TDM_CONFIG0_TDMNBCK_MAX                         15
+#define TFA98XX_TDM_CONFIG0_TDMNBCK_MSK                     0xf000
+
+
+/*
+ * (0x21)-tdm_config1
+ */
+
+/*
+ * tdm_nb_of_slots
+ */
+#define TFA98XX_TDM_CONFIG1_TDMSLOTS                      (0xf<<0)
+#define TFA98XX_TDM_CONFIG1_TDMSLOTS_POS                         0
+#define TFA98XX_TDM_CONFIG1_TDMSLOTS_LEN                         4
+#define TFA98XX_TDM_CONFIG1_TDMSLOTS_MAX                        15
+#define TFA98XX_TDM_CONFIG1_TDMSLOTS_MSK                       0xf
+
+/*
+ * tdm_slot_length
+ */
+#define TFA98XX_TDM_CONFIG1_TDMSLLN                      (0x1f<<4)
+#define TFA98XX_TDM_CONFIG1_TDMSLLN_POS                          4
+#define TFA98XX_TDM_CONFIG1_TDMSLLN_LEN                          5
+#define TFA98XX_TDM_CONFIG1_TDMSLLN_MAX                         31
+#define TFA98XX_TDM_CONFIG1_TDMSLLN_MSK                      0x1f0
+
+/*
+ * tdm_bits_remaining
+ */
+#define TFA98XX_TDM_CONFIG1_TDMBRMG                      (0x1f<<9)
+#define TFA98XX_TDM_CONFIG1_TDMBRMG_POS                          9
+#define TFA98XX_TDM_CONFIG1_TDMBRMG_LEN                          5
+#define TFA98XX_TDM_CONFIG1_TDMBRMG_MAX                         31
+#define TFA98XX_TDM_CONFIG1_TDMBRMG_MSK                     0x3e00
+
+/*
+ * tdm_data_delay
+ */
+#define TFA98XX_TDM_CONFIG1_TDMDEL                       (0x1<<14)
+#define TFA98XX_TDM_CONFIG1_TDMDEL_POS                          14
+#define TFA98XX_TDM_CONFIG1_TDMDEL_LEN                           1
+#define TFA98XX_TDM_CONFIG1_TDMDEL_MAX                           1
+#define TFA98XX_TDM_CONFIG1_TDMDEL_MSK                      0x4000
+
+/*
+ * tdm_data_adjustment
+ */
+#define TFA98XX_TDM_CONFIG1_TDMADJ                       (0x1<<15)
+#define TFA98XX_TDM_CONFIG1_TDMADJ_POS                          15
+#define TFA98XX_TDM_CONFIG1_TDMADJ_LEN                           1
+#define TFA98XX_TDM_CONFIG1_TDMADJ_MAX                           1
+#define TFA98XX_TDM_CONFIG1_TDMADJ_MSK                      0x8000
+
+
+/*
+ * (0x22)-tdm_config2
+ */
+
+/*
+ * tdm_audio_sample_compression
+ */
+#define TFA98XX_TDM_CONFIG2_TDMOOMP                       (0x3<<0)
+#define TFA98XX_TDM_CONFIG2_TDMOOMP_POS                          0
+#define TFA98XX_TDM_CONFIG2_TDMOOMP_LEN                          2
+#define TFA98XX_TDM_CONFIG2_TDMOOMP_MAX                          3
+#define TFA98XX_TDM_CONFIG2_TDMOOMP_MSK                        0x3
+
+/*
+ * tdm_sample_size
+ */
+#define TFA98XX_TDM_CONFIG2_TDMSSIZE                     (0x1f<<2)
+#define TFA98XX_TDM_CONFIG2_TDMSSIZE_POS                         2
+#define TFA98XX_TDM_CONFIG2_TDMSSIZE_LEN                         5
+#define TFA98XX_TDM_CONFIG2_TDMSSIZE_MAX                        31
+#define TFA98XX_TDM_CONFIG2_TDMSSIZE_MSK                      0x7c
+
+/*
+ * tdm_txdata_format
+ */
+#define TFA98XX_TDM_CONFIG2_TDMTXDFO                      (0x3<<7)
+#define TFA98XX_TDM_CONFIG2_TDMTXDFO_POS                         7
+#define TFA98XX_TDM_CONFIG2_TDMTXDFO_LEN                         2
+#define TFA98XX_TDM_CONFIG2_TDMTXDFO_MAX                         3
+#define TFA98XX_TDM_CONFIG2_TDMTXDFO_MSK                     0x180
+
+/*
+ * tdm_txdata_format_unused_slot_sd0
+ */
+#define TFA98XX_TDM_CONFIG2_TDMTXUS0                      (0x3<<9)
+#define TFA98XX_TDM_CONFIG2_TDMTXUS0_POS                         9
+#define TFA98XX_TDM_CONFIG2_TDMTXUS0_LEN                         2
+#define TFA98XX_TDM_CONFIG2_TDMTXUS0_MAX                         3
+#define TFA98XX_TDM_CONFIG2_TDMTXUS0_MSK                     0x600
+
+/*
+ * tdm_txdata_format_unused_slot_sd1
+ */
+#define TFA98XX_TDM_CONFIG2_TDMTXUS1                     (0x3<<11)
+#define TFA98XX_TDM_CONFIG2_TDMTXUS1_POS                        11
+#define TFA98XX_TDM_CONFIG2_TDMTXUS1_LEN                         2
+#define TFA98XX_TDM_CONFIG2_TDMTXUS1_MAX                         3
+#define TFA98XX_TDM_CONFIG2_TDMTXUS1_MSK                    0x1800
+
+/*
+ * tdm_txdata_format_unused_slot_sd2
+ */
+#define TFA98XX_TDM_CONFIG2_TDMTXUS2                     (0x3<<13)
+#define TFA98XX_TDM_CONFIG2_TDMTXUS2_POS                        13
+#define TFA98XX_TDM_CONFIG2_TDMTXUS2_LEN                         2
+#define TFA98XX_TDM_CONFIG2_TDMTXUS2_MAX                         3
+#define TFA98XX_TDM_CONFIG2_TDMTXUS2_MSK                    0x6000
+
+
+/*
+ * (0x23)-tdm_config3
+ */
+
+/*
+ * tdm_sink1_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMLE                         (0x1<<1)
+#define TFA98XX_TDM_CONFIG3_TDMLE_POS                            1
+#define TFA98XX_TDM_CONFIG3_TDMLE_LEN                            1
+#define TFA98XX_TDM_CONFIG3_TDMLE_MAX                            1
+#define TFA98XX_TDM_CONFIG3_TDMLE_MSK                          0x2
+
+/*
+ * tdm_sink2_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMRE                         (0x1<<2)
+#define TFA98XX_TDM_CONFIG3_TDMRE_POS                            2
+#define TFA98XX_TDM_CONFIG3_TDMRE_LEN                            1
+#define TFA98XX_TDM_CONFIG3_TDMRE_MAX                            1
+#define TFA98XX_TDM_CONFIG3_TDMRE_MSK                          0x4
+
+/*
+ * tdm_source1_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMVSRE                       (0x1<<4)
+#define TFA98XX_TDM_CONFIG3_TDMVSRE_POS                          4
+#define TFA98XX_TDM_CONFIG3_TDMVSRE_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMVSRE_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMVSRE_MSK                       0x10
+
+/*
+ * tdm_source2_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMCSRE                       (0x1<<5)
+#define TFA98XX_TDM_CONFIG3_TDMCSRE_POS                          5
+#define TFA98XX_TDM_CONFIG3_TDMCSRE_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMCSRE_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMCSRE_MSK                       0x20
+
+/*
+ * tdm_source3_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMVSLE                       (0x1<<6)
+#define TFA98XX_TDM_CONFIG3_TDMVSLE_POS                          6
+#define TFA98XX_TDM_CONFIG3_TDMVSLE_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMVSLE_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMVSLE_MSK                       0x40
+
+/*
+ * tdm_source4_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMCSLE                       (0x1<<7)
+#define TFA98XX_TDM_CONFIG3_TDMCSLE_POS                          7
+#define TFA98XX_TDM_CONFIG3_TDMCSLE_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMCSLE_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMCSLE_MSK                       0x80
+
+/*
+ * tdm_source5_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMCFRE                       (0x1<<8)
+#define TFA98XX_TDM_CONFIG3_TDMCFRE_POS                          8
+#define TFA98XX_TDM_CONFIG3_TDMCFRE_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMCFRE_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMCFRE_MSK                      0x100
+
+/*
+ * tdm_source6_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMCFLE                       (0x1<<9)
+#define TFA98XX_TDM_CONFIG3_TDMCFLE_POS                          9
+#define TFA98XX_TDM_CONFIG3_TDMCFLE_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMCFLE_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMCFLE_MSK                      0x200
+
+/*
+ * tdm_source7_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMCF3E                      (0x1<<10)
+#define TFA98XX_TDM_CONFIG3_TDMCF3E_POS                         10
+#define TFA98XX_TDM_CONFIG3_TDMCF3E_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMCF3E_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMCF3E_MSK                      0x400
+
+/*
+ * tdm_source8_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMCF4E                      (0x1<<11)
+#define TFA98XX_TDM_CONFIG3_TDMCF4E_POS                         11
+#define TFA98XX_TDM_CONFIG3_TDMCF4E_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMCF4E_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMCF4E_MSK                      0x800
+
+/*
+ * tdm_source9_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMPD1E                      (0x1<<12)
+#define TFA98XX_TDM_CONFIG3_TDMPD1E_POS                         12
+#define TFA98XX_TDM_CONFIG3_TDMPD1E_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMPD1E_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMPD1E_MSK                     0x1000
+
+/*
+ * tdm_source10_enable
+ */
+#define TFA98XX_TDM_CONFIG3_TDMPD2E                      (0x1<<13)
+#define TFA98XX_TDM_CONFIG3_TDMPD2E_POS                         13
+#define TFA98XX_TDM_CONFIG3_TDMPD2E_LEN                          1
+#define TFA98XX_TDM_CONFIG3_TDMPD2E_MAX                          1
+#define TFA98XX_TDM_CONFIG3_TDMPD2E_MSK                     0x2000
+
+
+/*
+ * (0x24)-tdm_config4
+ */
+
+/*
+ * tdm_sink1_io
+ */
+#define TFA98XX_TDM_CONFIG4_TDMLIO                        (0x3<<2)
+#define TFA98XX_TDM_CONFIG4_TDMLIO_POS                           2
+#define TFA98XX_TDM_CONFIG4_TDMLIO_LEN                           2
+#define TFA98XX_TDM_CONFIG4_TDMLIO_MAX                           3
+#define TFA98XX_TDM_CONFIG4_TDMLIO_MSK                         0xc
+
+/*
+ * tdm_sink2_io
+ */
+#define TFA98XX_TDM_CONFIG4_TDMRIO                        (0x3<<4)
+#define TFA98XX_TDM_CONFIG4_TDMRIO_POS                           4
+#define TFA98XX_TDM_CONFIG4_TDMRIO_LEN                           2
+#define TFA98XX_TDM_CONFIG4_TDMRIO_MAX                           3
+#define TFA98XX_TDM_CONFIG4_TDMRIO_MSK                        0x30
+
+/*
+ * tdm_source1_io
+ */
+#define TFA98XX_TDM_CONFIG4_TDMVSRIO                      (0x3<<8)
+#define TFA98XX_TDM_CONFIG4_TDMVSRIO_POS                         8
+#define TFA98XX_TDM_CONFIG4_TDMVSRIO_LEN                         2
+#define TFA98XX_TDM_CONFIG4_TDMVSRIO_MAX                         3
+#define TFA98XX_TDM_CONFIG4_TDMVSRIO_MSK                     0x300
+
+/*
+ * tdm_source2_io
+ */
+#define TFA98XX_TDM_CONFIG4_TDMCSRIO                     (0x3<<10)
+#define TFA98XX_TDM_CONFIG4_TDMCSRIO_POS                        10
+#define TFA98XX_TDM_CONFIG4_TDMCSRIO_LEN                         2
+#define TFA98XX_TDM_CONFIG4_TDMCSRIO_MAX                         3
+#define TFA98XX_TDM_CONFIG4_TDMCSRIO_MSK                     0xc00
+
+/*
+ * tdm_source3_io
+ */
+#define TFA98XX_TDM_CONFIG4_TDMVSLIO                     (0x3<<12)
+#define TFA98XX_TDM_CONFIG4_TDMVSLIO_POS                        12
+#define TFA98XX_TDM_CONFIG4_TDMVSLIO_LEN                         2
+#define TFA98XX_TDM_CONFIG4_TDMVSLIO_MAX                         3
+#define TFA98XX_TDM_CONFIG4_TDMVSLIO_MSK                    0x3000
+
+/*
+ * tdm_source4_io
+ */
+#define TFA98XX_TDM_CONFIG4_TDMCSLIO                     (0x3<<14)
+#define TFA98XX_TDM_CONFIG4_TDMCSLIO_POS                        14
+#define TFA98XX_TDM_CONFIG4_TDMCSLIO_LEN                         2
+#define TFA98XX_TDM_CONFIG4_TDMCSLIO_MAX                         3
+#define TFA98XX_TDM_CONFIG4_TDMCSLIO_MSK                    0xc000
+
+
+/*
+ * (0x25)-tdm_config5
+ */
+
+/*
+ * tdm_source5_io
+ */
+#define TFA98XX_TDM_CONFIG5_TDMCFRIO                      (0x3<<0)
+#define TFA98XX_TDM_CONFIG5_TDMCFRIO_POS                         0
+#define TFA98XX_TDM_CONFIG5_TDMCFRIO_LEN                         2
+#define TFA98XX_TDM_CONFIG5_TDMCFRIO_MAX                         3
+#define TFA98XX_TDM_CONFIG5_TDMCFRIO_MSK                       0x3
+
+/*
+ * tdm_source6_io
+ */
+#define TFA98XX_TDM_CONFIG5_TDMCFLIO                      (0x3<<2)
+#define TFA98XX_TDM_CONFIG5_TDMCFLIO_POS                         2
+#define TFA98XX_TDM_CONFIG5_TDMCFLIO_LEN                         2
+#define TFA98XX_TDM_CONFIG5_TDMCFLIO_MAX                         3
+#define TFA98XX_TDM_CONFIG5_TDMCFLIO_MSK                       0xc
+
+/*
+ * tdm_source7_io
+ */
+#define TFA98XX_TDM_CONFIG5_TDMCF3IO                      (0x3<<4)
+#define TFA98XX_TDM_CONFIG5_TDMCF3IO_POS                         4
+#define TFA98XX_TDM_CONFIG5_TDMCF3IO_LEN                         2
+#define TFA98XX_TDM_CONFIG5_TDMCF3IO_MAX                         3
+#define TFA98XX_TDM_CONFIG5_TDMCF3IO_MSK                      0x30
+
+/*
+ * tdm_source8_io
+ */
+#define TFA98XX_TDM_CONFIG5_TDMCF4IO                      (0x3<<6)
+#define TFA98XX_TDM_CONFIG5_TDMCF4IO_POS                         6
+#define TFA98XX_TDM_CONFIG5_TDMCF4IO_LEN                         2
+#define TFA98XX_TDM_CONFIG5_TDMCF4IO_MAX                         3
+#define TFA98XX_TDM_CONFIG5_TDMCF4IO_MSK                      0xc0
+
+/*
+ * tdm_source9_io
+ */
+#define TFA98XX_TDM_CONFIG5_TDMPD1IO                      (0x3<<8)
+#define TFA98XX_TDM_CONFIG5_TDMPD1IO_POS                         8
+#define TFA98XX_TDM_CONFIG5_TDMPD1IO_LEN                         2
+#define TFA98XX_TDM_CONFIG5_TDMPD1IO_MAX                         3
+#define TFA98XX_TDM_CONFIG5_TDMPD1IO_MSK                     0x300
+
+/*
+ * tdm_source10_io
+ */
+#define TFA98XX_TDM_CONFIG5_TDMPD2IO                     (0x3<<10)
+#define TFA98XX_TDM_CONFIG5_TDMPD2IO_POS                        10
+#define TFA98XX_TDM_CONFIG5_TDMPD2IO_LEN                         2
+#define TFA98XX_TDM_CONFIG5_TDMPD2IO_MAX                         3
+#define TFA98XX_TDM_CONFIG5_TDMPD2IO_MSK                     0xc00
+
+
+/*
+ * (0x26)-tdm_config6
+ */
+
+/*
+ * tdm_sink1_slot
+ */
+#define TFA98XX_TDM_CONFIG6_TDMLS                         (0xf<<4)
+#define TFA98XX_TDM_CONFIG6_TDMLS_POS                            4
+#define TFA98XX_TDM_CONFIG6_TDMLS_LEN                            4
+#define TFA98XX_TDM_CONFIG6_TDMLS_MAX                           15
+#define TFA98XX_TDM_CONFIG6_TDMLS_MSK                         0xf0
+
+/*
+ * tdm_sink2_slot
+ */
+#define TFA98XX_TDM_CONFIG6_TDMRS                         (0xf<<8)
+#define TFA98XX_TDM_CONFIG6_TDMRS_POS                            8
+#define TFA98XX_TDM_CONFIG6_TDMRS_LEN                            4
+#define TFA98XX_TDM_CONFIG6_TDMRS_MAX                           15
+#define TFA98XX_TDM_CONFIG6_TDMRS_MSK                        0xf00
+
+
+/*
+ * (0x27)-tdm_config7
+ */
+
+/*
+ * tdm_source1_slot
+ */
+#define TFA98XX_TDM_CONFIG7_TDMVSRS                       (0xf<<0)
+#define TFA98XX_TDM_CONFIG7_TDMVSRS_POS                          0
+#define TFA98XX_TDM_CONFIG7_TDMVSRS_LEN                          4
+#define TFA98XX_TDM_CONFIG7_TDMVSRS_MAX                         15
+#define TFA98XX_TDM_CONFIG7_TDMVSRS_MSK                        0xf
+
+/*
+ * tdm_source2_slot
+ */
+#define TFA98XX_TDM_CONFIG7_TDMCSRS                       (0xf<<4)
+#define TFA98XX_TDM_CONFIG7_TDMCSRS_POS                          4
+#define TFA98XX_TDM_CONFIG7_TDMCSRS_LEN                          4
+#define TFA98XX_TDM_CONFIG7_TDMCSRS_MAX                         15
+#define TFA98XX_TDM_CONFIG7_TDMCSRS_MSK                       0xf0
+
+/*
+ * tdm_source3_slot
+ */
+#define TFA98XX_TDM_CONFIG7_TDMVSLS                       (0xf<<8)
+#define TFA98XX_TDM_CONFIG7_TDMVSLS_POS                          8
+#define TFA98XX_TDM_CONFIG7_TDMVSLS_LEN                          4
+#define TFA98XX_TDM_CONFIG7_TDMVSLS_MAX                         15
+#define TFA98XX_TDM_CONFIG7_TDMVSLS_MSK                      0xf00
+
+/*
+ * tdm_source4_slot
+ */
+#define TFA98XX_TDM_CONFIG7_TDMCSLS                      (0xf<<12)
+#define TFA98XX_TDM_CONFIG7_TDMCSLS_POS                         12
+#define TFA98XX_TDM_CONFIG7_TDMCSLS_LEN                          4
+#define TFA98XX_TDM_CONFIG7_TDMCSLS_MAX                         15
+#define TFA98XX_TDM_CONFIG7_TDMCSLS_MSK                     0xf000
+
+
+/*
+ * (0x28)-tdm_config8
+ */
+
+/*
+ * tdm_source5_slot
+ */
+#define TFA98XX_TDM_CONFIG8_TDMCFRS                       (0xf<<0)
+#define TFA98XX_TDM_CONFIG8_TDMCFRS_POS                          0
+#define TFA98XX_TDM_CONFIG8_TDMCFRS_LEN                          4
+#define TFA98XX_TDM_CONFIG8_TDMCFRS_MAX                         15
+#define TFA98XX_TDM_CONFIG8_TDMCFRS_MSK                        0xf
+
+/*
+ * tdm_source6_slot
+ */
+#define TFA98XX_TDM_CONFIG8_TDMCFLS                       (0xf<<4)
+#define TFA98XX_TDM_CONFIG8_TDMCFLS_POS                          4
+#define TFA98XX_TDM_CONFIG8_TDMCFLS_LEN                          4
+#define TFA98XX_TDM_CONFIG8_TDMCFLS_MAX                         15
+#define TFA98XX_TDM_CONFIG8_TDMCFLS_MSK                       0xf0
+
+/*
+ * tdm_source7_slot
+ */
+#define TFA98XX_TDM_CONFIG8_TDMCF3S                       (0xf<<8)
+#define TFA98XX_TDM_CONFIG8_TDMCF3S_POS                          8
+#define TFA98XX_TDM_CONFIG8_TDMCF3S_LEN                          4
+#define TFA98XX_TDM_CONFIG8_TDMCF3S_MAX                         15
+#define TFA98XX_TDM_CONFIG8_TDMCF3S_MSK                      0xf00
+
+/*
+ * tdm_source8_slot
+ */
+#define TFA98XX_TDM_CONFIG8_TDMCF4S                      (0xf<<12)
+#define TFA98XX_TDM_CONFIG8_TDMCF4S_POS                         12
+#define TFA98XX_TDM_CONFIG8_TDMCF4S_LEN                          4
+#define TFA98XX_TDM_CONFIG8_TDMCF4S_MAX                         15
+#define TFA98XX_TDM_CONFIG8_TDMCF4S_MSK                     0xf000
+
+
+/*
+ * (0x29)-tdm_config9
+ */
+
+/*
+ * tdm_source9_slot
+ */
+#define TFA98XX_TDM_CONFIG9_TDMPD1S                       (0xf<<0)
+#define TFA98XX_TDM_CONFIG9_TDMPD1S_POS                          0
+#define TFA98XX_TDM_CONFIG9_TDMPD1S_LEN                          4
+#define TFA98XX_TDM_CONFIG9_TDMPD1S_MAX                         15
+#define TFA98XX_TDM_CONFIG9_TDMPD1S_MSK                        0xf
+
+/*
+ * tdm_source10_slot
+ */
+#define TFA98XX_TDM_CONFIG9_TDMPD2S                       (0xf<<4)
+#define TFA98XX_TDM_CONFIG9_TDMPD2S_POS                          4
+#define TFA98XX_TDM_CONFIG9_TDMPD2S_LEN                          4
+#define TFA98XX_TDM_CONFIG9_TDMPD2S_MAX                         15
+#define TFA98XX_TDM_CONFIG9_TDMPD2S_MSK                       0xf0
+
+
+/*
+ * (0x31)-pdm_config0
+ */
+
+/*
+ * pdm_mode
+ */
+#define TFA98XX_PDM_CONFIG0_PDMSM                         (0x1<<0)
+#define TFA98XX_PDM_CONFIG0_PDMSM_POS                            0
+#define TFA98XX_PDM_CONFIG0_PDMSM_LEN                            1
+#define TFA98XX_PDM_CONFIG0_PDMSM_MAX                            1
+#define TFA98XX_PDM_CONFIG0_PDMSM_MSK                          0x1
+
+/*
+ * pdm_side_tone_sel
+ */
+#define TFA98XX_PDM_CONFIG0_PDMSTSEL                      (0x3<<1)
+#define TFA98XX_PDM_CONFIG0_PDMSTSEL_POS                         1
+#define TFA98XX_PDM_CONFIG0_PDMSTSEL_LEN                         2
+#define TFA98XX_PDM_CONFIG0_PDMSTSEL_MAX                         3
+#define TFA98XX_PDM_CONFIG0_PDMSTSEL_MSK                       0x6
+
+/*
+ * pdm_left_sel
+ */
+#define TFA98XX_PDM_CONFIG0_PDMLSEL                       (0x1<<3)
+#define TFA98XX_PDM_CONFIG0_PDMLSEL_POS                          3
+#define TFA98XX_PDM_CONFIG0_PDMLSEL_LEN                          1
+#define TFA98XX_PDM_CONFIG0_PDMLSEL_MAX                          1
+#define TFA98XX_PDM_CONFIG0_PDMLSEL_MSK                        0x8
+
+/*
+ * pdm_right_sel
+ */
+#define TFA98XX_PDM_CONFIG0_PDMRSEL                       (0x1<<4)
+#define TFA98XX_PDM_CONFIG0_PDMRSEL_POS                          4
+#define TFA98XX_PDM_CONFIG0_PDMRSEL_LEN                          1
+#define TFA98XX_PDM_CONFIG0_PDMRSEL_MAX                          1
+#define TFA98XX_PDM_CONFIG0_PDMRSEL_MSK                       0x10
+
+/*
+ * enbl_micvdd
+ */
+#define TFA98XX_PDM_CONFIG0_MICVDDE                       (0x1<<5)
+#define TFA98XX_PDM_CONFIG0_MICVDDE_POS                          5
+#define TFA98XX_PDM_CONFIG0_MICVDDE_LEN                          1
+#define TFA98XX_PDM_CONFIG0_MICVDDE_MAX                          1
+#define TFA98XX_PDM_CONFIG0_MICVDDE_MSK                       0x20
+
+
+/*
+ * (0x32)-pdm_config1
+ */
+
+/*
+ * pdm_nbck
+ */
+#define TFA98XX_PDM_CONFIG1_PDMCLRAT                      (0x3<<0)
+#define TFA98XX_PDM_CONFIG1_PDMCLRAT_POS                         0
+#define TFA98XX_PDM_CONFIG1_PDMCLRAT_LEN                         2
+#define TFA98XX_PDM_CONFIG1_PDMCLRAT_MAX                         3
+#define TFA98XX_PDM_CONFIG1_PDMCLRAT_MSK                       0x3
+
+/*
+ * pdm_gain
+ */
+#define TFA98XX_PDM_CONFIG1_PDMGAIN                       (0xf<<2)
+#define TFA98XX_PDM_CONFIG1_PDMGAIN_POS                          2
+#define TFA98XX_PDM_CONFIG1_PDMGAIN_LEN                          4
+#define TFA98XX_PDM_CONFIG1_PDMGAIN_MAX                         15
+#define TFA98XX_PDM_CONFIG1_PDMGAIN_MSK                       0x3c
+
+/*
+ * sel_pdm_out_data
+ */
+#define TFA98XX_PDM_CONFIG1_PDMOSEL                       (0xf<<6)
+#define TFA98XX_PDM_CONFIG1_PDMOSEL_POS                          6
+#define TFA98XX_PDM_CONFIG1_PDMOSEL_LEN                          4
+#define TFA98XX_PDM_CONFIG1_PDMOSEL_MAX                         15
+#define TFA98XX_PDM_CONFIG1_PDMOSEL_MSK                      0x3c0
+
+/*
+ * sel_cf_haptic_data
+ */
+#define TFA98XX_PDM_CONFIG1_SELCFHAPD                    (0x1<<10)
+#define TFA98XX_PDM_CONFIG1_SELCFHAPD_POS                       10
+#define TFA98XX_PDM_CONFIG1_SELCFHAPD_LEN                        1
+#define TFA98XX_PDM_CONFIG1_SELCFHAPD_MAX                        1
+#define TFA98XX_PDM_CONFIG1_SELCFHAPD_MSK                    0x400
+
+
+/*
+ * (0x33)-haptic_driver_config
+ */
+
+/*
+ * haptic_duration
+ */
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME             (0xff<<0)
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_POS                 0
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_LEN                 8
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_MAX               255
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPTIME_MSK              0xff
+
+/*
+ * haptic_data
+ */
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL            (0xff<<8)
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_POS                8
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_LEN                8
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_MAX              255
+#define TFA98XX_HAPTIC_DRIVER_CONFIG_HAPLEVEL_MSK           0xff00
+
+
+/*
+ * (0x34)-gpio_datain_reg
+ */
+
+/*
+ * gpio_datain
+ */
+#define TFA98XX_GPIO_DATAIN_REG_GPIODIN                   (0xf<<0)
+#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_POS                      0
+#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_LEN                      4
+#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_MAX                     15
+#define TFA98XX_GPIO_DATAIN_REG_GPIODIN_MSK                    0xf
+
+
+/*
+ * (0x35)-gpio_config
+ */
+
+/*
+ * gpio_ctrl
+ */
+#define TFA98XX_GPIO_CONFIG_GPIOCTRL                      (0x1<<0)
+#define TFA98XX_GPIO_CONFIG_GPIOCTRL_POS                         0
+#define TFA98XX_GPIO_CONFIG_GPIOCTRL_LEN                         1
+#define TFA98XX_GPIO_CONFIG_GPIOCTRL_MAX                         1
+#define TFA98XX_GPIO_CONFIG_GPIOCTRL_MSK                       0x1
+
+/*
+ * gpio_dir
+ */
+#define TFA98XX_GPIO_CONFIG_GPIOCONF                      (0xf<<1)
+#define TFA98XX_GPIO_CONFIG_GPIOCONF_POS                         1
+#define TFA98XX_GPIO_CONFIG_GPIOCONF_LEN                         4
+#define TFA98XX_GPIO_CONFIG_GPIOCONF_MAX                        15
+#define TFA98XX_GPIO_CONFIG_GPIOCONF_MSK                      0x1e
+
+/*
+ * gpio_dataout
+ */
+#define TFA98XX_GPIO_CONFIG_GPIODOUT                      (0xf<<5)
+#define TFA98XX_GPIO_CONFIG_GPIODOUT_POS                         5
+#define TFA98XX_GPIO_CONFIG_GPIODOUT_LEN                         4
+#define TFA98XX_GPIO_CONFIG_GPIODOUT_MAX                        15
+#define TFA98XX_GPIO_CONFIG_GPIODOUT_MSK                     0x1e0
+
+
+/*
+ * (0x40)-interrupt_out_reg1
+ */
+
+/*
+ * int_out_flag_por
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS                (0x1<<0)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_POS                   0
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTVDDS_MSK                 0x1
+
+/*
+ * int_out_flag_pll_lock
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS                (0x1<<1)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_POS                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTPLLS_MSK                 0x2
+
+/*
+ * int_out_flag_otpok
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS                (0x1<<2)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_POS                   2
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOTDS_MSK                 0x4
+
+/*
+ * int_out_flag_ovpok
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS                (0x1<<3)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_POS                   3
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTOVDS_MSK                 0x8
+
+/*
+ * int_out_flag_uvpok
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS                (0x1<<4)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_POS                   4
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTUVDS_MSK                0x10
+
+/*
+ * int_out_flag_clocks_stable
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS                (0x1<<5)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_POS                   5
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTCLKS_MSK                0x20
+
+/*
+ * int_out_flag_mtp_busy
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB                (0x1<<6)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_POS                   6
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTMTPB_MSK                0x40
+
+/*
+ * int_out_flag_lost_clk
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK               (0x1<<7)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_POS                  7
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTNOCLK_MSK               0x80
+
+/*
+ * int_out_flag_cf_speakererror
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS                (0x1<<8)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_POS                   8
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSPKS_MSK               0x100
+
+/*
+ * int_out_flag_cold_started
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS                 (0x1<<9)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_POS                    9
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_LEN                    1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_MAX                    1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTACS_MSK                0x200
+
+/*
+ * int_out_flag_engage
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS                (0x1<<10)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_POS                   10
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_LEN                    1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_MAX                    1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTSWS_MSK                0x400
+
+/*
+ * int_out_flag_watchdog_reset
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS                (0x1<<11)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_POS                   11
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_LEN                    1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_MAX                    1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTWDS_MSK                0x800
+
+/*
+ * int_out_flag_enbl_amp
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS               (0x1<<12)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_POS                  12
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAMPS_MSK              0x1000
+
+/*
+ * int_out_flag_enbl_ref
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS              (0x1<<13)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_POS                 13
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTAREFS_MSK             0x2000
+
+/*
+ * int_out_flag_adc10_ready
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR              (0x1<<14)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_POS                 14
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTADCCR_MSK             0x4000
+
+/*
+ * int_out_flag_bod_vddd_nok
+ */
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK             (0x1<<15)
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_POS                15
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_LEN                 1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_MAX                 1
+#define TFA98XX_INTERRUPT_OUT_REG1_ISTBODNOK_MSK            0x8000
+
+
+/*
+ * (0x41)-interrupt_out_reg2
+ */
+
+/*
+ * int_out_flag_bst_bstcur
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU               (0x1<<0)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_POS                  0
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTCU_MSK                0x1
+
+/*
+ * int_out_flag_bst_hiz
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI               (0x1<<1)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_POS                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTHI_MSK                0x2
+
+/*
+ * int_out_flag_bst_ocpok
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC               (0x1<<2)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_POS                  2
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTOC_MSK                0x4
+
+/*
+ * int_out_flag_bst_peakcur
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR            (0x1<<3)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_POS               3
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_LEN               1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_MAX               1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTPKCUR_MSK             0x8
+
+/*
+ * int_out_flag_bst_voutcomp
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC               (0x1<<4)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_POS                  4
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBSTVC_MSK               0x10
+
+/*
+ * int_out_flag_bst_voutcomp86
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86               (0x1<<5)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_POS                  5
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST86_MSK               0x20
+
+/*
+ * int_out_flag_bst_voutcomp93
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93               (0x1<<6)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_POS                  6
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTBST93_MSK               0x40
+
+/*
+ * int_out_flag_rcvldop_ready
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD               (0x1<<7)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_POS                  7
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTRCVLD_MSK               0x80
+
+/*
+ * int_out_flag_ocp_alarm_left
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL                (0x1<<8)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_POS                   8
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPL_MSK               0x100
+
+/*
+ * int_out_flag_ocp_alarm_right
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR                (0x1<<9)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_POS                   9
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTOCPR_MSK               0x200
+
+/*
+ * int_out_flag_man_wait_src_settings
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC              (0x1<<10)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_POS                 10
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSRC_MSK              0x400
+
+/*
+ * int_out_flag_man_wait_cf_config
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC              (0x1<<11)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_POS                 11
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWCFC_MSK              0x800
+
+/*
+ * int_out_flag_man_start_mute_audio
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU              (0x1<<12)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_POS                 12
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTMWSMU_MSK             0x1000
+
+/*
+ * int_out_flag_cfma_err
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER              (0x1<<13)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_POS                 13
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMER_MSK             0x2000
+
+/*
+ * int_out_flag_cfma_ack
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC              (0x1<<14)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_POS                 14
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCFMAC_MSK             0x4000
+
+/*
+ * int_out_flag_clk_out_of_range
+ */
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR             (0x1<<15)
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_POS                15
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_LEN                 1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_MAX                 1
+#define TFA98XX_INTERRUPT_OUT_REG2_ISTCLKOOR_MSK            0x8000
+
+
+/*
+ * (0x42)-interrupt_out_reg3
+ */
+
+/*
+ * int_out_flag_tdm_error
+ */
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER               (0x1<<0)
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_POS                  0
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_LEN                  1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_MAX                  1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTTDMER_MSK                0x1
+
+/*
+ * int_out_flag_clip_left
+ */
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL                (0x1<<1)
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_POS                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPL_MSK                 0x2
+
+/*
+ * int_out_flag_clip_right
+ */
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR                (0x1<<2)
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_POS                   2
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTCLPR_MSK                 0x4
+
+/*
+ * int_out_flag_mic_ocpok
+ */
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM                (0x1<<3)
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_POS                   3
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_LEN                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_MAX                   1
+#define TFA98XX_INTERRUPT_OUT_REG3_ISTOCPM_MSK                 0x8
+
+
+/*
+ * (0x44)-interrupt_in_reg1
+ */
+
+/*
+ * int_in_flag_por
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS                 (0x1<<0)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_POS                    0
+#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLVDDS_MSK                  0x1
+
+/*
+ * int_in_flag_pll_lock
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS                 (0x1<<1)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_POS                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLPLLS_MSK                  0x2
+
+/*
+ * int_in_flag_otpok
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS                 (0x1<<2)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_POS                    2
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOTDS_MSK                  0x4
+
+/*
+ * int_in_flag_ovpok
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS                 (0x1<<3)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_POS                    3
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLOVDS_MSK                  0x8
+
+/*
+ * int_in_flag_uvpok
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS                 (0x1<<4)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_POS                    4
+#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLUVDS_MSK                 0x10
+
+/*
+ * int_in_flag_clocks_stable
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS                 (0x1<<5)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_POS                    5
+#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLCLKS_MSK                 0x20
+
+/*
+ * int_in_flag_mtp_busy
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB                 (0x1<<6)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_POS                    6
+#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLMTPB_MSK                 0x40
+
+/*
+ * int_in_flag_lost_clk
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK                (0x1<<7)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_POS                   7
+#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLNOCLK_MSK                0x80
+
+/*
+ * int_in_flag_cf_speakererror
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS                 (0x1<<8)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_POS                    8
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSPKS_MSK                0x100
+
+/*
+ * int_in_flag_cold_started
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLACS                  (0x1<<9)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_POS                     9
+#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_LEN                     1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_MAX                     1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLACS_MSK                 0x200
+
+/*
+ * int_in_flag_engage
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS                 (0x1<<10)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_POS                    10
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_LEN                     1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_MAX                     1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLSWS_MSK                 0x400
+
+/*
+ * int_in_flag_watchdog_reset
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS                 (0x1<<11)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_POS                    11
+#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_LEN                     1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_MAX                     1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLWDS_MSK                 0x800
+
+/*
+ * int_in_flag_enbl_amp
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS                (0x1<<12)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_POS                   12
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAMPS_MSK               0x1000
+
+/*
+ * int_in_flag_enbl_ref
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS               (0x1<<13)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_POS                  13
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLAREFS_MSK              0x2000
+
+/*
+ * int_in_flag_adc10_ready
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR               (0x1<<14)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_POS                  14
+#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLADCCR_MSK              0x4000
+
+/*
+ * int_in_flag_bod_vddd_nok
+ */
+#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK              (0x1<<15)
+#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_POS                 15
+#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_LEN                  1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_MAX                  1
+#define TFA98XX_INTERRUPT_IN_REG1_ICLBODNOK_MSK             0x8000
+
+
+/*
+ * (0x45)-interrupt_in_reg2
+ */
+
+/*
+ * int_in_flag_bst_bstcur
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU                (0x1<<0)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_POS                   0
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTCU_MSK                 0x1
+
+/*
+ * int_in_flag_bst_hiz
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI                (0x1<<1)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_POS                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTHI_MSK                 0x2
+
+/*
+ * int_in_flag_bst_ocpok
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC                (0x1<<2)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_POS                   2
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTOC_MSK                 0x4
+
+/*
+ * int_in_flag_bst_peakcur
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC                (0x1<<3)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_POS                   3
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTPC_MSK                 0x8
+
+/*
+ * int_in_flag_bst_voutcomp
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC                (0x1<<4)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_POS                   4
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBSTVC_MSK                0x10
+
+/*
+ * int_in_flag_bst_voutcomp86
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86                (0x1<<5)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_POS                   5
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST86_MSK                0x20
+
+/*
+ * int_in_flag_bst_voutcomp93
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93                (0x1<<6)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_POS                   6
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLBST93_MSK                0x40
+
+/*
+ * int_in_flag_rcvldop_ready
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD                (0x1<<7)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_POS                   7
+#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLRCVLD_MSK                0x80
+
+/*
+ * int_in_flag_ocp_alarm_left
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL                 (0x1<<8)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_POS                    8
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPL_MSK                0x100
+
+/*
+ * int_in_flag_ocp_alarm_right
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR                 (0x1<<9)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_POS                    9
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLOCPR_MSK                0x200
+
+/*
+ * int_in_flag_man_wait_src_settings
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC               (0x1<<10)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_POS                  10
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSRC_MSK               0x400
+
+/*
+ * int_in_flag_man_wait_cf_config
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC               (0x1<<11)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_POS                  11
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWCFC_MSK               0x800
+
+/*
+ * int_in_flag_man_start_mute_audio
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU               (0x1<<12)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_POS                  12
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLMWSMU_MSK              0x1000
+
+/*
+ * int_in_flag_cfma_err
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER               (0x1<<13)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_POS                  13
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMER_MSK              0x2000
+
+/*
+ * int_in_flag_cfma_ack
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC               (0x1<<14)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_POS                  14
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCFMAC_MSK              0x4000
+
+/*
+ * int_in_flag_clk_out_of_range
+ */
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR              (0x1<<15)
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_POS                 15
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_LEN                  1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_MAX                  1
+#define TFA98XX_INTERRUPT_IN_REG2_ICLCLKOOR_MSK             0x8000
+
+
+/*
+ * (0x46)-interrupt_in_reg3
+ */
+
+/*
+ * int_in_flag_tdm_error
+ */
+#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER                (0x1<<0)
+#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_POS                   0
+#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_LEN                   1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_MAX                   1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLTDMER_MSK                 0x1
+
+/*
+ * int_in_flag_clip_left
+ */
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL                 (0x1<<1)
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_POS                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPL_MSK                  0x2
+
+/*
+ * int_in_flag_clip_right
+ */
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR                 (0x1<<2)
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_POS                    2
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLCLPR_MSK                  0x4
+
+/*
+ * int_in_flag_mic_ocpok
+ */
+#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM                 (0x1<<3)
+#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_POS                    3
+#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_LEN                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_MAX                    1
+#define TFA98XX_INTERRUPT_IN_REG3_ICLOCPM_MSK                  0x8
+
+
+/*
+ * (0x48)-interrupt_enable_reg1
+ */
+
+/*
+ * int_enable_flag_por
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS              (0x1<<0)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_POS                 0
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEVDDS_MSK               0x1
+
+/*
+ * int_enable_flag_pll_lock
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS              (0x1<<1)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_POS                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEPLLS_MSK               0x2
+
+/*
+ * int_enable_flag_otpok
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS              (0x1<<2)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_POS                 2
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOTDS_MSK               0x4
+
+/*
+ * int_enable_flag_ovpok
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS              (0x1<<3)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_POS                 3
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEOVDS_MSK               0x8
+
+/*
+ * int_enable_flag_uvpok
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS              (0x1<<4)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_POS                 4
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEUVDS_MSK              0x10
+
+/*
+ * int_enable_flag_clocks_stable
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS              (0x1<<5)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_POS                 5
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IECLKS_MSK              0x20
+
+/*
+ * int_enable_flag_mtp_busy
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB              (0x1<<6)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_POS                 6
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEMTPB_MSK              0x40
+
+/*
+ * int_enable_flag_lost_clk
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK             (0x1<<7)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_POS                7
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IENOCLK_MSK             0x80
+
+/*
+ * int_enable_flag_cf_speakererror
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS              (0x1<<8)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_POS                 8
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESPKS_MSK             0x100
+
+/*
+ * int_enable_flag_cold_started
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS               (0x1<<9)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_POS                  9
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_LEN                  1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_MAX                  1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEACS_MSK              0x200
+
+/*
+ * int_enable_flag_engage
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS              (0x1<<10)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_POS                 10
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_LEN                  1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_MAX                  1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IESWS_MSK              0x400
+
+/*
+ * int_enable_flag_watchdog_reset
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS              (0x1<<11)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_POS                 11
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_LEN                  1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_MAX                  1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEWDS_MSK              0x800
+
+/*
+ * int_enable_flag_enbl_amp
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS             (0x1<<12)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_POS                12
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAMPS_MSK            0x1000
+
+/*
+ * int_enable_flag_enbl_ref
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS            (0x1<<13)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_POS               13
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEAREFS_MSK           0x2000
+
+/*
+ * int_enable_flag_adc10_ready
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR            (0x1<<14)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_POS               14
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEADCCR_MSK           0x4000
+
+/*
+ * int_enable_flag_bod_vddd_nok
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK           (0x1<<15)
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_POS              15
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_LEN               1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_MAX               1
+#define TFA98XX_INTERRUPT_ENABLE_REG1_IEBODNOK_MSK          0x8000
+
+
+/*
+ * (0x49)-interrupt_enable_reg2
+ */
+
+/*
+ * int_enable_flag_bst_bstcur
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU             (0x1<<0)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_POS                0
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTCU_MSK              0x1
+
+/*
+ * int_enable_flag_bst_hiz
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI             (0x1<<1)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_POS                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTHI_MSK              0x2
+
+/*
+ * int_enable_flag_bst_ocpok
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC             (0x1<<2)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_POS                2
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTOC_MSK              0x4
+
+/*
+ * int_enable_flag_bst_peakcur
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC             (0x1<<3)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_POS                3
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTPC_MSK              0x8
+
+/*
+ * int_enable_flag_bst_voutcomp
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC             (0x1<<4)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_POS                4
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBSTVC_MSK             0x10
+
+/*
+ * int_enable_flag_bst_voutcomp86
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86             (0x1<<5)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_POS                5
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST86_MSK             0x20
+
+/*
+ * int_enable_flag_bst_voutcomp93
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93             (0x1<<6)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_POS                6
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEBST93_MSK             0x40
+
+/*
+ * int_enable_flag_rcvldop_ready
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD             (0x1<<7)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_POS                7
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IERCVLD_MSK             0x80
+
+/*
+ * int_enable_flag_ocp_alarm_left
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL              (0x1<<8)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_POS                 8
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPL_MSK             0x100
+
+/*
+ * int_enable_flag_ocp_alarm_right
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR              (0x1<<9)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_POS                 9
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEOCPR_MSK             0x200
+
+/*
+ * int_enable_flag_man_wait_src_settings
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC            (0x1<<10)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_POS               10
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSRC_MSK            0x400
+
+/*
+ * int_enable_flag_man_wait_cf_config
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC            (0x1<<11)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_POS               11
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWCFC_MSK            0x800
+
+/*
+ * int_enable_flag_man_start_mute_audio
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU            (0x1<<12)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_POS               12
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IEMWSMU_MSK           0x1000
+
+/*
+ * int_enable_flag_cfma_err
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER            (0x1<<13)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_POS               13
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMER_MSK           0x2000
+
+/*
+ * int_enable_flag_cfma_ack
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC            (0x1<<14)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_POS               14
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECFMAC_MSK           0x4000
+
+/*
+ * int_enable_flag_clk_out_of_range
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR           (0x1<<15)
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_POS              15
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_LEN               1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_MAX               1
+#define TFA98XX_INTERRUPT_ENABLE_REG2_IECLKOOR_MSK          0x8000
+
+
+/*
+ * (0x4a)-interrupt_enable_reg3
+ */
+
+/*
+ * int_enable_flag_tdm_error
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER             (0x1<<0)
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_POS                0
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IETDMER_MSK              0x1
+
+/*
+ * int_enable_flag_clip_left
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL              (0x1<<1)
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_POS                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPL_MSK               0x2
+
+/*
+ * int_enable_flag_clip_right
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR              (0x1<<2)
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_POS                 2
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_LEN                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_MAX                 1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IECLPR_MSK               0x4
+
+/*
+ * int_enable_flag_mic_ocpok
+ */
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1             (0x1<<3)
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_POS                3
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_LEN                1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_MAX                1
+#define TFA98XX_INTERRUPT_ENABLE_REG3_IEOCPM1_MSK              0x8
+
+
+/*
+ * (0x4c)-status_polarity_reg1
+ */
+
+/*
+ * int_polarity_flag_por
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS              (0x1<<0)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_POS                 0
+#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOVDDS_MSK               0x1
+
+/*
+ * int_polarity_flag_pll_lock
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS              (0x1<<1)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_POS                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOPLLS_MSK               0x2
+
+/*
+ * int_polarity_flag_otpok
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS              (0x1<<2)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_POS                 2
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOTDS_MSK               0x4
+
+/*
+ * int_polarity_flag_ovpok
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS              (0x1<<3)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_POS                 3
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOOVDS_MSK               0x8
+
+/*
+ * int_polarity_flag_uvpok
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS              (0x1<<4)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_POS                 4
+#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOUVDS_MSK              0x10
+
+/*
+ * int_polarity_flag_clocks_stable
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS              (0x1<<5)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_POS                 5
+#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOCLKS_MSK              0x20
+
+/*
+ * int_polarity_flag_mtp_busy
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB              (0x1<<6)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_POS                 6
+#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOMTPB_MSK              0x40
+
+/*
+ * int_polarity_flag_lost_clk
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK             (0x1<<7)
+#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_POS                7
+#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG1_IPONOCLK_MSK             0x80
+
+/*
+ * int_polarity_flag_cf_speakererror
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS              (0x1<<8)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_POS                 8
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSPKS_MSK             0x100
+
+/*
+ * int_polarity_flag_cold_started
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOACS               (0x1<<9)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_POS                  9
+#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_LEN                  1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_MAX                  1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOACS_MSK              0x200
+
+/*
+ * int_polarity_flag_engage
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS              (0x1<<10)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_POS                 10
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_LEN                  1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_MAX                  1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOSWS_MSK              0x400
+
+/*
+ * int_polarity_flag_watchdog_reset
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS              (0x1<<11)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_POS                 11
+#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_LEN                  1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_MAX                  1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOWDS_MSK              0x800
+
+/*
+ * int_polarity_flag_enbl_amp
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS             (0x1<<12)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_POS                12
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAMPS_MSK            0x1000
+
+/*
+ * int_polarity_flag_enbl_ref
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS            (0x1<<13)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_POS               13
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOAREFS_MSK           0x2000
+
+/*
+ * int_polarity_flag_adc10_ready
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR            (0x1<<14)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_POS               14
+#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOADCCR_MSK           0x4000
+
+/*
+ * int_polarity_flag_bod_vddd_nok
+ */
+#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK           (0x1<<15)
+#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_POS              15
+#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_LEN               1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_MAX               1
+#define TFA98XX_STATUS_POLARITY_REG1_IPOBODNOK_MSK          0x8000
+
+
+/*
+ * (0x4d)-status_polarity_reg2
+ */
+
+/*
+ * int_polarity_flag_bst_bstcur
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU             (0x1<<0)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_POS                0
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTCU_MSK              0x1
+
+/*
+ * int_polarity_flag_bst_hiz
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI             (0x1<<1)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_POS                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTHI_MSK              0x2
+
+/*
+ * int_polarity_flag_bst_ocpok
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC             (0x1<<2)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_POS                2
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTOC_MSK              0x4
+
+/*
+ * int_polarity_flag_bst_peakcur
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC             (0x1<<3)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_POS                3
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTPC_MSK              0x8
+
+/*
+ * int_polarity_flag_bst_voutcomp
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC             (0x1<<4)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_POS                4
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBSTVC_MSK             0x10
+
+/*
+ * int_polarity_flag_bst_voutcomp86
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86             (0x1<<5)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_POS                5
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST86_MSK             0x20
+
+/*
+ * int_polarity_flag_bst_voutcomp93
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93             (0x1<<6)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_POS                6
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOBST93_MSK             0x40
+
+/*
+ * int_polarity_flag_rcvldop_ready
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD             (0x1<<7)
+#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_POS                7
+#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPORCVLD_MSK             0x80
+
+/*
+ * int_polarity_flag_ocp_alarm_left
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL              (0x1<<8)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_POS                 8
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPL_MSK             0x100
+
+/*
+ * int_polarity_flag_ocp_alarm_right
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR              (0x1<<9)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_POS                 9
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOOCPR_MSK             0x200
+
+/*
+ * int_polarity_flag_man_wait_src_settings
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC            (0x1<<10)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_POS               10
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSRC_MSK            0x400
+
+/*
+ * int_polarity_flag_man_wait_cf_config
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC            (0x1<<11)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_POS               11
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWCFC_MSK            0x800
+
+/*
+ * int_polarity_flag_man_start_mute_audio
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU            (0x1<<12)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_POS               12
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOMWSMU_MSK           0x1000
+
+/*
+ * int_polarity_flag_cfma_err
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER            (0x1<<13)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_POS               13
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMER_MSK           0x2000
+
+/*
+ * int_polarity_flag_cfma_ack
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC            (0x1<<14)
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_POS               14
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPOCFMAC_MSK           0x4000
+
+/*
+ * int_polarity_flag_clk_out_of_range
+ */
+#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR            (0x1<<15)
+#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_POS               15
+#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG2_IPCLKOOR_MSK           0x8000
+
+
+/*
+ * (0x4e)-status_polarity_reg3
+ */
+
+/*
+ * int_polarity_flag_tdm_error
+ */
+#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER             (0x1<<0)
+#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_POS                0
+#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_LEN                1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_MAX                1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOTDMER_MSK              0x1
+
+/*
+ * int_polarity_flag_clip_left
+ */
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL              (0x1<<1)
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_POS                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPL_MSK               0x2
+
+/*
+ * int_polarity_flag_clip_right
+ */
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR              (0x1<<2)
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_POS                 2
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOCLPR_MSK               0x4
+
+/*
+ * int_polarity_flag_mic_ocpok
+ */
+#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM              (0x1<<3)
+#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_POS                 3
+#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_LEN                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_MAX                 1
+#define TFA98XX_STATUS_POLARITY_REG3_IPOOCPM_MSK               0x8
+
+
+/*
+ * (0x50)-bat_prot_config
+ */
+
+/*
+ * vbat_prot_attack_time
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSSCR                     (0x3<<0)
+#define TFA98XX_BAT_PROT_CONFIG_BSSCR_POS                        0
+#define TFA98XX_BAT_PROT_CONFIG_BSSCR_LEN                        2
+#define TFA98XX_BAT_PROT_CONFIG_BSSCR_MAX                        3
+#define TFA98XX_BAT_PROT_CONFIG_BSSCR_MSK                      0x3
+
+/*
+ * vbat_prot_thlevel
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSST                      (0xf<<2)
+#define TFA98XX_BAT_PROT_CONFIG_BSST_POS                         2
+#define TFA98XX_BAT_PROT_CONFIG_BSST_LEN                         4
+#define TFA98XX_BAT_PROT_CONFIG_BSST_MAX                        15
+#define TFA98XX_BAT_PROT_CONFIG_BSST_MSK                      0x3c
+
+/*
+ * vbat_prot_max_reduct
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSSRL                     (0x3<<6)
+#define TFA98XX_BAT_PROT_CONFIG_BSSRL_POS                        6
+#define TFA98XX_BAT_PROT_CONFIG_BSSRL_LEN                        2
+#define TFA98XX_BAT_PROT_CONFIG_BSSRL_MAX                        3
+#define TFA98XX_BAT_PROT_CONFIG_BSSRL_MSK                     0xc0
+
+/*
+ * vbat_prot_release_time
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSSRR                     (0x7<<8)
+#define TFA98XX_BAT_PROT_CONFIG_BSSRR_POS                        8
+#define TFA98XX_BAT_PROT_CONFIG_BSSRR_LEN                        3
+#define TFA98XX_BAT_PROT_CONFIG_BSSRR_MAX                        7
+#define TFA98XX_BAT_PROT_CONFIG_BSSRR_MSK                    0x700
+
+/*
+ * vbat_prot_hysterese
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSSHY                    (0x3<<11)
+#define TFA98XX_BAT_PROT_CONFIG_BSSHY_POS                       11
+#define TFA98XX_BAT_PROT_CONFIG_BSSHY_LEN                        2
+#define TFA98XX_BAT_PROT_CONFIG_BSSHY_MAX                        3
+#define TFA98XX_BAT_PROT_CONFIG_BSSHY_MSK                   0x1800
+
+/*
+ * sel_vbat
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSSR                     (0x1<<14)
+#define TFA98XX_BAT_PROT_CONFIG_BSSR_POS                        14
+#define TFA98XX_BAT_PROT_CONFIG_BSSR_LEN                         1
+#define TFA98XX_BAT_PROT_CONFIG_BSSR_MAX                         1
+#define TFA98XX_BAT_PROT_CONFIG_BSSR_MSK                    0x4000
+
+/*
+ * bypass_clipper
+ */
+#define TFA98XX_BAT_PROT_CONFIG_BSSBY                    (0x1<<15)
+#define TFA98XX_BAT_PROT_CONFIG_BSSBY_POS                       15
+#define TFA98XX_BAT_PROT_CONFIG_BSSBY_LEN                        1
+#define TFA98XX_BAT_PROT_CONFIG_BSSBY_MAX                        1
+#define TFA98XX_BAT_PROT_CONFIG_BSSBY_MSK                   0x8000
+
+
+/*
+ * (0x51)-audio_control
+ */
+
+/*
+ * batsense_steepness
+ */
+#define TFA98XX_AUDIO_CONTROL_BSSS                        (0x1<<0)
+#define TFA98XX_AUDIO_CONTROL_BSSS_POS                           0
+#define TFA98XX_AUDIO_CONTROL_BSSS_LEN                           1
+#define TFA98XX_AUDIO_CONTROL_BSSS_MAX                           1
+#define TFA98XX_AUDIO_CONTROL_BSSS_MSK                         0x1
+
+/*
+ * soft_mute
+ */
+#define TFA98XX_AUDIO_CONTROL_INTSMUTE                    (0x1<<1)
+#define TFA98XX_AUDIO_CONTROL_INTSMUTE_POS                       1
+#define TFA98XX_AUDIO_CONTROL_INTSMUTE_LEN                       1
+#define TFA98XX_AUDIO_CONTROL_INTSMUTE_MAX                       1
+#define TFA98XX_AUDIO_CONTROL_INTSMUTE_MSK                     0x2
+
+/*
+ * cf_mute_left
+ */
+#define TFA98XX_AUDIO_CONTROL_CFSML                       (0x1<<2)
+#define TFA98XX_AUDIO_CONTROL_CFSML_POS                          2
+#define TFA98XX_AUDIO_CONTROL_CFSML_LEN                          1
+#define TFA98XX_AUDIO_CONTROL_CFSML_MAX                          1
+#define TFA98XX_AUDIO_CONTROL_CFSML_MSK                        0x4
+
+/*
+ * cf_mute_right
+ */
+#define TFA98XX_AUDIO_CONTROL_CFSMR                       (0x1<<3)
+#define TFA98XX_AUDIO_CONTROL_CFSMR_POS                          3
+#define TFA98XX_AUDIO_CONTROL_CFSMR_LEN                          1
+#define TFA98XX_AUDIO_CONTROL_CFSMR_MAX                          1
+#define TFA98XX_AUDIO_CONTROL_CFSMR_MSK                        0x8
+
+/*
+ * bypass_hp_left
+ */
+#define TFA98XX_AUDIO_CONTROL_HPFBYPL                     (0x1<<4)
+#define TFA98XX_AUDIO_CONTROL_HPFBYPL_POS                        4
+#define TFA98XX_AUDIO_CONTROL_HPFBYPL_LEN                        1
+#define TFA98XX_AUDIO_CONTROL_HPFBYPL_MAX                        1
+#define TFA98XX_AUDIO_CONTROL_HPFBYPL_MSK                     0x10
+
+/*
+ * bypass_hp_right
+ */
+#define TFA98XX_AUDIO_CONTROL_HPFBYPR                     (0x1<<5)
+#define TFA98XX_AUDIO_CONTROL_HPFBYPR_POS                        5
+#define TFA98XX_AUDIO_CONTROL_HPFBYPR_LEN                        1
+#define TFA98XX_AUDIO_CONTROL_HPFBYPR_MAX                        1
+#define TFA98XX_AUDIO_CONTROL_HPFBYPR_MSK                     0x20
+
+/*
+ * enbl_dpsa_left
+ */
+#define TFA98XX_AUDIO_CONTROL_DPSAL                       (0x1<<6)
+#define TFA98XX_AUDIO_CONTROL_DPSAL_POS                          6
+#define TFA98XX_AUDIO_CONTROL_DPSAL_LEN                          1
+#define TFA98XX_AUDIO_CONTROL_DPSAL_MAX                          1
+#define TFA98XX_AUDIO_CONTROL_DPSAL_MSK                       0x40
+
+/*
+ * enbl_dpsa_right
+ */
+#define TFA98XX_AUDIO_CONTROL_DPSAR                       (0x1<<7)
+#define TFA98XX_AUDIO_CONTROL_DPSAR_POS                          7
+#define TFA98XX_AUDIO_CONTROL_DPSAR_LEN                          1
+#define TFA98XX_AUDIO_CONTROL_DPSAR_MAX                          1
+#define TFA98XX_AUDIO_CONTROL_DPSAR_MSK                       0x80
+
+/*
+ * cf_volume
+ */
+#define TFA98XX_AUDIO_CONTROL_VOL                        (0xff<<8)
+#define TFA98XX_AUDIO_CONTROL_VOL_POS                            8
+#define TFA98XX_AUDIO_CONTROL_VOL_LEN                            8
+#define TFA98XX_AUDIO_CONTROL_VOL_MAX                          255
+#define TFA98XX_AUDIO_CONTROL_VOL_MSK                       0xff00
+
+
+/*
+ * (0x52)-amplifier_config
+ */
+
+/*
+ * ctrl_rcv
+ */
+#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV                 (0x1<<0)
+#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_POS                    0
+#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_LEN                    1
+#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_MAX                    1
+#define TFA98XX_AMPLIFIER_CONFIG_HNDSFRCV_MSK                  0x1
+
+/*
+ * ctrl_cc
+ */
+#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL                 (0x7<<2)
+#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_POS                    2
+#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_LEN                    3
+#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_MAX                    7
+#define TFA98XX_AMPLIFIER_CONFIG_CLIPCTRL_MSK                 0x1c
+
+/*
+ * gain
+ */
+#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN                 (0xff<<5)
+#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_POS                     5
+#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_LEN                     8
+#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_MAX                   255
+#define TFA98XX_AMPLIFIER_CONFIG_AMPGAIN_MSK                0x1fe0
+
+/*
+ * ctrl_slopectrl
+ */
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE                  (0x1<<13)
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_POS                     13
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_LEN                      1
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_MAX                      1
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPEE_MSK                 0x2000
+
+/*
+ * ctrl_slope
+ */
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET                (0x3<<14)
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_POS                   14
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_LEN                    2
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_MAX                    3
+#define TFA98XX_AMPLIFIER_CONFIG_SLOPESET_MSK               0xc000
+
+
+/*
+ * (0x5a)-audio_control2
+ */
+
+/*
+ * cf_volume_sec
+ */
+#define TFA98XX_AUDIO_CONTROL2_VOLSEC                    (0xff<<0)
+#define TFA98XX_AUDIO_CONTROL2_VOLSEC_POS                        0
+#define TFA98XX_AUDIO_CONTROL2_VOLSEC_LEN                        8
+#define TFA98XX_AUDIO_CONTROL2_VOLSEC_MAX                      255
+#define TFA98XX_AUDIO_CONTROL2_VOLSEC_MSK                     0xff
+
+/*
+ * sw_profile
+ */
+#define TFA98XX_AUDIO_CONTROL2_SWPROFIL                  (0xff<<8)
+#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_POS                      8
+#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_LEN                      8
+#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_MAX                    255
+#define TFA98XX_AUDIO_CONTROL2_SWPROFIL_MSK                 0xff00
+
+
+/*
+ * (0x70)-dcdc_control0
+ */
+
+/*
+ * boost_volt
+ */
+#define TFA98XX_DCDC_CONTROL0_DCVO                        (0x7<<0)
+#define TFA98XX_DCDC_CONTROL0_DCVO_POS                           0
+#define TFA98XX_DCDC_CONTROL0_DCVO_LEN                           3
+#define TFA98XX_DCDC_CONTROL0_DCVO_MAX                           7
+#define TFA98XX_DCDC_CONTROL0_DCVO_MSK                         0x7
+
+/*
+ * boost_cur
+ */
+#define TFA98XX_DCDC_CONTROL0_DCMCC                       (0xf<<3)
+#define TFA98XX_DCDC_CONTROL0_DCMCC_POS                          3
+#define TFA98XX_DCDC_CONTROL0_DCMCC_LEN                          4
+#define TFA98XX_DCDC_CONTROL0_DCMCC_MAX                         15
+#define TFA98XX_DCDC_CONTROL0_DCMCC_MSK                       0x78
+
+/*
+ * bst_coil_value
+ */
+#define TFA98XX_DCDC_CONTROL0_DCCV                        (0x3<<7)
+#define TFA98XX_DCDC_CONTROL0_DCCV_POS                           7
+#define TFA98XX_DCDC_CONTROL0_DCCV_LEN                           2
+#define TFA98XX_DCDC_CONTROL0_DCCV_MAX                           3
+#define TFA98XX_DCDC_CONTROL0_DCCV_MSK                       0x180
+
+/*
+ * boost_intel
+ */
+#define TFA98XX_DCDC_CONTROL0_DCIE                        (0x1<<9)
+#define TFA98XX_DCDC_CONTROL0_DCIE_POS                           9
+#define TFA98XX_DCDC_CONTROL0_DCIE_LEN                           1
+#define TFA98XX_DCDC_CONTROL0_DCIE_MAX                           1
+#define TFA98XX_DCDC_CONTROL0_DCIE_MSK                       0x200
+
+/*
+ * boost_speed
+ */
+#define TFA98XX_DCDC_CONTROL0_DCSR                       (0x1<<10)
+#define TFA98XX_DCDC_CONTROL0_DCSR_POS                          10
+#define TFA98XX_DCDC_CONTROL0_DCSR_LEN                           1
+#define TFA98XX_DCDC_CONTROL0_DCSR_MAX                           1
+#define TFA98XX_DCDC_CONTROL0_DCSR_MSK                       0x400
+
+/*
+ * dcdc_synchronisation
+ */
+#define TFA98XX_DCDC_CONTROL0_DCSYNCP                    (0x7<<11)
+#define TFA98XX_DCDC_CONTROL0_DCSYNCP_POS                       11
+#define TFA98XX_DCDC_CONTROL0_DCSYNCP_LEN                        3
+#define TFA98XX_DCDC_CONTROL0_DCSYNCP_MAX                        7
+#define TFA98XX_DCDC_CONTROL0_DCSYNCP_MSK                   0x3800
+
+/*
+ * dcdcoff_mode
+ */
+#define TFA98XX_DCDC_CONTROL0_DCDIS                      (0x1<<14)
+#define TFA98XX_DCDC_CONTROL0_DCDIS_POS                         14
+#define TFA98XX_DCDC_CONTROL0_DCDIS_LEN                          1
+#define TFA98XX_DCDC_CONTROL0_DCDIS_MAX                          1
+#define TFA98XX_DCDC_CONTROL0_DCDIS_MSK                     0x4000
+
+
+/*
+ * (0x90)-cf_controls
+ */
+
+/*
+ * cf_rst_dsp
+ */
+#define TFA98XX_CF_CONTROLS_RST                           (0x1<<0)
+#define TFA98XX_CF_CONTROLS_RST_POS                              0
+#define TFA98XX_CF_CONTROLS_RST_LEN                              1
+#define TFA98XX_CF_CONTROLS_RST_MAX                              1
+#define TFA98XX_CF_CONTROLS_RST_MSK                            0x1
+
+/*
+ * cf_dmem
+ */
+#define TFA98XX_CF_CONTROLS_DMEM                          (0x3<<1)
+#define TFA98XX_CF_CONTROLS_DMEM_POS                             1
+#define TFA98XX_CF_CONTROLS_DMEM_LEN                             2
+#define TFA98XX_CF_CONTROLS_DMEM_MAX                             3
+#define TFA98XX_CF_CONTROLS_DMEM_MSK                           0x6
+
+/*
+ * cf_aif
+ */
+#define TFA98XX_CF_CONTROLS_AIF                           (0x1<<3)
+#define TFA98XX_CF_CONTROLS_AIF_POS                              3
+#define TFA98XX_CF_CONTROLS_AIF_LEN                              1
+#define TFA98XX_CF_CONTROLS_AIF_MAX                              1
+#define TFA98XX_CF_CONTROLS_AIF_MSK                            0x8
+
+/*
+ * cf_int
+ */
+#define TFA98XX_CF_CONTROLS_CFINT                         (0x1<<4)
+#define TFA98XX_CF_CONTROLS_CFINT_POS                            4
+#define TFA98XX_CF_CONTROLS_CFINT_LEN                            1
+#define TFA98XX_CF_CONTROLS_CFINT_MAX                            1
+#define TFA98XX_CF_CONTROLS_CFINT_MSK                         0x10
+
+/*
+ * cf_cgate_off
+ */
+#define TFA98XX_CF_CONTROLS_CFCGATE                       (0x1<<5)
+#define TFA98XX_CF_CONTROLS_CFCGATE_POS                          5
+#define TFA98XX_CF_CONTROLS_CFCGATE_LEN                          1
+#define TFA98XX_CF_CONTROLS_CFCGATE_MAX                          1
+#define TFA98XX_CF_CONTROLS_CFCGATE_MSK                       0x20
+
+/*
+ * cf_req_cmd
+ */
+#define TFA98XX_CF_CONTROLS_REQCMD                        (0x1<<8)
+#define TFA98XX_CF_CONTROLS_REQCMD_POS                           8
+#define TFA98XX_CF_CONTROLS_REQCMD_LEN                           1
+#define TFA98XX_CF_CONTROLS_REQCMD_MAX                           1
+#define TFA98XX_CF_CONTROLS_REQCMD_MSK                       0x100
+
+/*
+ * cf_req_reset
+ */
+#define TFA98XX_CF_CONTROLS_REQRST                        (0x1<<9)
+#define TFA98XX_CF_CONTROLS_REQRST_POS                           9
+#define TFA98XX_CF_CONTROLS_REQRST_LEN                           1
+#define TFA98XX_CF_CONTROLS_REQRST_MAX                           1
+#define TFA98XX_CF_CONTROLS_REQRST_MSK                       0x200
+
+/*
+ * cf_req_mips
+ */
+#define TFA98XX_CF_CONTROLS_REQMIPS                      (0x1<<10)
+#define TFA98XX_CF_CONTROLS_REQMIPS_POS                         10
+#define TFA98XX_CF_CONTROLS_REQMIPS_LEN                          1
+#define TFA98XX_CF_CONTROLS_REQMIPS_MAX                          1
+#define TFA98XX_CF_CONTROLS_REQMIPS_MSK                      0x400
+
+/*
+ * cf_req_mute_ready
+ */
+#define TFA98XX_CF_CONTROLS_REQMUTED                     (0x1<<11)
+#define TFA98XX_CF_CONTROLS_REQMUTED_POS                        11
+#define TFA98XX_CF_CONTROLS_REQMUTED_LEN                         1
+#define TFA98XX_CF_CONTROLS_REQMUTED_MAX                         1
+#define TFA98XX_CF_CONTROLS_REQMUTED_MSK                     0x800
+
+/*
+ * cf_req_volume_ready
+ */
+#define TFA98XX_CF_CONTROLS_REQVOL                       (0x1<<12)
+#define TFA98XX_CF_CONTROLS_REQVOL_POS                          12
+#define TFA98XX_CF_CONTROLS_REQVOL_LEN                           1
+#define TFA98XX_CF_CONTROLS_REQVOL_MAX                           1
+#define TFA98XX_CF_CONTROLS_REQVOL_MSK                      0x1000
+
+/*
+ * cf_req_damage
+ */
+#define TFA98XX_CF_CONTROLS_REQDMG                       (0x1<<13)
+#define TFA98XX_CF_CONTROLS_REQDMG_POS                          13
+#define TFA98XX_CF_CONTROLS_REQDMG_LEN                           1
+#define TFA98XX_CF_CONTROLS_REQDMG_MAX                           1
+#define TFA98XX_CF_CONTROLS_REQDMG_MSK                      0x2000
+
+/*
+ * cf_req_calibrate_ready
+ */
+#define TFA98XX_CF_CONTROLS_REQCAL                       (0x1<<14)
+#define TFA98XX_CF_CONTROLS_REQCAL_POS                          14
+#define TFA98XX_CF_CONTROLS_REQCAL_LEN                           1
+#define TFA98XX_CF_CONTROLS_REQCAL_MAX                           1
+#define TFA98XX_CF_CONTROLS_REQCAL_MSK                      0x4000
+
+/*
+ * cf_req_reserved
+ */
+#define TFA98XX_CF_CONTROLS_REQRSV                       (0x1<<15)
+#define TFA98XX_CF_CONTROLS_REQRSV_POS                          15
+#define TFA98XX_CF_CONTROLS_REQRSV_LEN                           1
+#define TFA98XX_CF_CONTROLS_REQRSV_MAX                           1
+#define TFA98XX_CF_CONTROLS_REQRSV_MSK                      0x8000
+
+
+/*
+ * (0x91)-cf_mad
+ */
+
+/*
+ * cf_madd
+ */
+#define TFA98XX_CF_MAD_MADD                            (0xffff<<0)
+#define TFA98XX_CF_MAD_MADD_POS                                  0
+#define TFA98XX_CF_MAD_MADD_LEN                                 16
+#define TFA98XX_CF_MAD_MADD_MAX                              65535
+#define TFA98XX_CF_MAD_MADD_MSK                             0xffff
+
+
+/*
+ * (0x92)-cf_mem
+ */
+
+/*
+ * cf_mema
+ */
+#define TFA98XX_CF_MEM_MEMA                            (0xffff<<0)
+#define TFA98XX_CF_MEM_MEMA_POS                                  0
+#define TFA98XX_CF_MEM_MEMA_LEN                                 16
+#define TFA98XX_CF_MEM_MEMA_MAX                              65535
+#define TFA98XX_CF_MEM_MEMA_MSK                             0xffff
+
+
+/*
+ * (0x93)-cf_status
+ */
+
+/*
+ * cf_err
+ */
+#define TFA98XX_CF_STATUS_ERR                            (0xff<<0)
+#define TFA98XX_CF_STATUS_ERR_POS                                0
+#define TFA98XX_CF_STATUS_ERR_LEN                                8
+#define TFA98XX_CF_STATUS_ERR_MAX                              255
+#define TFA98XX_CF_STATUS_ERR_MSK                             0xff
+
+/*
+ * cf_ack_cmd
+ */
+#define TFA98XX_CF_STATUS_ACKCMD                          (0x1<<8)
+#define TFA98XX_CF_STATUS_ACKCMD_POS                             8
+#define TFA98XX_CF_STATUS_ACKCMD_LEN                             1
+#define TFA98XX_CF_STATUS_ACKCMD_MAX                             1
+#define TFA98XX_CF_STATUS_ACKCMD_MSK                         0x100
+
+/*
+ * cf_ack_reset
+ */
+#define TFA98XX_CF_STATUS_ACKRST                          (0x1<<9)
+#define TFA98XX_CF_STATUS_ACKRST_POS                             9
+#define TFA98XX_CF_STATUS_ACKRST_LEN                             1
+#define TFA98XX_CF_STATUS_ACKRST_MAX                             1
+#define TFA98XX_CF_STATUS_ACKRST_MSK                         0x200
+
+/*
+ * cf_ack_mips
+ */
+#define TFA98XX_CF_STATUS_ACKMIPS                        (0x1<<10)
+#define TFA98XX_CF_STATUS_ACKMIPS_POS                           10
+#define TFA98XX_CF_STATUS_ACKMIPS_LEN                            1
+#define TFA98XX_CF_STATUS_ACKMIPS_MAX                            1
+#define TFA98XX_CF_STATUS_ACKMIPS_MSK                        0x400
+
+/*
+ * cf_ack_mute_ready
+ */
+#define TFA98XX_CF_STATUS_ACKMUTED                       (0x1<<11)
+#define TFA98XX_CF_STATUS_ACKMUTED_POS                          11
+#define TFA98XX_CF_STATUS_ACKMUTED_LEN                           1
+#define TFA98XX_CF_STATUS_ACKMUTED_MAX                           1
+#define TFA98XX_CF_STATUS_ACKMUTED_MSK                       0x800
+
+/*
+ * cf_ack_volume_ready
+ */
+#define TFA98XX_CF_STATUS_ACKVOL                         (0x1<<12)
+#define TFA98XX_CF_STATUS_ACKVOL_POS                            12
+#define TFA98XX_CF_STATUS_ACKVOL_LEN                             1
+#define TFA98XX_CF_STATUS_ACKVOL_MAX                             1
+#define TFA98XX_CF_STATUS_ACKVOL_MSK                        0x1000
+
+/*
+ * cf_ack_damage
+ */
+#define TFA98XX_CF_STATUS_ACKDMG                         (0x1<<13)
+#define TFA98XX_CF_STATUS_ACKDMG_POS                            13
+#define TFA98XX_CF_STATUS_ACKDMG_LEN                             1
+#define TFA98XX_CF_STATUS_ACKDMG_MAX                             1
+#define TFA98XX_CF_STATUS_ACKDMG_MSK                        0x2000
+
+/*
+ * cf_ack_calibrate_ready
+ */
+#define TFA98XX_CF_STATUS_ACKCAL                         (0x1<<14)
+#define TFA98XX_CF_STATUS_ACKCAL_POS                            14
+#define TFA98XX_CF_STATUS_ACKCAL_LEN                             1
+#define TFA98XX_CF_STATUS_ACKCAL_MAX                             1
+#define TFA98XX_CF_STATUS_ACKCAL_MSK                        0x4000
+
+/*
+ * cf_ack_reserved
+ */
+#define TFA98XX_CF_STATUS_ACKRSV                         (0x1<<15)
+#define TFA98XX_CF_STATUS_ACKRSV_POS                            15
+#define TFA98XX_CF_STATUS_ACKRSV_LEN                             1
+#define TFA98XX_CF_STATUS_ACKRSV_MAX                             1
+#define TFA98XX_CF_STATUS_ACKRSV_MSK                        0x8000
+
+
+/*
+ * (0xa1)-mtpkey2_reg
+ */
+
+/*
+ * mtpkey2
+ */
+#define TFA98XX_MTPKEY2_REG_MTPK                         (0xff<<0)
+#define TFA98XX_MTPKEY2_REG_MTPK_POS                             0
+#define TFA98XX_MTPKEY2_REG_MTPK_LEN                             8
+#define TFA98XX_MTPKEY2_REG_MTPK_MAX                           255
+#define TFA98XX_MTPKEY2_REG_MTPK_MSK                          0xff
+
+
+/*
+ * (0xa2)-mtp_status
+ */
+
+/*
+ * key01_locked
+ */
+#define TFA98XX_MTP_STATUS_KEY1LOCKED                     (0x1<<0)
+#define TFA98XX_MTP_STATUS_KEY1LOCKED_POS                        0
+#define TFA98XX_MTP_STATUS_KEY1LOCKED_LEN                        1
+#define TFA98XX_MTP_STATUS_KEY1LOCKED_MAX                        1
+#define TFA98XX_MTP_STATUS_KEY1LOCKED_MSK                      0x1
+
+/*
+ * key02_locked
+ */
+#define TFA98XX_MTP_STATUS_KEY2LOCKED                     (0x1<<1)
+#define TFA98XX_MTP_STATUS_KEY2LOCKED_POS                        1
+#define TFA98XX_MTP_STATUS_KEY2LOCKED_LEN                        1
+#define TFA98XX_MTP_STATUS_KEY2LOCKED_MAX                        1
+#define TFA98XX_MTP_STATUS_KEY2LOCKED_MSK                      0x2
+
+
+/*
+ * (0xa3)-KEY_protected_mtp_control
+ */
+
+/*
+ * auto_copy_iic_to_mtp
+ */
+#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP           (0x1<<6)
+#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_POS              6
+#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_LEN              1
+#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_MAX              1
+#define TFA98XX_KEY_PROTECTED_MTP_CONTROL_CIMTP_MSK           0x40
+
+
+/*
+ * (0xa5)-mtp_data_out_msb
+ */
+
+/*
+ * mtp_man_data_out_msb
+ */
+#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB              (0xffff<<0)
+#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_POS                    0
+#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_LEN                   16
+#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_MAX                65535
+#define TFA98XX_MTP_DATA_OUT_MSB_MTPRDMSB_MSK               0xffff
+
+
+/*
+ * (0xa6)-mtp_data_out_lsb
+ */
+
+/*
+ * mtp_man_data_out_lsb
+ */
+#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB              (0xffff<<0)
+#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_POS                    0
+#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_LEN                   16
+#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_MAX                65535
+#define TFA98XX_MTP_DATA_OUT_LSB_MTPRDLSB_MSK               0xffff
+
+
+/*
+ * (0xb1)-temp_sensor_config
+ */
+
+/*
+ * ext_temp
+ */
+#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS                (0x1ff<<0)
+#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_POS                     0
+#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_LEN                     9
+#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_MAX                   511
+#define TFA98XX_TEMP_SENSOR_CONFIG_EXTTS_MSK                 0x1ff
+
+/*
+ * ext_temp_sel
+ */
+#define TFA98XX_TEMP_SENSOR_CONFIG_TROS                   (0x1<<9)
+#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_POS                      9
+#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_LEN                      1
+#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_MAX                      1
+#define TFA98XX_TEMP_SENSOR_CONFIG_TROS_MSK                  0x200
+
+
+/*
+ * (0xf0)-KEY2_protected_MTP0
+ */
+
+/*
+ * calibration_onetime
+ */
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC                (0x1<<0)
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS                   0
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_LEN                   1
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MAX                   1
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK                 0x1
+
+/*
+ * calibr_ron_done
+ */
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX                 (0x1<<1)
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS                    1
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_LEN                    1
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MAX                    1
+#define TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK                  0x2
+
+/*
+ * calibr_dcdc_api_calibrate
+ */
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI              (0x1<<2)
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_POS                 2
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_LEN                 1
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_MAX                 1
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCAPI_MSK               0x4
+
+/*
+ * calibr_dcdc_delta_sign
+ */
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB               (0x1<<3)
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_POS                  3
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_LEN                  1
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_MAX                  1
+#define TFA98XX_KEY2_PROTECTED_MTP0_DCMCCSB_MSK                0x8
+
+/*
+ * calibr_dcdc_delta
+ */
+#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF               (0x7<<4)
+#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_POS                  4
+#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_LEN                  3
+#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_MAX                  7
+#define TFA98XX_KEY2_PROTECTED_MTP0_USERDEF_MSK               0x70
+
+
+/*
+ * (0xf4)-KEY1_protected_MTP4
+ */
+
+
+/*
+ * (0xf5)-KEY1_protected_MTP5
+ */
+
+#endif /* TFA98XX_GENREGS_H */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_parameters.h b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_parameters.h
new file mode 100644
index 0000000..5ab6d28
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_parameters.h
@@ -0,0 +1,754 @@
+/*
+ * tfa98xx_parameters.h
+ *
+ *  Created on: Jul 22, 2013
+ *      Author: NLV02095
+ */
+
+#ifndef TFA98XXPARAMETERS_H_
+#define TFA98XXPARAMETERS_H_
+
+//#include "config.h"
+// workaround for Visual Studio: 
+// fatal error C1083: Cannot open include file: 'config.h': No such file or directory
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#include "tfa_service.h"
+
+#if (defined(WIN32) || defined(_X64))
+/* These warnings are disabled because it is only given by Windows and there is no easy fix */
+#pragma warning(disable:4200)
+#pragma warning(disable:4214)
+#endif
+
+/*
+ * profiles & volumesteps
+ *
+ */
+#define TFA_MAX_PROFILES                (64)
+#define TFA_MAX_VSTEPS                  (64)
+#define TFA_MAX_VSTEP_MSG_MARKER        (100) /* This marker  is used to indicate if all msgs need to be written to the device */
+#define TFA_MAX_MSGS                    (10)
+
+// the pack pragma is required to make that the size in memory
+// matches the actual variable lenghts
+// This is to assure that the binary files can be transported between
+// different platforms.
+#pragma pack (push, 1)
+
+/*
+ * typedef for 24 bit value using 3 bytes
+ */
+typedef struct uint24 {
+  uint8_t b[3];
+} uint24_t;
+/*
+ * the generic header
+ *   all char types are in ASCII
+ */
+typedef struct nxpTfaHeader {
+	uint16_t id;
+    char version[2];     // "V_" : V=version, vv=subversion
+    char subversion[2];  // "vv" : vv=subversion
+    uint16_t size;       // data size in bytes following CRC
+    uint32_t CRC;        // 32-bits CRC for following data
+    char customer[8];    // “name of customer”
+    char application[8]; // “application name”
+    char type[8];		 // “application type name”
+} nxpTfaHeader_t;
+
+typedef enum nxpTfaSamplerate {
+	fs_8k,       // 8kHz
+	fs_11k025,   // 11.025kHz
+	fs_12k,      // 12kHz
+	fs_16k,      // 16kHz
+	fs_22k05,    // 22.05kHz
+	fs_24k,      // 24kHz
+	fs_32k,      // 32kHz
+	fs_44k1,     // 44.1kHz
+	fs_48k,      // 48kHz
+	fs_96k       // 96kHz
+} nxpTfaSamplerate_t;
+
+/*
+ * coolflux direct memory access
+ */
+typedef struct nxpTfaDspMem {
+	uint8_t  type;            /* 0--3: p, x, y, iomem */
+	uint16_t address;		/* target address */
+	uint8_t size; 				/* data size in words */
+	int words[]; 				/* payload  in signed 32bit integer (two's complement) */
+} nxpTfaDspMem_t;
+
+/*
+ * the biquad coefficients for the API together with index in filter
+ *  the biquad_index is the actual index in the equalizer +1
+ */
+#define BIQUAD_COEFF_SIZE       6
+
+/*
+* Output fixed point coeffs structure
+*/
+typedef struct {
+	int a2;
+	int a1;	
+	int b2;	
+	int b1;	
+	int b0;	
+}nxpTfaBiquad_t;
+
+typedef struct nxpTfaBiquadOld {
+  uint8_t bytes[BIQUAD_COEFF_SIZE*sizeof(uint24_t)];
+}nxpTfaBiquadOld_t;
+
+typedef struct nxpTfaBiquadFloat {
+  float headroom;
+  float b0;
+  float b1;
+  float b2;
+  float a1;
+  float a2;
+} nxpTfaBiquadFloat_t;
+
+/*
+* EQ filter definitions
+*/
+typedef enum nxpTfaFilterType {
+       fFlat,           //Vary only gain
+       fLowpass,        //2nd order Butterworth low pass
+       fHighpass,       //2nd order Butterworth high pass
+       fLowshelf,
+       fHighshelf,
+       fNotch,
+       fPeak,
+       fBandpass,
+       f1stLP,
+       f1stHP,
+       fElliptic
+} nxpTfaFilterType_t;
+
+/*
+ * filter parameters for biquad (re-)calculation
+ */
+typedef struct nxpTfaFilter {
+  nxpTfaBiquadOld_t biquad;
+  uint8_t enabled;
+  uint8_t type; // (== enum FilterTypes, assure 8bits length)
+  float frequency;
+  float Q;
+  float gain;
+} nxpTfaFilter_t ;  //8 * float + int32 + byte == 37
+
+/* 
+ * biquad params for calculation
+*/
+
+#define TFA_BQ_EQ_INDEX 0
+#define TFA_BQ_ANTI_ALIAS_INDEX 10
+#define TFA_BQ_INTEGRATOR_INDEX 13
+
+/*
+* Loudspeaker Compensation filter definitions
+*/
+typedef struct nxpTfaLsCompensationFilter {
+  nxpTfaBiquad_t biquad;
+  uint8_t lsCompOn;  //      Loudspeaker compensation on/off; when 'off', the DSP code doesn't apply the bwExt => bwExtOn GUI flag should be gray to avoid confusion
+  uint8_t bwExtOn;   //      Bandwidth extension on/off
+  float fRes;        // [Hz] speaker resonance frequency
+  float Qt;          //      speaker resonance Q-factor
+  float fBwExt;      // [Hz] Band width extension frequency
+  float samplingFreq;// [Hz] Sampling frequency
+} nxpTfaLsCompensationFilter_t;
+
+/*
+* Anti Aliasing Elliptic filter definitions
+*/
+typedef struct nxpTfaAntiAliasFilter {
+  nxpTfaBiquad_t biquad;	/**< Output results fixed point coeffs */
+  uint8_t enabled;
+  float cutOffFreq;   // cut off frequency
+  float samplingFreq; // sampling frequency
+  float rippleDb;     // range: [0.1 3.0]
+  float rolloff;      // range: [-1.0 1.0]
+} nxpTfaAntiAliasFilter_t;
+
+/**
+* Integrator filter input definitions
+*/
+typedef struct nxpTfaIntegratorFilter {
+  nxpTfaBiquad_t biquad; /**< Output results fixed point coeffs */
+  uint8_t type;             /**< Butterworth filter type: high or low pass */
+  float  cutOffFreq;        /**< cut off frequency in Hertz; range: [100.0 4000.0] */
+  float  samplingFreq;      /**< sampling frequency in Hertz */
+  float  leakage;           /**< leakage factor; range [0.0 1.0] */
+} nxpTfaIntegratorFilter_t;
+
+
+typedef struct nxpTfaEqFilter {
+  nxpTfaBiquad_t biquad;
+  uint8_t enabled;
+  uint8_t type;       // (== enum FilterTypes, assure 8bits length)
+  float cutOffFreq;   // cut off frequency, // range: [100.0 4000.0]
+  float samplingFreq; // sampling frequency
+  float Q;            // range: [0.5 5.0]
+  float gainDb;       // range: [-10.0 10.0]
+} nxpTfaEqFilter_t ;  //8 * float + int32 + byte == 37
+
+typedef struct nxpTfaContAntiAlias {
+	int8_t index; 	/**< index determines destination type; anti-alias, integrator,eq */
+	uint8_t type;
+	float cutOffFreq;   // cut off frequency
+	float samplingFreq;
+	float rippleDb;     // integrator leakage
+	float rolloff;
+	uint8_t bytes[5*3];	// payload 5*24buts coeffs
+}nxpTfaContAntiAlias_t;
+
+typedef struct nxpTfaContIntegrator {
+	int8_t index; 	/**< index determines destination type; anti-alias, integrator,eq */
+	uint8_t type;
+	float cutOffFreq;   // cut off frequency
+	float samplingFreq;
+	float leakage;     // integrator leakage
+	float reserved;
+	uint8_t bytes[5*3];	// payload 5*24buts coeffs
+}nxpTfaContIntegrator_t;
+typedef struct nxpTfaContEq {
+  int8_t index;
+  uint8_t type;       // (== enum FilterTypes, assure 8bits length)
+  float cutOffFreq;   // cut off frequency, // range: [100.0 4000.0]
+  float samplingFreq; // sampling frequency
+  float Q;            // range: [0.5 5.0]
+  float gainDb;       // range: [-10.0 10.0]
+  uint8_t bytes[5*3];	// payload 5*24buts coeffs
+} nxpTfaContEq_t ;  //8 * float + int32 + byte == 37
+
+typedef union nxpTfaContBiquad {
+	nxpTfaContEq_t eq;
+	nxpTfaContAntiAlias_t aa;
+	nxpTfaContIntegrator_t in;
+}nxpTfaContBiquad_t;
+
+#define TFA_BQ_EQ_INDEX 0
+#define TFA_BQ_ANTI_ALIAS_INDEX 10
+#define TFA_BQ_INTEGRATOR_INDEX 13
+
+#define TFA98XX_MAX_EQ 10
+typedef struct nxpTfaEqualizer {
+  nxpTfaFilter_t filter[TFA98XX_MAX_EQ];// note: API index counts from 1..10
+} nxpTfaEqualizer_t;
+
+/*
+ * files
+ */
+#define HDR(c1,c2) (c2<<8|c1) // little endian
+typedef enum nxpTfaHeaderType {
+    paramsHdr		= HDR('P','M'), /* containter file */
+    volstepHdr	 	= HDR('V','P'),
+    patchHdr	 	= HDR('P','A'),
+    speakerHdr	 	= HDR('S','P'),
+    presetHdr	 	= HDR('P','R'),
+    configHdr	 	= HDR('C','O'),
+    equalizerHdr	= HDR('E','Q'),
+    drcHdr		= HDR('D','R'),
+    msgHdr		= HDR('M','G'),	/* generic message */
+    infoHdr		= HDR('I','N')
+} nxpTfaHeaderType_t;
+
+/*
+ * equalizer file
+ */
+#define NXPTFA_EQ_VERSION    '1'
+#define NXPTFA_EQ_SUBVERSION "00"
+typedef struct nxpTfaEqualizerFile {
+	nxpTfaHeader_t hdr;
+	uint8_t samplerate; 				 // ==enum samplerates, assure 8 bits
+    nxpTfaFilter_t filter[TFA98XX_MAX_EQ];// note: API index counts from 1..10
+} nxpTfaEqualizerFile_t;
+
+/*
+ * patch file
+ */
+#define NXPTFA_PA_VERSION    '1'
+#define NXPTFA_PA_SUBVERSION "00"
+typedef struct nxpTfaPatchFile {
+	nxpTfaHeader_t hdr;
+	uint8_t data[];
+} nxpTfaPatch_t;
+
+/*
+ * generic message file
+ *   -  the payload of this file includes the opcode and is send straight to the DSP
+ */
+#define NXPTFA_MG_VERSION    '3'
+#define NXPTFA_MG_SUBVERSION "00"
+typedef struct nxpTfaMsgFile {
+	nxpTfaHeader_t hdr;
+	uint8_t data[];
+} nxpTfaMsgFile_t;
+
+/*
+ * NOTE the tfa98xx API defines the enum Tfa98xx_config_type that defines
+ *          the subtypes as decribes below.
+ *          tfa98xx_dsp_config_parameter_type() can be used to get the
+ *           supported type for the active device..
+ */
+/*
+ * config file V1 sub 1
+ */
+#define NXPTFA_CO_VERSION    '1'
+#define NXPTFA_CO3_VERSION   '3'
+#define NXPTFA_CO_SUBVERSION1 "01"
+typedef struct nxpTfaConfigS1File {
+	nxpTfaHeader_t hdr;
+	uint8_t data[55*3];
+} nxpTfaConfigS1_t;
+/*
+ * config file V1 sub 2
+ */
+#define NXPTFA_CO_SUBVERSION2 "02"
+typedef struct nxpTfaConfigS2File {
+	nxpTfaHeader_t hdr;
+	uint8_t data[67*3];
+} nxpTfaConfigS2_t;
+/*
+ * config file V1 sub 3
+ */
+#define NXPTFA_CO_SUBVERSION3 "03"
+typedef struct nxpTfaConfigS3File {
+	nxpTfaHeader_t hdr;
+	uint8_t data[67*3];
+} nxpTfaConfigS3_t;
+
+/*
+ * config file V1.0
+ */
+#define NXPTFA_CO_SUBVERSION "00"
+typedef struct nxpTfaConfigFile {
+	nxpTfaHeader_t hdr;
+	uint8_t data[];
+} nxpTfaConfig_t;
+
+/*
+ * preset file
+ */
+#define NXPTFA_PR_VERSION    '1'
+#define NXPTFA_PR_SUBVERSION "00"
+
+typedef struct nxpTfaPresetFile {
+	nxpTfaHeader_t hdr;
+	uint8_t data[];
+} nxpTfaPreset_t;
+/*
+ * drc file
+ */
+#define NXPTFA_DR_VERSION    '1'
+#define NXPTFA_DR_SUBVERSION "00"
+typedef struct nxpTfaDrcFile {
+	nxpTfaHeader_t hdr;
+	uint8_t data[];
+} nxpTfaDrc_t;
+
+/*
+ * drc file
+ * for tfa 2 there is also a xml-version
+ */
+#define NXPTFA_DR3_VERSION    '3'
+#define NXPTFA_DR3_SUBVERSION "00"
+typedef struct nxpTfaDrcFile2 {
+	nxpTfaHeader_t hdr;
+	uint8_t version[3];
+	uint8_t data[];
+} nxpTfaDrc2_t;
+
+
+/*
+ * volume step structures
+ */
+// VP01
+#define NXPTFA_VP1_VERSION    '1'
+#define NXPTFA_VP1_SUBVERSION "01"
+typedef struct nxpTfaVolumeStep1 {
+    float attenuation;              // IEEE single float
+    uint8_t preset[TFA98XX_PRESET_LENGTH];
+} nxpTfaVolumeStep1_t;
+
+// VP02
+#define NXPTFA_VP2_VERSION    '2'
+#define NXPTFA_VP2_SUBVERSION "01"
+typedef struct nxpTfaVolumeStep2 {
+    float attenuation;              // IEEE single float
+    uint8_t preset[TFA98XX_PRESET_LENGTH];
+    nxpTfaFilter_t filter[TFA98XX_MAX_EQ];// note: API index counts from 1..10
+} nxpTfaVolumeStep2_t;
+
+// VP03 is obsolete
+
+// VP04
+/** obsolete -DRC is now a different file
+#define NXPTFA_VP4_VERSION    "4"
+#define NXPTFA_VP4_SUBVERSION "01"
+typedef struct nxpTfaVolumeStep4 {
+    float attenuation;              // IEEE single float
+    uint8_t preset[TFA98XX_PRESET_LENGTH];
+    nxpTfaEqualizer_t eq;
+#if (defined(TFA9887B) || defined(TFA98XX_FULL))
+    uint8_t drc[TFA98XX_DRC_LENGTH];
+#endif
+} nxpTfaVolumeStep4_t;
+**/
+/*
+ * volumestep file
+ */
+#define NXPTFA_VP_VERSION    '1'
+#define NXPTFA_VP_SUBVERSION "00"
+typedef struct nxpTfaVolumeStepFile {
+	nxpTfaHeader_t hdr;
+	uint8_t vsteps;  	// can also be calulated from size+type
+	uint8_t samplerate; // ==enum samplerates, assure 8 bits
+	uint8_t payload; 	//start of variable length contents:N times volsteps
+}nxpTfaVolumeStepFile_t;
+/*
+ * volumestep2 file
+ */
+typedef struct nxpTfaVolumeStep2File {
+	nxpTfaHeader_t hdr;
+	uint8_t vsteps;  	// can also be calulated from size+type
+	uint8_t samplerate; // ==enum samplerates, assure 8 bits
+	nxpTfaVolumeStep2_t vstep[]; 	//start of variable length contents:N times volsteps
+}nxpTfaVolumeStep2File_t;
+
+/*
+ * volumestepMax2 file
+ */
+typedef struct nxpTfaVolumeStepMax2File {
+	nxpTfaHeader_t hdr;
+	uint8_t version[3]; 
+	uint8_t NrOfVsteps;
+	uint8_t vstepsBin[]; 
+}nxpTfaVolumeStepMax2File_t;
+
+/*
+ * volumestepMax2 file
+ * This volumestep should ONLY be used for the use of bin2hdr!
+ * This can only be used to find the messagetype of the vstep (without header)
+ */
+typedef struct nxpTfaVolumeStepMax2_1File {
+	uint8_t version[3]; 
+	uint8_t NrOfVsteps;
+	uint8_t vstepsBin[]; 
+}nxpTfaVolumeStepMax2_1File_t;
+
+struct nxpTfaVolumeStepRegisterInfo {
+	uint8_t NrOfRegisters;
+	uint16_t registerInfo[];
+};
+
+struct nxpTfaVolumeStepMessageInfo {
+	uint8_t NrOfMessages;
+	uint8_t MessageType;
+	uint24_t MessageLength;
+	uint8_t CmdId[3];
+	uint8_t ParameterData[];
+};
+/**************************old v2 *************************************************/
+
+/*
+ * subv 00 volumestep file
+ */
+typedef struct nxpTfaOldHeader {
+	uint16_t id;
+	char version[2];     // "V_" : V=version, vv=subversion
+	char subversion[2];  // "vv" : vv=subversion
+	uint16_t size;       // data size in bytes following CRC
+	uint32_t CRC;        // 32-bits CRC for following data
+} nxpTfaOldHeader_t;
+
+typedef struct nxpOldTfaFilter {
+  double bq[5];
+  int32_t type;
+  double frequency;
+  double Q;
+  double gain;
+  uint8_t enabled;
+} nxpTfaOldFilter_t ;  //8 * float + int32 + byte == 37
+typedef struct nxpTfaOldVolumeStep2 {
+    float attenuation;              // IEEE single float
+    uint8_t preset[TFA98XX_PRESET_LENGTH];
+    nxpTfaOldFilter_t eq[10];
+} nxpTfaOldVolumeStep2_t;
+typedef struct nxpTfaOldVolumeStepFile {
+	nxpTfaOldHeader_t hdr;
+	nxpTfaOldVolumeStep2_t step[];
+//	uint8_t payload; 	//start of variable length contents:N times volsteps
+
+}nxpTfaOldVolumeStep2File_t;
+/**************************end old v2 *************************************************/
+
+/*
+ * speaker file header
+ */
+struct nxpTfaSpkHeader {
+	struct nxpTfaHeader hdr;
+	char name[8];				// speaker nick name (e.g. “dumbo”)
+	char vendor[16];
+	char type[8];
+	//	dimensions (mm)
+	uint8_t height;
+	uint8_t width;
+	uint8_t depth;
+	uint16_t ohm;
+};
+
+
+/*
+ * speaker file
+ */
+#define NXPTFA_SP_VERSION    '1'
+#define NXPTFA_SP_SUBVERSION "00"
+typedef struct nxpTfaSpeakerFile {
+	nxpTfaHeader_t hdr;
+	char name[8];				// speaker nick name (e.g. “dumbo”)
+	char vendor[16];
+	char type[8];
+	//	dimensions (mm)
+	uint8_t height;
+	uint8_t width;
+	uint8_t depth;
+	uint8_t ohm_primary;
+	uint8_t ohm_secondary;
+	uint8_t data[]; //payload TFA98XX_SPEAKERPARAMETER_LENGTH
+} nxpTfaSpeakerFile_t;
+
+#if ( defined( TFA9888 ) || defined( TFA98XX_FULL ))
+
+#define NXPTFA_VP3_VERSION    '3'
+#define NXPTFA_VP3_SUBVERSION "00"
+
+struct nxpTfaFWVer {
+	uint8_t Major;
+	uint8_t minor;
+	uint8_t minor_update:6;
+	uint8_t Update:2;
+}; 
+
+struct nxpTfaCmdID {
+	int a;
+	//uint16_t a:8;
+	//uint16_t b:8;
+	//uint16_t c:8;
+}; 
+
+struct nxpTfaFWMsg {
+	struct nxpTfaFWVer fwVersion;
+	struct nxpTfaMsg payload;
+};
+
+typedef struct nxpTfaLiveData {
+	uint8_t liveData_size;
+        char name[25];
+	char addrs[25];
+        int tracker;
+	int scalefactor[MEMTRACK_MAX_WORDS];
+} nxpTfaLiveData_t;
+
+#define NXPTFA_SP3_VERSION  '3'
+#define NXPTFA_SP3_SUBVERSION "00"
+struct nxpTfaSpeakerFileMax2 {
+	nxpTfaHeader_t hdr;
+	char name[8];				// speaker nick name (e.g. “dumbo”)
+	char vendor[16];
+	char type[8];
+	//	dimensions (mm)
+	uint8_t height;
+	uint8_t width;
+	uint8_t depth;
+	uint8_t ohm_primary;
+	uint8_t ohm_secondary;
+	struct nxpTfaFWMsg FWmsg; //payload including FW ver and Cmd ID
+};
+#endif
+
+/*
+ * parameter container file
+ */
+/*
+ * descriptors
+ */
+typedef enum nxpTfaDescriptorType {
+	dscDevice,		// device list
+	dscProfile,		// profile list
+	dscRegister,	        // register patch
+	dscString,		// ascii, zero terminated string
+	dscFile,		// filename + file contents
+	dscPatch,               // patch file
+	dscMarker,		// marker to indicate end of a list
+	dscMode,
+#if 1 // TODO: remove me?
+	dscSetInputSelect,
+	dscSetOutputSelect,
+	dscSetProgramConfig,
+	dscSetLagW,
+	dscSetGains,
+	dscSetvBatFactors,
+	dscSetSensesCal,
+	dscSetSensesDelay,
+#endif
+	dscBitfield,
+	dscDefault,             // used to reset bitfields to there default values
+	dscLiveData,
+	dscLiveDataString,
+	dscGroup,
+	dscCmd,
+#if 1 // TODO: remove me?
+	dscSetMBDrc,
+#endif
+	dscFilter,
+	dscNoInit,
+        dscFeatures,
+	dscCfMem, // coolflux memory x,y,io
+	dsc_last	// trailer
+} nxpTfaDescriptorType_t;
+
+#define TFA_BITFIELDDSCMSK 0x7fffffff
+
+typedef struct nxpTfaDescPtr {
+	uint32_t offset:24;
+	uint32_t  type:8; // (== enum nxpTfaDescriptorType, assure 8bits length)
+}nxpTfaDescPtr_t;
+
+/*
+ * generic file descriptor
+ */
+typedef struct nxpTfaFileDsc {
+	nxpTfaDescPtr_t name;
+	uint32_t size;	// file data length in bytes
+	uint8_t data[]; //payload
+} nxpTfaFileDsc_t;
+
+
+/*
+ * device descriptor list
+ */
+typedef struct nxpTfaDeviceList {
+	uint8_t length;			// nr of items in the list
+	uint8_t bus;			// bus
+	uint8_t dev;			// device
+	uint8_t func;			// subfunction or subdevice
+	uint32_t devid;		        // device  hw fw id
+	nxpTfaDescPtr_t name;	        // device name
+	nxpTfaDescPtr_t list[];	        // items list
+} nxpTfaDeviceList_t;
+
+/*
+ * profile descriptor list
+ */
+typedef struct nxpTfaProfileList {
+	uint32_t length:8;		// nr of items in the list + name
+	uint32_t group:8;		// profile group number
+	uint32_t ID:16;			// profile ID
+	nxpTfaDescPtr_t name;	        // profile name
+	nxpTfaDescPtr_t list[];	        // items list (lenght-1 items)
+} nxpTfaProfileList_t;
+#define TFA_PROFID 0x1234
+
+/*
+ * livedata descriptor list
+ */
+typedef struct nxpTfaLiveDataList {
+	uint32_t length:8;		// nr of items in the list
+	uint32_t ID:24;			// profile ID
+	nxpTfaDescPtr_t name;	        // livedata name
+	nxpTfaDescPtr_t list[];	        // items list
+} nxpTfaLiveDataList_t;
+#define TFA_LIVEDATAID 0x5678
+
+/*
+ * Bitfield descriptor
+ */
+typedef struct nxpTfaBitfield {
+	uint16_t  value;
+	uint16_t  field; // ==datasheet defined, 16 bits
+} nxpTfaBitfield_t;
+
+/*
+ * Bitfield enumuration bits descriptor
+ */
+typedef struct nxpTfaBfEnum {
+	unsigned int  len:4;		// this is the actual length-1
+	unsigned int  pos:4;
+	unsigned int  address:8;
+} nxpTfaBfEnum_t;
+
+/*
+ * Register patch descriptor
+ */
+typedef struct nxpTfaRegpatch {
+	uint8_t   address;	// register address
+	uint16_t  value;	// value to write
+	uint16_t  mask;		// mask of bits to write
+} nxpTfaRegpatch_t;
+
+/*
+ * Mode descriptor
+ */
+typedef struct nxpTfaUseCase {
+	int value;	// mode value, maps to enum Tfa98xx_Mode
+} nxpTfaMode_t;
+
+/*
+ * NoInit descriptor
+ */
+typedef struct nxpTfaNoInit {
+	uint8_t value;	// noInit value
+} nxpTfaNoInit_t;
+
+/*
+ * Features descriptor
+ */
+typedef struct nxpTfaFeatures {
+	uint16_t value[3];	// features value
+} nxpTfaFeatures_t;
+
+typedef struct nxpTfaCmd {
+	uint16_t id;
+	unsigned char value[3];
+} nxpTfaCmd_t;
+
+/*
+ * the container file
+ *   - the size field is 32bits long (generic=16)
+ *   - all char types are in ASCII
+ */
+#define NXPTFA_PM_VERSION  '1'
+#define NXPTFA_PM3_VERSION '3'
+#define NXPTFA_PM_SUBVERSION '1'
+typedef struct nxpTfaContainer {
+    char id[2];          // "XX" : XX=type
+    char version[2];     // "V_" : V=version, vv=subversion
+    char subversion[2];  // "vv" : vv=subversion
+    uint32_t size;       // data size in bytes following CRC
+    uint32_t CRC;        // 32-bits CRC for following data
+    uint16_t rev;		 // "extra chars for rev nr"
+    char customer[8];    // “name of customer”
+    char application[8]; // “application name”
+    char type[8];		 // “application type name”
+    uint16_t ndev;	 	 // "nr of device lists"
+    uint16_t nprof;	 	 // "nr of profile lists"
+    uint16_t nliveData;          // "nr of livedata lists"
+    nxpTfaDescPtr_t index[]; // start of item index table
+} nxpTfaContainer_t;
+
+
+#pragma pack (pop)
+
+/*
+ * bitfield enums (generated from tfa9890)
+ */
+
+
+#endif /* TFA98XXPARAMETERS_H_ */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_tfafieldnames.h b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_tfafieldnames.h
new file mode 100644
index 0000000..8e55f39
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa98xx_tfafieldnames.h
@@ -0,0 +1,90 @@
+
+typedef struct TfaBfName {
+   unsigned short bfEnum;
+   char  *bfName;
+} tfaBfName_t;
+
+typedef struct TfaIrqName {
+	unsigned short irqEnum;
+	char  *irqName;
+} tfaIrqName_t;
+
+#include "tfa1_tfafieldnames.h"
+#include "tfa2_tfafieldnames_N1C.h"
+/* diffs for specific devices */
+#include "tfa9887_tfafieldnames.h"
+#include "tfa9890_tfafieldnames.h"
+#include "tfa9891_tfafieldnames.h"
+
+/* missing 'common' defs break the build but unused in TFA1 context */
+#define TFA1_BF_AMPINSEL -1
+#define TFA1_BF_MANSCONF -1
+#define TFA1_BF_MANCOLD  -1
+#define TFA1_BF_INTSMUTE -1
+#define TFA1_BF_CFSMR    -1
+#define TFA1_BF_CFSML    -1
+#define TFA1_BF_DCMCCAPI -1
+#define TFA1_BF_DCMCCSB  -1
+#define TFA1_BF_USERDEF  -1
+#define TFA1_BF_MANSTATE -1
+#define TFA1_BF_MANOPER  -1
+#define TFA1_BF_REFCKSEL -1
+#define TFA1_BF_VOLSEC	 -1
+#define TFA1_BF_FRACTDEL -1
+#define TFA1_BF_ACKDMG	 -1
+#define TFA1_BF_SSRIGHTE -1
+#define TFA1_BF_SSLEFTE	 -1
+#define TFA1_BF_SWPROFIL 0x8045    /*!< profile save   */
+#define TFA1_BF_SWVSTEP  0x80a5    /*!< vstep save  */
+
+/* missing 'common' defs break the build but unused in TFA2 context */
+#define TFA2_BF_CFSM	-1
+
+
+/* MTP access uses registers
+ *  defs are derived from corresponding bitfield names as used in the BF macros
+ */
+#define MTPKEY2  	MTPK		/* unlock key2 MTPK */
+#define MTP0     	MTPOTC 	/* MTP data */
+#define MTP_CONTROL CIMTP	/* copy i2c to mtp */
+
+/* interrupt enable register uses HW name in TFA2 */
+#define TFA2_BF_INTENVDDS TFA2_BF_IEVDDS
+
+
+/* interrupt bit field names of TFA2 and TFA1 do not match */
+#define TFA1_BF_IEACS TFA1_BF_INTENACS
+#define TFA1_BF_IPOACS TFA1_BF_INTPOLACS
+#define TFA1_BF_ISTACS TFA1_BF_INTOACS
+#define TFA1_BF_ISTVDDS TFA1_BF_INTOVDDS
+#define TFA1_BF_ICLVDDS TFA1_BF_INTIVDDS
+#define TFA1_BF_IPOVDDS TFA1_BF_INTPOLVDDS
+#define TFA1_BF_IENOCLK TFA1_BF_INTENNOCLK
+#define TFA1_BF_ISTNOCLK TFA1_BF_INTONOCLK
+#define TFA1_BF_IPONOCLK TFA1_BF_INTPOLNOCLK
+
+/* interrupt bit fields not available on TFA1 */
+#define TFA1_BF_IECLKOOR -1
+#define TFA1_BF_ISTCLKOOR -1
+#define TFA1_BF_IEMWSRC -1
+#define TFA1_BF_ISTMWSRC -1
+#define TFA1_BF_IPOMWSRC -1
+#define TFA1_BF_IEMWSMU -1
+#define TFA1_BF_ISTMWSMU -1
+#define TFA1_BF_IPOMWSMU -1
+#define TFA1_BF_IEMWCFC -1
+#define TFA1_BF_ISTMWCFC -1
+#define TFA1_BF_IPOMWCFC -1
+#define TFA1_BF_CLKOOR -1
+#define TFA1_BF_MANWAIT1 -1
+#define TFA1_BF_MANWAIT2 -1
+#define TFA1_BF_MANMUTE -1
+#define TFA1_BF_IPCLKOOR -1
+#define TFA1_BF_ICLCLKOOR -1
+#define TFA1_BF_IPOSWS -1
+#define TFA1_BF_IESWS -1
+#define TFA1_BF_ISTSWS -1
+#define TFA1_BF_IESPKS -1
+#define TFA1_BF_ISTSPKS -1
+#define TFA1_BF_IPOSPKS -1
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_container.c b/techpack/audio/asoc/codecs/tfa98xx/tfa_container.c
new file mode 100644
index 0000000..85aa842
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_container.c
@@ -0,0 +1,2125 @@
+/*
+ *Copyright 2014 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *            
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *             
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+
+#include "tfa_service.h"
+#include "tfa_container.h"
+#include "config.h"
+#include "tfa.h"
+#include "tfa_dsp_fw.h"
+#include "tfa98xx_tfafieldnames.h"
+
+/* module globals */
+static int tfa98xx_cnt_verbose;
+
+static nxpTfaContainer_t *g_cont=NULL; /* container file */
+static int g_devs=-1; // nr of devices TODO use direct access to cont?
+static nxpTfaDeviceList_t *g_dev[TFACONT_MAXDEVS];
+static int g_profs[TFACONT_MAXDEVS];
+static int g_liveds[TFACONT_MAXDEVS];
+static nxpTfaProfileList_t  *g_prof[TFACONT_MAXDEVS][TFACONT_MAXPROFS];
+static nxpTfaLiveDataList_t  *g_lived[TFACONT_MAXDEVS][TFACONT_MAXPROFS];
+static int nxp_tfa_vstep[TFACONT_MAXDEVS];
+static char errorname[] = "!ERROR!";
+static char nonename[] = "NONE";
+
+static void cont_get_devs(nxpTfaContainer_t *cont);
+
+static int float_to_int(uint32_t x)
+{
+	unsigned e = (0x7F + 31) - ((*(unsigned *) &x & 0x7F800000) >> 23);
+	unsigned m = 0x80000000 | (*(unsigned *) &x << 8);
+	return -(int)((m >> e) & -(e < 32));
+}
+
+/*
+ * check the container file and set module global
+*/
+enum tfa_error tfa_load_cnt(void *cnt, int length) {
+	nxpTfaContainer_t  *cntbuf = (nxpTfaContainer_t  *)cnt;
+
+	g_cont = NULL;
+
+	if (length > TFA_MAX_CNT_LENGTH) {
+		pr_err("incorrect length\n");
+		return tfa_error_container;
+	}
+
+	if (HDR(cntbuf->id[0],cntbuf->id[1]) == 0) {
+		pr_err("header is 0\n");
+		return tfa_error_container;
+	}
+
+	if ( (HDR(cntbuf->id[0],cntbuf->id[1])) != paramsHdr ) {
+		pr_err("wrong header type: 0x%02x 0x%02x\n", cntbuf->id[0],cntbuf->id[1]);
+		return tfa_error_container;
+	}
+
+	if (cntbuf->size == 0) {
+		pr_err("data size is 0\n");
+		return tfa_error_container;
+	}
+
+	/* check CRC */
+	if ( tfaContCrcCheckContainer(cntbuf)) {
+		pr_err("CRC error\n");
+		return tfa_error_container;
+	}
+
+	/* check sub version level */
+	if ( (cntbuf->subversion[1] == NXPTFA_PM_SUBVERSION) &&
+		 (cntbuf->subversion[0] == '0') ) {
+		g_cont = cntbuf;
+		cont_get_devs(g_cont);
+	} else {
+		pr_err("container sub-version not supported: %c%c\n",
+				cntbuf->subversion[0], cntbuf->subversion[1]);
+		return tfa_error_container;
+	}
+
+	return tfa_error_ok;
+}
+
+void tfa_deinit(void)
+{
+	g_cont = NULL;
+	g_devs = -1;
+}
+
+/*
+ * Set the debug option
+ */
+void tfa_cnt_verbose(int level) {
+	tfa98xx_cnt_verbose = level;
+}
+
+/* start count from 1, 0 is invalid */
+void tfaContSetCurrentVstep(int channel, int vstep_idx) {
+	if( channel<TFACONT_MAXDEVS)
+		nxp_tfa_vstep[channel] = vstep_idx+1;
+	else
+		pr_err("channel nr %d>%d\n", channel, TFACONT_MAXDEVS-1);
+}
+
+/* start count from 1, 0 is invalid */
+int tfaContGetCurrentVstep(int channel) {
+	if( channel<TFACONT_MAXDEVS)
+		return nxp_tfa_vstep[channel]-1;
+
+	pr_err("channel nr %d>%d\n", channel, TFACONT_MAXDEVS-1);
+	return -1;
+}
+
+nxpTfaContainer_t * tfa98xx_get_cnt(void) {
+	return g_cont;
+}
+
+/*
+ * Dump the contents of the file header
+ */
+void tfaContShowHeader(nxpTfaHeader_t *hdr) {
+	char _id[2];
+
+	pr_debug("File header\n");
+
+	_id[1] = hdr->id >> 8;
+	_id[0] = hdr->id & 0xff;
+	pr_debug("\tid:%.2s version:%.2s subversion:%.2s\n", _id,
+		   hdr->version, hdr->subversion);
+	pr_debug("\tsize:%d CRC:0x%08x \n", hdr->size, hdr->CRC);
+	pr_debug( "\tcustomer:%.8s application:%.8s type:%.8s\n", hdr->customer,
+			   hdr->application, hdr->type);
+}
+
+/*
+ * return device list dsc from index
+ */
+nxpTfaDeviceList_t *tfaContGetDevList(nxpTfaContainer_t * cont, int dev_idx)
+{
+	uint8_t *base = (uint8_t *) cont;
+
+	if ( (dev_idx < 0) || (dev_idx >= cont->ndev))
+		return NULL;
+
+	if (cont->index[dev_idx].type != dscDevice)
+		return NULL;
+
+	base += cont->index[dev_idx].offset;
+	return (nxpTfaDeviceList_t *) base;
+}
+
+/*
+ * get the Nth profile for the Nth device
+ */
+nxpTfaProfileList_t *tfaContGetDevProfList(nxpTfaContainer_t * cont, int devIdx,
+					   int profIdx)
+{
+	nxpTfaDeviceList_t *dev;
+	int idx, hit;
+	uint8_t *base = (uint8_t *) cont;
+
+	dev = tfaContGetDevList(cont, devIdx);
+	if (dev) {
+		for (idx = 0, hit = 0; idx < dev->length; idx++) {
+			if (dev->list[idx].type == dscProfile) {
+				if (profIdx == hit++)
+					return (nxpTfaProfileList_t *) (dev->
+									list
+									[idx].
+									offset +
+									base);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/*
+ * get the Nth lifedata for the Nth device
+ */
+nxpTfaLiveDataList_t *tfaContGetDevLiveDataList(nxpTfaContainer_t * cont, int devIdx,
+					   int lifeDataIdx)
+{
+	nxpTfaDeviceList_t *dev;
+	int idx, hit;
+	uint8_t *base = (uint8_t *) cont;
+
+	dev = tfaContGetDevList(cont, devIdx);
+	if (dev) {
+		for (idx = 0, hit = 0; idx < dev->length; idx++) {
+			if (dev->list[idx].type == dscLiveData) {
+				if (lifeDataIdx == hit++)
+                                        return (nxpTfaLiveDataList_t *) 
+                                        (dev->list[idx].offset + base);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+/*
+ * Get the max volume step associated with Nth profile for the Nth device
+ */
+int tfacont_get_max_vstep(int dev_idx, int prof_idx) {
+	nxpTfaVolumeStep2File_t *vp;
+	struct nxpTfaVolumeStepMax2File *vp3;
+	int vstep_count = 0;
+	vp = (nxpTfaVolumeStep2File_t *) tfacont_getfiledata(dev_idx, prof_idx, volstepHdr);
+	if (vp == NULL)
+		return 0;
+	/* check the header type to load different NrOfVStep appropriately */
+	if (tfa98xx_dev_family(dev_idx) == 2) {
+		/* this is actually tfa2, so re-read the buffer*/
+		vp3 = (struct nxpTfaVolumeStepMax2File *)
+		tfacont_getfiledata(dev_idx, prof_idx, volstepHdr);
+		if ( vp3 ) {
+			vstep_count = vp3->NrOfVsteps;
+		}
+	} else {
+		/* this is max1*/
+		if ( vp ) {
+			vstep_count = vp->vsteps;
+		}
+	}
+	return vstep_count;
+}
+
+/**
+ * Get the file contents associated with the device or profile
+ * Search within the device tree, if not found, search within the profile
+ * tree. There can only be one type of file within profile or device.
+  */
+nxpTfaFileDsc_t *tfacont_getfiledata(int dev_idx, int prof_idx, enum nxpTfaHeaderType type)
+{
+	nxpTfaDeviceList_t *dev;
+	nxpTfaProfileList_t *prof;
+	nxpTfaFileDsc_t *file;
+	nxpTfaHeader_t *hdr;
+	unsigned int i;
+
+	if( g_cont==0 )
+		return NULL;
+
+	dev = tfaContGetDevList(g_cont, dev_idx);
+
+	if( dev==0 )
+		return NULL;
+
+	/* process the device list until a file type is encountered */
+	for(i=0;i<dev->length;i++) {
+		if ( dev->list[i].type == dscFile ) {
+			file = (nxpTfaFileDsc_t *)(dev->list[i].offset+(uint8_t *)g_cont);
+			hdr = (nxpTfaHeader_t *)file->data;
+			/* check for file type */
+			if ( hdr->id == type) {
+				//pr_debug("%s: file found of type %d in device %s \n", __FUNCTION__, type, tfaContDeviceName(devIdx));
+				return (nxpTfaFileDsc_t *)&file->data;
+			}
+		}
+	}
+
+	/* File not found in device tree.
+	 * So, look in the profile list until the file type is encountered
+	 */
+	prof=tfaContGetDevProfList(g_cont, dev_idx, prof_idx);
+	for(i=0;i<prof->length;i++) {
+		if (prof->list[i].type == dscFile) {
+			file = (nxpTfaFileDsc_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+			hdr= (nxpTfaHeader_t *)file->data;
+			/* check for file type */
+			if ( hdr->id == type) {
+				//pr_debug("%s: file found of type %d in profile %s\n", __FUNCTION__, type, tfaContProfileName(devIdx, profIdx));
+				return (nxpTfaFileDsc_t *)&file->data;
+			}
+		}
+	}
+
+	if ( tfa98xx_cnt_verbose )
+		pr_debug("%s: no file found of type %d\n", __FUNCTION__, type);
+
+	return NULL;
+}
+
+/*
+ * fill globals
+ */
+static void cont_get_devs(nxpTfaContainer_t *cont) {
+	nxpTfaProfileList_t *prof;
+        nxpTfaLiveDataList_t *liveD;
+	int i,j;
+	int count;
+
+	// get nr of devlists+1
+	for(i=0 ; i < cont->ndev ; i++) {
+		g_dev[i] = tfaContGetDevList(cont, i); // cache it
+	}
+
+	g_devs=cont->ndev;
+	// walk through devices and get the profile lists
+	for (i = 0; i < g_devs; i++) {
+		j=0;
+		count=0;
+		while ((prof = tfaContGetDevProfList(cont, i, j)) != NULL) {
+			count++;
+			g_prof[i][j++] = prof;
+		}
+		g_profs[i] = count;    // count the nr of profiles per device	
+	}
+
+        g_devs=cont->ndev;
+	// walk through devices and get the livedata lists
+	for (i = 0; i < g_devs; i++) {
+		j=0;
+		count=0;
+		while ((liveD = tfaContGetDevLiveDataList(cont, i, j)) != NULL) {
+			count++;
+			g_lived[i][j++] = liveD;
+		}
+		g_liveds[i] = count;    // count the nr of livedata per device	
+	}
+}
+
+static char nostring[]="Undefined string";
+
+//TODO add to API
+#define MODULE_BIQUADFILTERBANK 2
+#define BIQUAD_COEFF_SIZE       6
+/*
+ * write a parameter file to the device
+ */
+static enum Tfa98xx_Error tfaContWriteVstep(int dev_idx,  nxpTfaVolumeStep2File_t *vp, int vstep) 
+{
+	enum Tfa98xx_Error err;
+	unsigned short vol;
+
+	if (vstep < vp->vsteps) {
+		/* vol = (unsigned short)(voldB / (-0.5f)); */
+		vol = (unsigned short)(-2 * float_to_int(*((uint32_t *)&vp->vstep[vstep].attenuation)));
+		if (vol > 255)	/* restricted to 8 bits */
+			vol = 255;
+
+		err = tfa98xx_set_volume_level(dev_idx, vol);
+		if (err != Tfa98xx_Error_Ok)
+			return err;
+
+		err = tfa98xx_dsp_write_preset( dev_idx, sizeof(vp->vstep[0].preset), vp->vstep[vstep].preset);
+		if (err != Tfa98xx_Error_Ok)
+			return err;
+		err = tfa_cont_write_filterbank(dev_idx, vp->vstep[vstep].filter);
+
+	} else {
+		pr_err("Incorrect volume given. The value vstep[%d] >= %d\n", nxp_tfa_vstep[dev_idx] , vp->vsteps);
+		err = Tfa98xx_Error_Bad_Parameter;
+	}
+
+	if ( tfa98xx_cnt_verbose ) pr_debug("vstep[%d][%d]\n", dev_idx, vstep);
+
+	return err;
+}
+
+static enum Tfa98xx_Error tfaContWriteVstepMax2(int dev_idx, nxpTfaVolumeStepMax2File_t *vp, int vstep_idx, int vstep_msg_idx)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	struct nxpTfaVolumeStepRegisterInfo *regInfo = {0};
+	struct nxpTfaVolumeStepMessageInfo *msgInfo = {0};
+	nxpTfaBitfield_t bitF;
+	int msgLength=0, i, j, size=0, nrMessages, modified=0;
+	uint8_t cmdid_changed[3];
+
+	if(vstep_idx >= vp->NrOfVsteps) {
+		pr_debug("Volumestep %d is not available \n", vstep_idx);
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	for(i=0; i<=vstep_idx; i++) {
+		regInfo = (struct nxpTfaVolumeStepRegisterInfo*)(vp->vstepsBin + size);
+		msgInfo = (struct nxpTfaVolumeStepMessageInfo*)(vp->vstepsBin+
+				(regInfo->NrOfRegisters * sizeof(uint32_t)+sizeof(regInfo->NrOfRegisters)+size));
+
+		nrMessages = msgInfo->NrOfMessages;
+		for(j=0; j<nrMessages; j++) {
+			/* location of message j, from vstep i */
+			msgInfo = (struct nxpTfaVolumeStepMessageInfo*)(vp->vstepsBin+
+					(regInfo->NrOfRegisters * sizeof(uint32_t)+sizeof(regInfo->NrOfRegisters)+size));
+			/* message length */
+			msgLength = ( (msgInfo->MessageLength.b[0] << 16) + (msgInfo->MessageLength.b[1] << 8) + msgInfo->MessageLength.b[2]);
+			if (i == vstep_idx) {
+				/* If no vstepMsgIndex is passed on, all message needs to be send */
+				if ((vstep_msg_idx >= TFA_MAX_VSTEP_MSG_MARKER) || (vstep_msg_idx == j)) {
+					/* 
+					 * The algoparams and mbdrc msg id will be changed to the reset type when SBSL=0
+					 * if SBSL=1 the msg will remain unchanged. It's up to the tuning engineer to choose the 'without_reset' 
+					 * types inside the vstep. In other words: the reset msg is applied during SBSL==0 else it remains unchanged.
+					 */
+					if(TFA_GET_BF(dev_idx, SBSL) == 0) {
+						if(msgInfo->MessageType == 0) { /* If the messagetype(0) is AlgoParams */
+							/* Only do this when not set already */
+							if(msgInfo->CmdId[2] != SB_PARAM_SET_ALGO_PARAMS) {
+								cmdid_changed[0] = msgInfo->CmdId[0];
+								cmdid_changed[1] = msgInfo->CmdId[1];
+								cmdid_changed[2] = SB_PARAM_SET_ALGO_PARAMS;
+								modified = 1;
+							}
+						} else if(msgInfo->MessageType == 2) { /* If the messagetype(2) is MBDrc */
+							/* Only do this when not set already */
+							if(msgInfo->CmdId[2] != SB_PARAM_SET_MBDRC) {
+								cmdid_changed[0] = msgInfo->CmdId[0];
+								cmdid_changed[1] = msgInfo->CmdId[1];
+								cmdid_changed[2] = SB_PARAM_SET_MBDRC;
+								modified = 1;
+							}
+						}
+					}
+					/* Messagetype(3) is Smartstudio Info! Dont send this! */
+					if(msgInfo->MessageType != 3) { 
+						if(modified == 1) {
+							if (tfa98xx_cnt_verbose) {
+								if(cmdid_changed[2] == SB_PARAM_SET_ALGO_PARAMS)
+									pr_debug("P-ID for SetAlgoParams modified!: ");
+								else
+									pr_debug("P-ID for SetMBDrc modified!: ");
+
+								pr_debug("Command-ID used: 0x%02x%02x%02x \n", 
+									cmdid_changed[0], cmdid_changed[1], cmdid_changed[2]);
+							}
+							/* Send payload to dsp (Remove 1 from the length for cmdid) */
+							err = tfa_dsp_msg_id(dev_idx, (msgLength-1) * 3, (const char *)msgInfo->ParameterData, cmdid_changed);
+							if (err != Tfa98xx_Error_Ok)
+								return err;
+						} else {
+							/* Send cmdId + payload to dsp */
+							err = tfa_dsp_msg(dev_idx, msgLength * 3,(const char *)msgInfo->CmdId);
+							if (err != Tfa98xx_Error_Ok)
+								return err;
+						}
+					
+						/* Set back to zero every time */
+						modified = 0;
+					}
+				}
+			}
+
+			if(msgInfo->MessageType == 3) {
+				/* MessageLength is in bytes */
+				size += sizeof(msgInfo->MessageType) + sizeof(msgInfo->MessageLength) + msgLength;
+			} else {
+				/* MessageLength is in words (3 bytes) */
+				size += sizeof(msgInfo->MessageType) + sizeof(msgInfo->MessageLength) + sizeof(msgInfo->CmdId) + ((msgLength-1) * 3);
+			}
+		}
+		size += sizeof(regInfo->NrOfRegisters) + (regInfo->NrOfRegisters * sizeof(uint32_t)) + sizeof(msgInfo->NrOfMessages);
+	}
+
+	if (regInfo->NrOfRegisters == 0) {
+		pr_debug("No registers in selected vstep (%d)!\n", vstep_idx);
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	for(i=0; i<regInfo->NrOfRegisters*2; i++) {
+		/* Byte swap the datasheetname */
+		bitF.field = (uint16_t)(regInfo->registerInfo[i]>>8) | (regInfo->registerInfo[i]<<8);
+		i++;
+		bitF.value = (uint16_t)regInfo->registerInfo[i]>>8;
+		err = tfaRunWriteBitfield(dev_idx , bitF);
+		if (err != Tfa98xx_Error_Ok)
+			return err;
+	}
+
+	/* Save the current vstep */
+	tfa_set_swvstep(dev_idx, (unsigned short)vstep_idx);
+
+	return err;
+}
+
+/*
+ * Write DRC message to the dsp
+ * If needed modify the cmd-id
+ */
+
+enum Tfa98xx_Error tfaContWriteDrcFile(int dev_idx, int size, uint8_t data[])
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	uint8_t cmdid_changed[3], modified = 0;
+
+	if(TFA_GET_BF(dev_idx, SBSL) == 0) {
+		/* Only do this when not set already */
+		if(data[2] != SB_PARAM_SET_MBDRC) {
+			cmdid_changed[0] = data[0];
+			cmdid_changed[1] = data[1];
+			cmdid_changed[2] = SB_PARAM_SET_MBDRC;
+			modified = 1;
+
+			if (tfa98xx_cnt_verbose) {
+				pr_debug("P-ID for SetMBDrc modified!: ");
+				pr_debug("Command-ID used: 0x%02x%02x%02x \n", 
+				cmdid_changed[0], cmdid_changed[1], cmdid_changed[2]);
+			}
+		}
+	}
+
+	if(modified == 1) {
+		/* Send payload to dsp (Remove 3 from the length for cmdid) */
+		err = tfa_dsp_msg_id(dev_idx, size-3, (const char *)data, cmdid_changed);
+	} else {
+		/* Send cmdId + payload to dsp */
+		err = tfa_dsp_msg(dev_idx, size, (const char *)data);
+	}
+
+	return err;
+}
+
+
+/*
+ * write a parameter file to the device
+ * The VstepIndex and VstepMsgIndex are only used to write a specific msg from the vstep file.
+ */
+enum Tfa98xx_Error tfaContWriteFile(int dev_idx,  nxpTfaFileDsc_t *file, int vstep_idx, int vstep_msg_idx)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaHeader_t *hdr = (nxpTfaHeader_t *)file->data;
+	nxpTfaHeaderType_t type;
+	int size;	
+
+	if ( tfa98xx_cnt_verbose ) {
+		tfaContShowHeader(hdr);
+	}
+
+	type = (nxpTfaHeaderType_t) hdr->id;
+
+	switch (type) {
+	case msgHdr: /* generic DSP message */
+		size = hdr->size - sizeof(nxpTfaMsgFile_t);
+		err = tfa_dsp_msg(dev_idx, size, (const char *)((nxpTfaMsgFile_t *)hdr)->data);
+		break;
+	case volstepHdr:
+		if (tfa98xx_dev_family(dev_idx) == 2) {
+			err = tfaContWriteVstepMax2(dev_idx, (nxpTfaVolumeStepMax2File_t *)hdr, vstep_idx, vstep_msg_idx);
+		} else {
+			err = tfaContWriteVstep(dev_idx, (nxpTfaVolumeStep2File_t *)hdr, vstep_idx);
+		}
+
+		/* If writing the vstep was succesfull, set new current vstep */
+		if(err == Tfa98xx_Error_Ok) {
+			tfaContSetCurrentVstep(dev_idx, vstep_idx);
+		}
+
+		break;
+	case speakerHdr:
+		if (tfa98xx_dev_family(dev_idx) == 2) {
+			/* Remove header and xml_id */
+			size = hdr->size - sizeof(struct nxpTfaSpkHeader) - sizeof(struct nxpTfaFWVer);
+
+			err = tfa_dsp_msg(dev_idx, size,
+					(const char *)(((nxpTfaSpeakerFile_t *)hdr)->data + (sizeof(struct nxpTfaFWVer))));
+		} else {
+			size = hdr->size - sizeof(nxpTfaSpeakerFile_t);
+			err = tfa98xx_dsp_write_speaker_parameters( dev_idx, size,
+					(const unsigned char *)((nxpTfaSpeakerFile_t *)hdr)->data);
+		}
+		break;
+	case presetHdr:
+		size = hdr->size - sizeof(nxpTfaPreset_t);
+		err = tfa98xx_dsp_write_preset( dev_idx, size, (const unsigned char *)((nxpTfaPreset_t *)hdr)->data);
+		break;
+	case equalizerHdr:
+		err = tfa_cont_write_filterbank(dev_idx, ((nxpTfaEqualizerFile_t *)hdr)->filter);
+		break;
+	case patchHdr:
+		size = hdr->size - sizeof(nxpTfaPatch_t ); // size is total length
+		err = tfa_dsp_patch(dev_idx,  size, (const unsigned char *) ((nxpTfaPatch_t *)hdr)->data);
+		break;
+	case configHdr:
+		size = hdr->size - sizeof(nxpTfaConfig_t);
+		err = tfa98xx_dsp_write_config(dev_idx, size, (const unsigned char *)((nxpTfaConfig_t *)hdr)->data);
+		break;
+	case drcHdr:
+		if(hdr->version[0] == NXPTFA_DR3_VERSION) {
+			/* Size is total size - hdrsize(36) - xmlversion(3) */
+			size = hdr->size - sizeof(nxpTfaDrc2_t);
+			err = tfaContWriteDrcFile(dev_idx, size, ((nxpTfaDrc2_t *)hdr)->data);
+		} else {
+			/*
+			 * The DRC file is split as:
+			 * 36 bytes for generic header (customer, application, and type)
+			 * 127x3 (381) bytes first block contains the device and sample rate
+			 * 				independent settings
+			 * 127x3 (381) bytes block the device and sample rate specific values.
+			 * The second block can always be recalculated from the first block,
+			 * if vlsCal and the sample rate are known.
+			 */
+			//size = hdr->size - sizeof(nxpTfaDrc_t);
+			size = 381; /* fixed size for first block */
+
+			//+381 is done to only send the second part of the drc block
+			err = tfa98xx_dsp_write_drc( dev_idx, size, ((const unsigned char *)((nxpTfaDrc_t *)hdr)->data+381));
+		}
+		break;
+	case infoHdr:
+		/* Ignore */
+		break;
+	default:
+		pr_err("Header is of unknown type: 0x%x\n", type);
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	return err;
+}
+
+/**
+ * get the 1st of this dsc type this devicelist
+ */
+nxpTfaDescPtr_t *tfa_cnt_get_dsc(nxpTfaContainer_t *cnt, nxpTfaDescriptorType_t type, int dev_idx)
+{
+	nxpTfaDeviceList_t *dev = tfaContDevice (dev_idx);
+	nxpTfaDescPtr_t *this;
+	int i;
+
+	if ( !dev ) {
+		return NULL;
+	}
+	/* process the list until a the type is encountered */
+	for(i=0;i<dev->length;i++) {
+		if ( dev->list[i].type == (uint32_t)type ) {
+			this = (nxpTfaDescPtr_t *)(dev->list[i].offset+(uint8_t *)cnt);
+			return this;
+		}
+
+	}
+
+	return NULL;
+}
+
+/**
+ * get the device type from the patch in this devicelist
+ *  - find the patch file for this devidx
+ *  - return the devid from the patch or 0 if not found
+ */
+int tfa_cnt_get_devid(nxpTfaContainer_t *cnt, int dev_idx) {
+	nxpTfaPatch_t *patchfile;
+	nxpTfaDescPtr_t *patchdsc;
+	uint8_t *patchheader;
+	unsigned short devid, checkaddress;
+	int checkvalue;
+
+	patchdsc = tfa_cnt_get_dsc(cnt, dscPatch, dev_idx);
+	patchdsc += 2; /* first the filename dsc and filesize, so skip them */
+	patchfile = (nxpTfaPatch_t *)patchdsc;
+
+	patchheader = patchfile->data;
+
+	checkaddress = (patchheader[1] << 8) + patchheader[2];
+	checkvalue = 
+		(patchheader[3] << 16) + (patchheader[4] << 8) + patchheader[5];
+
+	devid = patchheader[0];
+
+	if(checkaddress == 0xFFFF && checkvalue != 0xFFFFFF && checkvalue != 0) {
+		devid = patchheader[5]<<8 | patchheader[0]; /* full revid */
+	}
+
+	return devid;
+}
+
+/*
+ * get the slave for the device if it exists
+ */
+enum Tfa98xx_Error tfaContGetSlave(int dev_idx, uint8_t *slave_addr) {
+	nxpTfaDeviceList_t *dev = tfaContDevice (dev_idx);
+
+	if (dev==0 ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	*slave_addr = dev->dev;
+	return Tfa98xx_Error_Ok;
+}
+
+/*
+ * write a bit field
+ */
+enum Tfa98xx_Error tfaRunWriteBitfield(Tfa98xx_handle_t dev_idx,  nxpTfaBitfield_t bf) {
+	enum Tfa98xx_Error error;
+        uint16_t value;
+	union {
+		uint16_t field;
+		nxpTfaBfEnum_t Enum;
+	} bfUni;
+        
+	value=bf.value;
+	bfUni.field = bf.field;
+#ifdef TFA_DEBUG
+	if ( tfa98xx_cnt_verbose )
+		pr_debug("bitfield: %s=%d (0x%x[%d..%d]=0x%x)\n", tfaContBfName(bfUni.field, tfa98xx_dev_revision(dev_idx)), value,
+			bfUni.Enum.address, bfUni.Enum.pos, bfUni.Enum.pos+bfUni.Enum.len, value);
+#endif
+        error = tfa_set_bf(dev_idx, bfUni.field, value);
+
+	return error;
+}
+
+/*
+ * read a bit field
+ */
+enum Tfa98xx_Error tfaRunReadBitfield(Tfa98xx_handle_t dev_idx,  nxpTfaBitfield_t *bf) {
+	enum Tfa98xx_Error error;
+	union {
+		uint16_t field;
+		nxpTfaBfEnum_t Enum;
+	} bfUni;
+	uint16_t regvalue, msk;
+
+	bfUni.field = bf->field;
+
+	error = tfa98xx_read_register16(dev_idx, (unsigned char)(bfUni.Enum.address), &regvalue);
+	if (error) return error;
+
+	msk = ((1<<(bfUni.Enum.len+1))-1)<<bfUni.Enum.pos;
+
+	regvalue &= msk;
+	bf->value = regvalue>>bfUni.Enum.pos;
+
+	return error;
+}
+
+/*
+ dsp mem direct write
+ */
+enum Tfa98xx_Error tfaRunWriteDspMem(Tfa98xx_handle_t dev, nxpTfaDspMem_t *cfmem)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	int i;
+
+	for(i=0;i<cfmem->size;i++) {
+		if ( tfa98xx_cnt_verbose )
+			pr_debug("dsp mem (%d): 0x%02x=0x%04x\n", cfmem->type, (cfmem->address+i), cfmem->words[i]);
+
+		error = tfa98xx_dsp_write_mem_word(dev, (cfmem->address+i), cfmem->words[i], cfmem->type);
+		if (error) return error;
+	}
+
+	return error;
+}
+
+/*
+ * write filter payload to DSP
+ *  note that the data is in an aligned union for all filter variants
+ *  the aa data is used but it's the same for all of them
+ */
+enum Tfa98xx_Error tfaRunWriteFilter(Tfa98xx_handle_t dev, nxpTfaContBiquad_t *bq) {
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	enum Tfa98xx_DMEM dmem;
+	uint16_t address;
+	uint8_t data[3*3+sizeof(bq->aa.bytes)];
+	int i, channel=0, runs=1;
+	int8_t saved_index=bq->aa.index; /* This is used to set back the index */
+
+	/* Channel=1 is primary, Channel=2 is secondary*/
+	if (bq->aa.index > 100) {
+		bq->aa.index -= 100;
+		channel = 2;
+	} else if (bq->aa.index > 50) {
+		bq->aa.index -= 50;
+		channel = 1;
+	} else if(tfa98xx_dev_family(dev) == 2) {
+			runs=2;
+	}
+
+	if ( tfa98xx_cnt_verbose ) {
+		if(channel == 2)
+			pr_debug("filter[%d,S]", bq->aa.index);
+		else if(channel == 1)
+			pr_debug("filter[%d,P]", bq->aa.index);
+		else
+			pr_debug("filter[%d]", bq->aa.index);
+	}
+
+	for(i=0; i<runs; i++) {
+		if(runs==2)
+			channel++;
+
+		/* get the target address for the filter on this device */
+		dmem = tfa98xx_filter_mem(dev, bq->aa.index, &address, channel);
+		if(dmem<0)
+			return Tfa98xx_Error_Bad_Parameter;
+
+		/* send a DSP memory message that targets the devices specific memory for the filter
+		 * msg params: which_mem, start_offset, num_words
+		 */
+		memset(data, 0, 3*3);
+		data[2] = dmem; /* output[0] = which_mem */
+		data[4] = address >> 8; /* output[1] = start_offset */
+		data[5] = address & 0xff;
+		data[8] = sizeof(bq->aa.bytes)/3; /*output[2] = num_words */
+		memcpy( &data[9], bq->aa.bytes, sizeof(bq->aa.bytes)); /* payload */
+
+		if(tfa98xx_dev_family(dev) == 2) {
+			error = tfa_dsp_cmd_id_write(dev, MODULE_FRAMEWORK, FW_PAR_ID_SET_MEMORY, sizeof(data), data);
+		} else {
+			error = tfa_dsp_cmd_id_write(dev, MODULE_FRAMEWORK, 4 /* param */ , sizeof(data), data);
+		}
+	}
+
+#ifdef TFA_DEBUG
+	if ( tfa98xx_cnt_verbose ) {
+		if (bq->aa.index==13) {
+			pr_debug("=%d,%.0f,%.2f \n",
+				bq->in.type, bq->in.cutOffFreq, bq->in.leakage);
+		} else if(bq->aa.index >= 10 && bq->aa.index <= 12) {
+			pr_debug("=%d,%.0f,%.1f,%.1f \n", bq->aa.type,
+				bq->aa.cutOffFreq, bq->aa.rippleDb, bq->aa.rolloff);
+		} else {
+			pr_debug("= unsupported filter index \n");
+		}
+	}
+#endif
+
+	/* Because we can load the same filters multiple times
+	 * For example: When we switch profile we re-write in operating mode.
+	 * We then need to remember the index (primary, secondary or both)
+	 */
+	bq->aa.index = saved_index;
+
+	return error;
+}
+
+/*
+ * write the register based on the input address, value and mask
+ *  only the part that is masked will be updated
+ */
+enum Tfa98xx_Error tfaRunWriteRegister(Tfa98xx_handle_t handle, nxpTfaRegpatch_t *reg)
+{
+	enum Tfa98xx_Error error;
+	uint16_t value,newvalue;
+
+	if ( tfa98xx_cnt_verbose )
+		pr_debug("register: 0x%02x=0x%04x (msk=0x%04x)\n", reg->address, reg->value, reg->mask);
+
+	error = tfa98xx_read_register16(handle, reg->address, &value);
+	if (error) return error;
+
+	value &= ~reg->mask;
+	newvalue = reg->value & reg->mask;
+
+	value |= newvalue;
+	error = tfa98xx_write_register16(handle,  reg->address, value);
+
+	return error;
+
+}
+
+/*
+ * return the bitfield
+ */
+nxpTfaBitfield_t tfaContDsc2Bf(nxpTfaDescPtr_t dsc) {
+	uint32_t *ptr = (uint32_t *) (&dsc);
+	union {
+	nxpTfaBitfield_t bf;
+	uint32_t num;
+	} num_bf;
+
+	num_bf.num = *ptr; // & TFA_BITFIELDDSCMSK;
+
+	return num_bf.bf;
+}
+
+// write  reg  and bitfield items in the devicelist to the target
+enum Tfa98xx_Error tfaContWriteRegsDev(int dev_idx) {
+	nxpTfaDeviceList_t *dev = tfaContDevice (dev_idx);
+	nxpTfaBitfield_t *bitF;
+	int i;
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	if ( !dev ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	/* process the list until a patch, file of profile is encountered */
+	for(i=0;i<dev->length;i++) {
+		if ( dev->list[i].type == dscPatch ||
+			  dev->list[i].type ==dscFile  ||
+			  dev->list[i].type ==dscProfile ) break;
+
+		if  ( dev->list[i].type == dscBitfield) {
+			bitF = (nxpTfaBitfield_t *)( dev->list[i].offset+(uint8_t *)g_cont);
+			err = tfaRunWriteBitfield(dev_idx , *bitF);
+		}
+		if  ( dev->list[i].type == dscRegister ) {
+			err = tfaRunWriteRegister( dev_idx, (nxpTfaRegpatch_t *)
+                                                ( dev->list[i].offset+(char*)g_cont));
+		}
+
+		if ( err ) break;
+	}
+	return err;
+}
+
+// write reg and bitfield items in the profilelist the target
+enum Tfa98xx_Error tfaContWriteRegsProf(int dev_idx, int prof_idx) {
+	nxpTfaProfileList_t *prof = tfaContProfile( dev_idx, prof_idx);
+	nxpTfaBitfield_t *bitf;
+	unsigned int i;
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	if ( !prof ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	if ( tfa98xx_cnt_verbose )
+		pr_debug("----- profile: %s (%d) -----\n", tfaContGetString(&prof->name), prof_idx);
+
+	/* process the list until the end of the profile or the default section */
+	for(i=0;i<prof->length;i++) {
+		/* We only want to write the values before the default section when we switch profile */
+		if(prof->list[i].type == dscDefault)
+			break;
+
+		if  ( prof->list[i].type == dscBitfield) {
+			bitf = (nxpTfaBitfield_t *)( prof->list[i].offset+(uint8_t *)g_cont);
+			err = tfaRunWriteBitfield(dev_idx , *bitf);
+		}
+		if  ( prof->list[i].type == dscRegister ) {
+			err = tfaRunWriteRegister( dev_idx, (nxpTfaRegpatch_t *)( !prof->list[i].offset+g_cont));
+		}
+		if ( err ) break;
+	}
+	return err;
+}
+
+// write  patchfile in the devicelist to the target
+enum Tfa98xx_Error tfaContWritePatch(int dev_idx) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaDeviceList_t *dev = tfaContDevice(dev_idx);
+	nxpTfaFileDsc_t *file;
+	nxpTfaPatch_t *patchfile;
+	int size, i;
+
+	if ( !dev ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+	/* process the list until a patch  is encountered */
+	for(i=0;i<dev->length;i++) {
+		if ( dev->list[i].type == dscPatch ) {
+			file = (nxpTfaFileDsc_t *)(dev->list[i].offset+(uint8_t *)g_cont);
+			patchfile =(nxpTfaPatch_t *)&file->data;
+			if ( tfa98xx_cnt_verbose ) tfaContShowHeader(&patchfile->hdr);
+			size = patchfile->hdr.size - sizeof(nxpTfaPatch_t ); // size is total length
+			err = tfa_dsp_patch(dev_idx,  size, (const unsigned char *) patchfile->data);
+			if ( err ) return err;
+		}
+
+	}
+
+	return Tfa98xx_Error_Ok;
+}
+
+// write all  param files in the devicelist to the target
+enum Tfa98xx_Error tfaContWriteFiles(int dev_idx) {
+	nxpTfaDeviceList_t *dev = tfaContDevice(dev_idx);
+	nxpTfaFileDsc_t *file;
+	nxpTfaCmd_t *cmd;
+        enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+        char buffer[(MEMTRACK_MAX_WORDS * 3) + 3] = {0}; //every word requires 3 bytes, and 3 is the msg
+	int i, size = 0;
+
+	if ( !dev ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	/* process the list and write all files  */
+	for(i=0;i<dev->length;i++) {
+		if ( dev->list[i].type == dscFile ) {
+			file = (nxpTfaFileDsc_t *)(dev->list[i].offset+(uint8_t *)g_cont);
+			if ( tfaContWriteFile(dev_idx,  file, 0 , TFA_MAX_VSTEP_MSG_MARKER) ){
+				return Tfa98xx_Error_Bad_Parameter;
+			}
+		}
+
+		if  ( dev->list[i].type == dscSetInputSelect || 
+		      dev->list[i].type == dscSetOutputSelect || 
+		      dev->list[i].type == dscSetProgramConfig ||
+		      dev->list[i].type == dscSetLagW ||
+		      dev->list[i].type == dscSetGains ||
+		      dev->list[i].type == dscSetvBatFactors ||
+		      dev->list[i].type == dscSetSensesCal ||
+		      dev->list[i].type == dscSetSensesDelay ||
+		      dev->list[i].type == dscSetMBDrc ) {
+			create_dsp_buffer_msg((nxpTfaMsg_t *)
+			                      ( dev->list[i].offset+(char*)g_cont), buffer, &size);
+			err = tfa_dsp_msg(dev_idx, size, buffer);
+			if ( tfa98xx_cnt_verbose ) {
+					pr_debug("command: %s=0x%02x%02x%02x \n",
+					tfaContGetCommandString(dev->list[i].type),
+				(unsigned char)buffer[0], (unsigned char)buffer[1], (unsigned char)buffer[2]);
+			}
+		}
+
+		if  ( dev->list[i].type == dscCmd ) {
+			size = *(uint16_t *)(dev->list[i].offset+(char*)g_cont);
+			err = tfa_dsp_msg(dev_idx, size,  dev->list[i].offset+2+(char*)g_cont);
+			if ( tfa98xx_cnt_verbose ) {
+				cmd = (nxpTfaCmd_t *)(dev->list[i].offset+(uint8_t *)g_cont);
+				pr_debug("Writing cmd=0x%02x%02x%02x \n", cmd->value[0], cmd->value[1], cmd->value[2]);
+			}
+		}
+		if (err != Tfa98xx_Error_Ok)
+			break;
+
+		if  ( dev->list[i].type == dscCfMem ) {
+			err = tfaRunWriteDspMem(dev_idx, (nxpTfaDspMem_t *)(dev->list[i].offset+(uint8_t *)g_cont));
+		}
+
+		if (err != Tfa98xx_Error_Ok)
+			break;
+	}
+
+	return err;
+}
+
+/*
+ *  write all  param files in the profilelist to the target
+ *   this is used during startup when maybe ACS is set
+ */
+enum Tfa98xx_Error tfaContWriteFilesProf(int dev_idx, int prof_idx, int vstep_idx) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaProfileList_t *prof = tfaContProfile(dev_idx, prof_idx);
+	unsigned int i;
+	nxpTfaFileDsc_t *file;
+	nxpTfaPatch_t *patchfile;
+	int size;
+
+	if ( !prof ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	/* process the list and write all files  */
+	for(i=0;i<prof->length;i++) {
+		switch (prof->list[i].type) {
+			case dscFile:
+				file = (nxpTfaFileDsc_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+				err = tfaContWriteFile(dev_idx,  file, vstep_idx, TFA_MAX_VSTEP_MSG_MARKER);
+				break;
+			case dscFilter:
+				/* Filters are not written during coldstart
+				 * Since calibration, SBSL and many other actions can overwrite them again
+				 * They are written during operating mode (tfa_start)
+				 */
+				//err = tfaRunWriteFilter(dev_idx, (nxpTfaContBiquad_t *)(prof->list[i].offset+(uint8_t *)g_cont));
+				break;
+			case dscPatch:
+				file = (nxpTfaFileDsc_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+				patchfile =(nxpTfaPatch_t *)&file->data;
+				if ( tfa98xx_cnt_verbose ) tfaContShowHeader(&patchfile->hdr);
+				size = patchfile->hdr.size - sizeof(nxpTfaPatch_t ); // size is total length
+				err = tfa_dsp_patch(dev_idx,  size, (const unsigned char *) patchfile->data);
+				break;
+			case dscCfMem:
+				err = tfaRunWriteDspMem(dev_idx, (nxpTfaDspMem_t *)(prof->list[i].offset+(uint8_t *)g_cont));
+				break;
+			default:
+				/* ignore any other type */
+				break;
+		}
+	}
+
+	return err;
+}
+
+enum Tfa98xx_Error tfaContWriteItem(int dev_idx, nxpTfaDescPtr_t * dsc) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	//nxpTfaFileDsc_t *file;
+	nxpTfaRegpatch_t *reg;
+	nxpTfaMode_t *cas;
+	nxpTfaBitfield_t *bitf;
+
+	switch (dsc->type) {
+        case dscDefault:
+	case dscDevice: // ignore
+	case dscProfile:    // profile list
+		break;
+	case dscRegister:   // register patch
+		reg = (nxpTfaRegpatch_t *)(dsc->offset+(uint8_t *)g_cont);
+		return tfaRunWriteRegister(dev_idx, reg);
+		//pr_debug("$0x%2x=0x%02x,0x%02x\n", reg->address, reg->mask, reg->value);
+		break;
+	case dscString: // ascii: zero terminated string
+		pr_debug(";string: %s\n", tfaContGetString(dsc));
+		break;
+	case dscFile:       // filename + file contents
+	case dscPatch:
+		break;
+	case dscMode:
+		cas = (nxpTfaMode_t *)(dsc->offset+(uint8_t *)g_cont);
+		if(cas->value == Tfa98xx_Mode_RCV)
+			tfa98xx_select_mode(dev_idx, Tfa98xx_Mode_RCV);
+		else
+			tfa98xx_select_mode(dev_idx, Tfa98xx_Mode_Normal);
+		break;
+	case dscCfMem:
+		err = tfaRunWriteDspMem(dev_idx, (nxpTfaDspMem_t *)(dsc->offset+(uint8_t *)g_cont));
+		break;
+	case dscBitfield:
+		bitf = (nxpTfaBitfield_t *)(dsc->offset+(uint8_t *)g_cont);
+		return tfaRunWriteBitfield(dev_idx , *bitf);
+		break;
+	case dscFilter:
+		return tfaRunWriteFilter(dev_idx, (nxpTfaContBiquad_t *)(dsc->offset+(uint8_t *)g_cont));
+		break;
+	}
+
+	return err;
+}
+
+static unsigned int tfa98xx_sr_from_field(unsigned int field)
+{
+	switch (field) {
+		case 0:
+			return 8000;
+		case 1:
+			return 11025;
+		case 2:
+			return 12000;
+		case 3:
+			return 16000;
+		case 4:
+			return 22050;
+		case 5:
+			return 24000;
+		case 6:
+			return 32000;
+		case 7:
+			return 44100;
+		case 8:
+			return 48000;
+		default:
+			return 0;
+	}
+}
+
+enum Tfa98xx_Error tfa_write_filters(int dev_idx, int prof_idx) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaProfileList_t *prof = tfaContProfile(dev_idx, prof_idx);
+	unsigned int i;
+	int status;
+
+	if ( !prof ) {
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	if ( tfa98xx_cnt_verbose ) {
+		pr_debug("----- profile: %s (%d) -----\n", tfaContGetString(&prof->name), prof_idx);
+		pr_debug("Waiting for CLKS... \n");
+	}
+
+	for(i=10; i>0; i--) {
+		err = tfa98xx_dsp_system_stable(dev_idx, &status);
+		if(status)
+			break;
+		else
+			msleep_interruptible(10);
+	}
+
+	if(i==0) {
+		if ( tfa98xx_cnt_verbose )
+			pr_err("Unable to write filters, CLKS=0 \n");
+				
+		return Tfa98xx_Error_StateTimedOut;	
+	}
+
+	/* process the list until the end of the profile or the default section */
+	for(i=0;i<prof->length;i++) {
+		if  ( prof->list[i].type == dscFilter ) {
+			if (tfaContWriteItem(dev_idx, &prof->list[i]) != Tfa98xx_Error_Ok)
+				return Tfa98xx_Error_Bad_Parameter;
+		}
+	}
+
+	return err;
+}
+
+unsigned int tfa98xx_get_profile_sr(int dev_idx, unsigned int prof_idx)
+{
+	nxpTfaBitfield_t *bitf;
+	unsigned int i;
+	nxpTfaDeviceList_t *dev;
+	nxpTfaProfileList_t *prof;
+	int fs_profile = -1;
+
+	dev = tfaContDevice (dev_idx);
+	if (!dev)
+		return 0;
+
+	prof = tfaContProfile(dev_idx, prof_idx);
+	if (!prof)
+		return 0;
+
+	/* Check profile fields first */
+	for(i = 0; i < prof->length; i++) {
+		if(prof->list[i].type == dscDefault)
+			break;
+
+		/* check for profile settingd (AUDFS) */
+		if ( prof->list[i].type == dscBitfield ) {
+			bitf = (nxpTfaBitfield_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+			if(bitf->field == TFA_FAM(dev_idx, AUDFS)) {
+				fs_profile = bitf->value;
+				break;
+			}
+		}
+	}
+
+	pr_debug("%s - profile fs: 0x%x = %dHz (%d - %d)\n", __FUNCTION__, fs_profile,
+					tfa98xx_sr_from_field(fs_profile),
+					dev_idx, prof_idx);
+	if (fs_profile != -1)
+		return tfa98xx_sr_from_field(fs_profile);
+
+	/* Check for container default setting */
+	/* process the list until a patch, file of profile is encountered */
+	for(i = 0; i < dev->length; i++) {
+		if ( dev->list[i].type == dscPatch ||
+			  dev->list[i].type ==dscFile  ||
+			  dev->list[i].type ==dscProfile ) break;
+
+		if  ( dev->list[i].type == dscBitfield) {
+			bitf = (nxpTfaBitfield_t *)( dev->list[i].offset+(uint8_t *)g_cont);
+			if(bitf->field == TFA_FAM(dev_idx, AUDFS)) {
+				fs_profile = bitf->value;
+				break;
+			}
+		}
+		/* Ignore register case */
+	}
+
+	pr_debug("%s - default fs: 0x%x = %dHz (%d - %d)\n", __FUNCTION__, fs_profile,
+					tfa98xx_sr_from_field(fs_profile),
+					dev_idx, prof_idx);
+	if (fs_profile != -1)
+		return tfa98xx_sr_from_field(fs_profile);
+
+	return 48000;
+}
+
+enum Tfa98xx_Error get_sample_rate_info(int dev_idx, nxpTfaProfileList_t *prof, nxpTfaProfileList_t *previous_prof, int fs_previous_profile)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaBitfield_t *bitf;
+	unsigned int i;
+	int fs_default_profile=8;	/* default is 48kHz */
+	int fs_next_profile=8;		/* default is 48kHz */
+
+
+	/* ---------- default settings previous profile ---------- */
+	for(i=0;i<previous_prof->length;i++) {
+		/* Search for the default section */
+		if(i == 0) {
+			while(previous_prof->list[i].type != dscDefault && i < previous_prof->length) {
+				i++;
+			}
+			i++;
+		}
+
+		/* Only if we found the default section search for AUDFS */
+		if(i < previous_prof->length) {
+			if ( previous_prof->list[i].type == dscBitfield ) {
+				bitf = (nxpTfaBitfield_t *)(previous_prof->list[i].offset+(uint8_t *)g_cont);
+				if(bitf->field == TFA_FAM(dev_idx, AUDFS)) {
+					fs_default_profile = bitf->value;
+					break;
+				}
+			}
+		}
+	}
+
+	/* ---------- settings next profile ---------- */
+	for(i=0;i<prof->length;i++) {
+		/* We only want to write the values before the default section */
+		if(prof->list[i].type == dscDefault)
+			break;
+		/* search for AUDFS */
+		if ( prof->list[i].type == dscBitfield ) {
+			bitf = (nxpTfaBitfield_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+			if(bitf->field == TFA_FAM(dev_idx, AUDFS)) {
+				fs_next_profile = bitf->value;
+				break;
+			}
+		}
+	}
+
+	/* Enable if needed for debugging!
+	if ( tfa98xx_cnt_verbose ) {
+		pr_debug("sample rate from the previous profile: %d \n", fs_previous_profile);
+		pr_debug("sample rate in the default section: %d \n", fs_default_profile);
+		pr_debug("sample rate for the next profile: %d \n", fs_next_profile);
+	}
+	*/
+
+	if(fs_next_profile != fs_default_profile) {
+		if ( tfa98xx_cnt_verbose )
+			pr_debug("Writing delay tables for AUDFS=%d \n", fs_next_profile);
+
+		/* If the AUDFS from the next profile is not the same as 
+		 * the AUDFS from the default we need to write new delay tables 
+		 */
+		err = tfa98xx_dsp_write_tables(dev_idx, fs_next_profile);
+	} else if(fs_default_profile != fs_previous_profile) {
+		if ( tfa98xx_cnt_verbose )
+			pr_debug("Writing delay tables for AUDFS=%d \n", fs_default_profile);
+
+		/* But if we do not have a new AUDFS in the next profile and 
+		 * the AUDFS from the default profile is not the same as the AUDFS 
+		 * from the previous profile we also need to write new delay tables 
+		 */
+		err = tfa98xx_dsp_write_tables(dev_idx, fs_default_profile);
+	}
+
+	return err;
+}
+
+/*
+ *  process all items in the profilelist
+ *   NOTE an error return during processing will leave the device muted
+ *
+ */
+enum Tfa98xx_Error tfaContWriteProfile(int dev_idx, int prof_idx, int vstep_idx) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaProfileList_t *prof = tfaContProfile(dev_idx, prof_idx);
+	nxpTfaProfileList_t *previous_prof = tfaContProfile(dev_idx, tfa_get_swprof(dev_idx));
+	char buffer[(MEMTRACK_MAX_WORDS * 3) + 3] = {0}; //every word requires 3 bytes, and 3 is the msg
+	unsigned int i, k=0, j=0, tries=0;
+	nxpTfaFileDsc_t *file;
+	nxpTfaCmd_t *cmd;
+	int size = 0, ready, fs_previous_profile = 8; /* default fs is 48kHz*/
+    int dev_family = tfa98xx_dev_family(dev_idx);
+
+	if ( !prof || !previous_prof ) {
+		pr_err("Error trying to get the (previous) swprofile \n");
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	if ( tfa98xx_cnt_verbose ) {
+		tfa98xx_trace_printk("device:%s profile:%s vstep:%d\n", tfaContDeviceName(dev_idx),
+					tfaContProfileName(dev_idx,prof_idx),vstep_idx);
+	}
+
+	/* We only make a power cycle when the profiles are not in the same group */
+	if (prof->group == previous_prof->group && prof->group != 0) {
+		if ( tfa98xx_cnt_verbose ) {
+			pr_debug("The new profile (%s) is in the same group as the current profile (%s) \n", 
+				tfaContGetString(&prof->name), tfaContGetString(&previous_prof->name));
+		}
+	} else {
+		/* mute */
+		err = tfaRunMute(dev_idx);
+		if (Tfa98xx_Error_Ok != err){
+			pr_err("tfaContWriteProfile()	  tfaRunMute	error(%d)\n", err);
+		}
+
+		/* Get current sample rate before we start switching */
+		fs_previous_profile = TFA_GET_BF(dev_idx, AUDFS);
+
+		/* clear SBSL to make sure we stay in initCF state */
+		if(tfa98xx_dev_family(dev_idx) == 2) {
+			TFA_SET_BF_VOLATILE(dev_idx, SBSL, 0);
+		}
+
+		/* When we switch profile we first power down the subsystem 
+		 * This should only be done when we are in operating mode
+		 * */
+		if (((dev_family == 2) && (TFA_GET_BF(dev_idx, MANSTATE) == 9)) || (dev_family != 2)) {
+			err = tfa98xx_powerdown(dev_idx, 1);
+			if (err) return err;
+			
+			/* Wait until we are in PLL powerdown */
+			do {
+				err = tfa98xx_dsp_system_stable(dev_idx, &ready);
+				if (!ready)
+					break;
+				else
+					msleep_interruptible(10); /* wait 10ms to avoid busload */
+				tries++;
+			} while (tries <= 100);
+
+			if (tries > 100) {
+				pr_debug("Wait for PLL powerdown timed out!\n");
+				return Tfa98xx_Error_StateTimedOut;
+			}
+		} else {
+			pr_debug("No need to go to powerdown now \n");
+		}
+	}
+
+	/* set all bitfield settings */
+	/* First set all default settings */
+	if (tfa98xx_cnt_verbose) {
+		pr_debug("---------- default settings profile: %s (%d) ---------- \n", 
+				tfaContGetString(&previous_prof->name), tfa_get_swprof(dev_idx));
+
+		if(tfa98xx_dev_family(dev_idx) == 2)
+			err = show_current_state(dev_idx);
+	}
+
+	/* Loop profile length */
+	for(i=0;i<previous_prof->length;i++) {
+		/* Search for the default section */
+		if(i == 0) {
+			while(previous_prof->list[i].type != dscDefault && i < previous_prof->length) {
+				i++;
+			}
+			i++;
+		}
+
+		/* Only if we found the default section try writing the items */
+		if(i < previous_prof->length) {
+			if ( tfaContWriteItem(dev_idx,  &previous_prof->list[i]) != Tfa98xx_Error_Ok )
+				return Tfa98xx_Error_Bad_Parameter;
+		}
+	}
+
+	if ( tfa98xx_cnt_verbose )
+		pr_debug("---------- new settings profile: %s (%d) ---------- \n", 
+				tfaContGetString(&prof->name), prof_idx);
+
+	/* set new settings */
+	for(i=0;i<prof->length;i++) {
+		/* Remember where we currently are with writing items*/
+		j = i;
+
+		/* We only want to write the values before the default section when we switch profile */
+		/* process and write all non-file items */
+		switch (prof->list[i].type) {
+			case dscFile:
+			case dscPatch:
+			case dscSetInputSelect:
+			case dscSetOutputSelect:
+			case dscSetProgramConfig:
+			case dscSetLagW:
+			case dscSetGains:
+			case dscSetvBatFactors:
+			case dscSetSensesCal:
+			case dscSetSensesDelay:
+			case dscSetMBDrc:
+			case dscCmd:
+			case dscFilter:
+			case dscDefault:
+				/* When one of these files are found, we exit */
+				i = prof->length;
+				break;
+			default:
+				err = tfaContWriteItem(dev_idx,  &prof->list[i]);
+				if ( err != Tfa98xx_Error_Ok )
+					return Tfa98xx_Error_Bad_Parameter;
+				break;
+		}
+	}
+
+	if (prof->group != previous_prof->group || prof->group == 0) {
+		if(tfa98xx_dev_family(dev_idx) == 2)
+			TFA_SET_BF_VOLATILE(dev_idx, MANSCONF, 1);
+
+		/* Leave powerdown state */
+		err = tfa_cf_powerup(dev_idx);
+		if (err) return err;
+		if (tfa98xx_cnt_verbose && tfa98xx_dev_family(dev_idx) == 2)
+			err = show_current_state(dev_idx);
+
+		if (tfa98xx_dev_family(dev_idx) == 2) {
+			/* Reset SBSL to 0 (workaround of enbl_powerswitch=0) */
+			TFA_SET_BF_VOLATILE(dev_idx, SBSL, 0);
+			/* Sending commands to DSP we need to make sure RST is 0 (otherwise we get no response)*/
+			TFA_SET_BF(dev_idx, RST, 0);
+		}
+	}
+
+	/* Check if there are sample rate changes */
+	err = get_sample_rate_info(dev_idx, prof, previous_prof, fs_previous_profile);
+	if (err) return err;
+
+	/* Write files from previous profile (default section)
+	 * Should only be used for the patch&trap patch (file)
+	 */
+	if(tfa98xx_dev_family(dev_idx) == 2) {
+		for(i=0;i<previous_prof->length;i++) {
+			/* Search for the default section */
+			if(i == 0) {
+				while(previous_prof->list[i].type != dscDefault && i < previous_prof->length) {
+					i++;
+				}
+				i++;
+			}
+
+			/* Only if we found the default section try writing the file */
+			if(i < previous_prof->length) {
+				if(previous_prof->list[i].type == dscFile || previous_prof->list[i].type == dscPatch) {
+					/* Only write this once */
+					if ( tfa98xx_cnt_verbose && k==0) {
+						pr_debug("---------- files default profile: %s (%d) ---------- \n", 
+								tfaContGetString(&previous_prof->name), prof_idx);
+						k++;
+					}
+					file = (nxpTfaFileDsc_t *)(previous_prof->list[i].offset+(uint8_t *)g_cont);
+					err = tfaContWriteFile(dev_idx,  file, vstep_idx, TFA_MAX_VSTEP_MSG_MARKER);
+				}
+			}
+		}
+	}
+
+	if ( tfa98xx_cnt_verbose) {
+		pr_debug("---------- files new profile: %s (%d) ---------- \n", 
+				tfaContGetString(&prof->name), prof_idx);
+	}
+
+	/* write everything until end or the default section starts 
+	 * Start where we currenly left */
+	for(i=j;i<prof->length;i++) {
+		/* We only want to write the values before the default section when we switch profile */
+		if(prof->list[i].type == dscDefault)
+			break;
+
+		switch (prof->list[i].type) {
+			case dscFile:
+			case dscPatch:
+				file = (nxpTfaFileDsc_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+				err = tfaContWriteFile(dev_idx, file, vstep_idx, TFA_MAX_VSTEP_MSG_MARKER);
+				break;
+			case dscSetInputSelect:
+			case dscSetOutputSelect:
+			case dscSetProgramConfig:
+			case dscSetLagW:
+			case dscSetGains:
+			case dscSetvBatFactors:
+			case dscSetSensesCal:
+			case dscSetSensesDelay:
+			case dscSetMBDrc:
+				create_dsp_buffer_msg((nxpTfaMsg_t *)
+					( prof->list[i].offset+(char*)g_cont), buffer, &size);
+				err = tfa_dsp_msg(dev_idx, size, buffer);
+
+				if ( tfa98xx_cnt_verbose )
+					pr_debug("command: %s=0x%02x%02x%02x \n",
+						tfaContGetCommandString(prof->list[i].type), 
+					(unsigned char)buffer[0], (unsigned char)buffer[1], (unsigned char)buffer[2]);
+				break;
+			case dscCmd:
+				size = *(uint16_t *)(prof->list[i].offset+(char*)g_cont);
+				err = tfa_dsp_msg(dev_idx, size, prof->list[i].offset+2+(char*)g_cont);
+
+				if ( tfa98xx_cnt_verbose ) {
+					cmd = (nxpTfaCmd_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+					pr_debug("Writing cmd=0x%02x%02x%02x \n", cmd->value[0], cmd->value[1], cmd->value[2]);
+				}
+				break;
+			default:
+				/* This allows us to write bitfield, registers or xmem after files */
+				if (tfaContWriteItem(dev_idx,  &prof->list[i]) != Tfa98xx_Error_Ok)
+					return Tfa98xx_Error_Bad_Parameter;
+				break;
+		}
+
+		if (err != Tfa98xx_Error_Ok)
+			return err;
+	}
+
+	if ((prof->group != previous_prof->group || prof->group == 0) && tfa98xx_dev_family(dev_idx) == 2) {
+		if (TFA_GET_BF(dev_idx, REFCKSEL) == 0) {
+			/* set SBSL to go to operation mode */		
+			TFA_SET_BF_VOLATILE(dev_idx, SBSL, 1);
+		}
+	}
+
+	return err;
+}
+
+/*
+ *  process only vstep in the profilelist
+ *
+ */
+enum Tfa98xx_Error tfaContWriteFilesVstep(int dev_idx, int prof_idx, int vstep_idx)
+{
+	nxpTfaProfileList_t *prof = tfaContProfile(dev_idx, prof_idx);
+	unsigned int i;
+	nxpTfaFileDsc_t *file;
+	nxpTfaHeader_t *hdr;
+	nxpTfaHeaderType_t type;
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	if ( !prof )
+		return Tfa98xx_Error_Bad_Parameter;
+
+	if ( tfa98xx_cnt_verbose )
+		tfa98xx_trace_printk("device:%s profile:%s vstep:%d\n", tfaContDeviceName(dev_idx),
+					tfaContProfileName(dev_idx,prof_idx),vstep_idx);
+
+	/* write vstep file only! */
+	for(i=0;i<prof->length;i++) {
+		if ( prof->list[i].type == dscFile ) {
+			file = (nxpTfaFileDsc_t *)(prof->list[i].offset+(uint8_t *)g_cont);
+			hdr = (nxpTfaHeader_t *)file->data;
+			type = (nxpTfaHeaderType_t) hdr->id;
+
+			switch (type) {
+			case volstepHdr:
+				if ( tfaContWriteFile(dev_idx, file, vstep_idx, TFA_MAX_VSTEP_MSG_MARKER) )
+					return Tfa98xx_Error_Bad_Parameter;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+	return err;
+}
+
+
+char *tfaContGetString(nxpTfaDescPtr_t * dsc)
+{
+	if ( dsc->type != dscString)
+		return nostring;
+
+	return dsc->offset+(char*)g_cont;
+}
+
+void individual_calibration_results(Tfa98xx_handle_t handle)
+{
+	int value_P, value_S;
+
+	/* Read the calibration result in xmem (529=primary channel) (530=secondary channel) */
+	tfa98xx_dsp_read_mem(handle, 529, 1, &value_P);  
+	tfa98xx_dsp_read_mem(handle, 530, 1, &value_S);  
+	
+	if(value_P != 1 && value_S != 1)
+		pr_debug("Calibration failed on both channels! \n");
+	else if(value_P != 1) {
+		pr_debug("Calibration failed on Primary (Left) channel! \n");
+		TFA_SET_BF_VOLATILE(handle, SSLEFTE, 0); /* Disable the sound for the left speaker */
+	}
+	else if(value_S != 1) {
+		pr_debug("Calibration failed on Secondary (Right) channel! \n");
+		TFA_SET_BF_VOLATILE(handle, SSRIGHTE, 0); /* Disable the sound for the right speaker */
+	}
+
+	TFA_SET_BF_VOLATILE(handle, AMPINSEL, 0); /* Set amplifier input to TDM */
+	TFA_SET_BF_VOLATILE(handle, SBSL, 1);
+}
+
+char *tfaContGetCommandString(uint32_t type)
+{
+	if(type == dscSetInputSelect)
+		return "setInputSelector";
+	else if(type == dscSetOutputSelect)
+		return "setOutputSelector";
+	else if(type == dscSetProgramConfig)
+		return "setProgramConfig";
+	else if(type == dscSetLagW)
+		return "setLagW";
+	else if(type == dscSetGains)
+		return "setGains";
+	else if(type == dscSetvBatFactors)
+		return "setvBatFactors";
+	else if(type == dscSetSensesCal)
+		return "setSensesCal";
+	else if(type == dscSetSensesDelay)
+		return "setSensesDelay";
+	else if(type == dscSetMBDrc)
+		return "setMBDrc";
+	else if(type == dscFilter)
+		return "filter";
+	else
+		return nostring;
+}
+
+/*	
+ * Get the name of the device at a certain index in the container file
+ *  return device name
+ */
+char  *tfaContDeviceName(int dev_idx) {
+	nxpTfaDeviceList_t *dev;
+
+	if ( dev_idx >= tfa98xx_cnt_max_device() )
+		return errorname;
+
+	if ( (dev = tfaContDevice(dev_idx)) == NULL )
+		return errorname;
+
+	return tfaContGetString(&dev->name);
+}
+
+/*
+ * Get the application name from the container file application field
+ * note that the input stringbuffer should be sizeof(application field)+1
+ *
+ */
+int tfa_cnt_get_app_name(char *name)
+{
+	unsigned int i;
+	int len = 0;
+
+	for(i=0; i<sizeof(g_cont->application); i++) {
+		if (isalnum(g_cont->application[i])) /* copy char if valid */
+			name[len++] = g_cont->application[i];
+		if (g_cont->application[i]=='\0') {
+			break;
+		}
+	}
+	name[len++] = '\0';
+
+	return len;
+}
+
+/*
+ * Get profile index of the calibration profile. 
+ * Returns: (profile index) if found, (-2) if no
+ * calibration profile is found or (-1) on error
+ */
+int tfaContGetCalProfile(int dev_idx) {
+	int prof, nprof, cal_idx = -2;
+
+	if ( (dev_idx < 0) || (dev_idx >= tfa98xx_cnt_max_device()) )
+		return -1;
+
+	nprof = tfaContMaxProfile(dev_idx);
+	/* search for the calibration profile in the list of profiles */
+	for (prof = 0; prof < nprof; prof++) {
+		if(strstr(tfaContProfileName(dev_idx, prof), ".cal") != NULL) {
+			cal_idx = prof;
+			pr_debug("Using calibration profile: '%s'\n", tfaContProfileName(dev_idx, prof));
+			break;
+		}
+	}
+	return cal_idx;
+}
+
+/**
+ * Is the profile a tap profile ?
+ * @param dev_idx the index of the device
+ * @param prof_idx the index of the profile
+ * @return 1 if the profile is a tap profile or 0 if not
+ */
+int tfaContIsTapProfile(int dev_idx, int prof_idx)
+{
+	if ( (dev_idx < 0) || (dev_idx >= tfa98xx_cnt_max_device()) )
+		return -1;
+
+	/* Check if next profile is tap profile */
+	if (strstr(tfaContProfileName(dev_idx, prof_idx), ".tap") != NULL) {
+		pr_debug("Using Tap profile: '%s'\n", tfaContProfileName(dev_idx, prof_idx));
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Get the name of the profile at certain index for a device in the container file
+ *  return profile name
+ */
+char *tfaContProfileName(int dev_idx, int prof_idx) {
+	nxpTfaProfileList_t *prof;
+
+	if ( (dev_idx < 0) || (dev_idx >= tfa98xx_cnt_max_device()) )
+		return errorname;
+	if ( (prof_idx < 0) || (prof_idx >= tfaContMaxProfile(dev_idx)) )
+		return nonename;
+
+	// the Nth profiles for this device
+	prof=tfaContGetDevProfList(g_cont, dev_idx, prof_idx);
+	return tfaContGetString(&prof->name);
+}
+
+/*
+ * return 1st profile list
+ */
+nxpTfaProfileList_t *tfaContGet1stProfList(nxpTfaContainer_t * cont)
+{
+	nxpTfaProfileList_t *prof;
+	uint8_t *b = (uint8_t *) cont;
+
+	int maxdev = 0;
+	nxpTfaDeviceList_t *dev;
+
+	// get nr of devlists
+	maxdev = cont->ndev;
+	// get last devlist
+	dev = tfaContGetDevList(cont, maxdev - 1);
+        if(dev == NULL)
+                return NULL;
+        // the 1st profile starts after the last device list
+	b = (uint8_t *) dev + sizeof(nxpTfaDeviceList_t) + dev->length * (sizeof(nxpTfaDescPtr_t));
+	prof = (nxpTfaProfileList_t *) b;
+	return prof;
+}
+
+/*
+ * return 1st livedata list
+ */
+nxpTfaLiveDataList_t *tfaContGet1stLiveDataList(nxpTfaContainer_t * cont)
+{
+        nxpTfaLiveDataList_t *ldata;
+        nxpTfaProfileList_t *prof;
+        nxpTfaDeviceList_t *dev;
+	uint8_t *b = (uint8_t *) cont;
+	int maxdev, maxprof;
+	
+	// get nr of devlists+1
+	maxdev = cont->ndev;
+        // get nr of proflists
+	maxprof = cont->nprof;
+	
+         // get last devlist
+	dev = tfaContGetDevList(cont, maxdev - 1);
+        // the 1st livedata starts after the last device list
+	b = (uint8_t *) dev + sizeof(nxpTfaDeviceList_t) + 
+                dev->length * (sizeof(nxpTfaDescPtr_t));
+
+        while(maxprof != 0) {
+                // get last proflist
+	        prof = (nxpTfaProfileList_t *) b; 
+                b += sizeof(nxpTfaProfileList_t) + 
+                     ((prof->length-1) * (sizeof(nxpTfaDescPtr_t)));
+                maxprof--;
+        }
+
+        /* Else the marker falls off */
+        b += 4; //bytes
+
+	ldata = (nxpTfaLiveDataList_t *) b;
+	return ldata;
+}
+
+
+enum Tfa98xx_Error tfaContOpen(int dev_idx)
+{
+	return tfa98xx_open((Tfa98xx_handle_t)dev_idx);
+}
+
+enum Tfa98xx_Error tfaContClose(int dev_idx)
+{
+	return tfa98xx_close(dev_idx);
+}
+
+/*
+ * return the device count in the container file
+ */
+int tfa98xx_cnt_max_device(void) {
+	return g_cont !=NULL ? g_cont->ndev : 0;
+}
+
+/*
+ * lookup slave and return device index
+ */
+int tfa98xx_cnt_slave2idx(int slave_addr) {
+	int idx;
+
+	for(idx=0;idx<g_devs;idx++) {
+		if (g_dev[idx]->dev == slave_addr )
+			return idx;
+	}
+
+	return -1;
+}
+
+/*
+ * lookup slave and return device revid
+ */
+int tfa98xx_cnt_slave2revid(int slave_addr) {
+	int idx = tfa98xx_cnt_slave2idx(slave_addr);
+	uint16_t revid;
+
+	if (idx<0)
+		return idx;
+
+	/* note that the device must have been opened before */
+	revid = tfa98xx_get_device_revision(idx);
+
+	/* quick check for valid contents */
+	return (revid&0xFF) >= 0x12 ? revid : -1 ;
+}
+
+/*
+ * return the device list pointer
+ */
+nxpTfaDeviceList_t *tfaContDevice(int dev_idx) {
+	if(dev_idx < g_devs)
+		return g_dev[dev_idx];
+	//pr_err("Devlist index too high:%d!", idx);
+	return NULL;
+}
+
+/*
+ * return the per device profile count
+ */
+int tfaContMaxProfile(int dev_idx) {
+	if ( dev_idx >= g_devs) {
+		//pr_err("Devlist index too high:%d!", ndev);
+		return 0;
+	}
+	return g_profs[dev_idx];
+}
+
+/*
+ * return the next profile:
+ *  - assume that all profiles are adjacent
+ *  - calculate the total length of the input
+ *  - the input profile + its length is the next profile
+ */
+nxpTfaProfileList_t* tfaContNextProfile(nxpTfaProfileList_t* prof) {
+	uint8_t *this, *next; /* byte pointers for byte pointer arithmetic */
+	nxpTfaProfileList_t* nextprof;
+	int listlength; /* total length of list in bytes */
+
+        if(prof == NULL)
+                return NULL;
+
+	if (prof->ID != TFA_PROFID)
+		return NULL;	/* invalid input */
+
+	this = (uint8_t *)prof;
+	/* nr of items in the list, length includes name dsc so - 1*/
+	listlength = (prof->length - 1)*sizeof(nxpTfaDescPtr_t);
+	/* the sizeof(nxpTfaProfileList_t) includes the list[0] length */
+	next = this + listlength + sizeof(nxpTfaProfileList_t);// - sizeof(nxpTfaDescPtr_t);
+	nextprof = (nxpTfaProfileList_t *)next;
+
+	if (nextprof->ID != TFA_PROFID)
+		return NULL;
+
+	return nextprof;
+}
+
+/*
+ * return the next livedata
+ */
+nxpTfaLiveDataList_t* tfaContNextLiveData(nxpTfaLiveDataList_t* livedata) {
+	nxpTfaLiveDataList_t* nextlivedata = (nxpTfaLiveDataList_t *)( (char*)livedata + (livedata->length*4) + 
+                                                                        sizeof(nxpTfaLiveDataList_t) -4);
+
+	if (nextlivedata->ID == TFA_LIVEDATAID)
+		return nextlivedata;
+
+	return NULL;
+}
+
+/*
+ * return the device list pointer
+ */
+nxpTfaProfileList_t* tfaContProfile(int dev_idx, int prof_ipx) {
+	if ( dev_idx >= g_devs) {
+		//pr_err("Devlist index too high:%d!", ndev);
+		return NULL;
+	}
+	if ( prof_ipx >= g_profs[dev_idx]) {
+		//pr_err("Proflist index too high:%d!", nprof);
+		return NULL;
+	}
+
+		return g_prof[dev_idx][prof_ipx];
+}
+
+/*
+ * check CRC for container
+ *   CRC is calculated over the bytes following the CRC field
+ *
+ *   return non zero value on error
+ */
+int tfaContCrcCheckContainer(nxpTfaContainer_t *cont) {
+	uint8_t *base;
+	size_t size;
+	uint32_t crc;
+
+	base = (uint8_t *)&cont->CRC + 4; // ptr to bytes following the CRC field
+	size = (size_t)(cont->size - (base - (uint8_t *)cont)); // nr of bytes following the CRC field
+	if (size < 0)
+		return 1;
+	crc = ~crc32_le(~0u, base, size);
+
+	return crc != cont->CRC;
+}
+
+/**
+ * Create a buffer which can be used to send to the dsp.
+ */
+void create_dsp_buffer_msg(nxpTfaMsg_t *msg, char *buffer, int *size) //TODO cleanup
+{
+        int i, j = 0;
+
+        /* Copy cmdId. Remember that the cmdId is reversed */
+        buffer[0] = msg->cmdId[2];
+        buffer[1] = msg->cmdId[1];
+        buffer[2] = msg->cmdId[0];
+
+        /* Copy the data to the buffer */
+        for(i=3; i<3+(msg->msg_size*3); i++) {
+                buffer[i] = (uint8_t) ((msg->data[j] >> 16) & 0xffff);
+                i++;
+                buffer[i] = (uint8_t) ((msg->data[j] >> 8) & 0xff);
+                i++;
+                buffer[i] = (uint8_t) (msg->data[j] & 0xff);
+                j++;
+        }
+
+        *size = (3+(msg->msg_size*3)) * sizeof(char);
+}
+
+void get_all_features_from_cnt(Tfa98xx_handle_t dev_idx, int *hw_feature_register, int sw_feature_register[2]) {
+        nxpTfaFeatures_t *features;
+        int i;
+
+        nxpTfaDeviceList_t *dev = tfaContDevice(dev_idx);
+  
+        /* Init values in case no keyword is defined in cnt file: */
+        *hw_feature_register = -1;
+        sw_feature_register[0] = -1;
+        sw_feature_register[1] = -1;
+
+        if(dev == NULL)
+                return;
+
+	// process the device list
+	for(i=0;i<dev->length;i++) {
+		if (dev->list[i].type == dscFeatures) {
+                        features = (nxpTfaFeatures_t *)(dev->list[i].offset+(uint8_t *)g_cont);
+                        *hw_feature_register = features->value[0];
+                        sw_feature_register[0] = features->value[1];
+                        sw_feature_register[1] = features->value[2];
+			break;
+		}
+	}
+}
+
+/* wrapper function */
+void get_hw_features_from_cnt(Tfa98xx_handle_t dev_idx, int *hw_feature_register) 
+{
+        int sw_feature_register[2]; 
+        get_all_features_from_cnt(dev_idx, hw_feature_register, sw_feature_register);
+}
+
+/* wrapper function */
+void get_sw_features_from_cnt(Tfa98xx_handle_t dev_idx, int sw_feature_register[2]) 
+{
+        int hw_feature_register; 
+        get_all_features_from_cnt(dev_idx, &hw_feature_register, sw_feature_register);
+}
+
+/* Factory trimming for the Boost converter */
+void tfa_factory_trimmer(Tfa98xx_handle_t dev_idx) 
+{
+	unsigned short currentValue, delta;
+	int result;
+
+	/* Factory trimming for the Boost converter */
+	/* check if there is a correction needed */
+	result = TFA_GET_BF(dev_idx, DCMCCAPI);
+	if (result) {
+		/* Get currentvalue of DCMCC and the Delta value */
+		currentValue = (unsigned short)TFA_GET_BF(dev_idx, DCMCC);
+		delta = (unsigned short)TFA_GET_BF(dev_idx, USERDEF);
+
+		/* check the sign bit (+/-) */
+		result = TFA_GET_BF(dev_idx, DCMCCSB);
+		if (result == 0) {
+			/* Do not exceed the maximum value of 15 */
+			if(currentValue + delta < 15) {
+				TFA_SET_BF_VOLATILE(dev_idx, DCMCC, currentValue + delta);
+				if (tfa98xx_cnt_verbose)
+					pr_debug("Max coil current is set to: %d \n", currentValue + delta);
+			} else {
+				TFA_SET_BF_VOLATILE(dev_idx, DCMCC, 15);
+				if (tfa98xx_cnt_verbose)
+					pr_debug("Max coil current is set to: 15 \n");
+			}
+		} else if (result == 1) {
+			/* Do not exceed the minimum value of 0 */
+			if(currentValue - delta > 0) {
+				TFA_SET_BF_VOLATILE(dev_idx, DCMCC, currentValue - delta);
+				if (tfa98xx_cnt_verbose)
+					pr_debug("Max coil current is set to: %d \n", currentValue - delta);
+			} else {
+				TFA_SET_BF_VOLATILE(dev_idx, DCMCC, 0);
+				if (tfa98xx_cnt_verbose)
+					pr_debug("Max coil current is set to: 0 \n");
+			}
+		}
+	}
+}
+
+enum Tfa98xx_Error tfa_set_filters(int dev_idx, int prof_idx) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaProfileList_t *prof = tfaContProfile(dev_idx, prof_idx);
+	unsigned int i;
+
+	if ( !prof )
+		return Tfa98xx_Error_Bad_Parameter;
+
+	/* If we are in powerdown there is no need to set filters */
+	if (TFA_GET_BF(dev_idx, PWDN) == 1)
+		return Tfa98xx_Error_Ok;
+
+	/* loop the profile to find filter settings */
+	for(i=0;i<prof->length;i++) {
+		/* We only want to write the values before the default section */
+		if(prof->list[i].type == dscDefault)
+			break;
+
+		/* write all filter settings */
+		if ( prof->list[i].type == dscFilter) {
+			if (tfaContWriteItem(dev_idx,  &prof->list[i]) != Tfa98xx_Error_Ok)
+				return err;
+		}
+	}
+
+	return err;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_container.h b/techpack/audio/asoc/codecs/tfa98xx/tfa_container.h
new file mode 100644
index 0000000..213b623
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_container.h
@@ -0,0 +1,397 @@
+/*
+ * tfaContainer.h
+ *
+ *  Created on: Sep 11, 2013
+ *      Author: wim
+ */
+
+#ifndef TFACONTAINER_H_
+#define TFACONTAINER_H_
+
+/* static limits */
+#define TFACONT_MAXDEVS  (4)   /* maximum nr of devices */
+#define TFACONT_MAXPROFS (16) /* maximum nr of profiles */
+
+#include "tfa98xx_parameters.h"
+
+/**
+ * Check the container file and set module global
+ * @param cnt pointer to container file
+ * @param length the length of the container file
+ * @return tfa_error
+ */
+enum tfa_error tfa_load_cnt(void *cnt, int length);
+
+/**
+ * Resets init variables
+ */
+void tfa_deinit(void);
+
+/**
+ * Verify the calibration results from each channel
+ * @param handle the index of the device
+ */
+void individual_calibration_results(Tfa98xx_handle_t handle);
+
+/**
+ * Return the descriptor string
+ * @param dsc pointer to nxpTfa descriptor
+ * @return descriptor string
+ */
+char *tfaContGetString(nxpTfaDescPtr_t *dsc); //TODO
+
+/**
+ * Gets the string for the given command type number
+ * @param type number representing a command
+ * @return string of a command
+ */
+char *tfaContGetCommandString(uint32_t type);
+
+/**
+ * get the device type from the patch in this devicelist
+ *  - find the patch file for this devidx
+ *  - return the devid from the patch or 0 if not found
+ * @param cnt pointer to container file
+ * @param dev_idx device index
+ * @return descriptor string
+ */
+int tfa_cnt_get_devid(nxpTfaContainer_t *cnt, int dev_idx) ;
+
+/**
+ * Get the number of devices from the container
+ * @return number of devices
+ */
+int tfa98xx_cnt_max_device(void);
+
+/**
+ * Set verbosity level
+ * @param level used as boolean
+ */
+void tfa_cnt_verbose(int level);
+
+/**
+ * Return the pointer to the loaded container file
+ * @return pointer to container, NULL if not loaded.
+ */
+nxpTfaContainer_t* tfa98xx_get_cnt(void);
+
+/**
+ * Lookup slave and return device index
+ * @param slave_addr address of the slave device
+ * @return device index
+ */
+int tfa98xx_cnt_slave2idx(int slave_addr);
+
+/**
+ * Lookup slave and return device revid.
+ * @param slave_addr address of the slave device
+ * @return device revid
+ */
+int tfa98xx_cnt_slave2revid(int slave_addr);
+
+/**
+ * Get the slave for the device if it exists.
+ * @param dev_idx the index of the device
+ * @param slave the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContGetSlave(int dev_idx, uint8_t *slave_addr);
+
+/**
+ * Write reg and bitfield items in the devicelist to the target.
+ * @param device the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWriteRegsDev(int dev_idx);
+
+/**
+ * Write  reg  and bitfield items in the profilelist to the target.
+ * @param device the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWriteRegsProf(int dev_idx, int prof_idx);
+
+/**
+ * Write a patchfile in the devicelist to the target.
+ * @param dev_idx the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWritePatch(int dev_idx);
+
+/**
+ * Write all  param files in the devicelist to the target.
+ * @param dev_idx the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWriteFiles(int dev_idx);
+
+/**
+ * Get sample rate from passed profile index
+ * @param dev_idx the index of the device
+ * @param prof_idx the index of the profile
+ * @return sample rate value
+ */
+unsigned int tfa98xx_get_profile_sr(int dev_idx, unsigned int prof_idx);
+
+/**
+ * Open the specified device after looking up the target address.
+ * @param dev_idx the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContOpen(int dev_idx);
+
+/**
+ * Close the  device.
+ * @param dev_idx the index of the device
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContClose(int dev_idx);
+
+/**
+ * Get the device name string
+ * @param dev_idx the index of the device
+ * @return device name string or error string if not found
+ */
+char  *tfaContDeviceName(int dev_idx);
+
+/**
+ * Get the application name from the container file application field
+ * @param name the input stringbuffer with size: sizeof(application field)+1
+ * @return actual string length
+ */
+int tfa_cnt_get_app_name(char *name);
+
+/**
+ * Get profile index of the calibration profile
+ * @param dev_idx the index of the device
+ * @return profile index, -2 if no calibration profile is found or -1 on error
+ */
+int tfaContGetCalProfile(int dev_idx);
+
+/**
+ * Is the profile a tap profile ?
+ * @param dev_idx the index of the device
+ * @param prof_idx the index of the profile
+ * @return 1 if the profile is a tap profile or 0 if not
+ */
+int tfaContIsTapProfile(int dev_idx, int prof_idx);
+
+/**
+ * Get the name of the profile at certain index for a device in the container file
+ * @param dev_idx the index of the device
+ * @param prof_idx the index of the profile
+ * @return profile name string or error string if not found
+ */
+char  *tfaContProfileName(int dev_idx, int prof_idx);
+
+/**
+ * Get the number of profiles for a device
+ * @param dev_idx index of the device
+ * @return the profile count
+ */
+int tfaContMaxProfile(int dev_idx);
+
+/**
+ * Process all items in the profilelist
+ * NOTE an error return during processing will leave the device muted
+ * @param dev_idx index of the device
+ * @param prof_idx index of the profile
+ * @param vstep_idx index of the vstep
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWriteProfile(int dev_idx, int prof_idx, int vstep_idx);
+
+/**
+ * Specify the speaker configurations (cmd id) (Left, right, both, none)
+ * @param dev_idx index of the device
+ * @param configuration name string of the configuration
+ */
+void tfa98xx_set_spkr_select(Tfa98xx_handle_t dev_idx, char *configuration);
+
+/**
+ * Set current vstep for a given channel
+ * @param vstep_idx index of the vstep
+ * @param channel index of the channel
+ */
+void tfaContSetCurrentVstep(int channel, int vstep_idx);
+
+/**
+ * Get current vstep for a given channel
+ * @param channel index of the channel
+ */
+int tfaContGetCurrentVstep(int channel);
+
+enum Tfa98xx_Error tfa_cont_write_filterbank(int dev_idx, nxpTfaFilter_t *filter);
+
+/**
+ * Write all  param files in the profilelist to the target
+ * this is used during startup when maybe ACS is set
+ * @param dev_idx the index of the device
+ * @param prof_idx the index of the profile
+ * @param vstep_idx the index of the vstep
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWriteFilesProf(int dev_idx, int prof_idx, int vstep_idx);
+
+
+enum Tfa98xx_Error tfaContWriteFilesVstep(int dev_idx, int prof_idx, int vstep_idx);
+enum Tfa98xx_Error tfaContWriteDrcFile(int dev_idx, int size, uint8_t data[]);
+
+/**
+ * Get the device list dsc from the tfaContainer
+ * @param cont pointer to the tfaContainer
+ * @param dev_idx the index of the device
+ * @return device list pointer
+ */
+nxpTfaDeviceList_t *tfaContGetDevList(nxpTfaContainer_t * cont, int dev_idx);
+
+/**
+ * Get the Nth profile for the Nth device
+ * @param cont pointer to the tfaContainer
+ * @param dev_idx the index of the device
+ * @param prof_idx the index of the profile
+ * @return profile list pointer
+ */
+nxpTfaProfileList_t *tfaContGetDevProfList(nxpTfaContainer_t *cont, int dev_idx, int prof_idx);
+
+/**
+ * Get the Nth livedata for the Nth device
+ * @param cont pointer to the tfaContainer
+ * @param dev_idx the index of the device
+ * @param livedata_idx the index of the livedata
+ * @return livedata list pointer
+ */
+nxpTfaLiveDataList_t *tfaContGetDevLiveDataList(nxpTfaContainer_t *cont, int dev_idx, int livedata_idx);
+
+/**
+ * Check CRC for container
+ * @param cont pointer to the tfaContainer
+ * @return error value 0 on error
+ */
+int tfaContCrcCheckContainer(nxpTfaContainer_t *cont);
+
+/**
+ * Get the device list pointer
+ * @param dev_idx the index of the device
+ * @return pointer to device list
+ */
+nxpTfaDeviceList_t *tfaContDevice(int dev_idx);
+
+/**
+ * Return the pointer to the profile in a list
+ * @param dev_idx the index of the device
+ * @param prof_ipx the index of the profile
+ * @return profile list pointer
+ */
+nxpTfaProfileList_t* tfaContProfile(int dev_idx, int prof_ipx);
+
+/**
+ * Return the pointer to the first profile in a list from the tfaContainer
+ * @param cont pointer to the tfaContainer
+ * @return pointer to first profile in profile list
+ */
+nxpTfaProfileList_t *tfaContGet1stProfList(nxpTfaContainer_t *cont);
+
+/**
+ * Return the pointer to the next profile in a list
+ * @param prof is the pointer to the profile list
+ * @return profile list pointer
+ */
+nxpTfaProfileList_t* tfaContNextProfile(nxpTfaProfileList_t *prof);
+
+/**
+ * Return the pointer to the first livedata in a list from the tfaContainer
+ * @param cont pointer to the tfaContainer
+ * @return pointer to first livedata in profile list
+ */
+nxpTfaLiveDataList_t *tfaContGet1stLiveDataList(nxpTfaContainer_t *cont);
+
+/**
+ * Return the pointer to the next livedata in a list
+ * @param livedata_idx is the pointer to the livedata list
+ * @return livedata list pointer
+ */
+nxpTfaLiveDataList_t* tfaContNextLiveData(nxpTfaLiveDataList_t *livedata_idx);
+
+/**
+ * Write a bit field
+ * @param dev_idx device index
+ * @param bf bitfield to write
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaRunWriteBitfield(Tfa98xx_handle_t dev_idx,  nxpTfaBitfield_t bf);//TODO move to run core
+
+/**
+ * Write a parameter file to the device
+ * @param dev_idx device index
+ * @param file filedescriptor pointer
+ * @param vstep_idx index to vstep
+ * @param vstep_msg_idx index to vstep message
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaContWriteFile(int dev_idx,  nxpTfaFileDsc_t *file, int vstep_idx, int vstep_msg_idx);
+
+/**
+ * Get the max volume step associated with Nth profile for the Nth device
+ * @param dev_idx device index
+ * @param prof_idx profile index
+ * @return the number of vsteps
+ */
+int tfacont_get_max_vstep(int dev_idx, int prof_idx);
+
+/**
+ * Get the file contents associated with the device or profile
+ * Search within the device tree, if not found, search within the profile
+ * tree. There can only be one type of file within profile or device.
+ * @param dev_idx I2C device index
+ * @param prof_idx I2C profile index in the device
+ * @param type file type
+ * @return 0 NULL if file type is not found
+ * @return 1 file contents
+ */
+nxpTfaFileDsc_t *tfacont_getfiledata(int dev_idx, int prof_idx, enum nxpTfaHeaderType type);
+
+/**
+ * Dump the contents of the file header
+ * @param hdr pointer to file header data
+ */
+void tfaContShowHeader(nxpTfaHeader_t *hdr);
+
+/**
+ * Read a bit field
+ * @param dev_idx device index
+ * @param bf bitfield to read out
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfaRunReadBitfield(Tfa98xx_handle_t dev_idx,  nxpTfaBitfield_t *bf);
+
+/**
+ * Get hw feature bits from container file
+ * @param dev_idx device index
+ * @param hw_feature_register pointer to where hw features are stored
+ */
+void get_hw_features_from_cnt(Tfa98xx_handle_t dev_idx, int *hw_feature_register);
+
+/**
+ * Get sw feature bits from container file
+ * @param dev_idx device index
+ * @param sw_feature_register pointer to where sw features are stored
+ */
+void get_sw_features_from_cnt(Tfa98xx_handle_t dev_idx, int sw_feature_register[2]);
+
+/**
+ * Factory trimming for the Boost converter
+ * check if there is a correction needed
+ * @param dev_idx device index
+ */
+void tfa_factory_trimmer(Tfa98xx_handle_t dev_idx);
+
+/**
+ * Search for filters settings and if found then write them to the device
+ * @param dev_idx device index
+ * @param prof_idx profile to look in
+ * @return Tfa98xx_Error
+ */
+enum Tfa98xx_Error tfa_set_filters(int dev_idx, int prof_idx);
+
+#endif /* TFACONTAINER_H_ */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_container_crc32.c b/techpack/audio/asoc/codecs/tfa98xx/tfa_container_crc32.c
new file mode 100644
index 0000000..b1ed92f
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_container_crc32.c
@@ -0,0 +1,108 @@
+/*
+ * tfaContainer_crc32.c
+ *
+ * Implement crc32 function
+ *
+ */
+
+#include "config.h"
+
+/*-
+ *  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
+ *  code or tables extracted from it, as desired without restriction.
+ *
+ *  First, the polynomial itself and its table of feedback terms.  The
+ *  polynomial is
+ *  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
+ *
+ *  Note that we take it "backwards" and put the highest-order term in
+ *  the lowest-order bit.  The X^32 term is "implied"; the LSB is the
+ *  X^31 term, etc.  The X^0 term (usually shown as "+1") results in
+ *  the MSB being 1
+ *
+ *  Note that the usual hardware shift register implementation, which
+ *  is what we're using (we're merely optimizing it by doing eight-bit
+ *  chunks at a time) shifts bits into the lowest-order term.  In our
+ *  implementation, that means shifting towards the right.  Why do we
+ *  do it this way?  Because the calculated CRC must be transmitted in
+ *  order from highest-order term to lowest-order term.  UARTs transmit
+ *  characters in order from LSB to MSB.  By storing the CRC this way
+ *  we hand it to the UART in the order low-byte to high-byte; the UART
+ *  sends each low-bit to hight-bit; and the result is transmission bit
+ *  by bit from highest- to lowest-order term without requiring any bit
+ *  shuffling on our part.  Reception works similarly
+ *
+ *  The feedback terms table consists of 256, 32-bit entries.  Notes
+ *
+ *      The table can be generated at runtime if desired; code to do so
+ *      is shown later.  It might not be obvious, but the feedback
+ *      terms simply represent the results of eight shift/xor opera
+ *      tions for all combinations of data and CRC register values
+ *
+ *      The values must be right-shifted by eight bits by the "updcrc
+ *      logic; the shift must be unsigned (bring in zeroes).  On some
+ *      hardware you could probably optimize the shift in assembler by
+ *      using byte-swap instructions
+ *      polynomial $edb88320
+ *
+ *
+ * CRC32 code derived from work by Gary S. Brown.
+ */
+
+static const uint32_t crc32_tab[] = {
+	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
+	0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
+	0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+	0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
+	0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
+	0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
+	0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
+	0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+	0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
+	0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
+	0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
+	0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
+	0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+	0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
+	0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
+	0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
+	0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
+	0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+	0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
+	0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
+	0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
+	0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+uint32_t crc32_le(uint32_t crc, unsigned char const *buf, size_t len)
+{
+	const uint8_t *p;
+
+	p = buf;
+
+	while (len--)
+		crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
+
+	return crc;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_debug.c b/techpack/audio/asoc/codecs/tfa98xx/tfa_debug.c
new file mode 100644
index 0000000..5f7b00d
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_debug.c
@@ -0,0 +1,302 @@
+
+#include "tfa_service.h"
+#include "tfa98xx_tfafieldnames.h"
+#include "config.h"
+
+/* support for error code translation into text */
+static char latest_errorstr[64];
+
+const char* tfa98xx_get_error_string(enum Tfa98xx_Error error)
+{
+  const char* pErrStr;
+
+  switch (error)
+  {
+  case Tfa98xx_Error_Ok:
+    pErrStr = "Ok";
+    break;
+  case Tfa98xx_Error_DSP_not_running:
+    pErrStr = "DSP_not_running";
+    break;
+  case Tfa98xx_Error_Bad_Parameter:
+    pErrStr = "Bad_Parameter";
+    break;
+  case Tfa98xx_Error_NotOpen:
+    pErrStr = "NotOpen";
+    break;
+  case Tfa98xx_Error_InUse:
+    pErrStr = "InUse";
+    break;
+  case Tfa98xx_Error_RpcBusy:
+    pErrStr = "RpcBusy";
+    break;
+  case Tfa98xx_Error_RpcModId:
+    pErrStr = "RpcModId";
+    break;
+  case Tfa98xx_Error_RpcParamId:
+    pErrStr = "RpcParamId";
+    break;
+  case Tfa98xx_Error_RpcInfoId:
+    pErrStr = "RpcInfoId";
+    break;
+  case Tfa98xx_Error_RpcNotAllowedSpeaker:
+    pErrStr = "RpcNotAllowedSpeaker";
+    break;
+  case Tfa98xx_Error_Not_Supported:
+    pErrStr = "Not_Supported";
+    break;
+  case Tfa98xx_Error_I2C_Fatal:
+    pErrStr = "I2C_Fatal";
+    break;
+  case Tfa98xx_Error_I2C_NonFatal:
+    pErrStr = "I2C_NonFatal";
+    break;
+  case Tfa98xx_Error_StateTimedOut:
+	pErrStr = "WaitForState_TimedOut";
+	break;
+  default:
+    sprintf(latest_errorstr, "Unspecified error (%d)", (int)error);
+    pErrStr = latest_errorstr;
+  }
+  return pErrStr;
+}
+/*****************************************************************************/
+/*      bitfield lookups */
+/*
+ * generic table lookup functions
+ */
+/**
+ * lookup bf in table
+ *   return 'unkown' if not found
+ */
+static char *tfa_bf2name(tfaBfName_t *table, uint16_t bf) {
+	int n=0;
+
+	do {
+		if ((table[n].bfEnum & 0xfff0 ) == (bf & 0xfff0 )) {
+			return table[n].bfName;
+		}
+	}
+	while( table[n++].bfEnum != 0xffff);
+
+	return table[n-1].bfName; /* last name says unkown */
+}
+/**
+ * lookup name in table
+ *   return 0xffff if not found
+ */
+static uint16_t tfa_name2bf(tfaBfName_t *table,const  char *name) {
+	int n = 0;
+
+	do {
+#if defined(WIN32) || defined(_X64)
+		if(_stricmp(name, table[n].bfName)==0)
+			return table[n].bfEnum;
+#else
+		if(strcasecmp(name, table[n].bfName)==0)
+			return table[n].bfEnum;
+#endif
+	} while (table[n++].bfEnum != 0xffff);
+
+	return 0xffff;
+}
+
+/*
+ * tfa2 bitfield name table
+ */
+TFA2_NAMETABLE
+TFA2_BITNAMETABLE
+
+/*
+ * tfa1 bitfield name tables
+ */
+TFA1_NAMETABLE
+TFA9890_NAMETABLE
+TFA9891_NAMETABLE
+TFA9887_NAMETABLE
+TFA1_BITNAMETABLE
+TFA9890_BITNAMETABLE
+TFA9891_BITNAMETABLE
+TFA9887_BITNAMETABLE
+char *tfaContBitName(uint16_t num, unsigned short rev)
+{
+	char *name;
+	 /* end of list for the unknown string */
+	int tableLength = sizeof(Tfa1DatasheetNames)/sizeof(tfaBfName_t);
+	const char *unknown=Tfa1DatasheetNames[tableLength-1].bfName;
+
+	switch (rev & 0xff) {
+	case 0x88:
+		name =  tfa_bf2name(Tfa2BitNames, num);
+		break;
+	case 0x97:
+		name =  tfa_bf2name(Tfa1BitNames, num);
+		break;
+	case 0x92:
+		name =  tfa_bf2name(Tfa9891BitNames, num);
+		if (strcmp(unknown, name)==0)
+			name = tfa_bf2name(Tfa9891BitNames, num);/* try long bitname table */
+		break;
+	case 0x91:
+	case 0x80:
+	case 0x81:
+		name = tfa_bf2name(Tfa9890BitNames, num); /* my tabel 1st */
+		if (strcmp(unknown, name)==0)
+			name = tfa_bf2name(Tfa1BitNames, num); /* try generic table */
+		break;
+	case 0x12:
+		name = tfa_bf2name(Tfa9887BitNames, num); /* my tabel 1st */
+		if (strcmp(unknown, name)==0)
+			name = tfa_bf2name(Tfa1BitNames, num);/* try generic table */
+		break;
+	default:
+		PRINT_ERROR("unknown REVID:0x%0x\n", rev);
+		tableLength = sizeof(Tfa1BitNames)/sizeof(tfaBfName_t); /* end of list */
+		name = (char *)unknown;
+		break;
+	}
+	return name;
+}
+
+char *tfaContDsName(uint16_t num, unsigned short rev)
+{
+	char *name;
+	 /* end of list for the unknown string */
+	int tableLength = sizeof(Tfa1DatasheetNames)/sizeof(tfaBfName_t);
+	const char *unknown=Tfa1DatasheetNames[tableLength-1].bfName;
+
+	switch (rev & 0xff) {
+	case 0x88:
+		name =  tfa_bf2name(Tfa2DatasheetNames, num);
+		break;
+	case 0x97:
+		name =  tfa_bf2name(Tfa1DatasheetNames, num);
+		break;
+	case 0x92:
+		name =  tfa_bf2name(Tfa9891DatasheetNames, num);
+		if (strcmp(unknown, name)==0)
+			name = tfa_bf2name(Tfa9891BitNames, num);/* try long bitname table */
+		break;
+	case 0x91:
+	case 0x80:
+	case 0x81:
+		name = tfa_bf2name(Tfa9890DatasheetNames, num); /* my tabel 1st */
+		if (strcmp(unknown, name)==0)
+			name = tfa_bf2name(Tfa1DatasheetNames, num); /* try generic table */
+		break;
+	case 0x12:
+		name = tfa_bf2name(Tfa9887DatasheetNames, num); /* my tabel 1st */
+		if (strcmp(unknown, name)==0)
+			name = tfa_bf2name(Tfa1DatasheetNames, num);/* try generic table */
+		break;
+	default:
+		PRINT_ERROR("unknown REVID:0x%0x\n", rev);
+		tableLength = sizeof(Tfa1DatasheetNames)/sizeof(tfaBfName_t); /* end of list */
+		name = (char *)unknown;
+		break;
+	}
+	return name;
+}
+
+char *tfaContBfName(uint16_t num, unsigned short rev)
+{
+	char *name;
+	/* end of list for the unknown string */
+	int tableLength = sizeof(Tfa1DatasheetNames)/sizeof(tfaBfName_t);
+	const char *unknown=Tfa1DatasheetNames[tableLength-1].bfName;
+
+	/* if datasheet name does not exist look for bitfieldname */
+	name = tfaContDsName(num, rev);
+	if (strcmp(unknown, name)==0)
+		name = tfaContBitName(num, rev);
+
+	return name;
+}
+
+uint16_t tfaContBfEnum(const char *name, unsigned short rev)
+{
+	uint16_t bfnum;
+
+	switch (rev & 0xff) {
+	case 0x88:
+		bfnum =  tfa_name2bf(Tfa2DatasheetNames, name);
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa2BitNames, name);/* try long bitname table */
+		break;
+	case 0x97:
+		bfnum =  tfa_name2bf(Tfa1DatasheetNames, name);
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa1BitNames, name);/* try generic table */
+		break;
+	case 0x92:
+		bfnum =  tfa_name2bf(Tfa9891DatasheetNames, name);
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa9891BitNames, name);/* try long bitname table */
+		break;
+	case 0x91:
+	case 0x80:
+	case 0x81:
+		bfnum = tfa_name2bf(Tfa9890DatasheetNames, name); /* my tabel 1st */
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa1DatasheetNames, name);/* try generic table */
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa1BitNames, name); /* try 2nd generic table */
+		break;
+	case 0x12:
+		bfnum = tfa_name2bf(Tfa9887DatasheetNames, name); /* my tabel 1st */
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa1DatasheetNames, name);/* try generic table */
+		if (bfnum==0xffff)
+			bfnum = tfa_name2bf(Tfa1BitNames, name);/* try 2nd generic table */
+		break;
+	default:
+		PRINT_ERROR("unknown REVID:0x%0x\n", rev);
+		bfnum=0xffff;
+		break;
+	}
+
+	return bfnum;
+}
+
+/*
+ * check all lists for a hit
+ *  this is for the parser to know if it's  an existing bitname
+ */
+uint16_t tfaContBfEnumAny(const char *name)
+{
+	uint16_t bfnum;
+
+		/* datasheet names first */
+		bfnum =  tfa_name2bf(Tfa2DatasheetNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa1DatasheetNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa9891DatasheetNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa9890DatasheetNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa9887DatasheetNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		/* and then bitfield names */
+		bfnum =  tfa_name2bf(Tfa2BitNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa1BitNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa9891BitNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa9890BitNames, name);
+		if (bfnum!=0xffff)
+			return bfnum;
+		bfnum =  tfa_name2bf(Tfa9887BitNames, name);
+
+		return bfnum;
+
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_dsp.c b/techpack/audio/asoc/codecs/tfa98xx/tfa_dsp.c
new file mode 100644
index 0000000..21c32ec
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_dsp.c
@@ -0,0 +1,3278 @@
+/*
+ *Copyright 2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+
+#include "config.h"
+
+#include "tfa98xx_tfafieldnames.h"
+#include "tfa_internal.h"
+#include "tfa.h"
+#include "tfa_service.h"
+#include "tfa_container.h"
+#include "tfa_dsp_fw.h"
+/* TODO: remove genregs usage? */
+#include "tfa98xx_genregs_N1C.h"
+
+/* handle macro for bitfield */
+#define TFA_MK_BF(reg, pos, len) ((reg<<8)|(pos<<4)|(len-1))
+
+/* abstract family for register */
+#define FAM_TFA98XX_CF_CONTROLS (TFA_FAM(handle,RST) >> 8)
+#define FAM_TFA98XX_CF_MEM      (TFA_FAM(handle,MEMA)>> 8)
+#define FAM_TFA98XX_MTP0        (TFA_FAM(handle,MTPOTC) >> 8)
+#define FAM_TFA98xx_INT_EN      (TFA_FAM(handle,INTENVDDS) >> 8)
+
+#define CF_STATUS_I2C_CMD_ACK 0x01
+
+#if (defined(TFA9888) || defined(TFA98XX_FULL))
+void tfa9888_ops(struct tfa_device_ops *ops);
+#endif
+#if (defined(TFA9891) || defined(TFA98XX_FULL))
+void tfa9891_ops(struct tfa_device_ops *ops);
+#endif
+#if (defined(TFA9897) || defined(TFA98XX_FULL))
+void tfa9897_ops(struct tfa_device_ops *ops);
+#endif
+#if (defined(TFA9890) || defined(TFA98XX_FULL))
+void tfa9890_ops(struct tfa_device_ops *ops);
+#endif
+#if (defined(TFA9887B) || defined(TFA98XX_FULL))
+int tfa9887B_is87(Tfa98xx_handle_t handle);
+void tfa9887B_ops(struct tfa_device_ops *ops);
+#endif
+#if (defined(TFA9887) || defined(TFA98XX_FULL))
+void tfa9887_ops(struct tfa_device_ops *ops);
+#endif
+
+#ifndef MIN
+#define MIN(A,B) (A<B?A:B)
+#endif
+
+// retry values
+#define CFSTABLE_TRIES   10
+#define PWDNWAIT_TRIES   50
+#define AMPOFFWAIT_TRIES 50
+#define MTPBWAIT_TRIES   50
+#define MTPEX_WAIT_NTRIES 25
+
+static int tfa98xx_runtime_verbose;
+static int tfa98xx_trace_level;
+
+/* 4 possible I2C addresses
+ */
+#define MAX_HANDLES 4
+TFA_INTERNAL struct Tfa98xx_handle_private handles_local[MAX_HANDLES];
+
+/*
+ * static functions
+ */
+
+TFA_INTERNAL int tfa98xx_handle_is_open(Tfa98xx_handle_t h)
+{
+	int retval = 0;
+
+	if ((h >= 0) && (h < MAX_HANDLES))
+		retval = handles_local[h].in_use != 0;
+
+	return retval;
+}
+
+int print_calibration(Tfa98xx_handle_t handle, char *str, size_t size)
+{
+	return snprintf(str, size, " Prim:%d mOhms, Sec:%d mOhms\n",
+				handles_local[handle].mohm[0],
+				handles_local[handle].mohm[1]);
+}
+
+int tfa_get_calibration_info(Tfa98xx_handle_t handle, int channel) {
+		return handles_local[handle].mohm[channel];
+}
+/*
+ * open
+ */
+
+/*
+ *  set device info and register device ops
+ */
+static void tfa_set_query_info (int dev_idx) {
+
+	if (dev_idx > MAX_HANDLES) {
+		_ASSERT(dev_idx >= MAX_HANDLES);
+		return;
+	}
+	
+	/* invalidate  device struct cached values */
+	handles_local[dev_idx].hw_feature_bits = -1;
+	handles_local[dev_idx].sw_feature_bits[0] = -1;
+	handles_local[dev_idx].sw_feature_bits[1] = -1;
+	handles_local[dev_idx].profile = -1;
+	handles_local[dev_idx].vstep[0] = -1;
+	handles_local[dev_idx].vstep[1] = -1;
+	/* defaults */
+	handles_local[dev_idx].tfa_family = 1;
+	handles_local[dev_idx].daimap = Tfa98xx_DAI_I2S;		/* all others */
+	handles_local[dev_idx].spkr_count = 1;
+	handles_local[dev_idx].spkr_select = 0;
+	handles_local[dev_idx].support_tcoef = supportYes;
+	handles_local[dev_idx].supportDrc = supportNotSet;
+	handles_local[dev_idx].support_saam = supportNotSet;
+         
+	/* TODO use the getfeatures() for retrieving the features [artf103523]
+	handles_local[dev_idx].supportDrc = supportNotSet;*/
+
+	switch (handles_local[dev_idx].rev & 0xff) {
+	case 0x88:
+		/* tfa9888 */
+		handles_local[dev_idx].tfa_family = 2;
+		handles_local[dev_idx].spkr_count = 2;
+		handles_local[dev_idx].daimap = Tfa98xx_DAI_TDM;
+		tfa9888_ops(&handles_local[dev_idx].dev_ops); /* register device operations */
+		break;
+	case 0x97:
+		/* tfa9897 */
+		handles_local[dev_idx].supportDrc = supportNo;
+		handles_local[dev_idx].spkr_count = 1;
+		handles_local[dev_idx].daimap = Tfa98xx_DAI_TDM;
+		tfa9897_ops(&handles_local[dev_idx].dev_ops); /* register device operations */
+		break;
+	case 0x92:
+		/* tfa9891 */
+		handles_local[dev_idx].spkr_count = 1;
+		handles_local[dev_idx].daimap = ( Tfa98xx_DAI_PDM | Tfa98xx_DAI_I2S );
+		tfa9891_ops(&handles_local[dev_idx].dev_ops); /* register device operations */
+		break;
+	case 0x91:
+		/* tfa9890B */
+		handles_local[dev_idx].spkr_count = 1;
+		handles_local[dev_idx].daimap = ( Tfa98xx_DAI_PDM | Tfa98xx_DAI_I2S );
+		break;
+	case 0x80:
+	case 0x81:
+		/* tfa9890 */
+		handles_local[dev_idx].spkr_count = 1;
+		handles_local[dev_idx].daimap = Tfa98xx_DAI_I2S;
+		handles_local[dev_idx].supportDrc = supportNo;
+		handles_local[dev_idx].supportFramework = supportNo;
+		tfa9890_ops(&handles_local[dev_idx].dev_ops); /* register device operations */
+		break;
+	case 0x12:
+		/* tfa9887 / tfa9887B / tfa9895 */
+		handles_local[dev_idx].spkr_count = 1;
+		handles_local[dev_idx].daimap = Tfa98xx_DAI_I2S;
+		if (tfa9887B_is87(dev_idx)) {
+			handles_local[dev_idx].support_tcoef = supportNo;
+			tfa9887_ops(&handles_local[dev_idx].dev_ops); /* register device operations */
+		} else
+			tfa9887B_ops(&handles_local[dev_idx].dev_ops); /* register device operations */
+		break;
+	default:
+		pr_err("unknown device type : 0x%02x\n", handles_local[dev_idx].rev);
+		_ASSERT(0);
+		break;
+	}
+}
+
+/*
+ * lookup the device type and return the family type
+ */
+int tfa98xx_dev2family(int dev_type) {
+	/* only look at the die ID part (lsb byte) */
+	switch(dev_type & 0xff) {
+	case 0x12:
+	case 0x80:
+	case 0x81:
+	case 0x91:
+	case 0x92:
+	case 0x97:
+		return 1;
+	case 0x88:
+		return 2;
+	case 0x50:
+		return 3;
+	default:
+		return 0;
+	}
+}
+
+int tfa98xx_dev_family(Tfa98xx_handle_t dev_idx) {
+	return handles_local[dev_idx].tfa_family;
+}
+
+unsigned short tfa98xx_dev_revision(Tfa98xx_handle_t dev_idx)
+{
+	return handles_local[dev_idx].rev;
+}
+
+void tfa98xx_set_spkr_select(Tfa98xx_handle_t dev_idx, char *configuration) {
+	 char firstLetter;
+
+	/* 4=Left, 2=Right, 1=none, 0=default */
+	if (configuration==NULL)
+		handles_local[dev_idx].spkr_select = 0;
+	else
+	{
+		firstLetter = (char)tolower((unsigned char)configuration[0]);
+		switch (firstLetter) {
+		        case 'b': /* SC / both -> apply primary also to secondary */
+				handles_local[dev_idx].spkr_select = 8;
+				handles_local[dev_idx].spkr_count = 2;
+				break;
+			case 'l':
+			case 'p': /* DS / left -> only use primary channel */
+				handles_local[dev_idx].spkr_select = 4;
+				handles_local[dev_idx].spkr_count = 1;
+				break;
+			case 'r':
+			case 's': /* DP / right -> only use secondary channel */
+				handles_local[dev_idx].spkr_select = 2;
+				handles_local[dev_idx].spkr_count = 1;
+				break;
+			case 'd': /* DC / disable -> skip applying configuration for both */
+				handles_local[dev_idx].spkr_select = 1;
+				handles_local[dev_idx].spkr_count = 2;
+				break;
+			default:
+				handles_local[dev_idx].spkr_select = 0;
+				handles_local[dev_idx].spkr_count = 2;
+				break;
+		}
+	}
+}
+
+void tfa_mock_probe(int dev_idx, unsigned short revid, int slave_address)
+{
+        handles_local[dev_idx].slave_address = (unsigned char)slave_address*2;
+        handles_local[dev_idx].rev = revid;
+        tfa_set_query_info(dev_idx);
+}
+
+enum Tfa98xx_Error
+tfa_soft_probe(int dev_idx, int revid)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	error = tfaContGetSlave(dev_idx, &handles_local[dev_idx].slave_address);
+	handles_local[dev_idx].slave_address *=2;
+	if (error)
+		return error;
+
+	handles_local[dev_idx].rev = (unsigned short)revid;
+	tfa_set_query_info(dev_idx);
+
+	return error;
+}
+
+/*
+ * TODO The slave/cnt check in tfa98xx_register_dsp() should be done here in tfa_probe()
+ */
+enum Tfa98xx_Error
+tfa_probe(unsigned char slave_address, Tfa98xx_handle_t *pHandle)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	int rev;
+	int idx;
+
+	_ASSERT(pHandle != NULL);
+	*pHandle = -1;
+
+	/* when available select index used in container file */
+	idx = tfa98xx_cnt_slave2idx(slave_address>>1);
+	if (idx < 0)
+		idx = 0; /* when no container file, use first instance */
+
+	if (handles_local[idx].in_use == 1)
+		return Tfa98xx_Error_InUse;
+
+	handles_local[idx].in_use = 1;
+
+	switch (slave_address) {
+	case TFA98XX_GENERIC_SLAVE_ADDRESS:     /* same as (0x0E<<1) test adr */
+	case 0x68:
+	case 0x6A:
+	case 0x6C:
+	case 0x6E:
+	case (0x1a<<1): //TODO properly implement foreign i2c addressing like uda1355
+		handles_local[idx].buffer_size =  NXP_I2C_BufferSize();
+		handles_local[idx].slave_address = slave_address;
+// TODO: how do we deal with old bugs?
+#if (defined(TFA9887)  || defined (TFA9887B) || defined(TFA98XX_FULL))
+		/* do a dummy read in order to generate
+		 * i2c clocks when accessing the device
+		 * for the first time
+		 */
+		rev = TFA_READ_REG(idx, REV);
+#endif
+		/* this can be the very first read, so check error here */
+		rev = TFA_READ_REG(idx, REV);
+		if (rev < 0) /* returns negative if error */
+			error = -rev;
+		if (Tfa98xx_Error_Ok != error) {
+			handles_local[idx].in_use = 0;
+			pr_debug("\nError: Unable to read revid from slave:0x%02x \n", slave_address/2);
+			return error;
+		}
+		handles_local[idx].rev = (unsigned short) rev;
+		*pHandle = idx;
+		error = Tfa98xx_Error_Ok;
+#ifdef __KERNEL__ /* don't spam userspace with information */
+		tfa98xx_trace_printk("slave:0x%02x revid:0x%04x\n", slave_address, rev);
+		pr_debug("slave:0x%02x revid:0x%04x\n", slave_address, rev);
+#endif
+		break;
+	default:
+		pr_info("Unknown slave adress! \n");
+		/* wrong slave address */
+		error = Tfa98xx_Error_Bad_Parameter;
+	}
+
+	tfa_set_query_info(idx);
+
+	handles_local[idx].in_use = 0;
+
+	return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_open(Tfa98xx_handle_t handle)
+{
+	if (tfa98xx_handle_is_open(handle)) {
+		return Tfa98xx_Error_InUse;
+	} else {
+		handles_local[handle].in_use = 1;
+		return Tfa98xx_Error_Ok;
+	}
+}
+
+/*
+ * close
+ */
+enum Tfa98xx_Error tfa98xx_close(Tfa98xx_handle_t handle)
+{
+	if (tfa98xx_handle_is_open(handle)) {
+		handles_local[handle].in_use = 0;
+		return Tfa98xx_Error_Ok;
+	} else {
+		return Tfa98xx_Error_NotOpen;
+	}
+}
+
+/*
+ * 	return the target address for the filter on this device
+  
+  filter_index:
+	[0..9] reserved for EQ (not deployed, calc. is available)
+	[10..12] anti-alias filter
+	[13]  integrator filter
+
+ */
+enum Tfa98xx_DMEM tfa98xx_filter_mem(Tfa98xx_handle_t dev, int filter_index, unsigned short *address, int channel)
+{
+	enum Tfa98xx_DMEM  dmem=-1;
+	int idx;
+	unsigned short bq_table[7][4] ={
+	/* index: 10, 11, 12, 13 */
+			{346,351,356,288}, //87 BRA_MAX_MRA4-2_7.00
+			{346,351,356,288}, //90 BRA_MAX_MRA6_9.02
+			{467,472,477,409}, //95 BRA_MAX_MRA7_10.02
+			{406,411,416,348}, //97 BRA_MAX_MRA9_12.01
+			{467,472,477,409}, //91 BRA_MAX_MRAA_13.02
+			{8832, 8837, 8842, 8847}, //88 part1
+			{8853, 8858, 8863, 8868}  //88 part2
+			/* Since the 88 is stereo we have 2 parts.
+			 * Every index has 5 values except index 13 this one has 6 values
+			 */
+	};
+
+	if ( (10 <= filter_index) && (filter_index <= 13) ) {
+		dmem = Tfa98xx_DMEM_YMEM; /* for all devices */
+		idx = filter_index-10;
+
+		switch (handles_local[dev].rev & 0xff ) { // only compare lower byte
+		case 0x12:
+			if ( tfa9887B_is87(dev) )
+	        		*address = bq_table[0][idx];
+			else
+				*address = bq_table[2][idx];
+			break;
+		case 0x97:
+			*address = bq_table[3][idx];
+			break;
+		case 0x80:
+		case 0x81: // for the RAM version
+		case 0x91:
+			*address = bq_table[1][idx];
+			break;
+		case 0x92:
+			*address = bq_table[4][idx];
+			break;
+		case 0x88:
+			/* Channel 1 = primary, 2 = secondary */
+			if(channel == 1)
+				*address = bq_table[5][idx];
+			else
+				*address = bq_table[6][idx];
+			break;
+		default:
+			/* unsupported case, possibly intermediate version */
+			return -1;
+			_ASSERT(0);
+		}
+	}
+	return dmem;
+}
+
+/************************ query functions ********************************************************/
+/* no device involved */
+/**
+ * return revision
+ */
+void tfa98xx_rev(int *major, int *minor, int *revision) {
+	*major = TFA98XX_API_REV_MAJOR;
+	*minor = TFA98XX_API_REV_MINOR;
+    *revision = TFA98XX_API_REV_REVISION;
+}
+
+/**
+ * Return the maximum nr of devices (SC39786)
+ */
+int tfa98xx_max_devices(void) //TODO get from cnt (now only called from contOpen)
+{
+	return MAX_HANDLES;
+}
+
+/* return the device revision id
+ */
+unsigned short tfa98xx_get_device_revision(Tfa98xx_handle_t handle)
+{
+	/* local function. Caller must make sure handle is valid */
+	return handles_local[handle].rev;
+}
+
+/**
+ * return the device digital audio interface (DAI) type bitmap
+ */
+enum Tfa98xx_DAI tfa98xx_get_device_dai(Tfa98xx_handle_t handle)
+{
+	/* local function. Caller must make sure handle is valid */
+	return handles_local[handle].daimap;
+}
+
+/**
+ * get the feature bits from the DSP
+ *  - the older tfa9887 does not support this getfeature and
+ *    also no tcoef support so we use this as the info for returning
+ *    this feature
+ */
+enum Tfa98xx_Error tfa98xx_dsp_support_tcoef(Tfa98xx_handle_t dev_idx,
+		int *pb_support_tCoef)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	/* if already set return that state , always assume supported */
+	if ( handles_local[dev_idx].support_tcoef != supportNotSet) {
+		*pb_support_tCoef = (handles_local[dev_idx].support_tcoef == supportYes);
+	}
+
+	handles_local[dev_idx].support_tcoef = *pb_support_tCoef ? supportYes : supportNo;
+
+	return error;
+}
+
+/**
+ * tfa98xx_supported_speakers
+ *  returns the number of the supported speaker count
+ */
+enum Tfa98xx_Error tfa98xx_supported_speakers(Tfa98xx_handle_t handle, int* spkr_count)
+{
+	if (tfa98xx_handle_is_open(handle)) {
+		*spkr_count = handles_local[handle].spkr_count;
+	} else
+		return Tfa98xx_Error_NotOpen;
+
+	return Tfa98xx_Error_Ok;
+}
+
+/**
+ * tfa98xx_supported_dai
+ *  returns the bitmap of the supported Digital Audio Interfaces
+ */
+enum Tfa98xx_Error tfa98xx_supported_dai(Tfa98xx_handle_t handle, enum Tfa98xx_DAI *daimap)
+{
+	if (tfa98xx_handle_is_open(handle)) {
+		*daimap = handles_local[handle].daimap;
+	} else
+		return Tfa98xx_Error_NotOpen;
+
+	return Tfa98xx_Error_Ok;
+}
+
+/*
+ * tfa98xx_supported_saam
+ *  returns the supportedspeaker as microphone feature
+ */
+enum Tfa98xx_Error tfa98xx_supported_saam(Tfa98xx_handle_t handle, enum Tfa98xx_saam *saam)
+{
+	int features;
+	enum Tfa98xx_Error error;
+
+	if (handles_local[handle].support_saam == supportNotSet) {
+		error = tfa98xx_dsp_get_hw_feature_bits(handle,&features);
+		if (error!=Tfa98xx_Error_Ok)
+			return error;
+		handles_local[handle].support_saam =
+				(features & 0x8000)? supportYes : supportNo; /* SAAM is bit15 */
+	}
+	*saam = handles_local[handle].support_saam == supportYes ? Tfa98xx_saam : Tfa98xx_saam_none ;
+
+	return Tfa98xx_Error_Ok;
+}
+
+/*
+ * tfa98xx_compare_features
+ *  Obtains features_from_MTP and features_from_cnt
+ */
+enum Tfa98xx_Error tfa98xx_compare_features(Tfa98xx_handle_t handle, int features_from_MTP[3], int features_from_cnt[3])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+        uint32_t value;
+	uint16_t mtpbf;
+        unsigned char bytes[3 * 2];
+
+        //int sw_feature_bits[2]; /* cached feature bits data */
+	//int hw_feature_bits; /* cached feature bits data */
+
+        /* Nothing to test without clock: */
+        int status;
+	tfa98xx_dsp_system_stable(handle, &status);
+	if (!status)
+                return Tfa98xx_Error_NoClock; // Only test when we have a clock.
+
+        /* Set proper MTP location per device: */
+        if (tfa98xx_dev_family(handle) == 1) {
+	        mtpbf=0x850f;  /* MTP5 for tfa1,16 bits */
+	} else {
+		mtpbf=0xf907;  /* MTP9 for tfa2, 8 bits */
+        }
+
+        /* Read HW features from MTP: */
+        value = tfa_read_reg(handle, mtpbf) & 0xffff;
+	features_from_MTP[0] = handles_local[handle].hw_feature_bits = value;
+
+        /* Read SW features: */
+        error = tfa_dsp_cmd_id_write_read(handle, MODULE_FRAMEWORK, 
+                FW_PAR_ID_GET_FEATURE_INFO, sizeof(bytes), bytes);
+	if (error != Tfa98xx_Error_Ok) 
+	        return error; /* old ROM code may respond with Tfa98xx_Error_RpcParamId */
+        tfa98xx_convert_bytes2data(sizeof(bytes), bytes, &features_from_MTP[1]);
+
+        /* check if feature bits from MTP match feature bits from cnt file: */
+        get_hw_features_from_cnt(handle, &features_from_cnt[0]);
+        get_sw_features_from_cnt(handle, &features_from_cnt[1]);
+
+	return error;
+}
+
+/********************************* device specific ops ************************************************/
+/* the wrapper for DspReset, in case of full */
+enum Tfa98xx_Error tfa98xx_dsp_reset(Tfa98xx_handle_t dev_idx, int state)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	if (tfa98xx_handle_is_open(dev_idx)) {
+		if (handles_local[dev_idx].dev_ops.tfa_dsp_reset)
+			error = (*handles_local[dev_idx].dev_ops.tfa_dsp_reset)(dev_idx, state);
+		else
+			/* generic function */
+			TFA_SET_BF_VOLATILE(dev_idx, RST, (uint16_t)state);
+	}
+	return error;
+}
+
+/* tfa98xx_dsp_system_stable
+ *  return: *ready = 1 when clocks are stable to allow DSP subsystem access
+ */
+
+/* This is the clean, default static
+ */
+static enum Tfa98xx_Error _tfa98xx_dsp_system_stable(Tfa98xx_handle_t handle,
+						int *ready)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned short status;
+	int value;
+
+	/* check the contents of the STATUS register */
+	value = TFA_READ_REG(handle, AREFS);
+	if (value < 0) {
+		error = -value;
+		*ready = 0;
+		_ASSERT(error);		/* an error here can be fatal */
+		return error;
+	}
+	status = (unsigned short)value;
+
+	/* check AREFS and CLKS: not ready if either is clear */
+	*ready = !((TFA_GET_BF_VALUE(handle, AREFS, status) == 0)
+		   || (TFA_GET_BF_VALUE(handle, CLKS, status) == 0));
+
+	return error;
+}
+
+/* deferred calibration */
+void tfa98xx_apply_deferred_calibration(Tfa98xx_handle_t handle)
+{
+	struct tfa98xx_controls *controls = &(handles_local[handle].dev_ops.controls);
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	unsigned short value;
+
+	if (controls->otc.deferrable && controls->otc.triggered) {
+		pr_debug("Deferred writing otc = %d\n", controls->otc.wr_value);
+		err = tfa98xx_set_mtp(handle,
+			(uint16_t)controls->otc.wr_value << TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS,
+			1 << TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS);
+		if (err != Tfa98xx_Error_Ok) {
+			pr_err("Unable to apply deferred MTP OTC write. Error=%d\n",
+									err);
+		} else {
+			controls->otc.triggered = false;
+			controls->otc.rd_valid = true;
+			err = tfa98xx_get_mtp(handle, &value);
+			if (err == Tfa98xx_Error_Ok)
+				controls->otc.rd_value =
+					(value & TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_MSK)
+					>> TFA98XX_KEY2_PROTECTED_MTP0_MTPOTC_POS;
+			else
+				controls->otc.rd_value = controls->otc.wr_value;
+		}
+	}
+
+	if (controls->mtpex.deferrable && controls->mtpex.triggered) {
+		pr_debug("Deferred writing mtpex = %d\n", controls->mtpex.wr_value);
+		err = tfa98xx_set_mtp(handle,
+			(uint16_t)controls->mtpex.wr_value << TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS,
+			1 << TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS);
+		if (err != Tfa98xx_Error_Ok) {
+			pr_err("Unable to apply deferred MTPEX write. Rrror=%d\n",
+									err);
+		} else {
+			controls->mtpex.triggered = false;
+			controls->mtpex.rd_valid = true;
+			err = tfa98xx_get_mtp(handle, &value);
+			if (err == Tfa98xx_Error_Ok)
+				controls->mtpex.rd_value =
+					(value & TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_MSK)
+					>> TFA98XX_KEY2_PROTECTED_MTP0_MTPEX_POS;
+			else
+				controls->mtpex.rd_value = controls->mtpex.wr_value;
+		}
+	}
+
+	if (controls->calib.triggered) {
+		err = tfa_calibrate(handle);
+		if(err) {
+			pr_info("Deferred calibration failed: %d\n", err);
+		} else {
+			pr_debug("Deferred calibration ok\n");
+			controls->calib.triggered = false;
+		}
+	}
+}
+
+/* the ops wrapper for tfa98xx_dsp_SystemStable */
+enum Tfa98xx_Error tfa98xx_dsp_system_stable(Tfa98xx_handle_t dev_idx, int *ready)
+{
+	enum Tfa98xx_Error error;
+
+	if (!tfa98xx_handle_is_open(dev_idx))
+		return Tfa98xx_Error_NotOpen;
+
+	if (handles_local[dev_idx].dev_ops.tfa_dsp_system_stable)
+		error = (*handles_local[dev_idx].dev_ops.tfa_dsp_system_stable)(dev_idx, ready);
+	else
+		/* generic function */
+		error = _tfa98xx_dsp_system_stable(dev_idx, ready);
+	return error;
+}
+
+/* the ops wrapper for tfa98xx_dsp_SystemStable */
+int tfa98xx_cf_enabled(Tfa98xx_handle_t dev_idx)
+{
+	if (!tfa98xx_handle_is_open(dev_idx))
+		return Tfa98xx_Error_NotOpen;
+
+	return TFA_GET_BF(dev_idx, CFE);
+}
+
+
+/*
+ * bring the device into a state similar to reset
+ */
+enum Tfa98xx_Error tfa98xx_init(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	uint16_t value=0;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	/* reset all i2C registers to default
+	 *  Write the register directly to avoid the read in the bitfield function.
+	 *  The I2CR bit may overwrite the full register because it is reset anyway.
+	 *  This will save a reg read transaction.
+	 */
+	TFA_SET_BF_VALUE(handle, I2CR, 1, &value );
+	TFA_WRITE_REG(handle, I2CR, value);
+
+	if (tfa98xx_dev_family(handle) == 2) {
+		/* restore MANSCONF and MANCOLD to POR state */
+		TFA_SET_BF_VOLATILE(handle, MANSCONF, 0);
+		TFA_SET_BF_VOLATILE(handle, MANCOLD, 1);
+	} else {
+		/* Mark TFA1 family chips OTC and MTPEX calibration accesses
+		 * as deferrable, since these registers cannot be accesed
+		 * while the I2S link is not up and running
+		 */
+		handles_local[handle].dev_ops.controls.otc.deferrable = true;
+		handles_local[handle].dev_ops.controls.mtpex.deferrable = true;
+	}
+	switch (TFA_GET_BF(handle, REV) & 0xff)
+	{
+        case 0x80:
+			pr_debug("tfa98xx_init Dev ID %x\n",(TFA_GET_BF(handle, REV) & 0xff));
+            break;
+        default:
+	        tfa98xx_dsp_reset(handle, 1); /* in pair of tfaRunStartDSP() */
+    }
+
+	/* some other registers must be set for optimal amplifier behaviour
+	 * This is implemented in a file specific for the type number
+	 */
+
+	if (handles_local[handle].dev_ops.tfa_init)
+		error = (*handles_local[handle].dev_ops.tfa_init)(handle);
+	//TODO warning here?
+
+	return error;
+}
+
+enum Tfa98xx_Error tfa98xx_dsp_write_tables(Tfa98xx_handle_t handle, int sample_rate)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	if (handles_local[handle].dev_ops.tfa_dsp_write_tables)
+		error = (*handles_local[handle].dev_ops.tfa_dsp_write_tables)(handle, sample_rate);
+
+	return error;
+}
+
+/********************* new tfa2 *********************************************************************/
+/* newly added messaging for tfa2 tfa1? */
+enum Tfa98xx_Error tfa98xx_dsp_get_memory(Tfa98xx_handle_t handle, int memoryType, 
+		int offset, int length, unsigned char bytes[])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	char msg[12];
+
+	msg[0] = 8;
+	msg[1] = MODULE_FRAMEWORK + 128;
+	msg[2] = FW_PAR_ID_GET_MEMORY;
+
+	msg[3] = 0;
+	msg[4] = 0;
+	msg[5] = (char)memoryType;
+
+	msg[6] = 0;
+	msg[7] = (offset>>8) & 0xff;
+	msg[8] = offset & 0xff;
+
+	msg[9] = 0;
+	msg[10] = (length>>8) & 0xff;
+	msg[11] = length & 0xff;
+
+	/* send msg */
+	error = tfa_dsp_msg(handle, sizeof(msg), (char *)msg);
+
+	if (error != Tfa98xx_Error_Ok)
+		return error;
+
+	/* read the data from the device (length * 3 = words) */
+	error = tfa_dsp_msg_read(handle, length * 3, bytes);	
+
+	return error;
+}
+
+enum Tfa98xx_Error tfa98xx_dsp_set_memory(Tfa98xx_handle_t handle, int memoryType, 
+		int offset, int length, int value)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	char msg[15];
+
+	msg[0] = 8;
+	msg[1] = MODULE_FRAMEWORK + 128;
+	msg[2] = FW_PAR_ID_SET_MEMORY;
+
+	msg[3] = 0;
+	msg[4] = 0;
+	msg[5] = (char)memoryType;
+
+	msg[6] = 0;
+	msg[7] = (offset>>8) & 0xff;
+	msg[8] = offset & 0xff;
+
+	msg[9] = 0;
+	msg[10] = (length>>8) & 0xff;
+	msg[11] = length & 0xff;
+
+	msg[12] = (value>>16) & 0xff;
+	msg[13] = (value>>8) & 0xff;
+	msg[14] = value & 0xff;
+
+	/* send msg */
+	error = tfa_dsp_msg(handle, sizeof(msg), (char *)msg);
+
+	return error;
+}
+/****************************** calibration support **************************/
+/*
+ * get/set the mtp with user controllable values
+ *
+ *  check if the relevant clocks are available
+ */
+enum Tfa98xx_Error tfa98xx_get_mtp(Tfa98xx_handle_t handle, uint16_t *value)
+{
+	int status;
+	int result;
+
+	/* not possible if PLL in powerdown */
+	if ( TFA_GET_BF(handle, PWDN) ) {
+		pr_debug("PLL in powerdown\n");
+		return Tfa98xx_Error_NoClock;
+	}
+
+	/* tfa1 needs audio PLL */
+	if (tfa98xx_dev_family(handle) == 1) {
+		tfa98xx_dsp_system_stable(handle, &status);
+		if (status==0) {
+			pr_debug("PLL not running\n");
+			return Tfa98xx_Error_NoClock;
+		}
+	}
+
+	result = TFA_READ_REG(handle, MTP0);
+	if (result <  0) {
+		return -result;
+	}
+	*value = (uint16_t)result;
+
+	return Tfa98xx_Error_Ok;
+}
+
+/*
+ * lock or unlock KEY2
+ *  lock = 1 will lock
+ *  lock = 0 will unlock
+ *
+ *  note that on return all the hidden key will be off
+ */
+void tfa98xx_key2(Tfa98xx_handle_t handle, int lock) {
+
+	/* unhide lock registers */
+	tfa98xx_write_register16(handle,
+				(tfa98xx_dev_family(handle) == 1) ? 0x40 :0x0F, 0x5A6B);
+	/* lock/unlock key2 MTPK */
+	TFA_WRITE_REG(handle, MTPKEY2, lock? 0 :0x5A );
+	/* unhide lock registers */
+	tfa98xx_write_register16(handle,
+				(tfa98xx_dev_family(handle) == 1) ? 0x40 :0x0F, 0);
+
+
+}
+
+enum Tfa98xx_Error tfa98xx_set_mtp(Tfa98xx_handle_t handle, uint16_t value,
+		uint16_t mask)
+{
+	unsigned short mtp_old, mtp_new;
+	int loop, status;
+	enum Tfa98xx_Error error;
+
+	error = tfa98xx_get_mtp(handle, &mtp_old);
+
+	if (error != Tfa98xx_Error_Ok)
+		return error;
+
+	mtp_new = (value & mask) | (mtp_old & ~mask);
+
+	if ( mtp_old == mtp_new) /* no change */
+		return Tfa98xx_Error_Ok;
+
+	/* assure that the clock is up, else we can't write MTP */
+	error = tfa98xx_dsp_system_stable(handle, &status);
+	if (error)
+		return error;
+	if (status==0)
+		return Tfa98xx_Error_NoClock;
+
+	tfa98xx_key2(handle , 0); /* unlock */
+	TFA_WRITE_REG(handle, MTP0, mtp_new); 	/* write to i2c shadow reg */
+	/* CIMTP=1 start copying all the data from i2c regs_mtp to mtp*/
+	TFA_SET_BF(handle, CIMTP, 1);
+	/* no check for MTPBUSY here, i2c delay assumed to be enough */
+	tfa98xx_key2(handle , 1); /* lock */
+
+	/* wait until MTP write is done
+	 */
+	for(loop=0; loop<100 /*x10ms*/ ;loop++) {
+		msleep_interruptible(10); 			/* wait 10ms to avoid busload */
+		if (TFA_GET_BF(handle, MTPB) == 0)
+			return Tfa98xx_Error_Ok;
+	}
+
+	return Tfa98xx_Error_StateTimedOut;
+}
+/*
+ * clear mtpex
+ * set ACS
+ * start tfa
+ */
+int tfa_calibrate(Tfa98xx_handle_t handle) {
+	enum Tfa98xx_Error error;
+
+	/* clear mtpex */
+	error = tfa98xx_set_mtp(handle, 0, 0x2);
+	if (error)
+		return error ;
+
+	/* set ACS/coldboot state */
+	error = tfaRunColdboot(handle, 1);
+
+	/* start tfa by playing */
+	return error;
+}
+
+static short twos(short x)
+{
+	 return (x<0)? x+512 : x;
+}
+void tfa98xx_set_exttemp(Tfa98xx_handle_t handle, short ext_temp)
+{
+	if ((-256 <= ext_temp) && (ext_temp <= 255)) {
+		/* make twos complement */
+		pr_debug("Using ext temp %d C\n", twos(ext_temp));
+		TFA_SET_BF(handle, TROS, 1);
+		TFA_SET_BF(handle, EXTTS, twos(ext_temp));
+	} else {
+		pr_debug("Clearing ext temp settings\n");
+		TFA_SET_BF(handle, TROS, 0);
+	}
+}
+short tfa98xx_get_exttemp(Tfa98xx_handle_t handle)
+{
+	short ext_temp = (short)TFA_GET_BF(handle, EXTTS);
+	return (twos(ext_temp));
+}
+
+/************************** tfa simple bitfield interfacing ***************************************/
+/* convenience functions */
+enum Tfa98xx_Error tfa98xx_set_volume_level(Tfa98xx_handle_t handle, unsigned short vol)
+{
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	if (vol > 255)	/* restricted to 8 bits */
+		vol = 255;
+
+	/* 0x00 -> 0.0 dB
+	 * 0x01 -> -0.5 dB
+	 * ...
+	 * 0xFE -> -127dB
+	 * 0xFF -> muted
+	 */
+
+	/* volume value is in the top 8 bits of the register */
+	return -TFA_SET_BF(handle, VOL, (uint16_t)vol);
+}
+
+static enum Tfa98xx_Error
+tfa98xx_set_mute_tfa2(Tfa98xx_handle_t handle, enum Tfa98xx_Mute mute)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	switch (mute) {
+	case Tfa98xx_Mute_Off:
+		TFA_SET_BF(handle, CFSMR, 0);
+		TFA_SET_BF(handle, CFSML, 0);
+		break;
+	case Tfa98xx_Mute_Amplifier:
+	case Tfa98xx_Mute_Digital:
+		TFA_SET_BF(handle, CFSMR, 1);
+		TFA_SET_BF(handle, CFSML, 1);
+		break;
+	default:
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	return error;
+}
+
+static enum Tfa98xx_Error
+tfa98xx_set_mute_tfa1(Tfa98xx_handle_t handle, enum Tfa98xx_Mute mute)
+{
+	enum Tfa98xx_Error error;
+	unsigned short audioctrl_value;
+	unsigned short sysctrl_value;
+	int value;
+
+	value = TFA_READ_REG(handle, CFSM); /* audio control register */
+	if (value < 0)
+		return -value;
+	audioctrl_value = (unsigned short)value;
+	value = TFA_READ_REG(handle, AMPE); /* system control register */
+	if (value < 0)
+		return -value;
+	sysctrl_value = (unsigned short)value;
+
+	switch (mute) {
+	case Tfa98xx_Mute_Off:
+		/* previous state can be digital or amplifier mute,
+		 * clear the cf_mute and set the enbl_amplifier bits
+		 *
+		 * To reduce PLOP at power on it is needed to switch the
+		 * amplifier on with the DCDC in follower mode
+		 * (enbl_boost = 0 ?).
+		 * This workaround is also needed when toggling the
+		 * powerdown bit!
+		 */
+		TFA_SET_BF_VALUE(handle, CFSM, 0, &audioctrl_value);
+		TFA_SET_BF_VALUE(handle, AMPE, 1, &sysctrl_value);
+		TFA_SET_BF_VALUE(handle, DCA, 1, &sysctrl_value);
+		break;
+	case Tfa98xx_Mute_Digital:
+		/* expect the amplifier to run */
+		/* set the cf_mute bit */
+		TFA_SET_BF_VALUE(handle, CFSM, 1, &audioctrl_value);
+		/* set the enbl_amplifier bit */
+		TFA_SET_BF_VALUE(handle, AMPE, 1, &sysctrl_value);
+		/* clear active mode */
+		TFA_SET_BF_VALUE(handle, DCA, 0, &sysctrl_value);
+		break;
+	case Tfa98xx_Mute_Amplifier:
+		/* clear the cf_mute bit */
+		TFA_SET_BF_VALUE(handle, CFSM, 0, &audioctrl_value);
+		/* clear the enbl_amplifier bit and active mode */
+		TFA_SET_BF_VALUE(handle, AMPE, 0, &sysctrl_value);
+		TFA_SET_BF_VALUE(handle, DCA, 0, &sysctrl_value);
+		break;
+	default:
+		return Tfa98xx_Error_Bad_Parameter;
+	}
+
+	error = -TFA_WRITE_REG(handle, CFSM, audioctrl_value);
+	if (error)
+		return error;
+	error = -TFA_WRITE_REG(handle, AMPE, sysctrl_value);
+	return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_set_mute(Tfa98xx_handle_t handle, enum Tfa98xx_Mute mute)
+{
+	if (!tfa98xx_handle_is_open(handle)) {
+		pr_err("device not opened\n");
+		return Tfa98xx_Error_NotOpen;
+	}
+
+	if (tfa98xx_dev_family(handle) == 1)
+		return tfa98xx_set_mute_tfa1(handle, mute);
+	else
+		return tfa98xx_set_mute_tfa2(handle, mute);
+}
+
+/****************** patching **********************************************************/
+static enum Tfa98xx_Error
+tfa98xx_process_patch_file(Tfa98xx_handle_t handle, int length,
+		 const unsigned char *bytes)
+{
+	unsigned short size;
+	int index = 0;
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	while (index < length) {
+		size = bytes[index] + bytes[index + 1] * 256;
+		index += 2;
+		if ((index + size) > length) {
+			/* outside the buffer, error in the input data */
+			return Tfa98xx_Error_Bad_Parameter;
+		}
+
+		if (size > handles_local[handle].buffer_size) {
+			/* too big, must fit buffer */
+			return Tfa98xx_Error_Bad_Parameter;
+		}
+
+		error = tfa98xx_write_raw(handle, size, &bytes[index]);
+		if (error != Tfa98xx_Error_Ok)
+			break;
+		index += size;
+	}
+	return  error;
+}
+
+
+
+/* the patch contains a header with the following
+ * IC revision register: 1 byte, 0xFF means don't care
+ * XMEM address to check: 2 bytes, big endian, 0xFFFF means don't care
+ * XMEM value to expect: 3 bytes, big endian
+ */
+static enum Tfa98xx_Error
+tfa98xx_check_ic_rom_version(Tfa98xx_handle_t handle, const unsigned char patchheader[])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned short checkrev, revid;
+	unsigned char lsb_revid;
+	unsigned short checkaddress;
+	int checkvalue;
+	int value = 0;
+	int status;
+	checkrev = patchheader[0];
+	lsb_revid = handles_local[handle].rev & 0xff; /* only compare lower byte */
+
+	if ((checkrev != 0xFF) && (checkrev != lsb_revid))
+		return Tfa98xx_Error_Not_Supported;
+
+	checkaddress = (patchheader[1] << 8) + patchheader[2];
+	checkvalue =
+	    (patchheader[3] << 16) + (patchheader[4] << 8) + patchheader[5];
+	if (checkaddress != 0xFFFF) {
+		/* before reading XMEM, check if we can access the DSP */
+		error = tfa98xx_dsp_system_stable(handle, &status);
+		if (error == Tfa98xx_Error_Ok) {
+			if (!status) {
+				/* DSP subsys not running */
+				error = Tfa98xx_Error_DSP_not_running;
+			}
+		}
+		/* read register to check the correct ROM version */
+		if (error == Tfa98xx_Error_Ok) {
+			error =
+			tfa98xx_dsp_read_mem(handle, checkaddress, 1, &value);
+		}
+		if (error == Tfa98xx_Error_Ok) {
+			if (value != checkvalue) {
+				pr_err("patch file romid type check failed [0x%04x]: expected 0x%02x, actual 0x%02x\n",
+						checkaddress, value, checkvalue);
+				error = Tfa98xx_Error_Not_Supported;
+			}
+		}
+	} else { /* == 0xffff */
+		/* check if the revid subtype is in there */
+		if ( checkvalue != 0xFFFFFF && checkvalue != 0) {
+			revid = patchheader[5]<<8 | patchheader[0]; /* full revid */
+			if ( revid != handles_local[handle].rev) {
+				pr_err("patch file device type check failed: expected 0x%02x, actual 0x%02x\n",
+						handles_local[handle].rev, revid);
+				return Tfa98xx_Error_Not_Supported;
+			}
+		}
+	}
+
+	return error;
+}
+
+
+#define PATCH_HEADER_LENGTH 6
+enum Tfa98xx_Error
+tfa_dsp_patch(Tfa98xx_handle_t handle, int patchLength,
+		 const unsigned char *patchBytes)
+{
+	enum Tfa98xx_Error error;
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+	if (patchLength < PATCH_HEADER_LENGTH)
+		return Tfa98xx_Error_Bad_Parameter;
+	error = tfa98xx_check_ic_rom_version(handle, patchBytes);
+	if (Tfa98xx_Error_Ok != error) {
+		return error;
+	}
+	error =
+	    tfa98xx_process_patch_file(handle, patchLength - PATCH_HEADER_LENGTH,
+			     patchBytes + PATCH_HEADER_LENGTH);
+	return error;
+}
+
+/******************  end patching **********************************************************/
+
+TFA_INTERNAL enum Tfa98xx_Error
+tfa98xx_wait_result(Tfa98xx_handle_t handle, int wait_retry_count)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	int cf_status; /* the contents of the CF_STATUS register */
+	int tries = 0;
+	do {
+		cf_status = TFA_GET_BF(handle, ACK);
+		if (cf_status < 0)
+			error = -cf_status;
+		tries++;
+	}
+	// i2c_cmd_ack
+	/* don't wait forever, DSP is pretty quick to respond (< 1ms) */
+	while ((error == Tfa98xx_Error_Ok) && ((cf_status & CF_STATUS_I2C_CMD_ACK) == 0)
+			&& (tries < wait_retry_count));
+	if (tries >= wait_retry_count) {
+		/* something wrong with communication with DSP */
+		error = Tfa98xx_Error_DSP_not_running;
+	}
+	return error;
+}
+
+/*
+ * *  support functions for data conversion
+ */
+/** 
+ convert memory bytes to signed 24 bit integers  
+   input:  bytes contains "num_bytes" byte elements 
+   output: data contains "num_bytes/3" int24 elements
+*/
+void tfa98xx_convert_bytes2data(int num_bytes, const unsigned char bytes[],
+			       int data[])
+{
+	int i;			/* index for data */
+	int k;			/* index for bytes */
+	int d;
+	int num_data = num_bytes / 3;
+	_ASSERT((num_bytes % 3) == 0);
+	for (i = 0, k = 0; i < num_data; ++i, k += 3) {
+		d = (bytes[k] << 16) | (bytes[k + 1] << 8) | (bytes[k + 2]);
+		_ASSERT(d >= 0);
+		_ASSERT(d < (1 << 24));	/* max 24 bits in use */
+		if (bytes[k] & 0x80)	/* sign bit was set */
+			d = -((1 << 24) - d);
+
+		data[i] = d;
+	}
+}
+
+/**
+ convert signed 24 bit integers to 32bit aligned bytes
+   input:   data contains "num_bytes/3" int24 elements
+   output:  bytes contains "num_bytes" byte elements
+*/
+void tfa98xx_convert_data2bytes(int num_data, const int data[],
+			       unsigned char bytes[])
+{
+	int i;			/* index for data */
+	int k;			/* index for bytes */
+	int d;
+	/* note: cannot just take the lowest 3 bytes from the 32 bit
+	 * integer, because also need to take care of clipping any
+	 * value > 2&23 */
+	for (i = 0, k = 0; i < num_data; ++i, k += 3) {
+		if (data[i] >= 0)
+			d = MIN(data[i], (1 << 23) - 1);
+		else {
+			/* 2's complement */
+			d = (1 << 24) - MIN(-data[i], 1 << 23);
+		}
+		_ASSERT(d >= 0);
+		_ASSERT(d < (1 << 24));	/* max 24 bits in use */
+		bytes[k] = (d >> 16) & 0xFF;	/* MSB */
+		bytes[k + 1] = (d >> 8) & 0xFF;
+		bytes[k + 2] = (d) & 0xFF;	/* LSB */
+	}
+}
+
+/*
+ *  DSP RPC message support functions
+ *   depending on framework to be up and running
+ *   need base i2c of memaccess (tfa1=0x70/tfa2=0x90)
+ */
+
+
+/* write dsp messages in function tfa_dsp_msg() */
+/*  note the 'old' write_parameter() was more efficient because all i2c was in one burst transaction */
+
+//TODO properly handle bitfields: state should be restored! (now it will change eg dmesg field to xmem)
+enum Tfa98xx_Error tfa_dsp_msg_write(Tfa98xx_handle_t handle, int length, const char *buffer)
+{
+	int offset = 0;
+	int chunk_size = ROUND_DOWN(handles_local[handle].buffer_size, 3);  /* XMEM word size */
+	int remaining_bytes = length;
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	uint16_t cfctl;
+	int value;
+
+	value = TFA_READ_REG(handle, DMEM);
+	if (value < 0) {
+		error = -value;
+		return error;
+	}
+	cfctl = (uint16_t)value;
+	/* assume no I2C errors from here */
+
+	TFA_SET_BF_VALUE(handle, DMEM, (uint16_t)Tfa98xx_DMEM_XMEM, &cfctl); /* set cf ctl to DMEM  */
+	TFA_SET_BF_VALUE(handle, AIF, 0, &cfctl ); /* set to autoincrement */
+	TFA_WRITE_REG(handle, DMEM, cfctl);
+
+	/* xmem[1] is start of message
+	 *  direct write to register to save cycles avoiding read-modify-write
+	 */
+	TFA_WRITE_REG(handle, MADD, 1);
+
+	/* due to autoincrement in cf_ctrl, next write will happen at
+	 * the next address */
+	while ((error == Tfa98xx_Error_Ok) && (remaining_bytes > 0)) {
+		if (remaining_bytes < chunk_size)
+			chunk_size = remaining_bytes;
+		/* else chunk_size remains at initialize value above */
+		error = tfa98xx_write_data(handle, FAM_TFA98XX_CF_MEM,
+				      chunk_size, (const unsigned char *)buffer + offset);
+		remaining_bytes -= chunk_size;
+		offset += chunk_size;
+	}
+
+	/* notify the DSP */
+	if (error == Tfa98xx_Error_Ok) {
+		/* cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
+		/* set the cf_req1 and cf_int bit */
+		TFA_SET_BF_VALUE(handle, REQCMD, 0x01, &cfctl ); /* bit 0 */
+		TFA_SET_BF_VALUE(handle, CFINT, 1, &cfctl );
+		error = -TFA_WRITE_REG(handle, CFINT, cfctl);
+	}
+
+	return error;
+}
+
+enum Tfa98xx_Error tfa_dsp_msg_write_id(Tfa98xx_handle_t handle, int length, const char *buffer, uint8_t cmdid[3])
+{
+        int offset = 0;
+	int chunk_size = ROUND_DOWN(handles_local[handle].buffer_size, 3);  /* XMEM word size */
+	int remaining_bytes = length;
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	uint16_t cfctl;
+	int value;
+
+	value = TFA_READ_REG(handle, DMEM);
+	if (value < 0) {
+		error = -value;
+		return error;
+	}
+	cfctl = (uint16_t)value;
+	/* assume no I2C errors from here */
+
+	TFA_SET_BF_VALUE(handle, DMEM, (uint16_t)Tfa98xx_DMEM_XMEM, &cfctl); /* set cf ctl to DMEM  */
+	TFA_SET_BF_VALUE(handle, AIF, 0, &cfctl ); /* set to autoincrement */
+	TFA_WRITE_REG(handle, DMEM, cfctl);
+
+	/* xmem[1] is start of message
+	 *  direct write to register to save cycles avoiding read-modify-write
+	 */
+	TFA_WRITE_REG(handle, MADD, 1);
+
+	/* write cmd-id */
+	error = tfa98xx_write_data(handle, FAM_TFA98XX_CF_MEM, 3, (const unsigned char *)cmdid);
+
+	/* due to autoincrement in cf_ctrl, next write will happen at
+	 * the next address */
+	while ((error == Tfa98xx_Error_Ok) && (remaining_bytes > 0)) {
+		if (remaining_bytes < chunk_size)
+			chunk_size = remaining_bytes;
+		/* else chunk_size remains at initialize value above */
+		error = tfa98xx_write_data(handle, FAM_TFA98XX_CF_MEM,
+				      chunk_size, (const unsigned char *)buffer + offset);
+		remaining_bytes -= chunk_size;
+		offset += chunk_size;
+	}
+
+	/* notify the DSP */
+	if (error == Tfa98xx_Error_Ok) {
+		/* cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
+		/* set the cf_req1 and cf_int bit */
+		TFA_SET_BF_VALUE(handle, REQCMD, 0x01, &cfctl ); /* bit 0 */
+		TFA_SET_BF_VALUE(handle, CFINT, 1, &cfctl );
+		error = -TFA_WRITE_REG(handle, CFINT, cfctl);
+	}
+
+	return error;
+}
+
+/*
+* status function used by tfa_dsp_msg() to retrieve command/msg status:
+* return a <0 status of the DSP did not ACK.
+*/
+enum Tfa98xx_Error tfa_dsp_msg_status(Tfa98xx_handle_t handle, int *pRpcStatus) {
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	error = tfa98xx_wait_result(handle, 2); /* 2 is only one try */
+	if (error == Tfa98xx_Error_DSP_not_running) {
+		*pRpcStatus = -1;
+		return Tfa98xx_Error_Ok;
+	}
+	else if (error != Tfa98xx_Error_Ok)
+		return error;
+
+	error = tfa98xx_check_rpc_status(handle, pRpcStatus);
+
+	return error;
+}
+
+const char* tfa98xx_get_i2c_status_id_string(int status)
+{
+        const char* p_id_str;
+
+        switch (status)
+        {
+                case Tfa98xx_DSP_Not_Running:
+                        p_id_str = "No response from DSP";
+                        break;
+                case Tfa98xx_I2C_Req_Done:
+                        p_id_str = "Ok";
+                        break;
+                case Tfa98xx_I2C_Req_Busy:
+                        p_id_str = "Request is being processed";
+                        break;
+                case Tfa98xx_I2C_Req_Invalid_M_ID:
+                        p_id_str = "Provided M-ID does not fit in valid rang [0..2]";
+                        break;
+                case Tfa98xx_I2C_Req_Invalid_P_ID:
+                        p_id_str = "Provided P-ID is not valid in the given M-ID context";
+                        break;
+                case Tfa98xx_I2C_Req_Invalid_CC:
+                        p_id_str = "Invalid channel configuration bits (SC|DS|DP|DC) combination";
+                        break;
+                case Tfa98xx_I2C_Req_Invalid_Seq:
+                        p_id_str = "Invalid sequence of commands, in case the DSP expects some commands in a specific order";
+                        break;
+                case Tfa98xx_I2C_Req_Invalid_Param:
+                        p_id_str = "Generic error";
+                        break;
+                case Tfa98xx_I2C_Req_Buffer_Overflow:
+                        p_id_str = "I2C buffer has overflowed: host has sent too many parameters, memory integrity is not guaranteed";
+                        break;
+                default:
+                        p_id_str = "Unspecified error";
+        }
+
+        return p_id_str;
+}
+
+enum Tfa98xx_Error tfa_dsp_msg_read(Tfa98xx_handle_t handle,int length, unsigned char *bytes){
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	int burst_size;		/* number of words per burst size */
+	int bytes_per_word = 3;
+	int num_bytes;
+	int offset = 0;
+	unsigned short start_offset=2; /* msg starts @xmem[2] ,[1]=cmd */
+
+	if ( length > TFA2_MAX_PARAM_SIZE)
+		return Tfa98xx_Error_Bad_Parameter;
+
+	TFA_SET_BF(handle, DMEM, (uint16_t)Tfa98xx_DMEM_XMEM);
+	error = -TFA_WRITE_REG(handle, MADD, start_offset);
+	if (error != Tfa98xx_Error_Ok)
+		return error;
+
+	num_bytes = length; /* input param */
+	while (num_bytes > 0) {
+		burst_size = ROUND_DOWN(handles_local[handle].buffer_size, bytes_per_word);
+		if (num_bytes < burst_size)
+			burst_size = num_bytes;
+		error = tfa98xx_read_data(handle, FAM_TFA98XX_CF_MEM, burst_size, bytes + offset);
+		if (error != Tfa98xx_Error_Ok)
+			return error;
+
+		num_bytes -= burst_size;
+		offset += burst_size;
+	}
+
+	return Tfa98xx_Error_Ok;
+}
+
+/*
+ *  write/read raw msg functions :
+ *  the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes.
+ *  The functions will return immediately and do not not wait for DSP reponse.
+ */
+#define MAX_WORDS (300)
+enum Tfa98xx_Error tfa_dsp_msg(Tfa98xx_handle_t handle, int length, const char *buf)
+{
+	enum Tfa98xx_Error error;
+	int tries, rpc_status = Tfa98xx_I2C_Req_Done;
+
+	/* write the message and notify the DSP */
+	error = tfa_dsp_msg_write(handle, length, buf);
+	if( error != Tfa98xx_Error_Ok)
+		return error;
+
+	/* get the result from the DSP (polling) */
+	for(tries=TFA98XX_WAITRESULT_NTRIES; tries>0;tries--) {
+		error = tfa_dsp_msg_status(handle, &rpc_status);
+                if (error == Tfa98xx_Error_Ok && rpc_status == Tfa98xx_I2C_Req_Done)
+			break;
+		/* If the rpc status is a specific error we want to know it.
+		 * If it is busy or not running it should retry
+		 */
+		if(rpc_status != Tfa98xx_I2C_Req_Busy && rpc_status != Tfa98xx_DSP_Not_Running)
+			break;
+	}
+
+	//if (tfa98xx_runtime_verbose)
+	//	PRINT("Number of tries: %d \n", TFA98XX_WAITRESULT_NTRIES-tries);
+
+	if (rpc_status != Tfa98xx_I2C_Req_Done) {
+		/* DSP RPC call returned an error */
+		error = (enum Tfa98xx_Error) (rpc_status + Tfa98xx_Error_RpcBase);
+                pr_debug("DSP msg status: %d (%s)\n", rpc_status, tfa98xx_get_i2c_status_id_string(rpc_status));
+	} 
+
+	return error;
+}
+
+/**
+ *  write/read raw msg functions:
+ *  the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes.
+ *  The functions will return immediately and do not not wait for DSP reponse.
+ *  An ID is added to modify the command-ID
+ */
+enum Tfa98xx_Error tfa_dsp_msg_id(Tfa98xx_handle_t handle, int length, const char *buf, uint8_t cmdid[3])
+{
+	enum Tfa98xx_Error error;
+	int tries, rpc_status = Tfa98xx_I2C_Req_Done;
+
+	/* write the message and notify the DSP */
+	error = tfa_dsp_msg_write_id(handle, length, buf, cmdid);
+	if( error != Tfa98xx_Error_Ok)
+		return error;
+
+	/* get the result from the DSP (polling) */
+	for(tries=TFA98XX_WAITRESULT_NTRIES; tries>0;tries--) {
+		error = tfa_dsp_msg_status(handle, &rpc_status);
+                if (error == Tfa98xx_Error_Ok && rpc_status == Tfa98xx_I2C_Req_Done)
+			break;
+	}
+
+	//if (tfa98xx_runtime_verbose)
+		//PRINT("Number of tries: %d \n", TFA98XX_WAITRESULT_NTRIES-tries);
+
+	if (rpc_status != Tfa98xx_I2C_Req_Done) {
+		/* DSP RPC call returned an error */
+		error = (enum Tfa98xx_Error) (rpc_status + Tfa98xx_Error_RpcBase);
+                pr_debug("DSP msg status: %d (%s)\n", rpc_status, tfa98xx_get_i2c_status_id_string(rpc_status));
+	} 
+
+	return error;
+}
+
+/* read the return code for the RPC call */
+TFA_INTERNAL enum Tfa98xx_Error
+tfa98xx_check_rpc_status(Tfa98xx_handle_t handle, int *pRpcStatus)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	/* the value to sent to the * CF_CONTROLS register: cf_req=00000000,
+	 * cf_int=0, cf_aif=0, cf_dmem=XMEM=01, cf_rst_dsp=0 */
+	unsigned short cf_ctrl = 0x0002;
+	/* memory address to be accessed (0: Status, 1: ID, 2: parameters) */
+	unsigned short cf_mad = 0x0000;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+	if (pRpcStatus == 0)
+		return Tfa98xx_Error_Bad_Parameter;
+
+	/* 1) write DMEM=XMEM to the DSP XMEM */
+	{
+		/* minimize the number of I2C transactions by making use of the autoincrement in I2C */
+		unsigned char buffer[4];
+		/* first the data for CF_CONTROLS */
+		buffer[0] = (unsigned char)((cf_ctrl >> 8) & 0xFF);
+		buffer[1] = (unsigned char)(cf_ctrl & 0xFF);
+		/* write the contents of CF_MAD which is the subaddress following CF_CONTROLS */
+		buffer[2] = (unsigned char)((cf_mad >> 8) & 0xFF);
+		buffer[3] = (unsigned char)(cf_mad & 0xFF);
+		error = tfa98xx_write_data(handle, FAM_TFA98XX_CF_CONTROLS, sizeof(buffer), buffer);
+	}
+	if (error == Tfa98xx_Error_Ok) {
+		/* read 1 word (24 bit) from XMEM */
+		error = tfa98xx_dsp_read_mem(handle, 0, 1, pRpcStatus);
+	}
+
+	return error;
+}
+
+/***************************** xmem only **********************************/
+enum Tfa98xx_Error
+tfa98xx_dsp_read_mem(Tfa98xx_handle_t handle,
+		unsigned int start_offset, int num_words, int *pValues)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned char *bytes;
+	int burst_size;		/* number of words per burst size */
+	const int bytes_per_word = 3;
+	int dmem;
+	int num_bytes;
+	int *p;
+
+	bytes = (unsigned char *)kmalloc(num_words*bytes_per_word, GFP_KERNEL);
+	if (bytes == NULL)
+		return Tfa98xx_Error_Fail;
+
+	/* If no offset is given, assume XMEM! */
+	if(((start_offset>>16) & 0xf) > 0 )
+		dmem = (start_offset>>16) & 0xf;
+	else
+		dmem = Tfa98xx_DMEM_XMEM;
+
+	/* Remove offset from adress */
+	start_offset = start_offset & 0xffff;
+	num_bytes = num_words * bytes_per_word;
+	p = pValues;
+
+	TFA_SET_BF(handle, DMEM, (uint16_t)dmem);
+	error = -TFA_WRITE_REG(handle, MADD, (unsigned short)start_offset);
+	if (error != Tfa98xx_Error_Ok)
+		goto tfa98xx_dsp_read_mem_exit;
+
+	for (; num_bytes > 0;) {
+		burst_size = ROUND_DOWN(handles_local[handle].buffer_size, bytes_per_word);
+		if (num_bytes < burst_size)
+			burst_size = num_bytes;
+
+		_ASSERT(burst_size <= sizeof(bytes));
+		error = tfa98xx_read_data( handle, FAM_TFA98XX_CF_MEM, burst_size, bytes);
+		if (error != Tfa98xx_Error_Ok)
+			goto tfa98xx_dsp_read_mem_exit;
+
+		tfa98xx_convert_bytes2data(burst_size, bytes, p);
+
+		num_bytes -= burst_size;
+		p += burst_size / bytes_per_word;
+	}
+
+tfa98xx_dsp_read_mem_exit:
+	kfree(bytes);
+	return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_dsp_write_mem_word(Tfa98xx_handle_t handle, unsigned short address, int value, int memtype)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned char bytes[3];
+
+	TFA_SET_BF(handle, DMEM, (uint16_t)memtype);
+
+	error = -TFA_WRITE_REG(handle, MADD, address);
+	if (error != Tfa98xx_Error_Ok)
+		return error;
+
+	tfa98xx_convert_data2bytes(1, &value, bytes);
+	error = tfa98xx_write_data(handle, FAM_TFA98XX_CF_MEM, 3, bytes);
+
+	return error;
+}
+
+enum Tfa98xx_Error tfa_cont_write_filterbank(int device, nxpTfaFilter_t *filter)
+{
+	unsigned char biquad_index;
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	for(biquad_index=0;biquad_index<10;biquad_index++) {
+		if (filter[biquad_index].enabled ) {
+			error = tfa_dsp_cmd_id_write(device, MODULE_BIQUADFILTERBANK,
+					biquad_index+1, //start @1
+					sizeof(filter[biquad_index].biquad.bytes),
+						filter[biquad_index].biquad.bytes);
+		} else {
+			error = Tfa98xx_DspBiquad_Disable(device, biquad_index+1);
+		}
+		if (error) return error;
+
+	}
+	return error;
+}
+
+enum Tfa98xx_Error
+Tfa98xx_DspBiquad_Disable(Tfa98xx_handle_t handle, int biquad_index)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	int coeff_buffer[BIQUAD_COEFF_SIZE];
+	unsigned char bytes[3 + BIQUAD_COEFF_SIZE * 3];
+
+	if (biquad_index > TFA98XX_BIQUAD_NUM)
+		return Tfa98xx_Error_Bad_Parameter;
+	if (biquad_index < 1)
+		return Tfa98xx_Error_Bad_Parameter;
+
+	/* make opcode */
+
+	/* set in correct order and format for the DSP */
+	coeff_buffer[0] = (int) - 8388608;	/* -1.0f */
+	coeff_buffer[1] = 0;
+	coeff_buffer[2] = 0;
+	coeff_buffer[3] = 0;
+	coeff_buffer[4] = 0;
+	coeff_buffer[5] = 0;
+	/* convert to packed 24 bits data */
+	tfa98xx_convert_data2bytes(BIQUAD_COEFF_SIZE, coeff_buffer, &bytes[3]);
+
+	bytes[0] = 0;
+	bytes[1] = MODULE_BIQUADFILTERBANK+128;
+	bytes[2] = (unsigned char)biquad_index;
+
+	error = tfa_dsp_msg(handle, 3 + BIQUAD_COEFF_SIZE * 3, (char *)bytes);
+	
+	return error;
+}
+
+/* wrapper for dsp_msg that adds opcode */
+enum Tfa98xx_Error tfa_dsp_cmd_id_write(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int num_bytes,
+                           const unsigned char data[])
+{
+	enum Tfa98xx_Error error;
+	unsigned char *buffer;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	buffer = kmalloc(3 + num_bytes, GFP_KERNEL);
+	if (buffer == NULL)
+		return Tfa98xx_Error_Fail;
+
+	buffer[0] = handles_local[handle].spkr_select;
+	buffer[1] = module_id + 128;
+	buffer[2] = param_id;
+
+	memcpy(&buffer[3], data, num_bytes);
+
+	error = tfa_dsp_msg(handle, 3 + num_bytes, (char *)buffer);
+
+	kfree(buffer);
+
+	return error;
+}
+
+/* wrapper for dsp_msg that adds opcode */
+/* this is as the former tfa98xx_dsp_get_param() */
+enum Tfa98xx_Error tfa_dsp_cmd_id_write_read(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int num_bytes,
+                           unsigned char data[])
+{
+	enum Tfa98xx_Error error;
+	unsigned char buffer[3];
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	buffer[0] = handles_local[handle].spkr_select;
+	buffer[1] = module_id + 128;
+	buffer[2] = param_id;
+
+	error = tfa_dsp_msg(handle, sizeof(unsigned char[3]), (char *)buffer);
+	if ( error!= Tfa98xx_Error_Ok)
+		return error;
+        /* read the data from the dsp */
+	error = tfa_dsp_msg_read(handle, num_bytes, data);	
+
+	return error;
+}
+
+/* wrapper for dsp_msg that adds opcode and 3 bytes required for coefs */
+enum Tfa98xx_Error tfa_dsp_cmd_id_coefs(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int num_bytes,
+			   unsigned char data[])
+{
+	enum Tfa98xx_Error error;
+	unsigned char buffer[6];
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	buffer[0] = handles_local[handle].spkr_select;
+	buffer[1] = module_id + 128;
+	buffer[2] = param_id;
+        buffer[3] = 0;
+        buffer[4] = 0;
+        buffer[5] = 0;
+
+	error = tfa_dsp_msg(handle, sizeof(unsigned char[6]), (char *)buffer);
+	if (error != Tfa98xx_Error_Ok)
+		return error;
+
+	/* read the data from the dsp */
+	error = tfa_dsp_msg_read(handle, num_bytes, data);
+
+	return error;
+}
+
+/* wrapper for dsp_msg that adds opcode and 3 bytes required for MBDrcDynamics */
+enum Tfa98xx_Error tfa_dsp_cmd_id_MBDrc_dynamics(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int index_subband,
+			   int num_bytes, unsigned char data[])
+{
+	enum Tfa98xx_Error error;
+	unsigned char buffer[6];
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	buffer[0] = handles_local[handle].spkr_select;
+	buffer[1] = module_id + 128;
+	buffer[2] = param_id;
+        buffer[3] = 0;
+        buffer[4] = 0;
+        buffer[5] = (unsigned char)index_subband;
+
+	error = tfa_dsp_msg(handle, sizeof(unsigned char[6]), (char *)buffer);
+	if(error != Tfa98xx_Error_Ok)
+		return error;
+
+	/* read the data from the dsp */
+	error = tfa_dsp_msg_read(handle, num_bytes, data);
+
+	return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_dsp_write_preset(Tfa98xx_handle_t handle, int length,
+		       const unsigned char *p_preset_bytes)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	if (p_preset_bytes != 0) {
+		/* by design: keep the data opaque and no
+		 * interpreting/calculation */
+		error = tfa_dsp_cmd_id_write(handle, MODULE_SPEAKERBOOST,
+					SB_PARAM_SET_PRESET, length,
+					p_preset_bytes);
+	} else {
+		error = Tfa98xx_Error_Bad_Parameter;
+	}
+	return error;
+}
+
+/*
+ * get features from MTP
+ */
+enum Tfa98xx_Error
+tfa98xx_dsp_get_hw_feature_bits(Tfa98xx_handle_t handle, int *features)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	uint32_t value;
+	uint16_t mtpbf;
+
+	/* return the cache data if it's valid */
+	if (handles_local[handle].hw_feature_bits != -1) {
+		*features = handles_local[handle].hw_feature_bits;
+	} else {
+		/* for tfa1 check if we have clock */
+		if (tfa98xx_dev_family(handle) == 1) {
+			int status;
+			tfa98xx_dsp_system_stable(handle, &status);
+			if (!status) {
+                                get_hw_features_from_cnt(handle, features);
+                                /* skip reading MTP: */
+                                return (*features == -1) ? Tfa98xx_Error_Fail : Tfa98xx_Error_Ok; 
+                        }
+			mtpbf=0x850f;  /* MTP5 for tfa1,16 bits */
+		} else
+			mtpbf=0xf907;  /* MTP9 for tfa2, 8 bits */
+		value = tfa_read_reg(handle, mtpbf) & 0xffff;
+		*features = handles_local[handle].hw_feature_bits = value;
+	}
+
+	return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_dsp_get_sw_feature_bits(Tfa98xx_handle_t handle, int features[2])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	unsigned char bytes[3 * 2];
+
+	/* return the cache data if it's valid */
+	if (handles_local[handle].sw_feature_bits[0] != -1) {
+		features[0] = handles_local[handle].sw_feature_bits[0];
+		features[1] = handles_local[handle].sw_feature_bits[1];
+	} else {
+		/* for tfa1 check if we have clock */
+		if (tfa98xx_dev_family(handle) == 1) {
+			int status;
+			tfa98xx_dsp_system_stable(handle, &status);
+			if (!status) {
+                                get_sw_features_from_cnt(handle, features);
+                                /* skip reading MTP: */
+                                return (features[0] == -1) ? Tfa98xx_Error_Fail : Tfa98xx_Error_Ok; 
+                        }
+		}
+		error = tfa_dsp_cmd_id_write_read(handle, MODULE_FRAMEWORK,
+				FW_PAR_ID_GET_FEATURE_INFO, sizeof(bytes), bytes);
+
+		if (error != Tfa98xx_Error_Ok) {
+			/* old ROM code may respond with Tfa98xx_Error_RpcParamId */
+			return error;
+		}
+		tfa98xx_convert_bytes2data(sizeof(bytes), bytes, features);
+	}
+	return error;
+}
+
+enum Tfa98xx_Error tfa98xx_dsp_get_state_info(Tfa98xx_handle_t handle, unsigned char bytes[], unsigned int *statesize)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+        int bSupportFramework = 0;
+        unsigned int stateSize = 9;
+
+	err = tfa98xx_dsp_support_framework(handle, &bSupportFramework);
+	if (err == Tfa98xx_Error_Ok) {
+		if (bSupportFramework) {
+			err = tfa_dsp_cmd_id_write_read(handle, MODULE_FRAMEWORK,
+				FW_PARAM_GET_STATE, 3 * stateSize, bytes);
+		} else {
+			/* old ROM code, ask SpeakerBoost and only do first portion */
+			stateSize = 8;
+			err = tfa_dsp_cmd_id_write_read(handle, MODULE_SPEAKERBOOST,
+				SB_PARAM_GET_STATE, 3 * stateSize, bytes);
+		}
+	}
+
+	*statesize = stateSize;
+
+	return err;
+}
+
+enum Tfa98xx_Error tfa98xx_dsp_support_drc(Tfa98xx_handle_t handle, int *pbSupportDrc)
+{
+    enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+    *pbSupportDrc = 0;
+
+    if (!tfa98xx_handle_is_open(handle))
+        return Tfa98xx_Error_NotOpen;
+    if (handles_local[handle].supportDrc != supportNotSet) {
+        *pbSupportDrc = (handles_local[handle].supportDrc == supportYes);
+    } else {
+        int featureBits[2];
+
+        error = tfa98xx_dsp_get_sw_feature_bits(handle, featureBits);
+        if (error == Tfa98xx_Error_Ok) {
+            /* easy case: new API available */
+            /* bit=0 means DRC enabled */
+            *pbSupportDrc = (featureBits[0] & FEATURE1_DRC) == 0;
+        } else if (error == Tfa98xx_Error_RpcParamId) {
+            /* older ROM code, doesn't support it */
+            *pbSupportDrc = 0;
+            error = Tfa98xx_Error_Ok;
+        }
+        /* else some other error, return transparently */
+        /* pbSupportDrc only changed when error == Tfa98xx_Error_Ok */
+
+        if (error == Tfa98xx_Error_Ok) {
+        	handles_local[handle].supportDrc = *pbSupportDrc ? supportYes : supportNo;
+        }
+    }
+    return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_dsp_support_framework(Tfa98xx_handle_t handle, int *pbSupportFramework)
+{
+    int featureBits[2] = { 0, 0 };
+    enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+    _ASSERT(pbSupportFramework != 0);
+
+    if (!tfa98xx_handle_is_open(handle))
+        return Tfa98xx_Error_NotOpen;
+
+    if (handles_local[handle].supportFramework != supportNotSet) {
+	    if(handles_local[handle].supportFramework == supportNo)
+		    *pbSupportFramework = 0;
+	    else
+		    *pbSupportFramework = 1;
+    } else {
+        error = tfa98xx_dsp_get_sw_feature_bits(handle, featureBits);
+        if (error == Tfa98xx_Error_Ok) {
+            *pbSupportFramework = 1;
+            handles_local[handle].supportFramework = supportYes;
+        } else {
+            *pbSupportFramework = 0;
+            handles_local[handle].supportFramework = supportNo;
+            error = Tfa98xx_Error_Ok;
+        }
+    }
+
+    /* *pbSupportFramework only changed when error == Tfa98xx_Error_Ok */
+    return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_dsp_write_speaker_parameters(Tfa98xx_handle_t handle,
+				  int length,
+				  const unsigned char *p_speaker_bytes)
+{
+	enum Tfa98xx_Error error;
+	if (p_speaker_bytes != 0) {
+		/* by design: keep the data opaque and no
+		 * interpreting/calculation */
+		/* Use long WaitResult retry count */
+		error = tfa_dsp_cmd_id_write(
+					handle,
+					MODULE_SPEAKERBOOST,
+					SB_PARAM_SET_LSMODEL, length,
+					p_speaker_bytes);
+	} else {
+		error = Tfa98xx_Error_Bad_Parameter;
+	}
+
+#if (defined(TFA9887B) || defined(TFA98XX_FULL))
+    {
+        int bSupportDrc;
+
+        if (error != Tfa98xx_Error_Ok)
+            return error;
+
+        error = tfa98xx_dsp_support_drc(handle, &bSupportDrc);
+        if (error != Tfa98xx_Error_Ok)
+            return error;
+
+        if (bSupportDrc) {
+            /* Need to set AgcGainInsert back to PRE,
+             * as the SetConfig forces it to POST */
+        	uint8_t bytes[3] = {0, 0, 0};
+
+        	error = tfa_dsp_cmd_id_write(handle,
+        				     MODULE_SPEAKERBOOST,
+        				     SB_PARAM_SET_AGCINS,
+        				     sizeof(bytes),
+        				     bytes);
+        }
+    }
+#endif
+
+    return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_dsp_write_config(Tfa98xx_handle_t handle, int length,
+               const unsigned char *p_config_bytes)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	error = tfa_dsp_cmd_id_write(handle,
+				      MODULE_SPEAKERBOOST,
+				      SB_PARAM_SET_CONFIG, length,
+				      p_config_bytes);
+
+#if (defined(TFA9887B) || defined(TFA98XX_FULL))
+    {
+        int bSupportDrc;
+
+        if (error != Tfa98xx_Error_Ok)
+            return error;
+
+        error = tfa98xx_dsp_support_drc(handle, &bSupportDrc);
+        if (error != Tfa98xx_Error_Ok)
+            return error;
+
+        if (bSupportDrc) {
+            /* Need to set AgcGainInsert back to PRE,
+             * as the SetConfig forces it to POST */
+        	uint8_t bytes[3] = {0, 0, 0};
+
+        	error = tfa_dsp_cmd_id_write(handle,
+        				     MODULE_SPEAKERBOOST,
+        				     SB_PARAM_SET_AGCINS,
+        				     sizeof(bytes),
+        				     bytes);
+        }
+    }
+#endif
+
+    return error;
+}
+
+#if (defined(TFA9887B) || defined(TFA98XX_FULL))
+/* load all the parameters for the DRC settings from a file */
+enum Tfa98xx_Error tfa98xx_dsp_write_drc(Tfa98xx_handle_t handle,
+                    int length, const unsigned char *p_drc_bytes)
+{
+    enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+    if (p_drc_bytes != 0) {
+	error = tfa_dsp_cmd_id_write(handle,
+				      MODULE_SPEAKERBOOST,
+				      SB_PARAM_SET_DRC, length,
+				      p_drc_bytes);
+
+    } else {
+        error = Tfa98xx_Error_Bad_Parameter;
+    }
+    return error;
+}
+#endif
+
+enum Tfa98xx_Error tfa98xx_powerdown(Tfa98xx_handle_t handle, int powerdown)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+        TFA_SET_BF(handle, PWDN, (uint16_t)powerdown);
+
+	return error;
+}
+
+enum Tfa98xx_Error
+tfa98xx_select_mode(Tfa98xx_handle_t handle, enum Tfa98xx_Mode mode)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	if (error == Tfa98xx_Error_Ok) {
+		switch (mode) {
+
+		default:
+			error = Tfa98xx_Error_Bad_Parameter;
+		}
+	}
+
+	return error;
+}
+
+int tfa_set_bf(Tfa98xx_handle_t dev_idx, const uint16_t bf, const uint16_t value)
+{
+	enum Tfa98xx_Error err;
+	uint16_t regvalue, msk, oldvalue;
+
+	/*
+	 * bitfield enum:
+	 * - 0..3  : len
+	 * - 4..7  : pos
+	 * - 8..15 : address
+	 */
+	uint8_t len = bf & 0x0f;
+	uint8_t pos = (bf >> 4) & 0x0f;
+	uint8_t address = (bf >> 8) & 0xff;
+
+	err = tfa98xx_read_register16(dev_idx, address, &regvalue);
+	if (err) {
+              pr_err("Error getting bf :%d \n", -err);
+              return -err;
+        }
+
+        oldvalue = regvalue;
+	msk = ((1<<(len+1))-1)<<pos;
+	regvalue &= ~msk;
+	regvalue |= value<<pos;
+
+        /* Only write when the current register value is not the same as the new value */
+        if(oldvalue != regvalue) {
+                err = tfa98xx_write_register16(dev_idx, address, regvalue);
+	        if (err) {
+                      pr_err("Error setting bf :%d \n", -err);
+                      return -err;
+                }
+        }
+
+	return 0;
+}
+
+int tfa_set_bf_volatile(Tfa98xx_handle_t dev_idx, const uint16_t bf, const uint16_t value)
+{
+	enum Tfa98xx_Error err;
+	uint16_t regvalue, msk;
+
+	/*
+	 * bitfield enum:
+	 * - 0..3  : len
+	 * - 4..7  : pos
+	 * - 8..15 : address
+	 */
+	uint8_t len = bf & 0x0f;
+	uint8_t pos = (bf >> 4) & 0x0f;
+	uint8_t address = (bf >> 8) & 0xff;
+
+	err = tfa98xx_read_register16(dev_idx, address, &regvalue);
+	if (err) {
+              pr_err("Error getting bf :%d \n", -err);
+              return -err;
+        }
+
+	msk = ((1<<(len+1))-1)<<pos;
+	regvalue &= ~msk;
+	regvalue |= value<<pos;
+
+        err = tfa98xx_write_register16(dev_idx, address, regvalue);
+	if (err) {
+                pr_err("Error setting bf :%d \n", -err);
+                return -err;
+        }
+
+	return 0;
+}
+
+int tfa_get_bf(Tfa98xx_handle_t dev_idx, const uint16_t bf)
+{
+	enum Tfa98xx_Error err;
+	uint16_t regvalue, msk;
+	uint16_t value;
+
+	/*
+	 * bitfield enum:
+	 * - 0..3  : len
+	 * - 4..7  : pos
+	 * - 8..15 : address
+	 */
+	uint8_t len = bf & 0x0f;
+	uint8_t pos = (bf >> 4) & 0x0f;
+	uint8_t address = (bf >> 8) & 0xff;
+
+	err = tfa98xx_read_register16(dev_idx, address, &regvalue);
+        if (err) {
+              pr_err("Error getting bf :%d \n", -err);
+              return -err;
+        }
+
+	msk = ((1<<(len+1))-1)<<pos;
+	regvalue &= msk;
+	value = regvalue>>pos;
+
+	return value;
+}
+
+int tfa_set_bf_value(const uint16_t bf, const uint16_t bf_value, uint16_t *p_reg_value)
+{
+	uint16_t regvalue, msk;
+
+	/*
+	 * bitfield enum:
+	 * - 0..3  : len
+	 * - 4..7  : pos
+	 * - 8..15 : address
+	 */
+	uint8_t len = bf & 0x0f;
+	uint8_t pos = (bf >> 4) & 0x0f;
+
+	regvalue = *p_reg_value;
+
+	msk = ((1<<(len+1))-1)<<pos;
+	regvalue &= ~msk;
+	regvalue |= bf_value<<pos;
+
+	*p_reg_value = regvalue;
+
+	return 0;
+}
+
+uint16_t tfa_get_bf_value(const uint16_t bf, const uint16_t reg_value)
+{
+	uint16_t msk, value;
+
+	/*
+	 * bitfield enum:
+	 * - 0..3  : len
+	 * - 4..7  : pos
+	 * - 8..15 : address
+	 */
+	uint8_t len = bf & 0x0f;
+	uint8_t pos = (bf >> 4) & 0x0f;
+
+	msk = ((1<<(len+1))-1)<<pos;
+	value = (reg_value & msk) >> pos;
+
+	return value;
+}
+
+
+int tfa_write_reg(Tfa98xx_handle_t dev_idx, const uint16_t bf, const uint16_t reg_value)
+{
+	enum Tfa98xx_Error err;
+
+	/* bitfield enum - 8..15 : address */
+	uint8_t address = (bf >> 8) & 0xff;
+
+	err = tfa98xx_write_register16(dev_idx, address, reg_value);
+	if (err)
+		return -err;
+
+	return 0;
+}
+
+int tfa_read_reg(Tfa98xx_handle_t dev_idx, const uint16_t bf)
+{
+	enum Tfa98xx_Error err;
+	uint16_t regvalue;
+
+	/* bitfield enum - 8..15 : address */
+	uint8_t address = (bf >> 8) & 0xff;
+
+	err = tfa98xx_read_register16(dev_idx, address, &regvalue);
+	if (err)
+		return -err;
+
+	return regvalue;
+}
+
+/*
+ * powerup the coolflux subsystem and wait for it
+ */
+enum Tfa98xx_Error tfa_cf_powerup(Tfa98xx_handle_t handle) {
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int tries, status;
+
+	/* power on the sub system */
+	TFA_SET_BF_VOLATILE(handle, PWDN, 0);
+
+	// wait until everything is stable, in case clock has been off
+	if (tfa98xx_runtime_verbose)
+		pr_info("Waiting for DSP system stable...\n");
+	for ( tries=CFSTABLE_TRIES; tries > 0; tries-- ) {
+		err = tfa98xx_dsp_system_stable(handle, &status);
+		_ASSERT(err == Tfa98xx_Error_Ok);
+		if ( status )
+			break;
+		else
+			msleep_interruptible(10); /* wait 10ms to avoid busload */
+	}
+	if (tries==0) {// timedout
+		pr_err("DSP subsystem start timed out\n");
+		return Tfa98xx_Error_StateTimedOut;
+	}
+
+	return err;
+}
+
+/*
+ * Enable/Disable the I2S output for TFA1 devices
+ * without TDM interface
+ */
+static enum Tfa98xx_Error tfa98xx_aec_output(Tfa98xx_handle_t handle, int enable)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	if ((tfa98xx_get_device_dai(handle) & Tfa98xx_DAI_TDM) == Tfa98xx_DAI_TDM)
+		return err;
+
+	if (tfa98xx_dev_family(handle) == 1)
+		err = -tfa_set_bf(handle, TFA1_BF_I2SDOE, (enable!=0));
+	else {
+		pr_err("I2SDOE on unsupported family\n");
+		err = Tfa98xx_Error_Not_Supported;
+	}
+
+	return err;
+}
+
+/*
+ * Print the current state of the hardware manager
+ * Device manager status information, man_state from TFA9888_N1B_I2C_regmap_V12
+ */
+enum Tfa98xx_Error show_current_state(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+        int manstate = -1;
+
+	if (tfa98xx_dev_family(handle) == 2) {
+		manstate = TFA_GET_BF(handle, MANSTATE);
+		if (manstate < 0)
+        		return -manstate;
+	}
+
+	pr_debug("Current HW manager state: ");
+
+	switch(manstate) {
+		case 0: pr_debug("power_down_state \n");
+			break;
+		case 1: pr_debug("wait_for_source_settings_state \n");
+			break;
+		case 2: pr_debug("connnect_pll_input_state \n");
+			break;
+		case 3: pr_debug("disconnect_pll_input_state \n");
+			break;
+		case 4: pr_debug("enable_pll_state \n");
+			break;
+		case 5: pr_debug("enable_cgu_state \n");
+			break;
+		case 6: pr_debug("init_cf_state \n");
+			break;
+		case 7: pr_debug("enable_amplifier_state \n");
+			break;
+		case 8: pr_debug("alarm_state \n");
+			break;
+		case 9: pr_debug("operating_state \n");
+			break;
+		case 10: pr_debug("mute_audio_state \n");
+			break;
+		case 11: pr_debug("disable_cgu_pll_state \n");
+			break;
+		default:
+			pr_debug("Unable to find current state \n");
+			break;
+	}
+
+	return err;
+}
+
+/*
+ *  start the speakerboost algorithm
+ *  this implies a full system startup when the system was not already started
+ *
+ */
+enum Tfa98xx_Error tfaRunSpeakerBoost(Tfa98xx_handle_t handle, int force, int profile)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int value;
+	int istap_prof = 0;
+
+	if ( force ) {
+		err= tfaRunColdStartup(handle, profile);
+		if ( err ) return err;
+		// DSP is running now
+	}
+
+	value = TFA_GET_BF(handle, ACS);
+
+#ifdef __KERNEL__ /* TODO try to combine this with the pr_debug below */
+	tfa98xx_trace_printk("%s %sstart\n",
+	             tfaContDeviceName(handle),
+	             value ? "cold" : "warm");
+#endif
+	/* Check if next profile is a tap profile */
+	istap_prof = tfaContIsTapProfile(handle, profile);
+
+	if ((value == 1) && (!istap_prof)) {
+		/* Run startup and write all files */
+		err = tfaRunSpeakerStartup(handle, force, profile);
+		if ( err ) return err;
+
+		/* Save the current profile and set the vstep to 0 */
+		/* This needs to be overwriten even in CF bypass */
+		tfa_set_swprof(handle, (unsigned short)profile);
+		tfa_set_swvstep(handle, 0);
+
+		/* Startup with CF in bypass then return here */
+		if (TFA_GET_BF(handle, CFE) == 0) {
+			return err;
+		}
+
+#ifdef __KERNEL__ /* TODO check if this can move to the tfa98xx.c */
+			/* Necessary here for early calibrate (MTPEX + ACS) */
+			tfa98xx_apply_deferred_calibration(handle);
+#endif
+		/* calibrate */
+		err = tfaRunSpeakerCalibration(handle, profile);
+	} else if (istap_prof)  {
+		/* Save the current profile and set the vstep to 0 */
+		/* This needs to be overwriten even in CF bypass and tap*/
+		tfa_set_swprof(handle, (unsigned short)profile);
+		tfa_set_swvstep(handle, 0);
+	}
+
+	return err;
+}
+
+enum Tfa98xx_Error tfaRunSpeakerStartup(Tfa98xx_handle_t handle, int force, int profile)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	pr_debug("coldstart%s :", force? " (forced)":"");
+
+	if ( !force ) { // in case of force CF already runnning
+		err = tfaRunStartup(handle, profile);
+		PRINT_ASSERT(err);
+		if ( err )
+			return err;
+		/* Startup with CF in bypass then return here */
+		if (TFA_GET_BF(handle, CFE) == 0)
+			return err;
+
+		err = tfaRunStartDSP(handle);
+		if ( err )
+			return err;
+	}
+	// DSP is running now
+	//
+	// NOTE that ACS may be active
+	//  no DSP reset/sample rate may be done until configured (SBSL)
+	// For the first configuration the DSP expects at least
+	// the speaker, config and a preset.
+	// Therefore all files from the device list as well as the file
+	// from the default profile are loaded before SBSL is set.
+	//
+	// Note that the register settings were already done before loading the patch
+	//
+	// write all the files from the device list (speaker, vstep and all messages)
+	err = tfaContWriteFiles(handle);
+	if (err)
+		return err;
+
+	// write all the files from the profile list (typically preset)
+	err = tfaContWriteFilesProf(handle, profile, 0); // use volumestep 0
+	if (err)
+		return err;	
+
+	return err;
+}
+
+/*
+ * Run calibration
+ */
+enum Tfa98xx_Error tfaRunSpeakerCalibration(Tfa98xx_handle_t handle, int profile)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int calibrateDone, spkr_count = 0;
+	/* Avoid warning in user-space */
+	profile=profile;
+
+#ifdef __KERNEL__ /* Necessary otherwise we are thrown out of operating mode in kernel (because of internal clock) */
+	if((strstr(tfaContProfileName(handle, profile), ".cal") == NULL) && (tfa98xx_dev_family(handle) == 2))
+    {
+        TFA_SET_BF_VOLATILE(handle, SBSL, 1);
+    }
+    else if (tfa98xx_dev_family(handle) != 2)
+#endif
+		TFA_SET_BF_VOLATILE(handle, SBSL, 1);
+
+	/* return if there is no audio running */
+	if (TFA_GET_BF(handle, NOCLK) && tfa98xx_dev_family(handle) == 2)
+		return Tfa98xx_Error_NoClock;
+
+	/* When MTPOTC is set (cal=once) unlock key2 */
+	if (TFA_GET_BF(handle, MTPOTC) == 1) {
+		tfa98xx_key2(handle, 0);
+	}	
+
+	/* await calibration, this should return ok */
+	err = tfaRunWaitCalibration(handle, &calibrateDone);
+	if (err == Tfa98xx_Error_Ok) {
+		err = tfa_dsp_get_calibration_impedance(handle);
+		PRINT_ASSERT(err);
+	}
+
+	/* Give reason why calibration failed! */
+	if (err != Tfa98xx_Error_Ok) {
+		if ((tfa98xx_dev_family(handle) == 2 && TFA_GET_BF(handle, REFCKSEL) == 1)) {
+			pr_err("Unable to calibrate the device with the internal clock! \n");
+		}
+	}
+
+	if (err == Tfa98xx_Error_Ok) {
+		err = tfa98xx_supported_speakers(handle, &spkr_count);
+
+		if (spkr_count == 1) {
+			pr_debug(" %d mOhms \n", handles_local[handle].mohm[0]);
+		} else {
+			pr_debug(" Prim:%d mOhms, Sec:%d mOhms\n",
+						handles_local[handle].mohm[0], 
+						handles_local[handle].mohm[1]);
+		}
+	}
+
+	/* When MTPOTC is set (cal=once) re-lock key2 */
+	if (TFA_GET_BF(handle, MTPOTC) == 1) {
+		tfa98xx_key2(handle, 1);
+	}
+
+	return err;
+}
+
+/*
+ * Set the debug option
+ */
+void tfa_verbose(int level)
+{
+	tfa98xx_trace_level = level;
+	tfa98xx_runtime_verbose = level!=0; /* any non-zero */
+	tfa_cnt_verbose(level);
+}
+
+enum Tfa98xx_Error tfaRunColdboot(Tfa98xx_handle_t handle, int state)
+{
+#define CF_CONTROL 0x8100
+	enum Tfa98xx_Error err=Tfa98xx_Error_Ok;
+	int tries = 10;
+
+	/* repeat set ACS bit until set as requested */
+	while ( state != TFA_GET_BF(handle, ACS)) {
+		/* set colstarted in CF_CONTROL to force ACS */
+                err = tfa98xx_dsp_write_mem_word(handle, CF_CONTROL, state, Tfa98xx_DMEM_IOMEM);
+		PRINT_ASSERT(err);
+
+		if (tries-- == 0) {
+			pr_debug("coldboot (ACS) did not %s\n", state ? "set":"clear");
+			return Tfa98xx_Error_Other;
+		}
+	}
+
+	return err;
+}
+
+
+
+/*
+ * load the patch if any
+ *   else tell no loaded
+ */
+static enum Tfa98xx_Error tfa_run_load_patch(Tfa98xx_handle_t handle)
+{
+	return tfaContWritePatch(handle);
+}
+
+/*
+ *  this will load the patch witch will implicitly start the DSP
+ *   if no patch is available the DPS is started immediately
+ */
+enum Tfa98xx_Error tfaRunStartDSP(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	err = tfa_run_load_patch(handle);
+	if (err) { /* patch load is fatal so return immediately*/
+		return err;
+	}
+
+	/* Clear count_boot, should be reset to 0 before the DSP reset is released */
+	err = tfa98xx_dsp_write_mem_word(handle, 512, 0, Tfa98xx_DMEM_XMEM);
+	PRINT_ASSERT(err);
+
+	/* Reset DSP once for sure after initializing */
+	if ( err == Tfa98xx_Error_Ok) {
+		err = tfa98xx_dsp_reset(handle, 0); /* in pair of tfa98xx_init() - tfaRunStartup() */
+		PRINT_ASSERT(err);
+	}
+
+	/* Sample rate is needed to set the correct tables */
+	err = tfa98xx_dsp_write_tables(handle, TFA_GET_BF(handle, AUDFS));
+	PRINT_ASSERT(err);
+
+	return err;
+}
+
+/*
+ * start the clocks and wait until the AMP is switching
+ *  on return the DSP sub system will be ready for loading
+ */
+enum Tfa98xx_Error tfaRunStartup(Tfa98xx_handle_t handle, int profile)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	nxpTfaDeviceList_t *dev = tfaContDevice(handle);
+	int tries, status, i, noinit=0;
+
+	if(dev == NULL)
+		return Tfa98xx_Error_Fail;
+
+	/* process the device list to see if the user implemented the noinit */
+	for(i=0;i<dev->length;i++) {
+		if (dev->list[i].type == dscNoInit) {
+			noinit=1;
+			break;
+		}
+	}
+
+	if(!noinit) {
+		/* load the optimal TFA98XX in HW settings */
+		err = tfa98xx_init(handle);
+		PRINT_ASSERT(err);
+	} else {
+		pr_debug("\nWarning: No init keyword found in the cnt file. Init is skipped! \n");
+	}
+
+	/* I2S settings to define the audio input properties
+	 *  these must be set before the subsys is up */
+	// this will run the list until a non-register item is encountered
+	err = tfaContWriteRegsDev(handle); // write device register settings
+	PRINT_ASSERT(err);
+	// also write register the settings from the default profile
+	// NOTE we may still have ACS=1 so we can switch sample rate here
+	err = tfaContWriteRegsProf(handle, profile);
+	PRINT_ASSERT(err);
+
+	if(tfa98xx_dev_family(handle) == 2) {
+		/* Factory trimming for the Boost converter */
+		tfa_factory_trimmer(handle);
+	}
+
+	/* leave power off state */
+	err = tfa98xx_powerdown(handle, 0);
+	PRINT_ASSERT(err);
+
+	if (tfa98xx_dev_family(handle) == 2) {
+	/* signal that the clock settings are done
+	 *  - PLL can start */
+		TFA_SET_BF_VOLATILE(handle, MANSCONF, 1);
+	}
+    switch (TFA_GET_BF(handle, REV) & 0xff)
+    {
+        case 0x80:
+            err = tfa98xx_dsp_reset(handle, 1);
+            pr_debug("tfaRunStartup Reset DSP after power on\n");
+            break;
+        default:
+            break;
+    }
+
+	/*  wait until the PLL is ready
+	 *    note that the DSP CPU is not running (RST=1) */
+	if (tfa98xx_runtime_verbose) {
+		if (TFA_GET_BF(handle, NOCLK) && (tfa98xx_dev_family(handle) == 2))
+			pr_debug("Using internal clock\n");
+		pr_debug("Waiting for DSP system stable...\n");
+	}
+	for ( tries=1; tries < CFSTABLE_TRIES; tries++ ) {
+		err = tfa98xx_dsp_system_stable(handle, &status);
+		_ASSERT(err == Tfa98xx_Error_Ok);
+		if ( status )
+			break;
+		else
+			msleep_interruptible(10); /* wait 10ms to avoid busload */
+	}
+	if (tries == CFSTABLE_TRIES) {
+		if (tfa98xx_runtime_verbose) pr_debug("Timed out\n");
+		return Tfa98xx_Error_StateTimedOut;
+	}  else
+		if (tfa98xx_runtime_verbose) pr_debug(" OK (tries=%d)\n", tries);
+
+	if (tfa98xx_runtime_verbose && tfa98xx_dev_family(handle) == 2)
+		err = show_current_state(handle);
+
+	return err;
+}
+
+/*
+ * run the startup/init sequence and set ACS bit
+ */
+enum Tfa98xx_Error tfaRunColdStartup(Tfa98xx_handle_t handle, int profile)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	err = tfaRunStartup(handle, profile);
+	PRINT_ASSERT(err);
+	if (err)
+		return err;
+
+	/* force cold boot */
+	err = tfaRunColdboot(handle, 1); // set ACS
+	PRINT_ASSERT(err);
+	if (err)
+		return err;
+
+	/* start */
+	err = tfaRunStartDSP(handle);
+	PRINT_ASSERT(err);
+
+	return err;
+}
+
+/*
+ *
+ */
+enum Tfa98xx_Error tfaRunMute(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int status;
+	int tries = 0;
+
+	/* signal the TFA98XX to mute  */
+	if(tfa98xx_dev_family(handle) == 1) {
+		err = tfa98xx_set_mute(handle, Tfa98xx_Mute_Amplifier);
+
+		if(err == Tfa98xx_Error_Ok) {
+			/* now wait for the amplifier to turn off */
+			do {
+				status = TFA_GET_BF(handle, SWS);
+				if (status != 0)
+					msleep_interruptible(10); /* wait 10ms to avoid busload */
+				else
+					break;
+				tries++;
+			}  while (tries < AMPOFFWAIT_TRIES);
+
+
+			if ( tfa98xx_runtime_verbose )
+				pr_debug("-------------------- muted --------------------\n");
+
+			/*The amplifier is always switching*/
+			if (tries == AMPOFFWAIT_TRIES)
+				return Tfa98xx_Error_Other;
+		}
+	}
+
+	return err;
+}
+/*
+ *
+ */
+enum Tfa98xx_Error tfaRunUnmute(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	/* signal the TFA98XX to mute  */
+	err = tfa98xx_set_mute(handle, Tfa98xx_Mute_Off);
+
+	if ( tfa98xx_runtime_verbose )
+	    pr_debug("-------------------unmuted ------------------\n");
+
+    return err;
+}
+
+
+/*
+ * wait for calibrateDone
+ */
+enum Tfa98xx_Error tfaRunWaitCalibration(Tfa98xx_handle_t handle, int *calibrateDone)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int tries = 0, mtp_busy = 1, tries_mtp_busy = 0;
+
+	*calibrateDone = 0;
+	
+	/* in case of calibrate once wait for MTPEX */
+	if (TFA_GET_BF(handle, MTPOTC)) {
+		// Check if MTP_busy is clear!
+		while (tries_mtp_busy < MTPBWAIT_TRIES)
+		{
+			mtp_busy = TFA_GET_BF(handle, MTPB);
+			if (mtp_busy == 1)
+				msleep_interruptible(10); /* wait 10ms to avoid busload */
+			else
+				break;
+			tries_mtp_busy++;
+		}
+
+		if (tries_mtp_busy < MTPBWAIT_TRIES) {
+			/* Because of the msleep TFA98XX_API_WAITRESULT_NTRIES is way to long! 
+				* Setting this to 25 will take it atleast 25*50ms = 1.25 sec 
+				*/
+			while ( (*calibrateDone == 0) && (tries < MTPEX_WAIT_NTRIES)) {	
+				*calibrateDone = TFA_GET_BF(handle, MTPEX);
+				if(*calibrateDone == 1)
+					break;
+				msleep_interruptible(50); /* wait 50ms to avoid busload */
+				tries++;
+			}
+
+			if (tries >= MTPEX_WAIT_NTRIES) {
+				tries = TFA98XX_API_WAITRESULT_NTRIES;
+			}
+		} else {
+			pr_err("MTP bussy after %d tries\n", MTPBWAIT_TRIES);
+		}
+	}
+
+	/* poll xmem for calibrate always 
+		* calibrateDone = 0 means "calibrating",
+		* calibrateDone = -1 (or 0xFFFFFF) means "fails"
+		* calibrateDone = 1 means calibration done 
+		*/
+	while ((*calibrateDone != 1) && (tries<TFA98XX_API_WAITRESULT_NTRIES)) {
+		err = tfa98xx_dsp_read_mem(handle, TFA_FW_XMEM_CALIBRATION_DONE, 1, calibrateDone);
+		tries++;
+	}
+
+	if(*calibrateDone != 1) {
+		pr_err("Calibration failed! \n");
+		err = Tfa98xx_Error_Bad_Parameter;
+	} else if (tries==TFA98XX_API_WAITRESULT_NTRIES) {
+		pr_debug("Calibration has timedout! \n");
+		err = Tfa98xx_Error_StateTimedOut;
+	} else if(tries_mtp_busy == 1000) {
+		pr_err("Calibrate Failed: MTP_busy stays high! \n");
+		err = Tfa98xx_Error_StateTimedOut;
+	}
+
+	/* Check which speaker calibration failed. Only for 88C */
+	if((err != Tfa98xx_Error_Ok) && ((handles_local[handle].rev & 0x0FFF) == 0xc88)) {
+		individual_calibration_results(handle);
+	}
+
+#ifdef CONFIG_DEBUG_FS
+	tfa98xx_deferred_calibration_status(handle, *calibrateDone);
+#endif
+	return err;
+}
+
+enum tfa_error tfa_start(int next_profile, int *vstep)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int dev, devcount = tfa98xx_cnt_max_device();
+	int cal_profile = -1, istap_prof = 0, active_profile = -1;
+#ifdef __KERNEL__
+	uint8_t kernel_sleep_timeout = 0;
+#endif
+
+	if ( devcount < 1 ) {
+		pr_err("No or wrong container file loaded\n");
+		return	tfa_error_bad_param;
+	}
+
+	for( dev=0; dev < devcount; dev++) {
+		err = tfaContOpen(dev);
+		if ( err != Tfa98xx_Error_Ok)
+			goto error_exit;
+
+		/* Get currentprofile */
+		active_profile = tfa_get_swprof(dev);
+		if (active_profile == 0xff)
+			active_profile = -1;
+
+		/* Search if there is a calibration profile
+		 * Only if the user did not give a specific profile and coldstart
+		 */
+		if (active_profile == -1 && next_profile < 1) {
+			cal_profile = tfaContGetCalProfile(dev);
+			if (cal_profile >= 0)
+				next_profile = cal_profile;
+		}
+		/* Check if next profile is a tap profile */
+		istap_prof = tfaContIsTapProfile(dev, next_profile);
+
+		/* tfaRun_SpeakerBoost implies un-mute */
+		if (tfa98xx_runtime_verbose) {
+			pr_debug("active_profile:%s, next_profile:%s\n",
+					tfaContProfileName(dev,active_profile ),
+					tfaContProfileName(dev, next_profile));
+			pr_debug("Starting device [%s]\n", tfaContDeviceName(dev));
+
+			if(tfa98xx_dev_family(dev) == 2) {
+				err = show_current_state(dev);
+			}
+		}
+
+		/* enable I2S output on TFA1 devices without TDM */
+		err = tfa98xx_aec_output(dev, 1);
+		if ( err != Tfa98xx_Error_Ok)
+			goto error_exit;
+
+		/* Check if we need coldstart or ACS is set */
+		err = tfaRunSpeakerBoost(dev, 0, next_profile);
+		if ( err != Tfa98xx_Error_Ok)
+			goto error_exit;
+
+		active_profile = tfa_get_swprof(dev);
+
+		/* After loading calibration profile we need to load acoustic shock profile */
+		if (cal_profile >= 0) {
+			next_profile = 0;
+			pr_debug("Loading %s profile! \n", tfaContProfileName(dev, next_profile));
+		}
+	}
+
+	for( dev=0; dev < devcount; dev++) {
+		/* check if the profile and steps are the one we want */
+		/* was it not done already */
+		if (( next_profile != active_profile && active_profile != -1)
+		       || (istap_prof == 1)) {
+			err = tfaContWriteProfile(dev, next_profile, vstep[dev]);
+			if (err!=Tfa98xx_Error_Ok)
+				goto error_exit;
+		} 
+
+		/* If the profile contains the .standby suffix go to powerdown
+		 * else we should be in operating state
+		 */
+		if(strstr(tfaContProfileName(dev, next_profile), ".standby") != NULL) {
+			err = tfa98xx_powerdown(dev, 1);
+		} else if (TFA_GET_BF(dev, PWDN) != 0) {
+			err = tfa98xx_powerdown(dev, 0);
+		}
+
+		if (err!=Tfa98xx_Error_Ok)
+			goto error_exit;
+
+		if (tfa98xx_runtime_verbose && tfa98xx_dev_family(dev) == 2)
+			err = show_current_state(dev);
+
+		/* Always search and apply filters after a startup */
+		err = tfa_set_filters(dev, next_profile);
+		if (err!=Tfa98xx_Error_Ok)
+			goto error_exit;
+
+#ifdef __KERNEL__
+		/* To write something in state 6 we need to be sure that SBSL is also set in IOMEM! 
+		 * More information can be found in the document about the powerswitch
+		 */
+		if (tfa98xx_dev_family(dev) == 2) {
+			/* If we are in state 0 or 1 we can skip setting SBSL and RST, but also filters and vstep (since there is no clk)
+			 * We can be in state 0 or 1 because of standby profile or switching profile with internal clock
+			 * No need to wait since we can only get out of state 0 or 1 by setting a bit (not by waiting)
+			 */
+			int manstate = TFA_GET_BF(dev, MANSTATE);
+			if (manstate > 1) {
+				/* Wait for the HW manager to be in state 6 (initCF)
+				 * Absolute worstcase the HW manager takes 28ms (norm = ~3)
+				 */
+				while ((manstate < 6) && (kernel_sleep_timeout < 28)) {
+					kernel_sleep_timeout++;
+					msleep_interruptible(1);
+					manstate = TFA_GET_BF(dev, MANSTATE);
+				}
+
+				if ((manstate == 6) && (TFA_GET_BF(dev, RST) == 1) && (TFA_GET_BF(dev, SBSL) == 0)) {
+					TFA_SET_BF_VOLATILE(dev, SBSL, 0);
+					TFA_SET_BF(dev, RST, 0);
+				}
+			}
+		}
+#endif
+
+		if (vstep[dev] != tfaContGetCurrentVstep(dev) && vstep[dev] != -1) {
+			err = tfaContWriteFilesVstep(dev, next_profile, vstep[dev]);
+			if ( err != Tfa98xx_Error_Ok)
+				goto error_exit;
+		}
+
+		tfa_set_swprof(dev, (unsigned short)next_profile);
+		tfa_set_swvstep(dev, (unsigned short)tfaContGetCurrentVstep(dev));
+	}
+
+error_exit:
+	if (tfa98xx_runtime_verbose && tfa98xx_dev_family(dev) == 2)
+		show_current_state(dev);
+
+	for( dev=0; dev < devcount; dev++) {
+		tfaRunUnmute(dev);	/* unmute */
+		tfaContClose(dev); /* close all of them */
+	}
+
+	return err;
+}
+
+enum tfa_error tfa_stop(void)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int dev, devcount = tfa98xx_cnt_max_device();
+
+	if ( devcount == 0 ) {
+		pr_err("No or wrong container file loaded\n");
+		return	tfa_error_bad_param;
+	}
+
+	for( dev=0; dev < devcount; dev++) {
+		err = tfaContOpen(dev);
+		if ( err != Tfa98xx_Error_Ok)
+			goto error_exit;
+		if (tfa98xx_runtime_verbose)
+			pr_debug("Stopping device [%s]\n", tfaContDeviceName(dev));
+		/* mute */
+		tfaRunMute(dev);
+		/* powerdown CF */
+		err = tfa98xx_powerdown(dev, 1 );
+		if ( err != Tfa98xx_Error_Ok)
+			goto error_exit;
+
+		/* disable I2S output on TFA1 devices without TDM */
+		err = tfa98xx_aec_output(dev, 0);
+		if ( err != Tfa98xx_Error_Ok)
+			goto error_exit;
+	}
+
+error_exit:
+	for( dev=0; dev < devcount; dev++)
+		tfaContClose(dev); /* close all of them */
+	return err;
+}
+
+/*
+ *  int registers and coldboot dsp
+ */
+int tfa98xx_reset(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+
+	TFA_SET_BF_VOLATILE(handle, I2CR, 1);
+	/* restore MANSCONF and MANCOLD to POR state */
+	TFA_SET_BF_VOLATILE(handle, MANSCONF, 0);
+	TFA_SET_BF_VOLATILE(handle, MANCOLD, 1);
+
+	/* powerup CF to access CF io */
+	tfa98xx_powerdown(handle, 0 );
+	/* for clock */
+	err = tfa_cf_powerup(handle);
+	PRINT_ASSERT(err);
+
+	/* force cold boot */
+	err = tfaRunColdboot(handle, 1); // set ACS
+	PRINT_ASSERT(err);
+
+	/* reset all i2C registers to default */
+	err = -TFA_SET_BF(handle, I2CR, 1);
+	PRINT_ASSERT(err);
+
+	return err;
+}
+
+enum tfa_error tfa_reset(void)
+{
+	enum Tfa98xx_Error err = Tfa98xx_Error_Ok;
+	int dev, devcount = tfa98xx_cnt_max_device();
+
+	for( dev=0; dev < devcount; dev++) {
+		err = tfaContOpen(dev);
+		if ( err != Tfa98xx_Error_Ok)
+			break;
+		if (tfa98xx_runtime_verbose)
+			pr_debug("resetting device [%s]\n", tfaContDeviceName(dev));
+		err = tfa98xx_reset(dev);
+		if ( err != Tfa98xx_Error_Ok)
+			break;
+	}
+
+	for( dev=0; dev < devcount; dev++) {
+		tfaContClose(dev);
+	}
+
+	return err;
+}
+
+/*
+ * Write all the bytes specified by num_bytes and data
+ */
+enum Tfa98xx_Error
+tfa98xx_write_data(Tfa98xx_handle_t handle,
+		  unsigned char subaddress, int num_bytes,
+		  const unsigned char data[])
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	/* subaddress followed by data */
+	const int bytes2write = num_bytes + 1;
+	unsigned char *write_data;
+
+	if (num_bytes > TFA2_MAX_PARAM_SIZE)
+		return Tfa98xx_Error_Bad_Parameter;
+
+	write_data = (unsigned char *)kmalloc(bytes2write, GFP_KERNEL);
+	if (write_data == NULL)
+		return Tfa98xx_Error_Fail;
+
+	write_data[0] = subaddress;
+	memcpy(&write_data[1], data, num_bytes);
+
+	error = tfa98xx_write_raw(handle, bytes2write, write_data);
+
+	kfree (write_data);
+	return error;
+}
+
+/*
+ * fill the calibration value as milli ohms in the struct
+ *
+ *  assume that the device has been calibrated
+ */
+enum Tfa98xx_Error
+tfa_dsp_get_calibration_impedance(Tfa98xx_handle_t handle)
+{
+	enum Tfa98xx_Error error = Tfa98xx_Error_Ok;
+	int spkr_count, nr_bytes, i;
+	unsigned char bytes[6] = {0};
+	int data[2];
+
+	error = tfa98xx_supported_speakers(handle, &spkr_count);
+	if (error == Tfa98xx_Error_Ok) {
+		/* If calibrate=once then get values from MTP */
+		if (TFA_GET_BF(handle, MTPOTC) && ((handles_local[handle].rev & 0xff) == 0x88)) { 
+			if (tfa98xx_runtime_verbose)
+				pr_debug("Getting calibration values from MTP\n");
+			for(i=0; i<spkr_count; i++) {
+				handles_local[handle].mohm[i] = tfa_read_reg(handle, (uint16_t)TFA_MK_BF((0xF4+i),0,16));
+			}
+		} else {	
+			/* Get values from speakerboost */
+			if (tfa98xx_runtime_verbose)
+				pr_debug("Getting calibration values from Speakerboost\n");
+			nr_bytes = spkr_count * 3;
+			error = tfa_dsp_cmd_id_write_read(handle,MODULE_SPEAKERBOOST,SB_PARAM_GET_RE0, nr_bytes, bytes);
+			if (error == Tfa98xx_Error_Ok) {
+				tfa98xx_convert_bytes2data(nr_bytes, bytes, data);
+				for(i=0; i<spkr_count; i++) {
+					handles_local[handle].mohm[i] = (data[i]*1000 )/TFA_FW_ReZ_SCALE;
+				}
+			} else {
+				for(i=0; i<spkr_count; i++)
+					handles_local[handle].mohm[i] = -1;
+			}
+		}
+	}
+
+	return error;
+}
+
+/* start count from 1, 0 is invalid */
+int tfa_get_swprof(Tfa98xx_handle_t handle) 
+{
+	/* get from register if not set yet */
+	if ( handles_local[handle].profile < 0)
+		/* get current profile, consider invalid if 0 */
+		handles_local[handle].profile = TFA_GET_BF(handle, SWPROFIL)-1;
+
+	return handles_local[handle].profile;
+}
+
+int tfa_set_swprof(Tfa98xx_handle_t handle, unsigned short new_value) {
+	int mtpk, active_value = tfa_get_swprof(handle);
+
+	handles_local[handle].profile=new_value;
+
+	if ( handles_local[handle].tfa_family > 1 ) {
+		TFA_SET_BF_VOLATILE(handle, SWPROFIL, new_value+1);
+	} else {
+		/* it's in MTP shadow, so unlock if not done already */
+		mtpk = TFA_GET_BF(handle, MTPK); /* get current key */
+		TFA_SET_BF_VOLATILE(handle, MTPK, 0x5a);
+		TFA_SET_BF_VOLATILE(handle, SWPROFIL, new_value+1); /* set current profile */
+		TFA_SET_BF_VOLATILE(handle, MTPK, (uint16_t)mtpk); /* restore key */
+	}
+
+	return active_value;
+}
+
+/*   same value for all channels
+ * start count from 1, 0 is invalid */
+int tfa_get_swvstep(Tfa98xx_handle_t handle){
+	int value;
+
+	if ( handles_local[handle].vstep[0]>0)
+		return handles_local[handle].vstep[0]-1;
+
+	value = TFA_GET_BF(handle, SWVSTEP); /* get current vstep[0] */
+
+	handles_local[handle].vstep[0] = value;
+	handles_local[handle].vstep[1] = value;
+	return value-1; /* invalid if 0 */
+
+}
+int tfa_set_swvstep(Tfa98xx_handle_t handle, unsigned short new_value) {
+	int mtpk, active_value = tfa_get_swvstep(handle);
+
+	handles_local[handle].vstep[0]=new_value;
+	handles_local[handle].vstep[1]=new_value;
+
+	if ( handles_local[handle].tfa_family > 1 ) {
+		TFA_SET_BF_VOLATILE(handle, SWVSTEP, new_value+1);
+	} else {
+		/* it's in MTP shadow, so unlock if not done already */
+		mtpk = TFA_GET_BF(handle, MTPK); /* get current key */
+		TFA_SET_BF_VOLATILE(handle, MTPK, 0x5a);
+		TFA_SET_BF_VOLATILE(handle, SWVSTEP, new_value+1); /* set current vstep[0] */
+		TFA_SET_BF_VOLATILE(handle, MTPK, (uint16_t)mtpk); /* restore key */
+	}
+
+	return active_value;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_dsp_fw.h b/techpack/audio/asoc/codecs/tfa98xx/tfa_dsp_fw.h
new file mode 100644
index 0000000..7d3829a
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_dsp_fw.h
@@ -0,0 +1,119 @@
+#ifndef TFA98XX_INTERNALS_H
+#define TFA98XX_INTERNALS_H
+
+#include "tfa_service.h"
+
+/*
+ * the order matches the ACK bits order in TFA98XX_CF_STATUS
+ */
+enum tfa_fw_event { /* not all available on each device */
+	tfa_fw_i2c_cmd_ack,
+	tfa_fw_reset_start,
+	tfa_fw_short_on_mips,
+	tfa_fw_soft_mute_ready,
+	tfa_fw_volume_ready,
+	tfa_fw_error_damage,
+	tfa_fw_calibrate_done,
+	tfa_fw_max
+};
+
+/* the following type mappings are compiler specific */
+#define subaddress_t unsigned char
+
+/* module Ids */
+#define MODULE_FRAMEWORK        0
+#define MODULE_SPEAKERBOOST     1
+#define MODULE_BIQUADFILTERBANK 2
+#define MODULE_SETRE 			9
+
+/* RPC commands */
+/* SET */
+#define FW_PAR_ID_SET_MEMORY            0x03
+#define FW_PAR_ID_SET_SENSES_DELAY      0x04
+#define FW_PAR_ID_SETSENSESCAL          0x05
+#define FW_PAR_ID_SET_INPUT_SELECTOR    0x06
+#define FW_PAR_ID_SET_OUTPUT_SELECTOR   0x08
+#define FW_PAR_ID_SET_PROGRAM_CONFIG    0x09
+#define FW_PAR_ID_SET_GAINS             0x0A
+#define FW_PAR_ID_SET_MEMTRACK          0x0B
+#define TFA1_FW_PAR_ID_SET_CURRENT_DELAY 0x03
+#define TFA1_FW_PAR_ID_SET_CURFRAC_DELAY 0x06
+/* GET */
+#define FW_PAR_ID_GET_MEMORY            0x83
+#define FW_PAR_ID_GLOBAL_GET_INFO       0x84
+#define FW_PAR_ID_GET_FEATURE_INFO      0x85
+#define FW_PAR_ID_GET_MEMTRACK          0x8B
+#define FW_PAR_ID_GET_TAG               0xFF
+
+/* Load a full model into SpeakerBoost. */
+/* SET */
+#define SB_PARAM_SET_ALGO_PARAMS        0x00
+#define SB_PARAM_SET_LAGW               0x01
+#define SB_PARAM_SET_ALGO_PARAMS_WITHOUT_RESET	0x02
+#define SB_PARAM_SET_LSMODEL            0x06
+#define SB_PARAM_SET_MBDRC              0x07
+#define SB_PARAM_SET_MBDRC_WITHOUT_RESET	0x08
+#define SB_PARAM_SET_DRC                0x0F
+/* GET */
+#define SB_PARAM_GET_ALGO_PARAMS        0x80
+#define SB_PARAM_GET_LAGW               0x81
+#define SB_PARAM_GET_RE0                0x85
+#define SB_PARAM_GET_LSMODEL            0x86
+#define SB_PARAM_GET_MBDRC	        	0x87
+#define SB_PARAM_GET_MBDRC_DYNAMICS		0x89
+#define SB_PARAM_GET_TAG                0xFF
+
+#define SB_PARAM_SET_EQ		        0x0A	/* 2 Equaliser Filters. */
+#define SB_PARAM_SET_PRESET             0x0D	/* Load a preset */
+#define SB_PARAM_SET_CONFIG	        0x0E	/* Load a config */
+#define SB_PARAM_SET_AGCINS             0x10
+#define SB_PARAM_SET_CURRENT_DELAY      0x03
+#define SB_PARAM_GET_STATE              0xC0
+#define SB_PARAM_GET_XMODEL             0xC1	/* Gets current Excursion Model. */
+
+/* sets the speaker calibration impedance (@25 degrees celsius) */
+#define SB_PARAM_SET_RE0                0x89
+
+#define BFB_PAR_ID_SET_COEFS            0x00
+#define BFB_PAR_ID_GET_COEFS            0x80
+#define BFB_PAR_ID_GET_CONFIG           0x81
+
+/* for compatibility */
+#define FW_PARAM_GET_STATE        	FW_PAR_ID_GLOBAL_GET_INFO
+#define FW_PARAM_GET_FEATURE_BITS 	FW_PAR_ID_GET_FEATURE_BITS
+
+
+/* RPC Status results */
+#define STATUS_OK                  0
+#define STATUS_INVALID_MODULE_ID   2
+#define STATUS_INVALID_PARAM_ID    3
+#define STATUS_INVALID_INFO_ID     4
+
+/* the maximum message length in the communication with the DSP */
+#define TFA2_MAX_PARAM_SIZE (507*3) /* TFA2 */
+#define TFA1_MAX_PARAM_SIZE (145*3) /* TFA1 */
+
+#define ROUND_DOWN(a,n) (((a)/(n))*(n))
+
+/* feature bits */
+#define FEATURE1_TCOEF 0x100 /* bit8 set means tCoefA expected */
+#define FEATURE1_DRC   0x200 /* bit9 NOT set means DRC expected */
+
+/* DSP firmware xmem defines */
+#define TFA1_FW_XMEM_CALIBRATION_DONE	231
+#define TFA2_FW_XMEM_CALIBRATION_DONE   516
+#define TFA1_FW_XMEM_COUNT_BOOT		  	0xa1
+#define TFA2_FW_XMEM_COUNT_BOOT		  	512
+#define TFA2_FW_XMEM_CMD_COUNT			520
+
+/* note that the following defs rely on the handle variable */
+#define TFA_FW_XMEM_CALIBRATION_DONE 	TFA_FAM_FW(handle,XMEM_CALIBRATION_DONE)
+#define TFA_FW_XMEM_COUNT_BOOT 			TFA_FAM_FW(handle,XMEM_COUNT_BOOT)
+#define TFA_FW_XMEM_CMD_COUNT 			TFA_FAM_FW(handle,XMEM_CMD_COUNT)
+
+#define TFA2_FW_ReZ_SCALE             	65536
+#define TFA1_FW_ReZ_SCALE             	16384
+#define TFA_FW_ReZ_SCALE              	TFA_FAM_FW(handle,ReZ_SCALE)
+
+
+#endif /* TFA98XX_INTERNALS_H */
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_hal.c b/techpack/audio/asoc/codecs/tfa98xx/tfa_hal.c
new file mode 100644
index 0000000..e4fbf6d
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_hal.c
@@ -0,0 +1,123 @@
+/*
+ *Copyright 2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "tfa_dsp_fw.h"
+#include "dbgprint.h"
+
+#include "NXP_I2C.h"
+#include "tfa_internal.h"
+
+
+/* translate a I2C driver error into an error for Tfa9887 API */
+static enum Tfa98xx_Error tfa98xx_classify_i2c_error(enum NXP_I2C_Error i2c_error)
+{
+	switch (i2c_error) {
+		case NXP_I2C_Ok:
+			return Tfa98xx_Error_Ok;
+		case NXP_I2C_NoAck:
+		case NXP_I2C_ArbLost:
+		case NXP_I2C_TimeOut:
+			return Tfa98xx_Error_I2C_NonFatal;
+		default:
+			return Tfa98xx_Error_I2C_Fatal;
+	}
+}
+/*
+ * write a 16 bit subaddress
+ */
+enum Tfa98xx_Error
+tfa98xx_write_register16(Tfa98xx_handle_t handle,
+			unsigned char subaddress, unsigned short value)
+{
+	enum NXP_I2C_Error i2c_error;
+	unsigned char write_data[3]; /* subaddress and 2 bytes of the value */
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+
+	write_data[0] = subaddress;
+	write_data[1] = (value >> 8) & 0xFF;
+	write_data[2] = value & 0xFF;
+
+	i2c_error = NXP_I2C_WriteRead(handles_local[handle].slave_address, sizeof(write_data), write_data, 0, NULL);
+
+	return tfa98xx_classify_i2c_error(i2c_error);
+}
+
+enum Tfa98xx_Error
+tfa98xx_read_register16(Tfa98xx_handle_t handle,
+		       unsigned char subaddress, unsigned short *pValue)
+{
+	enum NXP_I2C_Error i2c_error;
+	unsigned char write_data[1]; /* subaddress */
+	unsigned char read_buffer[2]; /* 2 data bytes */
+
+	_ASSERT(pValue != NULL);
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+	write_data[0] = subaddress;
+	read_buffer[0] = read_buffer[1] = 0;
+
+	i2c_error = NXP_I2C_WriteRead(handles_local[handle].slave_address, 
+			sizeof(write_data), write_data, sizeof(read_buffer), read_buffer);
+	if (tfa98xx_classify_i2c_error(i2c_error) != Tfa98xx_Error_Ok) {
+		return tfa98xx_classify_i2c_error(i2c_error);
+	} else {
+		*pValue = (read_buffer[0] << 8) + read_buffer[1];
+		return Tfa98xx_Error_Ok;
+	}
+}
+
+enum Tfa98xx_Error
+tfa98xx_read_data(Tfa98xx_handle_t handle,
+		 unsigned char subaddress, int num_bytes, unsigned char data[])
+{
+	enum NXP_I2C_Error i2c_error;
+	unsigned char write_data[1]; /* subaddress */
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+	if (num_bytes > handles_local[handle].buffer_size)
+		return Tfa98xx_Error_Bad_Parameter;
+
+	write_data[0] = subaddress;
+	i2c_error =
+	    NXP_I2C_WriteRead(handles_local[handle].slave_address, sizeof(write_data),
+			      write_data, num_bytes, data);
+	return tfa98xx_classify_i2c_error(i2c_error);
+}
+
+/*
+ * Write raw I2C data with no sub address
+ */
+enum Tfa98xx_Error
+tfa98xx_write_raw(Tfa98xx_handle_t handle,
+		  int num_bytes,
+		  const unsigned char data[])
+{
+	enum NXP_I2C_Error i2c_error;
+
+	if (!tfa98xx_handle_is_open(handle))
+		return Tfa98xx_Error_NotOpen;
+	if (num_bytes > handles_local[handle].buffer_size)
+		return Tfa98xx_Error_Bad_Parameter;
+	i2c_error =
+	    NXP_I2C_WriteRead(handles_local[handle].slave_address, num_bytes,
+			  data, 0, NULL);
+	return tfa98xx_classify_i2c_error(i2c_error);
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_internal.h b/techpack/audio/asoc/codecs/tfa98xx/tfa_internal.h
new file mode 100644
index 0000000..1f73806
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_internal.h
@@ -0,0 +1,113 @@
+/*
+	internal functions for TFA layer (not shared with SRV and HAL layer!)
+*/
+
+#ifndef __TFA_INTERNAL_H__
+#define __TFA_INTERNAL_H__
+
+#include "tfa_dsp_fw.h"
+#include "tfa_service.h"
+#include "config.h"
+
+#if __GNUC__ >= 4
+  #define TFA_INTERNAL __attribute__ ((visibility ("hidden")))
+#else
+  #define TFA_INTERNAL
+#endif
+
+
+#define TFA98XX_GENERIC_SLAVE_ADDRESS 0x1C
+
+enum featureSupport {
+	supportNotSet, /* the default is not set yet, so = 0 */
+	supportNo,
+	supportYes
+};
+
+typedef enum featureSupport featureSupport_t;
+
+/*
+ * tfa98xx control structure gathers data related to a single control
+ * (a 'control' can be related to an interface file)
+ * Some operations can be flagged as deferrable, meaning that they can be
+ *   scheduled for later execution. This can be used for operations that
+ *   require the i2s clock to run, and if it is not available while applying
+ *   the control.
+ * The Some operations can as well be cache-able (supposedly they are the same
+ *   operations as the deferrable). Cache-able means that the status or
+ *   register value may not be accesable while accessing the control. Caching
+ *   allows to get the last programmed value.
+ *
+ * Fields:
+ * deferrable:
+ *   true: means the action or register accces can be run later (for example
+ *   when an active i2s clock will be available).
+ *   false: meams the operation can be applied immediately
+ * triggered: true if the deferred operation was triggered and is scheduled
+ *   to run later
+ * wr_value: the value to write in the deferred action (if applicable)
+ * rd_value: the cached value to report on a cached read (if applicable)
+ * rd_valid: true if the rd_value was initialized (and can be reported)
+ */
+
+struct tfa98xx_control {
+	bool deferrable;
+	bool triggered;
+	int wr_value;
+	int rd_value;
+	bool rd_valid;
+};
+
+struct tfa98xx_controls {
+	struct tfa98xx_control otc;
+	struct tfa98xx_control mtpex;
+	struct tfa98xx_control calib;
+//	struct tfa98xx_control r;
+//	struct tfa98xx_control temp;
+};
+
+struct tfa_device_ops {
+	enum Tfa98xx_Error (*tfa_init)(Tfa98xx_handle_t dev_idx);
+	enum Tfa98xx_Error (*tfa_dsp_reset)(Tfa98xx_handle_t dev_idx, int state);
+	enum Tfa98xx_Error (*tfa_dsp_system_stable)(Tfa98xx_handle_t handle, int *ready);
+	enum Tfa98xx_Error (*tfa_dsp_write_tables)(Tfa98xx_handle_t dev_idx, int sample_rate);
+	struct tfa98xx_controls controls;
+};
+
+struct Tfa98xx_handle_private {
+	int in_use;
+	int buffer_size;
+	unsigned char slave_address;
+	unsigned short rev;
+	unsigned char tfa_family; /* tfa1/tfa2 */
+	enum featureSupport supportDrc;
+	enum featureSupport supportFramework;
+	enum featureSupport support_saam;
+	int sw_feature_bits[2]; /* cached feature bits data */
+	int hw_feature_bits; /* cached feature bits data */
+	int profile;	/* cached active profile */
+	int vstep[2]; /* cached active vsteps */
+//	TODO add? unsigned char rev_major; /* void tfa98xx_rev(int *major, int *minor, int *revision)*/
+//	unsigned char rev_minor;
+//	unsigned char rev_build;
+	unsigned char spkr_count;
+	unsigned char spkr_select;
+	unsigned char support_tcoef;
+	enum Tfa98xx_DAI daimap;
+	int mohm[3]; /* > speaker calibration values in milli ohms -1 is error */
+	struct tfa_device_ops dev_ops;
+	uint16_t interrupt_enable[3];
+	uint16_t interrupt_status[3];
+};
+
+/* tfa_core.c */
+extern TFA_INTERNAL struct Tfa98xx_handle_private handles_local[];
+TFA_INTERNAL int tfa98xx_handle_is_open(Tfa98xx_handle_t h);
+TFA_INTERNAL enum Tfa98xx_Error tfa98xx_check_rpc_status(Tfa98xx_handle_t handle, int *pRpcStatus);
+TFA_INTERNAL enum Tfa98xx_Error tfa98xx_wait_result(Tfa98xx_handle_t handle, int waitRetryCount);
+TFA_INTERNAL void tfa98xx_apply_deferred_calibration(Tfa98xx_handle_t handle);
+TFA_INTERNAL void tfa98xx_deferred_calibration_status(Tfa98xx_handle_t handle, int calibrateDone);
+TFA_INTERNAL int print_calibration(Tfa98xx_handle_t handle, char *str, size_t size);
+
+#endif /* __TFA_INTERNAL_H__ */
+
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_osal.c b/techpack/audio/asoc/codecs/tfa98xx/tfa_osal.c
new file mode 100644
index 0000000..8f7adc6
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_osal.c
@@ -0,0 +1,40 @@
+#include "config.h"
+
+#if (defined(WIN32) || defined(_X64))
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "tfa_internal.h"
+
+void *kmalloc(size_t size, gfpt_t flags)
+{
+	/* flags are not used outside the Linux kernel */
+	(void)flags;
+
+#if !defined(__REDLIB__)
+	return malloc(size);
+#else
+	// TODO !need malloc here
+#endif
+}
+
+void kfree(const void *ptr)
+{
+#if !defined(__REDLIB__)
+	free((void *)ptr);
+#else
+	// TODO !need free here
+#endif
+}
+
+unsigned long msleep_interruptible(unsigned int msecs)
+{
+#if (defined(WIN32) || defined(_X64))
+	Sleep(msecs);
+#else
+	usleep(1000 * msecs);
+#endif
+	return 0;
+}
diff --git a/techpack/audio/asoc/codecs/tfa98xx/tfa_service.h b/techpack/audio/asoc/codecs/tfa98xx/tfa_service.h
new file mode 100644
index 0000000..4a48555
--- /dev/null
+++ b/techpack/audio/asoc/codecs/tfa98xx/tfa_service.h
@@ -0,0 +1,1010 @@
+/*
+ *Copyright 2015 NXP Semiconductors
+ *
+ *Licensed under the Apache License, Version 2.0 (the "License");
+ *you may not use this file except in compliance with the License.
+ *You may obtain a copy of the License at
+ *
+ *http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing, software
+ *distributed under the License is distributed on an "AS IS" BASIS,
+ *WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *See the License for the specific language governing permissions and
+ *limitations under the License.
+ */
+
+#ifndef TFA_SERVICE_H
+#define TFA_SERVICE_H
+
+//#include "config.h"
+// workaround for Visual Studio: 
+// fatal error C1083: Cannot open include file: 'config.h': No such file or directory
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#include "NXP_I2C.h"
+#endif
+
+#define TFA98XX_API_REV_MAJOR			(2)	/* major API rev */
+#define TFA98XX_API_REV_MINOR			(10)	/* minor */
+#define TFA98XX_API_REV_REVISION		(2)
+#define TFA98XX_API_REV_STR			 "2.10.2"
+
+/*
+ * data previously defined in Tfa9888_dsp.h
+ */
+#define MEMTRACK_MAX_WORDS            50
+#define LSMODEL_MAX_WORDS            150
+#define TFA98XX_MAXTAG              (138)
+#define FW_VAR_API_VERSION          (521)
+
+// these indexes and scaling factors should be recovered from the ITF xml file.
+#define fs_IDX                128
+#define leakageFactor_IDX     130
+#define ReCorrection_IDX      131
+#define Bl_IDX                132
+#define tCoef_IDX             138
+#define ReZ_IDX               147
+
+#define fs_SCALE              (double)1
+#define leakageFactor_SCALE   (double)8388608
+#define ReCorrection_SCALE    (double)8388608
+#define Bl_SCALE              (double)2097152
+#define tCoef_SCALE           (double)8388608
+
+/* ---------------------------- Max1 ---------------------------- */
+/* Headroom applied to the main input signal */
+#define SPKRBST_HEADROOM		7
+/* Exponent used for AGC Gain related variables */
+#define SPKRBST_AGCGAIN_EXP		SPKRBST_HEADROOM
+#define SPKRBST_TEMPERATURE_EXP		9
+/* Exponent used for Gain Corection related variables */
+#define SPKRBST_LIMGAIN_EXP		4
+#define SPKRBST_TIMECTE_EXP		1
+#define DSP_MAX_GAIN_EXP		7
+/* -------------------------------------------------------------- */
+
+/* speaker related parameters */
+#define TFA2_SPEAKERPARAMETER_LENGTH		(3*151)	/* MAX2=450 */
+#define TFA1_SPEAKERPARAMETER_LENGTH		(3*141)	/* MAX1=423 */
+
+/* vstep related parameters */
+#define TFA2_ALGOPARAMETER_LENGTH		(3*304)	/* N1B = (304) 305 is including the cmd-id */
+#define TFA2_MBDRCPARAMETER_LENGTH		(3*152)	/* 154 is including the cmd-id */
+#define TFA1_PRESET_LENGTH			87
+#define TFA1_DRC_LENGTH				381	/* 127 words */
+#define TFA2_FILTERCOEFSPARAMETER_LENGTH	(3*168) /* 170 is including the cmd-id */
+
+/* Maximum number of retries for DSP result
+ * Keep this value low!
+ * If certain calls require longer wait conditions, the
+ * application should poll, not the API
+ * The total wait time depends on device settings. Those
+ * are application specific.
+ */
+#define TFA98XX_WAITRESULT_NTRIES          40
+#define TFA98XX_WAITRESULT_NTRIES_LONG   2000
+
+/* following lengths are in bytes */
+#define TFA98XX_PRESET_LENGTH              87
+
+/* make full the default */
+#if !(defined(TFA9887) || defined(TFA9890) || defined(TFA9887B) || defined(TFA9897))
+#ifndef TFA98XX_FULL
+#define TFA98XX_FULL
+#endif
+#endif
+
+#if (defined(TFA9887) || defined(TFA9890) || defined(TFA9897))
+#define TFA98XX_CONFIG_LENGTH           165
+#else
+#if (defined(TFA9887B) || defined(TFA98XX_FULL))
+#define TFA98XX_CONFIG_LENGTH           201
+#define TFA98XX_DRC_LENGTH              381	/* 127 words */
+	typedef unsigned char Tfa98xx_DrcParameters_t[TFA98XX_DRC_LENGTH];
+#endif
+#endif  
+
+/*
+MUST BE CONSISTANT: either one uses opaque arrays of bytes, or not!!!
+*/
+typedef unsigned char Tfa98xx_Config_t[TFA98XX_CONFIG_LENGTH];
+typedef unsigned char Tfa98xx_Preset_t[TFA98XX_PRESET_LENGTH];
+
+/* Type containing all the possible errors that can occur
+ *
+ */
+enum Tfa98xx_Error {
+	Tfa98xx_Error_Ok = 0,
+	Tfa98xx_Error_Device,		/* Currently only used to keep in sync with tfa_error */
+	Tfa98xx_Error_Bad_Parameter,
+    Tfa98xx_Error_Fail,             /* generic failure, avoid mislead message */
+	Tfa98xx_Error_NoClock,          /* no clock detected */
+	Tfa98xx_Error_StateTimedOut,
+	Tfa98xx_Error_DSP_not_running,	/* communication with the DSP failed */
+	Tfa98xx_Error_AmpOn,            /* amp is still running */
+	Tfa98xx_Error_NotOpen,	        /* the given handle is not open */
+	Tfa98xx_Error_InUse,	        /* too many handles */
+    Tfa98xx_Error_Buffer_too_small, /* if a buffer is too small */
+	/* the expected response did not occur within the expected time */
+	Tfa98xx_Error_RpcBase = 100,
+	Tfa98xx_Error_RpcBusy = 101,
+	Tfa98xx_Error_RpcModId = 102,
+	Tfa98xx_Error_RpcParamId = 103,
+	Tfa98xx_Error_RpcInfoId = 104,
+	Tfa98xx_Error_RpcNotAllowedSpeaker = 105,
+
+	Tfa98xx_Error_Not_Implemented,
+	Tfa98xx_Error_Not_Supported,
+	Tfa98xx_Error_I2C_Fatal,	/* Fatal I2C error occurred */
+	/* Nonfatal I2C error, and retry count reached */
+	Tfa98xx_Error_I2C_NonFatal,
+	Tfa98xx_Error_Other = 1000
+};
+
+/* 
+ * Type containing all the possible msg returns DSP can give
+ */
+enum Tfa98xx_Status_ID {
+        Tfa98xx_DSP_Not_Running = -1,           /* No response from DSP */
+	Tfa98xx_I2C_Req_Done = 0,               /* Request executed correctly and result, if any, is available for download */
+        Tfa98xx_I2C_Req_Busy = 1,               /* Request is being processed, just wait for result */
+	Tfa98xx_I2C_Req_Invalid_M_ID = 2,       /* Provided M-ID does not fit in valid rang [0..2] */
+        Tfa98xx_I2C_Req_Invalid_P_ID = 3,       /* Provided P-ID isn�t valid in the given M-ID context */
+        Tfa98xx_I2C_Req_Invalid_CC = 4,         /* Invalid channel configuration bits (SC|DS|DP|DC) combination */
+        Tfa98xx_I2C_Req_Invalid_Seq = 5,        /* Invalid sequence of commands, in case the DSP expects some commands in a specific order */
+        Tfa98xx_I2C_Req_Invalid_Param = 6,      /* Generic error */
+        Tfa98xx_I2C_Req_Buffer_Overflow = 7    /* I2C buffer has overflowed: host has sent too many parameters, memory integrity is not guaranteed */
+};
+
+/*
+ * speaker as microphone
+ */
+enum Tfa98xx_saam {
+	Tfa98xx_saam_none,	/*< SAAM feature not available */
+	Tfa98xx_saam			/*< SAAM feature available */
+};
+
+/*
+ * possible Digital Audio Interfaces bitmap
+ */
+enum Tfa98xx_DAI {
+	Tfa98xx_DAI_I2S  =  0x01,
+	Tfa98xx_DAI_TDM  =  0x02,
+	Tfa98xx_DAI_PDM  =  0x04,
+};
+
+/*
+ * config file subtypes
+ */
+enum Tfa98xx_config_type {
+	Tfa98xx_config_generic,
+	Tfa98xx_config_sub1,
+	Tfa98xx_config_sub2,
+	Tfa98xx_config_sub3,
+};
+
+enum Tfa98xx_AmpInputSel {
+	Tfa98xx_AmpInputSel_I2SLeft,
+	Tfa98xx_AmpInputSel_I2SRight,
+	Tfa98xx_AmpInputSel_DSP
+};
+
+enum Tfa98xx_OutputSel {
+	Tfa98xx_I2SOutputSel_CurrentSense,
+	Tfa98xx_I2SOutputSel_DSP_Gain,
+	Tfa98xx_I2SOutputSel_DSP_AEC,
+	Tfa98xx_I2SOutputSel_Amp,
+	Tfa98xx_I2SOutputSel_DataI3R,
+	Tfa98xx_I2SOutputSel_DataI3L,
+	Tfa98xx_I2SOutputSel_DcdcFFwdCur,
+};
+
+enum Tfa98xx_StereoGainSel {
+	Tfa98xx_StereoGainSel_Left,
+	Tfa98xx_StereoGainSel_Right
+};
+
+#define TFA98XX_MAXPATCH_LENGTH (3*1024)
+
+/* the number of biquads supported */
+#define TFA98XX_BIQUAD_NUM              10
+
+enum Tfa98xx_Channel {
+	Tfa98xx_Channel_L,
+	Tfa98xx_Channel_R,
+	Tfa98xx_Channel_L_R,
+	Tfa98xx_Channel_Stereo
+};
+
+enum Tfa98xx_Mode {
+	Tfa98xx_Mode_Normal = 0,
+	Tfa98xx_Mode_RCV
+};
+
+enum Tfa98xx_Mute {
+	Tfa98xx_Mute_Off,
+	Tfa98xx_Mute_Digital,
+	Tfa98xx_Mute_Amplifier
+};
+
+enum Tfa98xx_SpeakerBoostStatusFlags {
+	Tfa98xx_SpeakerBoost_Activity = 0,	/* Input signal activity. */
+	Tfa98xx_SpeakerBoost_S_Ctrl,	/* S Control triggers the limiter */
+	Tfa98xx_SpeakerBoost_Muted,	/* 1 when signal is muted */
+	Tfa98xx_SpeakerBoost_X_Ctrl,	/* X Control triggers the limiter */
+	Tfa98xx_SpeakerBoost_T_Ctrl,	/* T Control triggers the limiter */
+	Tfa98xx_SpeakerBoost_NewModel,	/* New model is available */
+	Tfa98xx_SpeakerBoost_VolumeRdy,	/* 0:stable vol, 1:still smoothing */
+	Tfa98xx_SpeakerBoost_Damaged,	/* Speaker Damage detected  */
+	Tfa98xx_SpeakerBoost_SignalClipping	/* input clipping detected */
+};
+
+struct Tfa98xx_DrcStateInfo {
+	float GRhighDrc1[2];
+	float GRhighDrc2[2];
+	float GRmidDrc1[2];
+	float GRmidDrc2[2];
+	float GRlowDrc1[2];
+	float GRlowDrc2[2];
+	float GRpostDrc1[2];
+	float GRpostDrc2[2];
+	float GRblDrc[2];
+};
+struct Tfa98xx_StateInfo {
+	/* SpeakerBoost State */
+	float agcGain;	/* Current AGC Gain value */
+	float limGain;	/* Current Limiter Gain value */
+	float sMax;	/* Current Clip/Lim threshold */
+	int T;		/* Current Speaker Temperature value */
+	int statusFlag;	/* Masked bit word */
+	float X1;	/* estimated excursion caused by Spkrboost gain ctrl */
+	float X2;	/* estimated excursion caused by manual gain setting */
+	float Re;	/* Loudspeaker blocked resistance */
+	/* Framework state */
+	/* increments each time a MIPS problem is detected on the DSP */
+	int shortOnMips;
+	/* DRC state, when enabled */
+	struct Tfa98xx_DrcStateInfo drcState;
+};
+
+typedef struct nxpTfaMsg {
+	uint8_t msg_size;
+        unsigned char cmdId[3];
+	int data[9];
+} nxpTfaMsg_t;
+
+typedef struct nxpTfaGroup {
+	uint8_t msg_size;
+        uint8_t profileId[64];
+} nxpTfaGroup_t;
+
+
+struct nxpTfa98xx_Memtrack_data {
+        int length;
+        float mValues[MEMTRACK_MAX_WORDS];
+        int mAdresses[MEMTRACK_MAX_WORDS];
+        int scalingFactor[MEMTRACK_MAX_WORDS];
+        int trackers[MEMTRACK_MAX_WORDS];
+};
+
+/* possible memory values for DMEM in CF_CONTROLs */
+enum Tfa98xx_DMEM {
+	Tfa98xx_DMEM_PMEM = 0,
+	Tfa98xx_DMEM_XMEM = 1,
+	Tfa98xx_DMEM_YMEM = 2,
+	Tfa98xx_DMEM_IOMEM = 3,
+};
+
+/**
+ * lookup the device type and return the family type
+ */
+int tfa98xx_dev2family(int dev_type);
+
+/**
+ *  register definition structure
+ */
+struct regdef {
+	unsigned char offset; /**< subaddress offset */
+	unsigned short pwronDefault;
+			      /**< register contents after poweron */
+	unsigned short pwronTestmask;
+			      /**< mask of bits not test */
+	char *name;	      /**< short register name */
+};
+
+#define Tfa98xx_handle_t int
+
+/**
+ * Open the instance handle
+ */
+enum Tfa98xx_Error tfa98xx_open(Tfa98xx_handle_t handle);
+
+/**
+ * Load the default HW settings in the device
+ */
+enum Tfa98xx_Error tfa98xx_init(Tfa98xx_handle_t handle);
+
+/**
+ * Return the tfa revision
+ */
+void tfa98xx_rev(int *major, int *minor, int *revision);
+
+enum Tfa98xx_DMEM tfa98xx_filter_mem(Tfa98xx_handle_t dev,
+			int filter_index, unsigned short *address, int channel);
+
+/**
+ * Return the maximum nr of devices
+ */
+int tfa98xx_max_devices(void);
+
+/**
+ * If needed, this function can be used to get a text version of the status ID code
+ * @param the given status ID code
+ * @return the I2C status ID string
+ */
+const char *tfa98xx_get_i2c_status_id_string(int status);
+
+/**
+ * Close the instance handle
+ */
+enum Tfa98xx_Error tfa98xx_close(Tfa98xx_handle_t handle);
+
+/* control the powerdown bit of the TFA9887
+ * @param powerdown must be 1 or 0
+ */
+enum Tfa98xx_Error tfa98xx_powerdown(Tfa98xx_handle_t handle,
+				  int powerdown);
+
+/* control the input_sel bits of the TFA9887, to indicate */
+/* what is sent to the amplfier and speaker
+ * @param input_sel, see Tfa98xx_AmpInputSel_t
+ */
+enum Tfa98xx_Error tfa98xx_select_amplifier_input(Tfa98xx_handle_t handle,
+					     enum Tfa98xx_AmpInputSel
+					     input_sel);
+
+/* control the I2S left output of the TFA9887
+ * @param output_sel, see Tfa98xx_OutputSel_t
+ */
+enum Tfa98xx_Error tfa98xx_select_i2s_output_left(Tfa98xx_handle_t handle,
+					    enum Tfa98xx_OutputSel
+					    output_sel);
+
+/* control the I2S right output of the TFA9887
+ * @param output_sel, see Tfa98xx_OutputSel_t
+ */
+enum Tfa98xx_Error tfa98xx_select_i2s_output_right(Tfa98xx_handle_t handle,
+					     enum Tfa98xx_OutputSel
+					     output_sel);
+
+/* indicates on which channel of DATAI2 the gain from the IC is set
+ * @param gain_sel, see Tfa98xx_StereoGainSel_t
+ */
+enum Tfa98xx_Error tfa98xx_select_stereo_gain_channel(Tfa98xx_handle_t handle,
+						enum Tfa98xx_StereoGainSel
+						gain_sel);
+
+/* TODO cleanup calibration support */
+
+/**
+ * set the mtp with user controllable values
+ * @param value to be written
+ * @param mask to be applied toi the bits affected
+ */
+enum Tfa98xx_Error tfa98xx_set_mtp(Tfa98xx_handle_t handle, uint16_t value, uint16_t mask);
+
+enum Tfa98xx_Error tfa98xx_get_mtp(Tfa98xx_handle_t handle, uint16_t *value);
+
+/**
+ * lock or unlock KEY2
+ * lock = 1 will lock
+ * lock = 0 will unlock
+ * note that on return all the hidden key will be off
+ */
+void tfa98xx_key2(Tfa98xx_handle_t handle, int lock);
+
+int tfa_calibrate(Tfa98xx_handle_t handle) ;
+void tfa98xx_set_exttemp(Tfa98xx_handle_t handle, short ext_temp);
+short tfa98xx_get_exttemp(Tfa98xx_handle_t handle);
+
+/* control the volume of the DSP
+ * @param vol volume in bit field. It must be between 0 and 255
+ */
+enum Tfa98xx_Error tfa98xx_set_volume_level(Tfa98xx_handle_t handle,
+				  unsigned short vol);
+
+/* read the TFA9887 of the sample rate of the I2S bus that will be used.
+ * @param pRate pointer to rate in Hz i.e 32000, 44100 or 48000
+ */
+enum Tfa98xx_Error tfa98xx_get_sample_rate(Tfa98xx_handle_t handle,
+				      int *pRate);
+
+/* set the input channel to use
+ * @param channel see Tfa98xx_Channel_t enumeration
+ */
+enum Tfa98xx_Error tfa98xx_select_channel(Tfa98xx_handle_t handle,
+				      enum Tfa98xx_Channel channel);
+
+/* set the mode for normal or receiver mode
+ * @param mode see Tfa98xx_Mode enumeration
+ */
+enum Tfa98xx_Error tfa98xx_select_mode(Tfa98xx_handle_t handle, enum Tfa98xx_Mode mode );
+
+/* mute/unmute the audio
+ * @param mute see Tfa98xx_Mute_t enumeration
+ */
+enum Tfa98xx_Error tfa98xx_set_mute(Tfa98xx_handle_t handle,
+				enum Tfa98xx_Mute mute);
+
+/*
+ * tfa98xx_supported_speakers - required for SmartStudio initialization
+ *  returns the number of the supported speaker count
+ */
+enum Tfa98xx_Error tfa98xx_supported_speakers(Tfa98xx_handle_t handle, int* spkr_count);
+
+/*
+ * Return the feature bits from MTP and cnt file for comparison
+ */
+enum Tfa98xx_Error 
+tfa98xx_compare_features(Tfa98xx_handle_t handle, int features_from_MTP[3], int features_from_cnt[3]);
+
+/*
+ * return feature bits
+ */
+enum Tfa98xx_Error
+tfa98xx_dsp_get_sw_feature_bits(Tfa98xx_handle_t handle, int features[2]);
+enum Tfa98xx_Error
+tfa98xx_dsp_get_hw_feature_bits(Tfa98xx_handle_t handle, int *features);
+/*
+ * tfa98xx_supported_dai
+ *  returns the bitmap of the supported Digital Audio Interfaces
+ * @param dai bitmap enum pointer
+ *  @return error code
+ */
+enum Tfa98xx_Error tfa98xx_supported_dai(Tfa98xx_handle_t handle, enum Tfa98xx_DAI *daimap);
+
+/*
+ * tfa98xx_supported_saam
+ *  returns the speaker as microphone feature
+ * @param saam enum pointer
+ *  @return error code
+ */
+enum Tfa98xx_Error tfa98xx_supported_saam(Tfa98xx_handle_t handle, enum Tfa98xx_saam *saam);
+
+/* load the tables to the DSP
+ *   called after patch load is done
+ *   @return error code
+ */
+enum Tfa98xx_Error tfa98xx_dsp_write_tables(Tfa98xx_handle_t handle, int sample_rate);
+
+/* set or clear DSP reset signal
+ * @param new state
+ * @return error code
+ */
+enum Tfa98xx_Error tfa98xx_dsp_reset(Tfa98xx_handle_t handle, int state);
+
+/* check the state of the DSP subsystem
+ * return ready = 1 when clocks are stable to allow safe DSP subsystem access
+ * @param pointer to state flag, non-zero if clocks are not stable
+ * @return error code
+ */
+enum Tfa98xx_Error tfa98xx_dsp_system_stable(Tfa98xx_handle_t handle,
+						int *ready);
+
+/** 
+ * check the state of the DSP coolflux
+ * returns the value of CFE
+ */
+int tfa98xx_cf_enabled(Tfa98xx_handle_t dev_idx);
+
+/* The following functions can only be called when the DSP is running
+ * - I2S clock must be active,
+ * - IC must be in operating mode
+ */
+
+/**
+ * patch the ROM code of the DSP 
+ * @param handle to opened instance
+ * @param patchLength the number of bytes of patchBytes
+ * @param patchBytes pointer to the bytes to patch
+ */
+enum Tfa98xx_Error tfa_dsp_patch(Tfa98xx_handle_t handle,
+				 int patchLength,
+				 const unsigned char *patchBytes);
+
+/* Check whether the DSP expects tCoef or tCoefA as last parameter in
+ * the speaker parameters
+ * *pbSupporttCoef=1 when DSP expects tCoef,
+ * *pbSupporttCoef=0 when it expects tCoefA (and the elaborate workaround
+ * to calculate tCoefA from tCoef on the host)
+ */
+enum Tfa98xx_Error tfa98xx_dsp_support_tcoef(Tfa98xx_handle_t handle,
+					int *pbSupporttCoef);
+
+/**
+ * return the tfa device family id
+ */
+int tfa98xx_dev_family(Tfa98xx_handle_t dev_idx);
+
+/**
+ * return the device revision id
+ */
+unsigned short tfa98xx_dev_revision(Tfa98xx_handle_t dev_idx);
+
+/** 
+ * load explicitly the speaker parameters in case of free speaker,
+ * or when using a saved speaker model 
+ */
+enum Tfa98xx_Error tfa98xx_dsp_write_speaker_parameters(
+				Tfa98xx_handle_t handle,
+				int length,
+				const unsigned char *pSpeakerBytes);
+
+/** 
+ * read the speaker parameters as used by the SpeakerBoost processing 
+ */
+enum Tfa98xx_Error tfa98xx_dsp_read_speaker_parameters(
+				Tfa98xx_handle_t handle,
+				int length,
+				unsigned char *pSpeakerBytes);
+
+/** 
+ * read the current status of the DSP, typically used for development, 
+ * not essential to be used in a product                               
+ */
+enum Tfa98xx_Error tfa98xx_dsp_get_state_info(
+				Tfa98xx_handle_t handle, 
+				unsigned char bytes[],
+				unsigned int *statesize);
+
+/** 
+ * Check whether the DSP supports DRC
+ * pbSupportDrc=1 when DSP supports DRC,
+ * pbSupportDrc=0 when DSP doesn't support it
+ */
+enum Tfa98xx_Error tfa98xx_dsp_support_drc(Tfa98xx_handle_t handle,
+				      int *pbSupportDrc);
+
+enum Tfa98xx_Error
+tfa98xx_dsp_support_framework(Tfa98xx_handle_t handle, int *pbSupportFramework);
+
+/** 
+ * read the speaker excursion model as used by SpeakerBoost processing 
+ */
+enum Tfa98xx_Error tfa98xx_dsp_read_excursion_model(
+				Tfa98xx_handle_t handle,
+				int length,
+				unsigned char *pSpeakerBytes);
+
+/** 
+ * load all the parameters for a preset from a file 
+ */
+enum Tfa98xx_Error tfa98xx_dsp_write_preset(Tfa98xx_handle_t handle,
+				       int length, const unsigned char
+				       *pPresetBytes);
+
+/** 
+ * wrapper for dsp_msg that adds opcode and only writes 
+ */
+enum Tfa98xx_Error tfa_dsp_cmd_id_write(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int num_bytes,
+                           const unsigned char data[]);
+
+/** 
+ * wrapper for dsp_msg that writes opcode and reads back the data 
+ */
+enum Tfa98xx_Error tfa_dsp_cmd_id_write_read(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int num_bytes,
+                           unsigned char data[]);
+
+/** 
+ * wrapper for dsp_msg that adds opcode and 3 bytes required for coefs 
+ */
+enum Tfa98xx_Error tfa_dsp_cmd_id_coefs(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int num_bytes,
+			   unsigned char data[]);
+
+/** 
+ * wrapper for dsp_msg that adds opcode and 3 bytes required for MBDrcDynamics 
+ */
+enum Tfa98xx_Error tfa_dsp_cmd_id_MBDrc_dynamics(Tfa98xx_handle_t handle,
+			   unsigned char module_id,
+			   unsigned char param_id, int index_subband,
+			   int num_bytes, unsigned char data[]);
+
+/**
+ * Disable a certain biquad.
+ * @param handle to opened instance
+ * @param biquad_index: 1-10 of the biquad that needs to be adressed
+*/
+enum Tfa98xx_Error Tfa98xx_DspBiquad_Disable(Tfa98xx_handle_t handle,
+					                int biquad_index);
+
+/**
+ * fill the calibration value as milli ohms in the struct
+ * assume that the device has been calibrated
+ */
+enum Tfa98xx_Error
+tfa_dsp_get_calibration_impedance(Tfa98xx_handle_t handle);
+
+/*
+ * return the mohm value
+ */
+int tfa_get_calibration_info(Tfa98xx_handle_t handle, int channel);
+
+/**
+ * Reads a number of words from dsp memory
+ * @param handle to opened instance
+ * @param subaddress write address to set in address register
+ * @param pValue pointer to read data
+*/
+enum Tfa98xx_Error tfa98xx_read_register16(Tfa98xx_handle_t handle,
+				       unsigned char subaddress,
+				       unsigned short *pValue);
+
+/**
+ * Reads a number of words from dsp memory
+ * @param handle to opened instance
+ * @param subaddress write address to set in address register
+ * @param value value to write int the memory
+*/
+enum Tfa98xx_Error tfa98xx_write_register16(Tfa98xx_handle_t handle,
+					unsigned char subaddress,
+					unsigned short value);
+
+/**
+ * Reads a number of words from dsp memory
+ * @param handle to opened instance
+ * @param start_offset offset from where to start reading
+ * @param num_words number of words to read
+ * @param pValues pointer to read data
+*/
+enum Tfa98xx_Error tfa98xx_dsp_read_mem(Tfa98xx_handle_t handle,
+				   unsigned int start_offset,
+				   int num_words, int *pValues);
+
+/**
+ * Write a value to dsp memory
+ * @param handle to opened instance
+ * @param address write address to set in address register
+ * @param value value to write int the memory
+ * @param memtype type of memory to write to
+*/
+enum Tfa98xx_Error tfa98xx_dsp_write_mem_word(Tfa98xx_handle_t handle,
+				    unsigned short address, 
+                                    int value, int memtype);
+
+/**
+ * Read data from dsp memory
+ * @param handle to opened instance
+ * @param subaddress write address to set in address register
+ * @param num_bytes number of bytes to read from dsp
+ * @param data the unsigned char buffer to read data into
+*/
+enum Tfa98xx_Error tfa98xx_read_data(Tfa98xx_handle_t handle,
+				 unsigned char subaddress,
+				 int num_bytes, unsigned char data[]);
+
+/**
+ * Write all the bytes specified by num_bytes and data to dsp memory
+ * @param handle to opened instance
+ * @param subaddress the subaddress to write to
+ * @param num_bytes number of bytes to write
+ * @param data actual data to write
+*/
+enum Tfa98xx_Error tfa98xx_write_data(Tfa98xx_handle_t handle,
+				  unsigned char subaddress,
+				  int num_bytes,
+				  const unsigned char data[]);
+
+enum Tfa98xx_Error tfa98xx_write_raw(Tfa98xx_handle_t handle,
+		  	  	  int num_bytes,
+		  	  	  const unsigned char data[]);
+
+/* support for converting error codes into text */
+const char *tfa98xx_get_error_string(enum Tfa98xx_Error error);
+
+/**
+ * convert signed 24 bit integers to 32bit aligned bytes
+ * input:   data contains "num_bytes/3" int24 elements
+ * output:  bytes contains "num_bytes" byte elements
+ * @param num_data length of the input data array
+ * @param data input data as integer array
+ * @param bytes output data as unsigned char array
+*/
+void tfa98xx_convert_data2bytes(int num_data, const int data[],
+			       unsigned char bytes[]);
+
+/* return the device revision id
+ */
+unsigned short tfa98xx_get_device_revision(Tfa98xx_handle_t handle);
+
+/** 
+ * return the device digital audio interface (DAI) type bitmap
+ */
+enum Tfa98xx_DAI tfa98xx_get_device_dai(Tfa98xx_handle_t handle);
+
+/**
+ * convert memory bytes to signed 24 bit integers  
+ * input:  bytes contains "num_bytes" byte elements 
+ * output: data contains "num_bytes/3" int24 elements
+ * @param num_bytes length of the input data array
+ * @param bytes input data as unsigned char array
+ * @param data output data as integer array
+*/
+void tfa98xx_convert_bytes2data(int num_bytes, const unsigned char bytes[],
+			       int data[]);
+
+/**
+ * Read a part of the dsp memory
+ * @param handle to opened instance
+ * @param memoryType indicator to the memory type
+ * @param offset from where to start reading
+ * @param length the number of bytes to read
+ * @param bytes output data as unsigned char array
+*/
+enum Tfa98xx_Error tfa98xx_dsp_get_memory(Tfa98xx_handle_t handle, int memoryType,
+                                        int offset, int length, unsigned char bytes[]);
+
+/**
+ * Write a value to the dsp memory
+ * @param handle to opened instance
+ * @param memoryType indicator to the memory type
+ * @param offset from where to start writing
+ * @param length the number of bytes to write
+ * @param value the value to write to the dsp
+*/
+enum Tfa98xx_Error tfa98xx_dsp_set_memory(Tfa98xx_handle_t handle, int memoryType,
+                                                        int offset, int length, int value);
+
+enum Tfa98xx_Error tfa98xx_dsp_write_config(Tfa98xx_handle_t handle, int length, const unsigned char *p_config_bytes);
+enum Tfa98xx_Error tfa98xx_dsp_write_drc(Tfa98xx_handle_t handle, int length, const unsigned char *p_drc_bytes);
+
+//TODO define
+/**
+ * write/read raw msg functions :
+ * the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes.
+ * The functions will return immediately and do not not wait for DSP reponse.
+ * @param handle to opened instance
+ * @param length length of the character buffer to write
+ * @param buf character buffer to write
+*/
+enum Tfa98xx_Error tfa_dsp_msg(Tfa98xx_handle_t handle, int length, const char *buf);
+
+/**
+ * write/read raw msg functions:
+ * the buffer is provided in little endian format, each word occupying 3 bytes, length is in bytes.
+ * The functions will return immediately and do not not wait for DSP reponse.
+ * An ID is added to modify the command-ID
+ * @param handle to opened instance
+ * @param length length of the character buffer to write
+ * @param buf character buffer to write
+ * @param cmdid command identifier
+*/
+enum Tfa98xx_Error tfa_dsp_msg_id(Tfa98xx_handle_t handle, int length, const char *buf, uint8_t cmdid[3]);
+
+/**
+ * write raw dsp msg functions
+ * @param handle to opened instance
+ * @param length length of the character buffer to write
+ * @param buffer character buffer to write
+*/
+enum Tfa98xx_Error tfa_dsp_msg_write(Tfa98xx_handle_t handle, int length, const char *buffer);
+
+/**
+ * write raw dsp msg functions
+ * @param handle to opened instance
+ * @param length length of the character buffer to write
+ * @param buf character buffer to write
+ * @param cmdid command identifier
+*/
+enum Tfa98xx_Error tfa_dsp_msg_write_id(Tfa98xx_handle_t handle, int length, const char *buffer, uint8_t cmdid[3]);
+
+/**
+ * status function used by tfa_dsp_msg() to retrieve command/msg status:
+ * return a <0 status of the DSP did not ACK.
+ * @param handle to opened instance
+ * @param pRpcStatus status for remote processor communication
+*/
+enum Tfa98xx_Error tfa_dsp_msg_status(Tfa98xx_handle_t handle, int *pRpcStatus);
+
+/**
+ * Read a message from dsp
+ * @param length number of bytes of the message
+ * @param bytes pointer to unsigned char buffer
+*/
+enum Tfa98xx_Error tfa_dsp_msg_read(Tfa98xx_handle_t handle,int length, unsigned char *bytes);
+
+void create_dsp_buffer_msg(nxpTfaMsg_t *msg, char *buffer, int *size);
+
+int tfa_set_bf(Tfa98xx_handle_t dev_idx, const uint16_t bf, const uint16_t value);
+int tfa_set_bf_volatile(Tfa98xx_handle_t dev_idx, const uint16_t bf, const uint16_t value);
+
+/** 
+ * Get the value of a given bitfield
+ * @param dev_idx this is the device index
+ * @param bf the value indicating which bitfield
+ */
+int tfa_get_bf(Tfa98xx_handle_t dev_idx, const uint16_t bf);
+
+/**
+ * Set the value of a given bitfield
+ * @param bf the value indicating which bitfield
+ * @param bf_value the value of the bitfield
+ * @param p_reg_value a pointer to the register where to write the bitfield value 
+ */
+int tfa_set_bf_value(const uint16_t bf, const uint16_t bf_value, uint16_t *p_reg_value);
+
+uint16_t tfa_get_bf_value(const uint16_t bf, const uint16_t reg_value);
+int tfa_write_reg(Tfa98xx_handle_t dev_idx, const uint16_t bf, const uint16_t reg_value);
+int tfa_read_reg(Tfa98xx_handle_t dev_idx, const uint16_t bf);
+
+/* bitfield */
+/** 
+ * get the datasheet name corresponding to the bitfield number
+ * @param num is the number for which to get the bitfield name
+ * @param rev is the device type
+ */
+char *tfaContBfName(uint16_t num, unsigned short rev);
+
+/** 
+ * get the bitfield name corresponding to the bitfield number
+ * @param num is the number for which to get the bitfield name
+ * @param rev is the device type
+ */
+char *tfaContBitName(uint16_t num, unsigned short rev);
+
+/** 
+ * get the bitfield number corresponding to the bitfield name
+ * @param name is the bitfield name for which to get the bitfield number
+ * @param rev is the device type
+ */
+uint16_t tfaContBfEnum(const char *name, unsigned short rev);
+
+/** 
+* get the bitfield number corresponding to the bitfield name, checks for all devices
+* @param name is the bitfield name for which to get the bitfield number
+ */
+uint16_t tfaContBfEnumAny(const char *name);
+
+#define TFA_FAM(dev_idx, fieldname) ((tfa98xx_dev_family(dev_idx) == 1) ? TFA1_BF_##fieldname :  TFA2_BF_##fieldname)
+#define TFA_FAM_FW(dev_idx, fwname) ((tfa98xx_dev_family(dev_idx) == 1) ? TFA1_FW_##fwname :  TFA2_FW_##fwname)
+
+/* set/get bit fields to HW register*/
+#define TFA_SET_BF(dev_idx, fieldname, value) tfa_set_bf(dev_idx, TFA_FAM(dev_idx, fieldname), value)
+#define TFA_SET_BF_VOLATILE(dev_idx, fieldname, value) tfa_set_bf_volatile(dev_idx, TFA_FAM(dev_idx, fieldname), value)
+#define TFA_GET_BF(dev_idx, fieldname) tfa_get_bf(dev_idx, TFA_FAM(dev_idx, fieldname))
+
+/* set/get bit field in variable */
+#define TFA_SET_BF_VALUE(dev_idx, fieldname, bf_value, p_reg_value) tfa_set_bf_value(TFA_FAM(dev_idx, fieldname), bf_value, p_reg_value)
+#define TFA_GET_BF_VALUE(dev_idx, fieldname, reg_value) tfa_get_bf_value(TFA_FAM(dev_idx, fieldname), reg_value)
+
+/* write/read registers using a bit field name to determine the register address */
+#define TFA_WRITE_REG(dev_idx, fieldname, value) tfa_write_reg(dev_idx, TFA_FAM(dev_idx, fieldname), value)
+#define TFA_READ_REG(dev_idx, fieldname) tfa_read_reg(dev_idx, TFA_FAM(dev_idx, fieldname))
+
+/* FOR CALIBRATION RETRIES */
+#define TFA98XX_API_WAITRESULT_NTRIES 3000 // defined in API
+
+/**
+ * run the startup/init sequence and set ACS bit
+ * @param state the cold start state that is requested
+ */
+enum Tfa98xx_Error tfaRunColdboot(Tfa98xx_handle_t handle, int state);
+enum Tfa98xx_Error tfaRunMute(Tfa98xx_handle_t handle);
+enum Tfa98xx_Error tfaRunUnmute(Tfa98xx_handle_t handle);
+
+/**
+ * wait for calibrateDone
+ * @param calibrateDone pointer to status of calibration
+ */
+enum Tfa98xx_Error tfaRunWaitCalibration(Tfa98xx_handle_t handle, int *calibrateDone);
+
+/**
+ * run the startup/init sequence and set ACS bit
+ * @param profile the profile that should be loaded
+ */
+enum Tfa98xx_Error tfaRunColdStartup(Tfa98xx_handle_t handle, int profile);
+
+/**
+ *  this will load the patch witch will implicitly start the DSP
+ *   if no patch is available the DPS is started immediately
+ */
+enum Tfa98xx_Error tfaRunStartDSP(Tfa98xx_handle_t handle);
+
+/**
+ * start the clocks and wait until the AMP is switching
+ * on return the DSP sub system will be ready for loading
+ * @param profile the profile that should be loaded on startup
+ */
+enum Tfa98xx_Error tfaRunStartup(Tfa98xx_handle_t handle, int profile);
+
+/**
+ * start the maximus speakerboost algorithm
+ * this implies a full system startup when the system was not already started
+ * @param force indicates wether a full system startup should be allowed
+ * @param profile the profile that should be loaded 
+ */
+enum Tfa98xx_Error tfaRunSpeakerBoost(Tfa98xx_handle_t handle, int force, int profile);
+
+/**
+ * Startup the device and write all files from device and profile section
+ * @param force indicates wether a full system startup should be allowed
+ * @param profile the profile that should be loaded on speaker startup
+ */
+enum Tfa98xx_Error tfaRunSpeakerStartup(Tfa98xx_handle_t handle, int force, int profile);
+
+/**
+ * Run calibration
+ * @param profile the profile that should be loaded 
+ */
+enum Tfa98xx_Error tfaRunSpeakerCalibration(Tfa98xx_handle_t handle, int profile);
+
+/**
+ * startup all devices. all step until patch loading is handled
+ */
+int tfaRunStartupAll(Tfa98xx_handle_t *handles);
+
+/**
+ * powerup the coolflux subsystem and wait for it
+ */
+enum Tfa98xx_Error tfa_cf_powerup(Tfa98xx_handle_t handle);
+
+/*
+ * print the current device manager state
+ */
+enum Tfa98xx_Error show_current_state(Tfa98xx_handle_t handle);
+
+/**
+ * set verbosity level
+ */
+void tfa_verbose(int level);
+
+/** 
+ * Init registers and coldboot dsp 
+ */
+int tfa98xx_reset(Tfa98xx_handle_t handle);
+
+/** 
+ * 
+ * @param dev_idx is the device index
+ * @param revid is the revision id
+ * @param slave_address is the slave address
+ */
+void tfa_mock_probe(int dev_idx, unsigned short revid, int slave_address);
+
+/** 
+ * 
+ * @param dev_idx is the device index
+ * @param revid is the revision id
+ */
+enum Tfa98xx_Error tfa_soft_probe(int dev_idx, int revid);
+
+/**
+ * Get profile from a register 
+ */
+int tfa_get_swprof(Tfa98xx_handle_t handle);
+
+/** 
+ * Save profile in a register 
+ */
+int tfa_set_swprof(Tfa98xx_handle_t handle, unsigned short new_value);
+
+int tfa_get_swvstep(Tfa98xx_handle_t handle);
+
+int tfa_set_swvstep(Tfa98xx_handle_t handle, unsigned short new_value);
+
+#ifdef __cplusplus
+}
+#endif
+#endif				/* TFA_SERVICE_H */
diff --git a/techpack/audio/asoc/sdm845.c b/techpack/audio/asoc/sdm845.c
index 0ff0f57..16fea1e 100644
--- a/techpack/audio/asoc/sdm845.c
+++ b/techpack/audio/asoc/sdm845.c
@@ -5006,6 +5006,15 @@ static struct snd_soc_ops msm_wcn_ops = {
 };
 
 
+#ifdef CONFIG_SND_SOC_TFA98XX
+static struct snd_soc_dai_link_component tfa98xx_soc_dai_link_component[] = {
+	{
+		.name = "tfa98xx.11-0034",
+		.dai_name = "tfa98xx-aif-b-34",
+	},
+};
+#endif
+
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link msm_common_dai_links[] = {
 	/* FrontEnd DAI Links */
@@ -6327,8 +6336,13 @@ static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
 		.stream_name = "Quaternary MI2S Playback",
 		.cpu_dai_name = "msm-dai-q6-mi2s.3",
 		.platform_name = "msm-pcm-routing",
+#ifdef CONFIG_SND_SOC_TFA98XX
+		.codecs = tfa98xx_soc_dai_link_component,
+		.num_codecs = 1,
+#else
 		.codec_name = "msm-stub-codec.1",
 		.codec_dai_name = "msm-stub-rx",
+#endif
 		.no_pcm = 1,
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_QUATERNARY_MI2S_RX,