[][Add Proslic SI3218x audio codec driver]
[Description]
Add Proslic SI3218x audio codec driver
[Release-log]
N/A
Change-Id: I30edf714fda413b220b6a0f3e301a7bc3f899c08
Reviewed-on: https://gerrit.mediatek.inc/c/openwrt/feeds/mtk_openwrt_feeds/+/5396999
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x-spi.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x-spi.c
new file mode 100644
index 0000000..0708def
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x-spi.c
@@ -0,0 +1,86 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/spi/spi.h>
+
+/* alsa sound header */
+#include <sound/soc.h>
+#include <sound/pcm_params.h>
+
+#include "si3218x/si3218x.h"
+
+enum si3218x_spi_type {
+ MTK_EXT_PROSLIC = 0,
+ MTK_EXT_TYPE_NUM
+};
+
+struct mtk_ext_spi_ctrl {
+ int (*spi_probe)(struct spi_device *spi, struct spi_driver *spi_drv);
+ int (*spi_remove)(struct spi_device *spi);
+ const char *stream_name;
+ const char *codec_dai_name;
+ const char *codec_name;
+};
+
+static struct mtk_ext_spi_ctrl mtk_ext_list[MTK_EXT_TYPE_NUM] = {
+ [MTK_EXT_PROSLIC] = {
+ .spi_probe = si3218x_spi_probe,
+ .spi_remove = si3218x_spi_remove,
+ },
+};
+
+static unsigned int mtk_ext_type;
+
+static int mtk_ext_spi_probe(struct spi_device *spi);
+static int mtk_ext_spi_remove(struct spi_device *spi)
+{
+ dev_info(&spi->dev, "%s()\n", __func__);
+
+ if (mtk_ext_list[mtk_ext_type].spi_remove)
+ mtk_ext_list[mtk_ext_type].spi_remove(spi);
+
+ return 0;
+}
+
+static const struct of_device_id mtk_ext_match_table[] = {
+ {.compatible = "silabs,proslic_spi",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, mtk_ext_match_table);
+
+static struct spi_driver mtk_ext_spi_driver = {
+ .driver = {
+ .name = "proslic_spi",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(mtk_ext_match_table),
+ },
+ .probe = mtk_ext_spi_probe,
+ .remove = mtk_ext_spi_remove,
+};
+
+module_spi_driver(mtk_ext_spi_driver);
+
+static int mtk_ext_spi_probe(struct spi_device *spi)
+{
+ int i, ret = 0;
+
+ dev_err(&spi->dev, "%s()\n", __func__);
+
+ mtk_ext_type = MTK_EXT_PROSLIC;
+ for (i = 0; i < MTK_EXT_TYPE_NUM; i++) {
+ if (!mtk_ext_list[i].spi_probe)
+ continue;
+
+ ret = mtk_ext_list[i].spi_probe(spi, &mtk_ext_spi_driver);
+ if (ret)
+ continue;
+
+ mtk_ext_type = i;
+ break;
+ }
+
+ return ret;
+}
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/Makefile b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/Makefile
new file mode 100644
index 0000000..907bb61
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/Makefile
@@ -0,0 +1,17 @@
+# Release Version 1.0.4
+# Add config define "CONFIG_SND_SOC_PROSLIC" to "y"
+# Add to Makefile of prented folder: obj-$(CONFIG_SND_SOC_PROSLIC) += proslic/
+
+# Platform
+subdir-ccflags-y += -DSI3218X
+subdir-ccflags-y += -DPROSLIC_LINUX_KERNEL
+subdir-ccflags-y += -Iinc
+subdir-ccflags-y += -Iconfig_inc
+
+
+# Basic
+snd-soc-si3218x-objs := proslic_sys_main.o proslic_sys_spi.o proslic_sys_timer.o si3218x.o proslic_spi_api.o proslic_timer_intf_linux.o
+
+obj-$(CONFIG_SND_SOC_SI3218X) += src/proslic.o src/proslic_tstin.o src/si_voice.o src/si_voice_version.o src/si3218x_intf.o src/vdaa.o src/vdaa_constants.o src/si3218x_LCCB_constants.o
+obj-$(CONFIG_SND_SOC_SI3218X) += patch_files/si3218x_patch_A_2017MAY25.o
+obj-$(CONFIG_SND_SOC_SI3218X) += snd-soc-si3218x.o
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/proslic_api_config.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/proslic_api_config.h
new file mode 100644
index 0000000..d75a2ef
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/proslic_api_config.h
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ *
+ */
+#ifndef PROSLIC_API_CFG
+#define PROSLIC_API_CFG
+
+/** @defgroup PROSLIC_CFG ProSLIC Configuration Options
+ * @{
+ */
+
+/** @defgroup PROSLIC_DRIVER_SEL ProSLIC Driver Selection
+* Define device driver to be compiled.
+* @{
+*/
+#ifdef PROSLIC_DOXYGEN
+#define SI3217X /**< Define to support Si3217x chipset family in the build */
+#undef SI3217X
+#define SI3217X_REVC_ONLY /**< Define to ONLY have Si3217x Rev C support (drop Rev B support) */
+#undef SI3217X_REVC_ONLY
+#define SI3217X_REVB_ONLY /**< Define to ONLY have Si3217x Rev B support (drop Rev C support) */
+#undef SI3217X_REVB_ONLY
+#define SI3218X /**< Define to support Si3218x chipset family in the build */
+#undef SI3218X
+#define SI3219X /**< Define to support Si3219x chipset family in the build */
+#undef SI3219X
+#define SI3226X /**< Define to support Si3226x chipset family in the build */
+#undef SI3226X
+#define SI3228X /**< Define to support Si3228x chipset family in the build */
+#undef SI3228X
+#error DO NOT BUILD WITH PROSLIC_DOXYGEN ENABLED
+#endif
+
+/** @} PROSLIC_DRIVER_SEL*/
+
+/** @defgroup CODE_OPTS Code feature options
+ * Select which options NOT to build - just uncomment out the undef to disable feature.
+ * @{
+ */
+#define DISABLE_VERIFY_PATCH /**< Disable patch load verification */
+#undef DISABLE_VERIFY_PATCH
+#define DISABLE_FSK_SETUP /**< Disable the FSK setup & associated functions */
+#undef DISABLE_FSK_SETUP
+#define DISABLE_TONE_SETUP /**< Disable Tone setup API */
+#undef DISABLE_TONE_SETUP
+#define DISABLE_RING_SETUP /**< Disable Ring setup API */
+#undef DISABLE_RING_SETUP
+#define DISABLE_DCFEED_SETUP /**< Disable DC FEED setup API */
+#undef DISABLE_DCFEED_SETUP
+#define DISABLE_GPIO_SETUP /**< Disable GPIO setup API */
+#undef DISABLE_GPIO_SETUP
+#define DISABLE_PCM_SETUP /**< Disable PCM setup API */
+#undef DISABLE_PCM_SETUP
+#define ENABLE_DEBUG /**< Enable debug messages - function entry, etc. */
+/* #undef ENABLE_DEBUG */
+#define DISABLE_CI_SETUP /**< Disable CI Setup */
+#undef DISABLE_CI_SETUP
+#define DISABLE_ZSYNTH_SETUP /**< Disable Zsyth/impedance setup */
+#undef DISABLE_ZSYNTH_SETUP
+#define DISABLE_MALLOC /**< Don't use MALLOC/FREE, instead assume user will statically allocate */
+#undef DISABLE_MALLOC
+#define DISABLE_HPF_WIDEBAND /**< Disable RX and TX HPF when in WIDEBAND mode */
+#undef DISABLE_HPF_WIDEBAND
+#define PROSLIC_OPTIMIZE_INTERRUPTS /**< Enable optimization for interrupts for dual channel devices. This
+ optimization assumes channel number is on even boundaries - that is
+ 0,2,4, are the first channel for each dual channel devices.
+ */
+#define ENABLE_TRACES /**< Enable this to see major API calls during software execution. NOT recommended for production code since it does add code space + can generate compiler warnings. */
+#undef ENABLE_TRACES
+
+#define SI_ENABLE_LOGGING /**< This will enable the ability to log to a file - this assumes the application supports this. See api_demo for example implementation */
+#undef SI_ENABLE_LOGGING
+
+#define DISABLE_HOOKCHANGE /**< Disable ProSLIC_HookChangeDetect() and associated functions */
+#undef DISABLE_HOOKCHANGE
+
+#define DISABLE_PULSEMETERING /**< Disable pulse metering functions */
+#undef DISABLE_PULSEMETERING
+
+/**@} */
+
+
+#define SIVOICE_NEON_MWI_SUPPORT /**< Enable NEON Message Waiting Indicator support */
+#undef SIVOICE_NEON_MWI_SUPPORT
+
+#define GCI_MODE /**< Set if GCI vs. SPI/PCM mode is to be used */
+#undef GCI_MODE
+
+#define ENABLE_HIRES_GAIN /**< Set for zsynth preset gains in dB*10 rather than dB */
+#undef ENABLE_HIRES_GAIN
+
+#define PRINT_TO_STRING 0 /**< Set this to 1 if printing to a string buffer vs. console - you may change/remove this*/
+
+
+/** @defgroup MULTI_BOM Multiple Device/BOM Option Support
+ * Assign patch structure names to macros used in device drivers
+* @{ */
+#define SIVOICE_MULTI_BOM_SUPPORT /**< Enable Multiple General Configuration Support */
+#undef SIVOICE_MULTI_BOM_SUPPORT
+
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+#define SI3217X_PATCH_B_FLBK si3217xPatchRevBFlbk /**< Si3217x B Flyback DCDC Converter patch */
+#define SI3217X_PATCH_B_BKBT si3217xPatchRevBBkbt /**< Si3217x B Buck-boost DCDC Converter patch */
+#define SI3217X_PATCH_B_PBB si3217xPatchRevBBkbt /**< Si3217x B PMOS Buck-boost DCDC Converter patch */
+#define SI3217X_PATCH_B_LCQCUK si3217xPatchRevBFlbk /**< Si3217x C Quasi-CUK DCDC Converter patch */
+#define SI3217X_PATCH_C_FLBK si3217xPatchRevCFlbk /**< Si3217x C Flyback DCDC Converter patch */
+#define SI3217X_PATCH_C_BKBT si3217xPatchRevCFlbk /**< Si3217x C Buck-boost DCDC Converter patch */
+#define SI3217X_PATCH_C_PBB si3217xPatchRevCFlbk /**< Si3217x C PMOS Buck-boost DCDC Converter patch */
+#define SI3217X_PATCH_C_LCQCUK si3217xPatchRevCFlbk /**< Si3217x C Quasi-CUK DCDC Converter patch */
+
+#define SI3218X_PATCH_A si3218xPatchRevALCQC /**< Si3218x LCQC 5W DCDC Converter patch */
+
+#define SI3219X_PATCH_A si3219xPatchRevALCQC /**< SI3219x patch */
+
+#define SI3226X_PATCH_C_FLBK si3226xPatchRevCFlbk /**< Si3226x RevC Flyback DCDC Converter Patch */
+#define SI3226X_PATCH_C_CUK si3226xPatchRevCFlbk /**< Si3226x RevC Full CUK DCDC Converter Patch */
+#define SI3226X_PATCH_C_QCUK si3226xPatchRevCFlbk /**< Si3226x RevC Quasi-CUK DCDC Converter Patch */
+#define SI3226X_PATCH_C_LCQCUK si3226xPatchRevCFlbk /**< Si3226x RevC Low-cost QCUK DCDC Converter Patch */
+#define SI3226X_PATCH_C_TSS si3226xPatchRevCTss /**< Si3226x RevC TSS DCDC Converter Patch */
+#define SI3226X_PATCH_C_TSS_ISO si3226xPatchRevCTssIso /**< Si3226x RevC TSS (isolated) DCDC Converter Patch */
+#define SI3226X_PATCH_C_PBB si3226xPatchRevCFlbk /**< Si3226x PMOS Buck-boost DCDC Converter patch */
+#define SI3226x_PATCH_C_FIXRL SI3226X_PATCH_C_TSS
+#define SI3226X_PATCH_C_QSS si3226xPatchRevCTss /**< Si3226x RevC QSS DCDC Converter Patch */
+#define SI3226X_PATCH_C_BB si3226xPatchRevCFlbk /**< Si3226x BJT Buck-boost DCDC Converter patch */
+
+#define SI3228X_PATCH_A si3228xPatchRevALCQC /**< Si3228x LCQC 5W DCDC Converter patch */
+
+#endif
+
+/* Default patch names for backwards compatibility */
+#define SI3217X_PATCH_B_DEFAULT RevBPatch
+#define SI3217X_PATCH_C_DEFAULT RevCPatch
+#define SI3218X_PATCH_A_DEFAULT RevAPatch
+#define SI3219X_PATCH_A_DEFAULT RevAPatch
+#define SI3226X_PATCH_C_DEFAULT RevCPatch
+#define SI3228X_PATCH_A_DEFAULT RevAPatch
+
+/** @} MULTI_BOM */
+
+
+#include <linux/module.h>
+#define LOGPRINT(...) printk(KERN_ERR __VA_ARGS__)
+#ifdef SI_ENABLE_LOGGING
+
+#ifdef PROSLIC_LINUX_KERNEL
+#error "Logging currently implemented only for userspace programs."
+#endif
+
+extern FILE *SILABS_LOG_FP; /* This global variable would need to be initialized by the user's program - see the api demo for example */
+#endif /* SI_ENABLE_LOGGING */
+
+#ifdef ENABLE_DEBUG
+#define DEBUG_ENABLED(X) ((X)->debugMode & 1)
+
+#ifdef SI_ENABLE_LOGGING
+#define DEBUG_PRINT(CHPTR,...) if( DEBUG_ENABLED(CHPTR) ){ fprintf(SILABS_LOG_FP, __VA_ARGS__); fflush(SILABS_LOG_FP);}
+#else
+#define DEBUG_PRINT(CHPTR,...) if( DEBUG_ENABLED(CHPTR) ) LOGPRINT(__VA_ARGS__)
+#endif /* Logging */
+
+#else /* No Debug */
+/* Handled in si_voice.h */
+#endif
+#define SI_ENABLE_LOGGING
+#ifdef ENABLE_TRACES
+#define TRACE_ENABLED(X) ((X)->debugMode & 2)
+
+#ifdef SI_ENABLE_LOGGING
+#define TRACEPRINT(CHPTR,FMT,...) if(TRACE_ENABLED(CHPTR)) {fprintf(SILABS_LOG_FP, "#TRC:%s channel: %d "FMT,__FUNCTION__, (CHPTR)->channel,__VA_ARGS__); fflush(SILABS_LOG_FP); }
+#define TRACEPRINT_NOCHAN(FMT,...) fprintf(SILABS_LOG_FP, "#TRC:%s "FMT,__FUNCTION__, __VA_ARGS__); fflush(SILABS_LOG_FP)
+#else
+#define TRACEPRINT(CHPTR,FMT,...) if(TRACE_ENABLED(CHPTR)) LOGPRINT("TRC:%s channel: %d "FMT,__FUNCTION__, (CHPTR)->channel,__VA_ARGS__)
+#define TRACEPRINT_NOCHAN(FMT,...) LOGPRINT("TRC:%s "FMT,__FUNCTION__, __VA_ARGS__)
+
+#endif /* SI_ENABLE_LOGGING */
+#else
+/* Handled in si_voice.h */
+#endif
+
+
+/** @defgroup PSTN_CFG PSTN Detection Options
+* @{ */
+#define PSTN_DET_ENABLE /**< Define to include Differential PSTN detection code */
+#undef PSTN_DET_ENABLE
+
+#define PSTN_DET_OPEN_FEMF_SETTLE 1500 /**< OPEN foreign voltage measurement settle time */
+#define PSTN_DET_DIFF_SAMPLES 4 /**< Number of I/V samples averaged [1 to 16] */
+#define PSTN_DET_MIN_ILOOP 700 /**< Minimum acceptable loop current */
+#define PSTN_DET_MAX_FEMF 10000 /**< Maximum OPEN state foreign voltage */
+#define PSTN_DET_POLL_RATE 10 /**< Rate of re-entrant code in ms */
+#define PSTN_DET_DIFF_IV1_SETTLE 1000 /**< Settle time before first I/V measurment in ms */
+#define PSTN_DET_DIFF_IV2_SETTLE 1000 /**< Settle time before first I/V measurment in ms */
+
+/** @} PSTN_CFG */
+#define SIVOICE_CFG_NEWTYPES_ONLY 1 /**< Set if not supporting Legacy types */
+
+
+/**@} */
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/si3218x_LCCB_constants.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/si3218x_LCCB_constants.h
new file mode 100644
index 0000000..94bdac1
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/si3218x_LCCB_constants.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *
+ * Si3218x ProSLIC API Configuration Tool Version 4.2.1
+ * Last Updated in API Release: 9.2.0
+ * source XML file: si3218x_LCCB_constants.xml
+ *
+ * Auto generated file from configuration tool.
+ */
+
+
+#ifndef SI3218X_CONSTANTS_H
+#define SI3218X_CONSTANTS_H
+
+/** Ringing Presets */
+enum {
+ DEFAULT_RINGING,
+ RING_F20_45VRMS_0VDC_LPR,
+ RINGING_LAST_ENUM
+};
+
+/** DC_Feed Presets */
+enum {
+ DCFEED_48V_20MA,
+ DCFEED_48V_25MA,
+ DCFEED_PSTN_DET_1,
+ DCFEED_PSTN_DET_2,
+ DC_FEED_LAST_ENUM
+};
+
+/** Impedance Presets */
+enum {
+ ZSYN_600_0_0_30_0,
+ ZSYN_270_750_150_30_0,
+ ZSYN_370_620_310_30_0,
+ ZSYN_220_820_120_30_0,
+ ZSYN_600_0_1000_30_0,
+ ZSYN_200_680_100_30_0,
+ ZSYN_220_820_115_30_0,
+ WB_ZSYN_600_0_0_20_0,
+ IMPEDANCE_LAST_ENUM
+};
+
+/** FSK Presets */
+enum {
+ DEFAULT_FSK,
+ ETSI_FSK,
+ FSK_LAST_ENUM
+};
+
+/** Pulse_Metering Presets */
+enum {
+ DEFAULT_PULSE_METERING,
+ PULSE_METERING_LAST_ENUM
+};
+
+/** Tone Presets */
+enum {
+ TONEGEN_FCC_DIAL,
+ TONEGEN_FCC_BUSY,
+ TONEGEN_FCC_RINGBACK,
+ TONEGEN_FCC_REORDER,
+ TONEGEN_FCC_CONGESTION,
+ TONEGEN_FCC_CAS,
+ TONEGEN_FCC_SAS,
+ TONEGEN_ETSI_DTAS,
+ TONEGEN_1004,
+ TONE_LAST_ENUM
+};
+
+/** PCM Presets */
+enum {
+ PCM_8ULAW,
+ PCM_8ALAW,
+ PCM_16LIN,
+ PCM_16LIN_WB,
+ PCM_LAST_ENUM
+};
+
+
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/si_voice_datatypes.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/si_voice_datatypes.h
new file mode 100644
index 0000000..520a79d
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/si_voice_datatypes.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * si_voice_datatypes.h
+ * ProSLIC datatypes file
+ *
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the header file that contains
+ * type definitions for the data types
+ * used in the demonstration code.
+ *
+ */
+#ifndef DATATYPES_H
+#define DATATYPES_H
+#include "proslic_api_config.h"
+
+#ifndef TRUE
+#define TRUE (1)
+#endif
+#ifndef FALSE
+#define FALSE (0)
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#include <linux/types.h>
+typedef u_int8_t BOOLEAN;
+typedef int8_t int8;
+typedef u_int8_t uInt8;
+typedef uInt8 uChar;
+typedef int16_t int16;
+typedef u_int16_t uInt16;
+typedef int32_t int32;
+typedef u_int32_t uInt32;
+typedef u_int32_t ramData;
+
+
+#include <linux/slab.h>
+#include <linux/kernel.h> /* for abs() */
+/* NOTE: kcalloc was introduced in ~2.6.14, otherwise use kzalloc() with (X)*(Y) for the block size */
+#define SIVOICE_CALLOC(X,Y) kcalloc((X),(Y), GFP_KERNEL)
+#define SIVOICE_FREE(X) kfree((X))
+#define SIVOICE_MALLOC(X) kmalloc((X), GFP_KERNEL)
+#define SIVOICE_STRCPY strcpy
+#define SIVOICE_STRNCPY strncpy
+#define SIVOICE_MEMSET memset
+#define SIVOICE_ABS abs
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/vdaa_api_config.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/vdaa_api_config.h
new file mode 100644
index 0000000..4967170
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/vdaa_api_config.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * vdaa_api_config.h
+ * VoiceDAA header config file
+ *
+ * Author(s):
+ * naqamar, laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This file is used
+ * in the VoiceDAA demonstration code.
+ *
+ *
+ */
+
+#ifndef VDAA_API_CFG_H
+#define VDAA_API_CFG_H
+
+/* #define DISABLE_MALLOC */
+/* #define DISABLE_VDAA_RING_DETECT_SETUP */
+/* #define DISABLE_VDAA_AUDIO_GAIN_SETUP */
+/* #define DISABLE_VDAA_PCM_SETUP */
+/* #define DISABLE_VDAA_COUNTRY_SETUP */
+/* #define DISABLE_VDAA_HYBRID_SETUP */
+#define DISABLE_VDAA_LOOPBACK_SETUP
+#define DISABLE_VDAA_IMPEDANCE_SETUP
+
+#ifndef ENABLE_DEBUG
+#define ENABLE_DEBUG
+#endif
+//#include "stdio.h"
+#include <linux/kernel.h>
+//#define LOGPRINT printf
+
+#endif
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/vdaa_constants.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/vdaa_constants.h
new file mode 100644
index 0000000..11940a6
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/config_inc/vdaa_constants.h
@@ -0,0 +1,57 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Si3217x ProSLIC API Configuration Tool Version 4.2.1
+ * Last Updated in API Release: 9.2.0
+ * source XML file: si3217x_FLBK_GDRV_constants.xml
+ *
+ * Auto generated file from configuration tool.
+*/
+
+
+#ifndef VDAA_CONSTANTS_H
+#define VDAA_CONSTANTS_H
+
+/** Vdaa_Country Presets */
+enum {
+ COU_USA,
+ COU_GERMANY,
+ COU_CHINA,
+ COU_AUSTRALIA,
+ VDAA_COUNTRY_LAST_ENUM
+};
+
+/** Vdaa_Audio_Gain Presets */
+enum {
+ AUDIO_GAIN_0DB,
+ AUDIO_ATTEN_4DB,
+ AUDIO_ATTEN_6DB,
+ AUDIO_ATTEN_11DB,
+ VDAA_AUDIO_GAIN_LAST_ENUM
+};
+
+/** Vdaa_Ring_Validation Presets */
+enum {
+ RING_DET_NOVAL_LOWV,
+ RING_DET_VAL_HIGHV,
+ VDAA_RING_VALIDATION_LAST_ENUM
+};
+
+/** Vdaa_PCM Presets */
+enum {
+ DAA_PCM_8ULAW,
+ DAA_PCM_8ALAW,
+ DAA_PCM_16LIN,
+ VDAA_PCM_LAST_ENUM
+};
+
+/** Vdaa_Hybrid Presets */
+enum {
+ HYB_600_0_0_500FT_24AWG,
+ HYB_270_750_150_500FT_24AWG,
+ HYB_200_680_100_500FT_24AWG,
+ HYB_220_820_120_500FT_24AWG,
+ VDAA_HYBRID_LAST_ENUM
+};
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/proslic.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/proslic.h
new file mode 100644
index 0000000..a85c342
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/proslic.h
@@ -0,0 +1,2697 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the header file for the ProSLIC driver.
+ *
+ */
+
+#ifndef PROSLIC_H
+#define PROSLIC_H
+
+/*include all the required headers*/
+#include "../config_inc/proslic_api_config.h"
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si_voice_ctrl.h"
+#include "../inc/si_voice_timer_intf.h"
+#include "../inc/si_voice.h"
+
+
+/* UNSORTED ADDITIONS - These common parameters have been moved from
+ the drivers to here to support simultaneous compile of multiple devices
+ */
+/* Patch Parameters */
+#define PATCH_NUM_LOW_ENTRIES 8
+#define PATCH_NUM_HIGH_ENTRIES 8
+#define PATCH_MAX_SUPPORT_RAM 128
+#define PATCH_MAX_SIZE 1024
+
+#define PROSLIC_RAM_MADC_VBAT 3
+#define PROSLIC_RAM_PATCHID 448
+#define PROSLIC_RAM_VERIFY_IO 449
+#define PROSLIC_RAM_PD_DCDC 1538
+#define PROSLIC_RAM_PRAM_ADDR 1358
+#define PROSLIC_RAM_PRAM_DATA 1359
+#define PATCH_JMPTBL_HIGH_ADDR 1597
+
+/* Common register values for 17x, 26x, 18x, 19x & 28x */
+#define PROSLIC_REG_ID 0
+#define PROSLIC_REG_RESET 1
+#define PROSLIC_REG_MSTRSTAT 3
+#define PROSLIC_REG_RAM_ADDR_HI 5
+#define PROSLIC_REG_PCMMODE 11
+#define PROSLIC_REG_PCMTXLO 12
+#define PROSLIC_REG_PCMTXHI 13
+#define PROSLIC_REG_PCMRXLO 14
+#define PROSLIC_REG_PCMRXHI 15
+#define PROSLIC_REG_IRQ 16
+#define PROSLIC_REG_IRQ0 17
+#define PROSLIC_REG_IRQ1 18
+#define PROSLIC_REG_IRQ4 21
+#define PROSLIC_REG_IRQEN1 22
+#define PROSLIC_REG_IRQEN2 23
+#define PROSLIC_REG_IRQEN3 24
+#define PROSLIC_REG_IRQEN4 25
+#define PROSLIC_REG_CALR0 26
+#define PROSLIC_REG_CALR3 29
+#define PROSLIC_REG_LINEFEED 30
+#define PROSLIC_REG_POLREV 31
+#define PROSLIC_REG_LCRRTP 34
+#define PROSLIC_REG_RINGCON 38
+#define PROSLIC_REG_RINGTALO 39
+#define PROSLIC_REG_RINGTAHI 40
+#define PROSLIC_REG_RINGTILO 41
+#define PROSLIC_REG_RINGTIHI 42
+#define PROSLIC_REG_LOOPBACK 43
+#define PROSLIC_REG_DIGCON 44
+#define PROSLIC_REG_ZCAL_EN 46
+#define PROSLIC_REG_ENHANCE 47
+#define PROSLIC_REG_OMODE 48
+#define PROSLIC_REG_OCON 49
+#define PROSLIC_REG_O1TALO 50
+#define PROSLIC_REG_O1TAHI 51
+#define PROSLIC_REG_O1TILO 52
+#define PROSLIC_REG_O1TIHI 53
+#define PROSLIC_REG_O2TALO 54
+#define PROSLIC_REG_O2TAHI 55
+#define PROSLIC_REG_O2TILO 56
+#define PROSLIC_REG_O2TIHI 57
+#define PROSLIC_REG_FSKDAT 58
+#define PROSLIC_REG_FSKDEPTH 59
+#define PROSLIC_REG_TONDTMF 60
+#define PROSLIC_REG_USERSTAT 66
+#define PROSLIC_REG_GPIO 67
+#define PROSLIC_REG_PMCON 75
+#define PROSLIC_REG_AUTORD 80
+#define PROSLIC_REG_JMPEN 81
+#define PATCH_JMPTBL_START_ADDR 82
+#define PATCH_JMPTBL_LOW_ADDR 82
+#define PROSLIC_REG_USERMODE_ENABLE 126
+
+/* Common RAM locations for most ProSLICs */
+#define PROSLIC_RAM_OSC1FREQ 26
+#define PROSLIC_RAM_OSC1AMP 27
+#define PROSLIC_RAM_OSC1PHAS 28
+#define PROSLIC_RAM_OSC2FREQ 29
+#define PROSLIC_RAM_OSC2AMP 30
+#define PROSLIC_RAM_OSC2PHAS 31
+#define PROSLIC_RAM_SLOPE_RING 637
+#define PROSLIC_RAM_V_VLIM 640
+#define PROSLIC_RAM_VOV_RING_BAT 753
+#define PROSLIC_RAM_RTPER 755
+#define PROSLIC_RAM_VBATR_EXPECT 768
+#define PROSLIC_RAM_FSKFREQ0 834
+#define PROSLIC_RAM_FSKFREQ1 835
+#define PROSLIC_RAM_FSKAMP0 836
+#define PROSLIC_RAM_FSKAMP1 837
+#define PROSLIC_RAM_FSK01 838
+#define PROSLIC_RAM_FSK10 839
+#define PROSLIC_RAM_RINGOF 843
+#define PROSLIC_RAM_RINGFR 844
+#define PROSLIC_RAM_RINGAMP 845
+#define PROSLIC_RAM_RTDCTH 847
+#define PROSLIC_RAM_RTACTH 848
+#define PROSLIC_RAM_RTDCDB 849
+#define PROSLIC_RAM_LCRMASK 854
+#define PROSLIC_RAM_IRING_LIM 860
+#define PROSLIC_RAM_VOV_RING_GND 896
+#define PROSLIC_RAM_MWI_V 914
+#define PROSLIC_RAM_DCDC_OITHRESH_LO 1006
+#define PROSLIC_RAM_DCDC_OITHRESH_HI 1007
+#define PROSLIC_RAM_CMDAC_FWD 1476
+#define PROSLIC_RAM_CMDAC_REV 1477
+#define PROSLIC_RAM_CAL_TRNRD_DACT 1458
+#define PROSLIC_RAM_CAL_TRNRD_DACR 1459
+#define PROSLIC_RAM_RDC_SUM 1499
+#define PROSLIC_RAM_DCDC_STATUS 1551
+#define PROSLIC_RAM_DCDC_RNGTYPE 1560
+
+#define PROSLIC_CHAN_BROADCAST 0xFF
+
+/* BOM Constants */
+#define BOM_KAUDIO_PM 0x8000000L
+#define BOM_KAUDIO_NO_PM 0x3A2E8BAL
+#define BOM_AC_ADC_GAIN_PM 0x151EB80L
+#define BOM_AC_ADC_GAIN_NO_PM 0x99999AL
+#define FIXRL_VDC_SCALE 0xAE924B9L /** vdc sense scale when using fixed-rail */
+
+/* Generic Constants */
+#define COMP_5V 0x51EB82L
+#define VBATL_13V 0xF00000L
+#define COMP_10V 0xA3D705L
+#define ZCAL_V_RASUM_IDEAL_VAL 0x8F00000L
+#define ZCAL_DC_DAC_OS_VAL 0x1FFE0000L
+
+/* MADC Constants */
+#define SCALE_V_MADC 1074 /* 1/(1000*931.32e-9) mV */
+#define SCALE_I_MADC 597 /* 1/(1e6*1.676e-9) uA */
+#define SCALE_P_MADC 2386 /* 1/(1e3*419.095e-9) mW */
+#define SCALE_R_MADC 1609 /* 1/(1e3*621.554e-9) mV */
+
+/* Calibration Constants */
+#define CAL_LB_CMDAC 0x0C
+#define CAL_LB_TRNRD 0x03
+#define CAL_LB_ALL 0x0F
+#define TIMEOUT_MADC_CAL 100
+#define TIMEOUT_GEN_CAL 300
+#define TIMEOUT_LB_CAL 2410
+
+/* MWI Constants */
+#define SIL_MWI_USTAT_SET 0x04
+#define SIL_MWI_USTAT_CLEAR 0xFB
+#define SIL_MWI_VPK_MAX 110
+#define SIL_MWI_VPK_MAX_LO 95
+#define SIL_MWI_VPK_MIN 80
+#define SIL_MWI_LCRMASK_MAX 2000
+#define SIL_MWI_LCRMASK_MIN 5
+#define SIL_MWI_LCRMASK_SCALE 65536
+#define SIL_MWI_FLASH_OFF 0
+#define SIL_MWI_FLASH_ON 1
+
+/* Depricated functions now mapped directly to SiVoice versions... */
+
+#define ProSLIC_clearErrorFlag SiVoice_clearErrorFlag
+#define ProSLIC_createChannel SiVoice_createChannel
+#define ProSLIC_createControlInterface SiVoice_createControlInterface
+#define ProSLIC_createDevice SiVoice_createDevice
+#define ProSLIC_destroyChannel SiVoice_destroyChannel
+#define ProSLIC_destroyControlInterface SiVoice_destroyControlInterface
+#define ProSLIC_destroyDevice SiVoice_destroyDevice
+#define ProSLIC_getChannelEnable SiVoice_getChannelEnable
+#define ProSLIC_getErrorFlag SiVoice_getErrorFlag
+#define ProSLIC_Reset SiVoice_Reset
+#define ProSLIC_setChannelEnable SiVoice_setChannelEnable
+#define ProSLIC_setControlInterfaceCtrlObj SiVoice_setControlInterfaceCtrlObj
+#define ProSLIC_setControlInterfaceDelay SiVoice_setControlInterfaceDelay
+#define ProSLIC_setControlInterfaceGetTime SiVoice_setControlInterfaceGetTime
+#define ProSLIC_setControlInterfaceReadRAM SiVoice_setControlInterfaceReadRAM
+#define ProSLIC_setControlInterfaceReadRegister SiVoice_setControlInterfaceReadRegister
+#define ProSLIC_setControlInterfaceReset SiVoice_setControlInterfaceReset
+#define ProSLIC_setControlInterfaceSemaphore SiVoice_setControlInterfaceSemaphore
+#define ProSLIC_setControlInterfaceTimeElapsed SiVoice_setControlInterfaceTimeElapsed
+#define ProSLIC_setControlInterfaceTimerObj SiVoice_setControlInterfaceTimerObj
+#define ProSLIC_setControlInterfaceWriteRAM SiVoice_setControlInterfaceWriteRAM
+#define ProSLIC_setControlInterfaceWriteRegister SiVoice_setControlInterfaceWriteRegister
+#define ProSLIC_setSWDebugMode SiVoice_setSWDebugMode
+#define ProSLIC_SWInitChan SiVoice_SWInitChan
+#define ProSLIC_Version SiVoice_Version
+#define ProSLIC_ReadReg SiVoice_ReadReg
+#define ProSLIC_WriteReg SiVoice_WriteReg
+#define ProSLIC_ShutdownChannel ProSLIC_PowerDownConverter
+#define ProSLIC_MWISetup(PCHAN,VPK,LCR) ProSLIC_MWISetV(PCHAN,VPK)
+#define ProSLIC_MWI ProSLIC_MWISetState
+
+#define SI_MAX_INTERRUPTS 4
+
+#define PROSLIC_EXTENDED_GAIN_MAX 9
+#define PROSLIC_GAIN_MAX 6
+#define PROSLIC_GAIN_MIN -30
+/*
+** Initialization Sequence Location - Used by 18x & 17x
+*/
+typedef enum
+{
+ INIT_SEQ_BEGINNING,
+ INIT_SEQ_READ_ID,
+ INIT_SEQ_PRE_PATCH_LOAD,
+ INIT_SEQ_POST_PATCH_LOAD,
+ INIT_SEQ_PRE_CAL,
+ INIT_SEQ_POST_CAL,
+ INIT_SEQ_END
+} initSeqType;
+
+/** @mainpage
+ * This document is a supplement to the ProSLIC API User Guide. It has most
+ * of the APIs documented and hyperlinked.
+ *
+ * This document has the following tabs:
+ *
+ * - Main Page (this page) - introduction to the document.
+ * - Related pages - mainly the deprecated list is located here.
+ * Although these identifiers are present in the current release, they are
+ * targeted for deletion in a future release. Any existing customer code
+ * using deprecated identifiers should be modified as indicated.
+ * - Modules - this is the meat of the document - this has each functional group in outline format listed here.
+ * - Data Structures - This has every data structure listed in in the ProSLIC API in alphabetical order.
+ * - Files - this has the source files in hyperlink format. @note In some cases the hyperlink generator will not properly
+ * generate the correct reference or not be able to find it. In this case please use an alternative method.
+ *
+ */
+
+/** @defgroup PROSLIC_TYPES ProSLIC General Datatypes/Function Definitions
+ * This section documents functions and data structures related to the
+ * ProSLIC/FXS chipsets.
+ * @{
+ */
+
+/*
+* ----------------ProSLIC Generic DataTypes/Function Definitions----
+**********************************************************************
+*/
+
+#define MAX_PROSLIC_IRQS 32 /**< How many interrupts are supported in the ProSLIC */
+
+#ifdef ENABLE_DEBUG
+#define PROSLIC_PRINT_ERROR(CHAN, ERROR)\
+ LOGPRINT("%sError encountered on channel: %d fault code: %d\n",\
+ LOGPRINT_PREFIX, (CHAN)->channel, (ERROR))
+#else
+#define PROSLIC_PRINT_ERROR(CHAN, ERROR)
+#endif
+
+/**********************************************************************/
+/**
+* Map Proslic types to SiVoice types
+*/
+typedef SiVoiceControlInterfaceType controlInterfaceType; /**< Map ProSLIC to SiVoice type */
+typedef SiVoiceControlInterfaceType proslicControlInterfaceType; /**< Map ProSLIC to SiVoice type */
+typedef SiVoiceDeviceType ProslicDeviceType; /**< Map ProSLIC to SiVoice type */
+typedef SiVoiceChanType proslicChanType; /**< Map ProSLIC to SiVoice type */
+
+/**
+* Define channel and device type pointers
+*/
+typedef ProslicDeviceType
+*proslicDeviceType_ptr; /**< Shortcut for pointer to a ProSLIC device type */
+typedef proslicChanType
+*proslicChanType_ptr; /**< Shortcut for pointer to a ProSLIC channel type */
+
+/** @} PROSLIC_TYPES */
+
+/** @addtogroup HC_DETECT
+ * @{
+ */
+/**
+* This is structure used to store pulse dial information
+*/
+typedef struct {
+ uInt8 currentPulseDigit;
+ void *onHookTime; /**< Timestamp for when the onhook detection occured */
+ void *offHookTime; /**< Timestamp for when the offhook detection occured */
+} pulseDialType;
+
+/**
+* Defines structure for configuring pulse dial detection
+*/
+typedef struct {
+ uInt8 minOnHook; /**< Min mSec for onhook */
+ uInt8 maxOnHook; /**< Max mSec for onhook */
+ uInt8 minOffHook; /**< Min mSec for offhook */
+ uInt8 maxOffHook; /**< Max mSec for offhook */
+} pulseDial_Cfg;
+/** @} PD_DETECT */
+
+/**
+* This is structure used to store pulse dial information
+*/
+#define SI_HC_NO_ACTIVITY 0x10
+#define SI_HC_NEED_MORE_POLLS 0x20
+#define SI_HC_ONHOOK_TIMEOUT 0x41
+#define SI_HC_OFFHOOK_TIMEOUT 0x42
+#define SI_HC_HOOKFLASH 0x43
+
+#define SI_HC_NONDIGIT_DONE(X) ((X) & 0x40)
+#define SI_HC_DIGIT_DONE(X) ((X) && ((X) < 11))
+
+typedef struct
+{
+ uInt8 currentPulseDigit;
+ uInt8 last_hook_state;
+ uInt8 lookingForTimeout;
+ uInt8 last_state_reported;
+ void *hookTime; /**< Timestamp for when the onhook detection occurred */
+} hookChangeType;
+
+/**
+* Defines structure for configuring hook change detection. Times are in mSec.
+*/
+typedef struct
+{
+ uInt16 minOnHook; /**< Min mSec for onhook/break time */
+ uInt16 maxOnHook; /**< Max mSec for onhook/break time */
+ uInt16 minOffHook; /**< Min mSec for offhook/make time */
+ uInt16 maxOffHook; /**< Max mSec for offhook/make time */
+ uInt16 minInterDigit; /**< Minimum interdigit time */
+ uInt16 minHookFlash; /**< minimum hook flash time */
+ uInt16 maxHookFlash; /**< maximum hook flash time */
+ uInt16 minHook; /**< Minimum hook time, which should be >> than maxHookFlash */
+} hookChange_Cfg;
+/** @} HC_DETECT*/
+
+
+/** @addtogroup PROSLIC_INTERRUPTS
+ * @{
+ */
+/**
+* Interrupt tags
+*/
+
+/* MAINTAINER NOTE: if this enum changes, update interrupt.c in the API demo */
+typedef enum
+{
+ IRQ_OSC1_T1,
+ IRQ_OSC1_T2,
+ IRQ_OSC2_T1,
+ IRQ_OSC2_T2,
+ IRQ_RING_T1,
+ IRQ_RING_T2,
+ IRQ_PM_T1,
+ IRQ_PM_T2,
+ IRQ_FSKBUF_AVAIL, /**< FSK FIFO depth reached */
+ IRQ_VBAT,
+ IRQ_RING_TRIP, /**< Ring Trip detected */
+ IRQ_LOOP_STATUS, /**< Loop Current changed */
+ IRQ_LONG_STAT,
+ IRQ_VOC_TRACK,
+ IRQ_DTMF, /**< DTMF Detected - call @ref ProSLIC_DTMFReadDigit to decode the value */
+ IRQ_INDIRECT, /**< Indirect/RAM access completed */
+ IRQ_TXMDM,
+ IRQ_RXMDM,
+ IRQ_PQ1, /**< Power alarm 1 */
+ IRQ_PQ2, /**< Power alarm 2 */
+ IRQ_PQ3, /**< Power alarm 3 */
+ IRQ_PQ4, /**< Power alarm 4 */
+ IRQ_PQ5, /**< Power alarm 5 */
+ IRQ_PQ6, /**< Power alarm 6 */
+ IRQ_RING_FAIL,
+ IRQ_CM_BAL,
+ IRQ_USER_0,
+ IRQ_USER_1,
+ IRQ_USER_2,
+ IRQ_USER_3,
+ IRQ_USER_4,
+ IRQ_USER_5,
+ IRQ_USER_6,
+ IRQ_USER_7,
+ IRQ_DSP,
+ IRQ_MADC_FS,
+ IRQ_P_HVIC,
+ IRQ_P_THERM, /**< Thermal alarm */
+ IRQ_P_OFFLD
+} ProslicInt;
+
+/**
+* Defines structure of interrupt data - used by @ref ProSLIC_GetInterrupts
+*/
+typedef struct
+{
+ ProslicInt
+ *irqs; /**< Pointer of an array of size MAX_PROSLIC_IRQS (this is to be allocated by the caller) */
+ uInt8 number; /**< Number of IRQs detected/pending */
+} proslicIntType;
+
+
+/** @} PROSLIC_INTERRUPTS */
+
+/** @addtogroup TONE_GEN
+ * @{
+ */
+/**
+* Defines structure for configuring 1 oscillator - see your data sheet for specifics or use the configuration
+* tool to have this filled in for you.
+*/
+typedef struct
+{
+ ramData freq;
+ ramData amp;
+ ramData phas;
+ uInt8 talo;
+ uInt8 tahi;
+ uInt8 tilo;
+ uInt8 tihi;
+} Oscillator_Cfg;
+
+/**
+ * Defines structure for tone configuration.
+ */
+typedef struct
+{
+ Oscillator_Cfg osc1;
+ Oscillator_Cfg osc2;
+ uInt8 omode;
+} ProSLIC_Tone_Cfg;
+
+typedef struct
+{
+ ramData fsk[2];
+ ramData fskamp[2];
+ ramData fskfreq[2];
+ uInt8 eightBit;
+ uInt8 fskdepth;
+} ProSLIC_FSK_Cfg;
+/** @} TONE_GEN */
+
+/*****************************************************************************/
+/** @addtogroup SIGNALING
+ * @{
+ */
+/**
+* Hook states - returned by @ref ProSLIC_ReadHookStatus()
+*/
+enum
+{
+ PROSLIC_ONHOOK, /**< Hook state is onhook */
+ PROSLIC_OFFHOOK /**< Hook state is offhook */
+};
+
+#ifndef SIVOICE_CFG_NEWTYPES_ONLY
+enum
+{
+ ONHOOK = PROSLIC_ONHOOK, /**< @deprecated- Please use PROSLIC_ONHOOK and PROSLIC_OFFHOOK for future code development */
+ OFFHOOK = PROSLIC_OFFHOOK
+};
+#endif
+
+/** @} SIGNALING */
+
+/*****************************************************************************/
+/** @addtogroup PCM_CONTROL
+ * @{
+* Loopback modes
+*/
+typedef enum
+{
+ PROSLIC_LOOPBACK_NONE, /**< Loopback disabled */
+ PROSLIC_LOOPBACK_DIG, /**< Loopback is toward the PCM side */
+ PROSLIC_LOOPBACK_ANA /**< Loopback is toward the analog side */
+} ProslicLoopbackModes;
+
+/**
+* Mute options - which direction to mute
+*/
+typedef enum
+{
+ PROSLIC_MUTE_NONE = 0, /**< Don't mute */
+ PROSLIC_MUTE_RX = 0x1, /**< Mute toward the RX side */
+ PROSLIC_MUTE_TX = 0x2, /**< Mute toward the TX side */
+ PROSLIC_MUTE_ALL = 0x3 /**< Mute both directions */
+} ProslicMuteModes;
+
+/** @} PCM_CONTROL */
+
+/*****************************************************************************/
+/** @addtogroup GAIN_CONTROL
+ * @{
+* Path Selector
+*/
+enum
+{
+ TXACGAIN_SEL = 0,
+ RXACGAIN_SEL = 1
+};
+
+
+/*
+** Defines structure for configuring audio gain on the fly
+*/
+typedef struct
+{
+ ramData acgain;
+ uInt8 mute;
+ ramData aceq_c0;
+ ramData aceq_c1;
+ ramData aceq_c2;
+ ramData aceq_c3;
+} ProSLIC_audioGain_Cfg;
+
+/** @} GAIN_CONTROL */
+
+/*****************************************************************************/
+/** @addtogroup LINESTATUS
+ * @{
+ */
+/**
+* enumeration of the Proslic polarity reversal states - used by ProSLIC_PolRev API
+*/
+enum
+{
+ POLREV_STOP, /**< Stop Polarity reversal */
+ POLREV_START, /**< Start Polarity reversal */
+ WINK_START, /**< Start Wink */
+ WINK_STOP /**< Stop Wink */
+};
+
+/**
+* Defines initialization data structures
+* Linefeed states - used in @ref ProSLIC_SetLinefeedStatus and @ref ProSLIC_SetLinefeedStatusBroadcast
+*/
+enum
+{
+ LF_OPEN, /**< Open circuit */
+ LF_FWD_ACTIVE, /**< Forward active */
+ LF_FWD_OHT, /**< Forward active, onhook transmission (used for CID/VMWI) */
+ LF_TIP_OPEN, /**< Tip open */
+ LF_RINGING, /**< Ringing */
+ LF_REV_ACTIVE, /**< Reverse battery/polarity reversed, active */
+ LF_REV_OHT, /**< Reverse battery/polarity reversed, active, onhook transmission (used for CID/VMWI) */
+ LF_RING_OPEN /**< Ring open */
+} ;
+/** @} LINESTATUS */
+
+
+
+
+/*****************************************************************************/
+/** @addtogroup GEN_CFG
+ * @{
+ */
+
+/**
+* Defines initialization data structures
+*/
+typedef struct
+{
+ uInt8 address;
+ uInt8 initValue;
+} ProslicRegInit;
+
+typedef struct
+{
+ uInt16 address;
+ ramData initValue;
+} ProslicRAMInit;
+
+/**
+* ProSLIC patch object
+*/
+typedef struct
+{
+ const ramData *patchData; /**< 1024 max*/
+ const uInt16 *patchEntries; /**< 8 max */
+ const uInt32 patchSerial;
+ const uInt16 *psRamAddr; /**< 128 max */
+ const ramData *psRamData; /**< 128 max */
+} proslicPatch;
+
+/** @} GEN_CFG */
+
+
+/*****************************************************************************/
+/** @addtogroup RING_CONTROL
+ * @{
+ */
+/**
+* Ringing type options
+* Ringing type options - Trapezoidal w/ a Crest factor CF11= Crest factor 1.1 or sinusoidal.
+*/
+typedef enum
+{
+ ProSLIC_RING_TRAP_CF11,
+ ProSLIC_RING_TRAP_CF12,
+ ProSLIC_RING_TRAP_CF13,
+ ProSLIC_RING_TRAP_CF14,
+ ProSLIC_RING_TRAP_CF15,
+ ProSLIC_RING_TRAP_CF16,
+ ProSLIC_RING_SINE /***< Plain old sinusoidal ringing */
+} ProSLIC_RINGTYPE_T;
+
+/**
+* Ringing (provisioned) object
+*/
+typedef struct
+{
+ ProSLIC_RINGTYPE_T
+ ringtype; /**< Is this a sinusoid or a trapezoidal ring shape? */
+ uInt8 freq; /**< In terms of Hz */
+ uInt8 amp; /**< in terms of 1 volt units */
+ uInt8 offset; /**< In terms of 1 volt units */
+} ProSLIC_dbgRingCfg;
+
+
+/** @} RING_CONTROL */
+
+/*****************************************************************************/
+/**
+* Line Monitor - returned by @ref ProSLIC_LineMonitor
+*/
+typedef struct
+{
+ int32 vtr; /**< Voltage, tip-ring in mV */
+ int32 vtip; /**< Voltage, tip-ground in mV */
+ int32 vring; /**< Voltage, ring-ground in mV */
+ int32 vbat; /**< Voltage, battery in mV */
+ int32 vdc; /**< Voltage, Vdc in mV */
+ int32 vlong; /**< Voltage, longitudinal in mV */
+ int32 itr; /**< Loop current, in uA tip-ring */
+ int32 itip; /**< Loop current, in uA tip */
+ int32 iring; /**< Loop current, in uA ring */
+ int32 ilong; /**< Loop current, in uA longitudinal */
+ int32 p_hvic; /**< On-chip Power Calculation in mw */
+} proslicMonitorType;
+
+/*****************************************************************************/
+/** @addtogroup PROSLIC_DCFEED
+ * @{
+ */
+/**
+* Powersave
+*/
+enum
+{
+ PWRSAVE_DISABLE = 0, /**< Disable power savings mode */
+ PWRSAVE_ENABLE = 1 /**< Enable power savings mode */
+};
+
+/**
+** DC Feed Preset
+*/
+typedef struct
+{
+ ramData slope_vlim;
+ ramData slope_rfeed;
+ ramData slope_ilim;
+ ramData delta1;
+ ramData delta2;
+ ramData v_vlim;
+ ramData v_rfeed;
+ ramData v_ilim;
+ ramData const_rfeed;
+ ramData const_ilim;
+ ramData i_vlim;
+ ramData lcronhk;
+ ramData lcroffhk;
+ ramData lcrdbi;
+ ramData longhith;
+ ramData longloth;
+ ramData longdbi;
+ ramData lcrmask;
+ ramData lcrmask_polrev;
+ ramData lcrmask_state;
+ ramData lcrmask_linecap;
+ ramData vcm_oh;
+ ramData vov_bat;
+ ramData vov_gnd;
+} ProSLIC_DCfeed_Cfg;
+
+/** @} PROSLIC_DCFEED */
+
+/*****************************************************************************/
+/** @defgroup ProSLIC_API ProSLIC API
+* proslic.c function declarations
+* @{
+*/
+
+/*****************************************************************************/
+/** @defgroup DIAGNOSTICS Diagnostics
+ * The functions in this group allow one to monitor the line state for abnormal
+ * situations.
+ * @{
+ */
+
+/**
+* Test State - used in polled tests (such as PSTN Check)
+*/
+typedef struct
+{
+ int32 stage; /**< What state is the test in */
+ int32 waitIterations; /**< How many iterations to stay in a particular state */
+ int32 sampleIterations; /**< How many samples have been collected */
+} proslicTestStateType;
+
+/**
+ * @brief
+ * This function allows one to monitor the instantaneous voltage and
+ * loop current values seen on tip/ring.
+ *
+ * @param[in] pProslic - which channel should the data be collected from
+ * @param[in,out] *monitor - the data collected
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_LineMonitor(proslicChanType_ptr pProslic,
+ proslicMonitorType *monitor);
+
+/**
+ * @brief
+ * This function reads the MADC a scaled value
+ *
+ * @param[in] pProslic - which channel should the data be collected from
+ * @param[in] addr - address to read from (MADC_ILOOP, MADC_ITIP, etc).
+ * @param[in] scale - scale to use (0 = determine based upon MADC address)
+ * @retval int32 - scaled value requested or -1 if not supported.
+ *
+ */
+
+int32 ProSLIC_ReadMADCScaled(proslicChanType_ptr pProslic, uInt16 addr,
+ int32 scale);
+
+/** @defgroup PSTN_CHECK PSTN Check
+ * Monitor for excessive longitudinal current, which
+ * would be present if a live pstn line was connected
+ * to the port. To operate these sets of functions:
+ *
+ * - Iniitalize the PSTN object by calling @ref ProSLIC_InitPSTNCheckObj
+ * - Poll at a constant rate and call @ref ProSLIC_PSTNCheck. Check the return code of this function.
+ *
+ * Alternatively, you can call the DiffPSTNCheck versions of the above two functions.
+ *
+ * @note These functions may be disabled by doing a undef of @ref PSTN_DET_ENABLE in the configuration file.
+ * @{
+*/
+#define MAX_ILONG_SAMPLES 32 /**< How many samples to collect for PSTN check */
+#define MAX_PSTN_SAMPLES 16 /**< Used in the PSTN check status code to indicate the number of samples to collect */
+
+/**
+* FEMF OPEN voltage test enable
+*/
+enum
+{
+ FEMF_MEAS_DISABLE, /**< Do not measure FEMF as part of PSTN Check */
+ FEMF_MEAS_ENABLE /**< Do measure FEMF as part of PSTN Check */
+};
+
+/** Standard line interfaces */
+typedef struct
+{
+ int32 avgThresh;
+ int32 singleThresh;
+ int32 ilong[MAX_ILONG_SAMPLES];
+ uInt8 count;
+ uInt8 samples;
+ int32 avgIlong;
+ BOOLEAN buffFull;
+} proslicPSTNCheckObjType;
+
+typedef proslicPSTNCheckObjType *proslicPSTNCheckObjType_ptr;
+
+
+/** Re-Injection line interfaces (differential) */
+typedef struct
+{
+ proslicTestStateType pState;
+ int dcfPreset1;
+ int dcfPreset2;
+ int entryDCFeedPreset;
+ uInt8 lfstate_entry;
+ uInt8 enhanceRegSave;
+ uInt8 samples;
+ int32 vdiff1[MAX_PSTN_SAMPLES];
+ int32 vdiff2[MAX_PSTN_SAMPLES];
+ int32 iloop1[MAX_PSTN_SAMPLES];
+ int32 iloop2[MAX_PSTN_SAMPLES];
+ int32 vdiff1_avg;
+ int32 vdiff2_avg;
+ int32 iloop1_avg;
+ int32 iloop2_avg;
+ int32 rl1;
+ int32 rl2;
+ int32 rl_ratio;
+ int femf_enable;
+ int32 vdiff_open;
+ int32 max_femf_vopen;
+ int return_status;
+} proslicDiffPSTNCheckObjType;
+
+typedef proslicDiffPSTNCheckObjType *proslicDiffPSTNCheckObjType_ptr;
+
+/** @}PSTN_CHECK */
+/** @}DIAGNOSTICS */
+/*****************************************************************************/
+/*
+** proslic.c function declarations
+*/
+
+/*****************************************************************************/
+/** @defgroup GEN_CFG General configuration
+ * @{
+ */
+
+/**
+ * @brief
+ * Loads patch and initializes all ProSLIC devices. Performs all calibrations except
+ * longitudinal balance.
+ *
+ * @param[in] hProslic - which channel(s) to initialize, if size > 1, then the start of the array
+ * of channels to be initialized.
+ * @param[in] size - the number of channels to initialize.
+ * @param[in] preset - general configuration preset to apply
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_Init
+ */
+
+int ProSLIC_Init_MultiBOM (proslicChanType_ptr *hProslic, int size, int preset);
+
+/**
+ * @brief
+ * Loads patch and initializes all ProSLIC devices. Performs all calibrations except
+ * longitudinal balance.
+ *
+ * @param[in] hProslic - which channel(s) to initialize, if size > 1, then the start of the array
+ * of channels to be initialized.
+ * @param[in] size - the number of channels to initialize.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_Init (proslicChanType_ptr *hProslic, int size);
+
+/**
+ * @brief
+ * Loads patch and initializes all ProSLIC devices.
+ *
+ * @param[in] hProslic - which channel(s) to initialize, if size > 1, then the start of the array
+ * of channels to be initialized.
+ * @param[in] size - the number of channels to initialize.
+ * @param[in] option - see initOptionsType
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_Init_with_Options (proslicChanType_ptr *hProslic, int size,
+ int option);
+
+/**
+ * @brief
+ * Performs soft reset then calls ProSLIC_Init()
+ *
+ * @param[in] hProslic - which channel(s) to re-initialize.
+ * of channels to be initialized.
+ * @param[in] size - the number of channels to initialize.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_Reinit (proslicChanType_ptr *hProslic, int size);
+
+/**
+ * @brief
+ * Loads registers and RAM in the ProSLICs specified.
+ *
+ * @param[in] pProslic - array of channels
+ * @param[in] pRamTable - array of RAM locations and values to write
+ * @param[in] pRegTable - array of register locations and values to write
+ * @param[in] bcast- is broadcast enabled.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function should NOT be used since it can bypass the standard initialization/operational state of the
+ * ProSLIC.
+ */
+
+int ProSLIC_LoadRegTable (proslicChanType *pProslic,
+ const ProslicRAMInit *pRamTable,
+ const ProslicRegInit *pRegTable,
+ int bcast);
+
+/**
+ * @brief
+ * Loads registers and RAM in the ProSLICs specified.
+ *
+ * @param[in] pProslic - array of channels
+ * @param[in] pRamTable - array of RAM locations and values to write
+ * @param[in] pRegTable - array of register locations and values to write
+ * @param[in] size - number of ProSLICS to write to.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function should NOT be used since it can bypass the standard initialization/operational state of the
+ * ProSLIC.
+ */
+
+int ProSLIC_LoadRegTables (proslicChanType_ptr *pProslic,
+ const ProslicRAMInit *pRamTable, const ProslicRegInit *pRegTable, int size);
+
+/**
+ * @brief
+ * Implement soft reset. For dual channel devices, you can specify a hard reset
+ * (which impacts both channels) or if the channel is actually the second
+ * channel. The default is to do a soft reset on the 1st channel.
+ *
+ * @param[in] hProslic - which channel to reset
+ * @param[in] resetOptions - PROSLIC_HARD_RESET (dual channel devices ONLY) | PROSLIC_SOFT_RESET_SECOND_CHAN (dual channel devices) | PROSLIC_BCAST_RESET | PROSLIC_SOFT_RESET
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note Will abort reset if in free run mode.
+ * @note Only perform a soft reset on 1 channel at a time.
+ */
+
+#define PROSLIC_BCAST_RESET 0x8000
+#define PROSLIC_HARD_RESET 3
+#define PROSLIC_SOFT_RESET_SECOND_CHAN 2
+#define PROSLIC_SOFT_RESET 1
+
+int ProSLIC_SoftReset(proslicChanType_ptr hProslic, uInt16 resetOptions);
+
+/**
+ * @brief
+ * Configure impedance synthesis
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which impedance configuration to load from the constants file.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be disabled by @ref DISABLE_ZSYNTH_SETUP
+ */
+
+int ProSLIC_ZsynthSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * This function configures the CI bits (GCI mode)
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which GCI preset to use from the constants file
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be disabled by @ref DISABLE_CI_SETUP
+ */
+#ifndef DISABLE_CI_SETUP
+int ProSLIC_GciCISetup (proslicChanType_ptr hProslic,int preset);
+#endif
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_DEBUG Debug
+ * This group of functions enables/disables debug messages as well as dump
+ * register contents.
+ * @{
+ */
+
+
+/**
+ * @brief
+ * This function allows access to SPI read RAM function pointer from interface
+ *
+ * @param[in] pProslic - pointer to channel structure
+ * @param[in] addr - address to read
+ * @retval ramData - RAM contents
+ *
+ */
+ramData ProSLIC_ReadRAM (proslicChanType *pProslic, uInt16 addr);
+
+/**
+ * @brief
+ * This function allows access to SPI write RAM function pointer from interface
+ *
+ * @param[in] pProslic - pointer to channel structure
+ * @param[in] addr - address to write
+ * @param[in] data to be written
+ * @retval int - @ref RC_NONE
+ *
+ */
+int ProSLIC_WriteRAM (proslicChanType *pProslic, uInt16 addr, ramData data);
+
+/**
+ * @brief
+ * This function dumps to console the register contents of several
+ * registers and RAM locations.
+ *
+ * @param[in] pProslic - which channel to dump the register contents of.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+int ProSLIC_PrintDebugData (proslicChanType *pProslic);
+
+/**
+ * @brief
+ * This function dumps the registers to the console using whatever
+ * I/O method is defined by LOGPRINT
+ *
+ * @param[in] pProslic - which channel to dump the register contents of.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+int ProSLIC_PrintDebugReg (proslicChanType *pProslic);
+
+/**
+ * @brief
+ * This function dumps the RAM to the console using whatever
+ * I/O method is defined by LOGPRINT
+ *
+ * @param[in] pProslic - which channel to dump the RAM contents of.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+int ProSLIC_PrintDebugRAM (proslicChanType *pProslic);
+
+/** @} PROSLIC_DEBUG */
+/*****************************************************************************/
+/** @defgroup PROSLIC_ENABLE Enable/disable channels (for init)
+ * @{
+ */
+
+/**
+ * @brief
+ * This function sets the channel enable status of the FXO channel on ProSLIC devices
+ * with integrated FXO. If NOT set, then when
+ * the various initialization routines such as @ref SiVoice_SWInitChan is called,
+ * then this particular channel will NOT be initialized.
+ *
+ * This function does not access the chipset directly, so SPI/GCI
+ * does not need to be up during this function call.
+ *
+ * @param[in,out] pProslic - which channel to return the status.
+ * @param[in] enable - The new value of the channel enable field. 0 = NOT enabled, 1 = enabled.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_getChannelEnable
+ */
+
+int ProSLIC_SetDAAEnable(proslicChanType *pProslic, int enable);
+
+/** @} PROSLIC_ENABLE */
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_PATCH Patch management.
+ * This group of functions write and verify the patch data needed by the
+ * ProSLIC chipset.
+ * @{
+ */
+
+/**
+ * @brief
+ * Calls patch loading function for a particular channel/ProSLIC
+ *
+ * @param[in] hProslic - which channel/ProSLIC should be patched
+ * @param[in] pPatch - the patch data
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function should not be called directly under normal circumstances since the initialization function should
+ * perform this operation.
+ *
+ * @sa ProSLIC_Init
+ */
+
+int ProSLIC_LoadPatch (proslicChanType_ptr hProslic,const proslicPatch *pPatch);
+
+/**
+ * @brief
+ * Verifies patch loading function for a particular channel/ProSLIC
+ *
+ * @param[in] hProslic - which channel/ProSLIC should be patched
+ * @param[in] pPatch - the patch data to verify was written to.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function should not be called directly under normal circumstances since the initialization function should
+ * perform this operation, unless @ref DISABLE_VERIFY_PATCH is defined.
+ *
+ * @sa ProSLIC_Init
+ */
+
+int ProSLIC_VerifyPatch (proslicChanType_ptr hProslic,const proslicPatch *pPatch);
+
+/** @} PROSLIC_PATCH */
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_GPIO GPIO Control
+ * This group of functions configure, read and write the GPIO status pins.
+ * @{
+ */
+
+/**
+ * @brief
+ * This function configures the ProSLIC GPIOs by loading a gpio preset that was
+ * set in the configuration tool.
+ * @param[in] hProslic - which channel to configure the GPIO pins.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_GPIOControl
+ */
+
+int ProSLIC_GPIOSetup (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function controls the GPIOs of the ProSLIC.
+ *
+ * @param[in] hProslic - which channel to modify
+ * @param[in,out] pGpioData - pointer to GPIO status (typically 1 byte)
+ * @param[in] read - 1 = Read the status, 0 = write the status
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_GPIOSetup
+ */
+
+int ProSLIC_GPIOControl (proslicChanType_ptr hProslic,uInt8 *pGpioData,
+ uInt8 read);
+
+/** @} PROSLIC_GPIO */
+/** @} GEN_CFG */
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_PULSE_METER Pulse Metering
+ *
+ * This group contains functions related to pulse metering.
+ * @{
+ */
+
+/**
+* @brief
+* This function configures the ProSLIC pulse metering by loading a pulse metering preset.
+*
+* @param[in] hProslic - which channel should be configured
+* @param[in] preset - which preset to load from the defined settings made in the configuration tool.
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_PulseMeterStart ProSLIC_PulseMeterStop
+*/
+
+int ProSLIC_PulseMeterSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * This function enables the pulse metering generator.
+ *
+ * @param[in] hProslic - which channel should play the tone.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_PulseMeterSetup ProSLIC_PulseMeterStop ProSLIC_PulseMeterDisable
+ *
+ */
+int ProSLIC_PulseMeterEnable (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function disables the pulse metering generator..
+ *
+ * @param[in] hProslic - which channel should play the tone.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_PulseMeterSetup ProSLIC_PulseMeterStop ProSLIC_PulseMeterEnable
+ *
+ */
+
+int ProSLIC_PulseMeterDisable (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function starts the pulse metering tone.
+ *
+ * @param[in] hProslic - which channel should play the tone.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_PulseMeterSetup ProSLIC_PulseMeterStop
+ *
+ */
+
+int ProSLIC_PulseMeterStart (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function stops the pulse metering tone.
+ *
+ * @param[in] hProslic - which channel should play the tone.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa PProSLIC_PulseMeterStart ProSLIC_PulseMeterSetup
+ *
+ */
+
+int ProSLIC_PulseMeterStop (proslicChanType_ptr hProslic);
+
+/** @} PROSLIC_PULSE_METER */
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_INTERRUPTS Interrupt control and decode
+ * @{
+ */
+
+/**
+ * @brief
+ * Enables interrupts configured in the general configuration data structure.
+ *
+ * @param[in] hProslic - which channel to enable the interrupts.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_EnableInterrupts (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function reads the interrupts from the ProSLIC and places them into
+ * a @ref proslicIntType structure which contains up to @ref MAX_PROSLIC_IRQS
+ * interrupts.
+ *
+ * @param[in] hProslic - which channel to enable the interrupts.
+ * @param[in,out] pIntData - this structure contains the interrupts pending and the number of interrupts.
+ * @retval int - number of interrupts pending or RC_CHANNEL_TYPE_ERR if wrong chip type or 0 for no interrupts.
+ *
+ */
+
+int ProSLIC_GetInterrupts (proslicChanType_ptr hProslic,
+ proslicIntType *pIntData);
+
+/**
+ * @brief
+ * This function disables and clears interrupts on the given channel.
+ *
+ * @param[in] hProslic - which channel to disable
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_DisableInterrupts (proslicChanType_ptr hProslic);
+
+/** @} PROSLIC_INTERRUPTS */
+
+/*****************************************************************************/
+/** @defgroup SIGNALING Signaling - ring & line state, and hook state
+ * @{
+ */
+
+/**
+* Function: PROSLIC_ReadHookStatus
+*
+* @brief
+* Determine hook status
+* @param[in] hProslic - which channel to read from.
+* @param[out] *pHookStat - will contain either @ref PROSLIC_ONHOOK or @ref PROSLIC_OFFHOOK
+*
+*/
+
+int ProSLIC_ReadHookStatus (proslicChanType_ptr hProslic,uInt8 *pHookStat);
+
+/*****************************************************************************/
+/** @defgroup LINESTATUS Line Feed status
+ * @{
+ */
+
+/**
+ * @brief
+ * This function sets the linefeed state.
+ *
+ * @param[in] hProslic - which channel to modify
+ * @param[in] newLinefeed - new line feed state - examples: LF_OPEN, LF_FWD_ACTIVE
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_SetLinefeedStatus (proslicChanType_ptr hProslic,uInt8 newLinefeed);
+
+/**
+ * @brief
+ * This function sets the linefeed state for all channels on the same daisychain.
+ *
+ * @param[in] hProslic - which channel to modify
+ * @param[in] newLinefeed - new line feed state - examples: LF_OPEN, LF_FWD_ACTIVE
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_SetLinefeedStatusBroadcast (proslicChanType_ptr hProslic,
+ uInt8 newLinefeed);
+
+/**
+ * @brief
+ * This function sets the polarity/wink state of the channel.
+ *
+ * @param[in] hProslic - which channel to modify
+ * @param[in] abrupt - to change the state immediately
+ * @param[in] newPolRevState - new polarity state - examples: POLREV_STOP, POLREV_START and WINK_START
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_PolRev (proslicChanType_ptr hProslic,uInt8 abrupt,
+ uInt8 newPolRevState);
+
+/** @} LINESTATUS */
+
+/*****************************************************************************/
+/** @defgroup RING_CONTROL Ring generation
+ * @{
+ */
+
+/**
+ * @brief
+ * Configure the ringer to the given preset (see your constants header file for exact value to use).
+ * This includes timing, cadence, OHT mode, voltage levels, etc.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which of the xxxx_Ring_Cfg structures to use to configure the channel.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be compiled out by defining @ref DISABLE_RING_SETUP
+ *
+ * @sa ProSLIC_dbgSetRinging ProSLIC_RingStart ProSLIC_RingStop
+ */
+
+int ProSLIC_RingSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * Starts the ringer as confgured by @ref ProSLIC_RingSetup . If the active and inactive timers are enabled,
+ * the ProSLIC will automatically turn on/off the ringer as programmed, else one will need to
+ * manually implement the ring cadence. In either case, one will need to call ProSLIC_RingStop to
+ * stop the ringer or one may call @ref ProSLIC_SetLinefeedStatus to change the state directly.
+ *
+ * @param[in] hProslic - which channel to enable ringing.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be compiled out by defining @ref DISABLE_RING_SETUP
+ * @deprecated - Will become a macro in a future release and later removed. Customers should just call ProSLIC_SetLinefeedStatus w/ LF_RINGING.
+ *
+ * @sa ProSLIC_dbgSetRinging ProSLIC_RingStop ProSLIC_RingSetup
+ */
+
+int ProSLIC_RingStart (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * Stop the ringer on the given channel and set the line state to forward active.
+ * @deprecated - Will become a macro in a future release. Customers should just call ProSLIC_SetLinefeedStatus w/ LF_FWD_ACTIVE.
+ *
+ * @param[in] hProslic - which channel to modify.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_RingSetup ProSLIC_RingStart
+ *
+ * @deprecated customers are encouraged to use ProSLIC_SetLinefeedStatus
+ */
+
+int ProSLIC_RingStop (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * Provision function for setting up Ring type, frequency, amplitude and dc offset and
+ * to store them in the given preset.
+ *
+ * @note: This function calculates the values, it does not set them.
+ * @note: This code assumes ProSLIC_RingSetup() was called earlier with the highest ringer
+ * requirements (possibly during initialization). After that, this function can
+ * be used for meeting provisioning requirements.
+ *
+ * @param[in] pProslic - which channel to modify
+ * @param[in] ringCfg - how to configure the channel's ringer
+ * @param[in] preset - where to store the new configuration.
+ * @sa ProSLIC_RingSetup ProSLIC_RingStart ProSLIC_RingStop
+ */
+
+int ProSLIC_dbgSetRinging (proslicChanType *pProslic,
+ ProSLIC_dbgRingCfg *ringCfg, int preset);
+
+/**
+ * @brief
+ * Enable abrupt ringing. Normally the ProSLIC would perform a smooth transistion
+ * to start the ring signal, but in cases where a delay is not acceptable, this
+ * function disables this feature.
+ *
+ * @param[in] pProslic - which channel to modify
+ * @param[in] isEnabled - is the abrupt ringing enbaled (smooth transistion disabled).
+ *
+ * @note Not all chipsets support this feature.
+ *
+ */
+
+int ProSLIC_EnableFastRingStart(proslicChanType_ptr pProslic, BOOLEAN isEnabled);
+
+/** @} RING_CONTROL */
+/** @} SIGNALING */
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_AUDIO Audio
+ * This group of functions contains routines to configure the PCM bus, to generate tones, and to send FSK data.
+ *
+ * In order to start using the PCM bus, you would typically initialize the PCM bus with code similar to
+ * the following:
+ *
+ * @code
+ * if( (ProSLIC_PCMSetup(myProSLIC, MY_COMPANDING) != RC_NONE)
+ * || (ProSLIC_PCMTimeSlotSetup(myProSLIC, pcm_ts, pcm_ts) != RC_NONE)
+ * || (ProSLIC_PCMStart(myProSLIC) != RC_NONE))
+ * {
+ * return MY_PCM_INIT_ERROR;
+ * }
+ * @endcode
+ *
+ * @{
+ * @defgroup TONE_GEN Tone generation
+ * This group of functions is related to playing out general tones - such as dial tone, busy tone, etc. One would
+ * typically call @ref ProSLIC_ToneGenSetup first followed by @ref ProSLIC_ToneGenStart and after some time, a call to
+ * @ref ProSLIC_ToneGenStop to stop the tone. The direction of the tone and cadence (if any) are configured using the
+ * GUI configuration tool's TONE dialog box and then saved in the constants file.
+ *
+ * @{
+ */
+/**
+ * @brief
+ * Configure the tone generator to the given preset (see your constants header file for exact value to use). It does NOT
+ * play a particular tone out.
+ *
+ * @warning If @ref ProSLIC_FSKSetup was called earlier, this function will need to be called again.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which of the xxxx_Tone_Cfg structures to use to configure the channel.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be compiled out by defining @ref DISABLE_TONE_SETUP.
+ *
+ * @note Typically, if one is using the ProSLIC for tone generation, you will be calling this function prior to each call
+ * into @ref ProSLIC_ToneGenStart so that the correct tone is played out.
+ */
+
+int ProSLIC_ToneGenSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * Configure the tone generator to the given preset (see your constants header file for exact value to use). It does NOT
+ * play a particular tone out.
+ *
+ * @warning If @ref ProSLIC_FSKSetup was called earlier, this function will need to be called again.
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] cfg - which of the xxxx_Tone_Cfg structures to use to configure the channel.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be compiled out by defining @ref DISABLE_TONE_SETUP.
+ *
+ * @note Typically, if one is using the ProSLIC for tone generation, you will be calling this function prior to each call
+ * into @ref ProSLIC_ToneGenStart so that the correct tone is played out.
+ */
+
+int ProSLIC_ToneGenSetupPtr(proslicChanType_ptr pProslic,
+ ProSLIC_Tone_Cfg *cfg);
+
+/**
+ * @brief
+ * This function starts the tone configured by @ref ProSLIC_ToneGenSetup.
+ * It is assumed that the @ref PROSLIC_AUDIO setup was performed
+ * prior to calling this function. Also, it is suggested that
+ * @ref ProSLIC_ToneGenSetup be called if @ref FSK_CONTROL
+ * functions were used.
+ *
+ * @param[in] hProslic - which channel should play the tone.
+ * @param[in] timerEn - are the timers to be enabled? 1 = Yes, 0 = No. When in doubt, set to 1.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_ToneGenSetup ProSLIC_ToneGenStop
+ */
+
+int ProSLIC_ToneGenStart (proslicChanType_ptr hProslic, uInt8 timerEn);
+
+/**
+ * @brief
+ * This function turns off tone generation initiated by @ref ProSLIC_ToneGenStart.
+ *
+ * @param[in] hProslic - which channel should stop playing the tone.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_ToneGenStart ProSLIC_ToneGenSetup
+ */
+
+int ProSLIC_ToneGenStop (proslicChanType_ptr hProslic);
+
+/** @} TONE_GEN */
+
+/*****************************************************************************/
+/** @defgroup FSK_CONTROL FSK/Caller ID generation
+ * This group of functions is related to FSK generation, typically used with Caller ID/Call Waiting
+ * functionality. To set the frequencies, the data rate, and the FSK FIFO depth, please use the configuration
+ * GUI FSK dialog box.
+ *
+ * Here's a simple example code fragment to send data via FSK:
+ *
+ * @note In a "real" application, you should not use ProSLIC_CheckCIDBuffer(), but instead
+ * call ProSLIC_GetInterrupts() and check if the FSK interrrupt fired off since the
+ * ProSLIC_GetInterrupts() will also report on loop closure/ring trip in addition FSK buffer
+ * interrupt and the two functions will conflict with each other.
+ *
+ * @code
+ *
+ * #define FIFO_DEPTH (7-FSKBUF_DEPTH) //When we report the buffer at FSK BUFFER DEPTH, we can send
+ * //at most 1 less than the maximum since that byte maybe still
+ * //be modulated. Therefore, we say we can send 7 bytes, not
+ * //8 after the interrupt.
+ *
+ * //ASSUME: FSK Buffer depth interrupt has been enabled in the constants file earlier...
+ *
+ * // This should be called every time since it is likely a tone was played
+ * // earlier which reprograms the oscillators...
+ * if( ProSLIC_FSKSetup(myProSLICChan, PROSLIC_NORTH_AMERICA_FSK) == RC_NONE)
+ * {
+ *
+ * // Enable the CID block, at this point no tones other than the FSK ones
+ * // should be played out...
+ * ProSLIC_EnableCID(myProSLICChan);
+ *
+ * // Pre-load the FSK FIFO buffer with at most 8 bytes.
+ * ProSLIC_SendCID(myProSLICChan,buf,MIN(bufsz,8));
+ *
+ * bytes_left_to_send = bufsz - MIN(bufsz,8);
+ *
+ * while(bytes_left_to_send > 0)
+ * {
+ * if(bytes_left_to_send < FIFO_DEPTH)
+ * {
+ * bytes_to_send = bytes_left_to_send;
+ * }
+ * else
+ * {
+ * bytes_to_send = FIFO_DEPTH;
+ * }
+ *
+ * if( ProSLIC_SendCID(myProSLICChan,buf,bytes_to_send) != RC_NONE)
+ * {
+ * ProSLIC_DisableCID(myProSLICChan);
+ * return MY_FSK_ERROR;
+ * }
+ *
+ * bytes_left_to_send -= bytes_to_send;
+ *
+ * if(bytes_left_to_send)
+ * {
+ * do
+ * {
+ * // See note above about this function...
+ * ProSLIC_CheckCIDBuffer(myProSLICChan, &is_fifo_empty);
+ *
+ * } while( is_fifo_empty != 1 );
+ * }
+ *
+ * };
+ *
+ * ProSLIC_DisableCID(myProSLICChan);
+ * @endcode
+ *
+ * @note The above code fragment is sub-optimal since it does constantly poll the CID buffer
+ * state - one may want to implement the actual code using interrupts.
+ *
+ * @note The ProSLIC API demo does have a working example for Type 1 CID MDMF format.
+ *
+ * @{
+ */
+
+/**
+ * @brief
+ * Configures the FSK generator from a configuration generated by the config tool.
+ *
+ * @warning If @ref ProSLIC_ToneGenSetup was called earlier, this function will need to be called again.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which FSK configuration to use.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be compiled out by defining DISABLE_FSK_SETUP
+ */
+
+int ProSLIC_FSKSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * Configures the FSK generator from a configuration generated by the config tool.
+ *
+ * @warning If @ref ProSLIC_ToneGenSetup was called earlier, this function will need to be called again.
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] cfg - which FSK configuration to use.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be compiled out by defining DISABLE_FSK_SETUP
+ */
+
+int ProSLIC_FSKSetupPtr (proslicChanType_ptr pProslic, ProSLIC_FSK_Cfg *cfg);
+
+/**
+ * @brief
+ * This function enables FSK mode and clears the FSK FIFO. It is assumed that PCM has been enabled and that @ref ProSLIC_FSKSetup
+ * has been called at some point.
+ *
+ * @warning If @ref ProSLIC_ToneGenSetup was called earlier, @ref ProSLIC_FSKSetup will need to be called again.
+ *
+ * @param[in] hProslic - which channel to check upon.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_EnableCID (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function disables FSK mode.
+ *
+ * @param[in] hProslic - which channel to disable FSK mode.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_DisableCID (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * Check if the FSK FIFO is empty or not. This should only be called after ProSLIC_SendCID.
+ *
+ * @param[in] hProslic - which channel to check upon.
+ * @param[out] fsk_buf_avail - is the buffer available? 1 = Yes, 0 = No.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note - This modifies the IRQ1 register contents, so some other interrupts may be lost. An alternative is to enable the
+ * FSK FIFO interrupt and trigger off of it when it does occur in your interrupt service routine and call ProSLIC_GetInterrupts() to decode the interrupts present.
+ */
+
+int ProSLIC_CheckCIDBuffer (proslicChanType_ptr hProslic, uInt8 *fsk_buf_avail);
+
+/**
+ * @brief
+ * Send numBytes as FSK encoded data. It is assumed that numBytes <= FIFO Depth (typically 8) and that the FIFO
+ * is free. It is also assumed that @ref ProSLIC_PCMStart has been called and that we're in
+ * @ref LF_FWD_OHT or @ref LF_REV_OHT mode for Type-1 or @ref LF_REV_ACTIVE or @ref LF_FWD_ACTIVE
+ * if we're in Type-2 caller ID.
+ *
+ * @param[in] hProslic - which channel to send the data through.
+ * @param[in] buffer - byte array of data to send.
+ * @param[in] numBytes - number of bytes to send. MUST be less than or equal to the FIFO size
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_CheckCIDBuffer ProSLIC_FSKSetup ProSLIC_EnableCID ProSLIC_DisableCID
+ */
+
+int ProSLIC_SendCID (proslicChanType_ptr hProslic, uInt8 *buffer,
+ uInt8 numBytes);
+
+/**
+ * @brief Control if the start/stop bits are enabled.
+ *
+ * @param[in] hProslic - which channel to adjust
+ * @param[in] enable_startStop - TRUE - start/stop bits are enabled, FALSE - disabled
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note: This does not replace @ref ProSLIC_FSKSetup, but is a supplement that toggles
+ * one of the registers that the preset modifies. It is assumed that @ref ProSLIC_FSKSetup
+ * was called at some point earlier in the code flow.
+ */
+
+int ProSLIC_ModifyCIDStartBits(proslicChanType_ptr hProslic,
+ uInt8 enable_startStop);
+
+
+/** @} FSK_CONTROL */
+
+/*****************************************************************************/
+/** @defgroup AUDIO_CONTROL Audio control/configuration
+ * @{
+ */
+/** @defgroup PCM_CONTROL PCM control
+ * This group of functions is used to configure and control the PCM bus. It is essential that @ref ProSLIC_PCMSetup,
+ * @ref ProSLIC_PCMTimeSlotSetup and @ref ProSLIC_PCMStart are called prior to any tone or FSK generation.
+ *
+ * See @ref PROSLIC_AUDIO code fragment on how the functions relate during initialization.
+ *
+ * @{
+ */
+
+/**
+ * @brief
+ * This configures the PCM bus with parameters such as companding and data latching timing.
+ *
+ * @param[in] hProslic - which channel should be configured
+ * @param[in] preset - which preset to use from the constants file (see configuration tool, PCM dialog box)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_PCMTimeSlotSetup ProSLIC_PCMStart
+ */
+
+int ProSLIC_PCMSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * This configures the ProSLIC to latch and send the PCM data at a particular timeslot in terms of PCM clocks (PCLK).
+ *
+ * Typically, for aLaw and uLaw, one can use the following calculation to set the rxcount and txcount parameters:
+ *
+ * rxcount = txcount = (channel_number)*8;
+ *
+ * For 16 bit linear, one can do the following:
+ *
+ * rxcount = txcount = (channel_number)*16;
+ *
+ * where channel_number = which ProSLIC channel on the PCM bus. For example, if one were to have 2 dual channel
+ * ProSLIC's on the same PCM bus, this value would range from 0 to 3.
+ *
+ * @param[in] hProslic - which channel should be configured
+ * @param[in] rxcount - how many clocks until reading data from the PCM bus
+ * @param[in] txcount - how many clocks until writing data to the PCM bus.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_PCMSetup ProSLIC_PCMStart
+ */
+
+int ProSLIC_PCMTimeSlotSetup (proslicChanType_ptr hProslic, uInt16 rxcount,
+ uInt16 txcount);
+
+/**
+ * @brief
+ * This enables PCM transfer on the given ProSLIC channel.
+ *
+ * @param[in] hProslic - - which channel should be enabled
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_PCMSetup ProSLIC_PCMTimeSlotSetup ProSLIC_PCMStop
+ */
+
+int ProSLIC_PCMStart (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This disables PCM transfer on the given ProSLIC channel. Typically, this is called for debugging
+ * purposes only.
+ *
+ * @param[in] hProslic - - which channel should be disabled
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_PCMSetup ProSLIC_PCMTimeSlotSetup ProSLIC_PCMStart
+ */
+
+int ProSLIC_PCMStop (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * Program desired loopback test mode for the given channel.
+ *
+ * @param[in] hProslic - which channel should be modified
+ * @param[in] newMode - what is the desired loopback mode.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_SetLoopbackMode (proslicChanType_ptr hProslic,
+ ProslicLoopbackModes newMode);
+
+/**
+ * @brief
+ * Program desired mute test mode for the given channel.
+ *
+ * @param[in] hProslic - which channel should be modified
+ * @param[in] muteEn - what is the desired mode.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_SetMuteStatus (proslicChanType_ptr hProslic,
+ ProslicMuteModes muteEn);
+
+/** @} PCM_CONTROL */
+
+/*****************************************************************************/
+/** @defgroup GAIN_CONTROL Gain control
+ * @{
+ */
+
+/**
+ * @brief
+ * Sets the TX audio gain (toward the network). This funcion DOES NOT actually calculate the values for the preset.
+ * To dynamically calculate the values, you would need to call @ref ProSLIC_dbgSetTXGain .
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which preset to use (this may be from the constants file)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note One can use this in conjunction with @ref ProSLIC_dbgSetTXGain to dynamically
+ * change the audio gain. It is important to have the presets of both routines match.
+ *
+ * The following code * fragment will set the TX audio gain to -5 dB:
+ *
+ * @code
+ * ProSLIC_dbgSetTXGain(myChannel, -5, MY_IMPEDENCE,0);
+ * ProSLIC_TXAudioGainSetup(myChannel,0);
+ * @endcode
+ *
+ * @sa ProSLIC_RXAudioGainSetup ProSLIC_dbgSetTXGain ProSLIC_AudioGainSetup
+ */
+
+int ProSLIC_TXAudioGainSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * Adjusts gain of TX audio path by scaling the PGA and Equalizer coefficients by the supplied values.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which preset to use (this may be from the constants file)
+ * @param[in] pga_scale - scale factor which pga coefficients are to be multiplied
+ * @param[in] eq_scale - scale factor which equalizer coefficients are to be multiplied
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be used in lieu of @ref ProSLIC_dbgSetTXGain to dynamically
+ * change the audio gain when gain steps of 0.1dB do not suffice, or if an attenuation
+ * > 30dB is required.
+ *
+ * The following code * fragment will scale the TX audio gain by a factor of (0.707)*(0.500)
+ *
+ * @code
+ * uInt32 pga_gain_scale = 707;
+ * uInt32 eq_gain_scale = 500;
+ * ProSLIC_TXAudioGainScale(pProslic,DEFAULT_PRESET,pga_gain_scale,eq_gain_scale);
+ * @endcode
+ *
+ * @sa ProSLIC_RXAudioGainScale
+ */
+int ProSLIC_TXAudioGainScale (proslicChanType_ptr hProslic,int preset,
+ uInt32 pga_scale,uInt32 eq_scale);
+
+/**
+ * @brief
+ * Configures the RX audio gain (toward the telephone). This function DOES NOT actually calculate the values for the preset.
+ * To dynamically calculate the values, you would need to call @ref ProSLIC_dbgSetRXGain .
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which preset to use (this may be from the constants file)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note One can use this in conjunction with @ref ProSLIC_dbgSetRXGain to dynamically
+ * change the audio gain. It is important to have the presets of both routines match.
+ *
+ * The following code * fragment will set the RX audio gain to -1 dB:
+ *
+ * @code
+ * ProSLIC_dbgSetRXGain(myChannel, -1, MY_IMPEDENCE,0);
+ * ProSLIC_RXAudioGainSetup(myChannel,0);
+ * @endcode
+ *
+ * @sa ProSLIC_TXAudioGainSetup ProSLIC_dbgSetRXGain ProSLIC_AudioGainSetup
+ */
+
+int ProSLIC_RXAudioGainSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * Adjusts gain of RX audio path by scaling the PGA and Equalizer coefficients by the supplied values.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - which preset to use (this may be from the constants file)
+ * @param[in] pga_scale - scale factor which pga coefficients are to be multiplied
+ * @param[in] eq_scale - scale factor which equalizer coefficients are to be multiplied
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be used in lieu of @ref ProSLIC_dbgSetRXGain to dynamically
+ * change the audio gain when gain steps of 0.1dB do not suffice, or if an attenuation
+ * > 30dB is required.
+ *
+ * The following code * fragment will scale the TX audio gain by a factor of (0.707)*(0.500)
+ *
+ * @code
+ * uInt32 pga_gain_scale = 707;
+ * uInt32 eq_gain_scale = 500;
+ * ProSLIC_RXAudioGainScale(pProslic,DEFAULT_PRESET,pga_gain_scale,eq_gain_scale);
+ * @endcode
+ *
+ * @sa ProSLIC_TXAudioGainScale
+ */
+int ProSLIC_RXAudioGainScale (proslicChanType_ptr hProslic,int preset,
+ uInt32 pga_scale,uInt32 eq_scale);
+
+/**
+ * @brief
+ * Configures and sets the audio gains - for both RX (toward the phone) and the TX (toward the network). Unlike
+ * the @ref ProSLIC_RXAudioGainSetup and @ref ProSLIC_TXAudioGainSetup this does both the calculations and then
+ * configures the given channel in one step. It is assumed that the preset gain array is at least 2 elements in size.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] rxgain - what is the gain/loss of the RX transmit path in 1 dB units (negative = attenuation)
+ * @param[in] txgain - what is the gain/loss of the TX transmit path in 1 dB units (negative = attenuation)
+ * @param[in] preset - what is the impedance preset value
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * The following code * fragment will set the RX audio gain to -1 dB snd TX audio gain to -5 dB:
+ *
+ * @code
+ * ProSLIC_AudioGain(myChannel, -1, -5, MY_IMPEDENCE);
+ * @endcode
+ *
+ * @sa ProSLIC_TXAudioGainSetup ProSLIC_dbgSetRXGain ProSLIC_dbgSetRXGain ProSLIC_dbgSetTXGain
+ */
+
+int ProSLIC_AudioGainSetup (proslicChanType_ptr hProslic,int32 rxgain,
+ int32 txgain,int preset);
+
+/**
+ * @brief
+ * This function calculates the preset values for the RX audio (toward the telephone) - it does NOT set the
+ * actual register values. For that, please use @ref ProSLIC_RXAudioGainSetup .
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] gain - gain to set the preset values to.
+ * @param[in] impedance_preset - impedence preset in the constants file.
+ * @param[in] audio_gain_preset - index to the audio gain preset to store the value.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_RXAudioGainSetup ProSLIC_AudioGainSetup ProSLIC_dbgSetTXGain
+ */
+
+int ProSLIC_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset);
+
+/**
+ * @brief
+ * This function calculates the preset values for the TX audio (toward the network) - it does NOT set the
+ * actual register values. For that, please use @ref ProSLIC_TXAudioGainSetup .
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] gain - gain to set the preset values to.
+ * @param[in] impedance_preset - impedance preset in the constants file.
+ * @param[in] audio_gain_preset - index to the audio gain preset to store the value.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_TXAudioGainSetup ProSLIC_AudioGainSetup ProSLIC_dbgSetRXGain
+ */
+
+int ProSLIC_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset);
+
+/** @} GAIN_CONTROL */
+/** @} AUDIO_CONTROL */
+/** @} PROSLIC_AUDIO */
+
+/*****************************************************************************/
+/** @defgroup HC_DETECT Hook Change detection
+ *
+ * This function group has routines used to implement a pulse dial, hook flash
+ * and general hook change detection. The outline of how to use these
+ * functions is as follows:
+ *
+ * - Initialize the data structure w/ @ref ProSLIC_InitializeHookChangeDetect
+ * - When hook change is detected or if there has been no activity for a minimum
+ * of the interdigit time, call @ref ProSLIC_HookChangeDetect. Keep on calling
+ * the function until we have a return code not equal to SI_HC_NEED_MORE_POLLS.
+ * Again, the function should be called, when no hook activity is detected at
+ * minimum of the interdigit time.
+ *
+ * General theory (pulse digit):
+ *
+ * ---|___|-----|__|---------
+ *
+ * A B C B D
+ *
+ * A - Offhook (time unknown)
+ * B - Onhook (break time)
+ * C - Offhook (make time)
+ * D - Interdigit delay
+ *
+ * We report after D occurs a pulse digit as long as the duration for B
+ * is met.
+ *
+ * For hook flash, we are looking at
+ *
+ * ----|________________|-----------
+ *
+ *
+ * Here we're looking for the pulse width meets a certain min/max time. If the
+ * time is exceeded, then we have likely a onhook or offhook event.
+ *
+ * @note This set of functions require that the elapsed timer functions
+ * documented in @ref PROSLIC_CUSTOMER_TIMER are implemented.
+ *
+ * @{
+ */
+
+/**
+ * @brief
+ * Initialize pulse dial/hook detection parameters.
+ *
+ * @param[in,out] pPulse - the structure that is to be initialized. Refer to your target market's pulse dial standard for exact values.
+ * @param[in] hookTime - a timer object suitable to be passed to a function of type @ref system_timeElapsed_fptr
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_InitializeHookChangeDetect(hookChangeType *pPulse,void *hookTime);
+
+/**
+ * @brief
+ * Implements pulse dial detection and should be called at every hook transition and after the minimum interdigit delay time (should continue calling until
+ * the function returns back with a value other than SI_HC_NEED_MORE_POLLS.
+ *
+ * @param[in] pProslic - which channel had a hook transition.
+ * @param[in] pPulsedialCfg - what is the criteria to determine on/off hook states.
+ * @param[in,out] pPulseDialData - contians the timer information that was set in
+ * @ref ProSLIC_InitializeHookChangeDetect as well as the pulse digit detected
+ *
+ * @retval int - either SI_HC_xxx values or a value between 1-10 for the number of pulses detected. In most cases, a 0 is 10 pulses. Please refer to
+ * your country's pulse dial standard for exact encoding.
+ */
+
+uInt8 ProSLIC_HookChangeDetect (proslicChanType *pProslic,
+ hookChange_Cfg *pPulsedialCfg, hookChangeType *pPulseDialData);
+
+/** @} HC_DETECT */
+
+/*****************************************************************************/
+/** @addtogroup PROSLIC_AUDIO
+ * @{
+ * @defgroup PROSLIC_DTMF_DECODE DTMF Decode
+ * This section covers DTMF decoding.
+ *
+ * @note Not all chipsets support this capability. Please review your chipset
+ * documentation to confirm this capability is supported.
+ * @{
+ */
+
+/**
+ * @brief
+ * Read/Decode DTMF digits. The "raw" hexcode is returned in this function and would require
+ * further processing. For example, on the Si3217x chipset, the following mapping exists:
+ *
+ * DTMF Digit | API output value
+ * :-|:---
+ * 0 | 0xA
+ * 1 | 1
+ * 2 | 2
+ * 3 | 3
+ * 4 | 4
+ * 5 | 5
+ * 6 | 6
+ * 7 | 7
+ * 8 | 8
+ * 9 | 9
+ * A | 0xD
+ * B | 0xE
+ * C | 0xF
+ * D | 0
+ * \*| 0xB
+ * \# |0xC
+ *
+ * @note This function is only valid after @ref IRQ_DTMF occurred and should be called shortly
+ * thereafter.
+ *
+ * @warning Not all ProSLIC chipsets have a DTMF decoder. Please review your chipset to make
+ * sure this capability exists.
+ *
+ * @param[in] hProslic - which channel is to be decoded.
+ * @param[out] pDigit - "raw" DTMF value (see comments in description)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ *
+ */
+
+int ProSLIC_DTMFReadDigit (proslicChanType_ptr hProslic,uInt8 *pDigit);
+
+/** @} PROSLIC_DTMF_DECODE */
+/** @} PROSLIC_AUDIO */
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_POWER_CONVERTER Power Converter control
+ * @{
+ */
+/**
+* @brief
+* Powers all DC/DC converters sequentially with delay to minimize peak power draw on VDC.
+* @param[in] hProslic - which channel to change state.
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_PowerDownConverter
+*
+*/
+
+int ProSLIC_PowerUpConverter(proslicChanType_ptr hProslic);
+
+/**
+* @brief
+* Safely power down dcdc converter after ensuring linefeed
+* is in the open state. Test power down by setting error
+* flag if detected voltage does no fall below 5v.
+*
+* @param[in] hProslic - which channel to change state.
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_PowerUpConverter
+*
+*/
+
+int ProSLIC_PowerDownConverter(proslicChanType_ptr hProslic);
+
+/**
+* @brief
+* Set channel flag to indicate that the polarity of the
+* DC-DC converter drive signal is to be inverted from what
+* is indicated in the General Parameters. This inversion is
+* relative to the polarity established by the General Parameters,
+* not an absolute polarity.
+*
+*
+* @param[in] hProslic - which channel to change state.
+* @param[in] flag - inversion flag (1 - inverted, 0 - no inversion)
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_PowerUpConverter
+*
+*/
+int ProSLIC_SetDCDCInversionFlag(proslicChanType_ptr hProslic, uInt8 flag);
+
+
+/** @} PROSLIC_POWER_CONVERTER */
+/*****************************************************************************/
+/** @defgroup PROSLIC_LB_CALIBRATION LB Calibration
+ * @{
+ */
+
+/**
+ * @brief
+ * Run canned longitudinal balance calibration.
+ *
+ * @param[in] pProslic - start channel to start from for calibration.
+ * @param[in] size - number of channels to calibrate
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note
+ * Use the @ref ProSLIC_Init function to perform all calibrations except Longitudinal Balance (LB).
+ * Use the @ref ProSLIC_LBCal function to perform LB calibration. LB Calibration typically needs
+ * to execute LB calibration once per system setup without a load connected. The LB calibration
+ * results can be stored in non-volatile storage (flash, eeprom) and retrieved during your normal
+ * ProSLIC initialization.
+ *
+* @sa ProSLIC_GetLBCalResult ProSLIC_LoadPreviousLBCal ProSLIC_LoadPreviousLBCalPacked ProSLIC_GetLBCalResultPacked
+ */
+
+int ProSLIC_LBCal (proslicChanType_ptr *pProslic, int size);
+
+/**
+ * @brief
+ * This function returns the coefficient results of the last LB calibration.
+ *
+ * @param[in] pProslic - which channel to retrieve the values from.
+ * @param[out] result1 - results read from the last calibration
+ * @param[out] result2 - results read from the last calibration
+ * @param[out] result3 - results read from the last calibration
+ * @param[out] result4 - results read from the last calibration
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_LBCal ProSLIC_LoadPreviousLBCal ProSLIC_LoadPreviousLBCalPacked ProSLIC_LBCal ProSLIC_GetLBCalResultPacked
+*/
+
+int ProSLIC_GetLBCalResult (proslicChanType *pProslic,int32 *result1,
+ int32 *result2,int32 *result3,int32 *result4);
+
+/**
+ * @brief
+ * This function loads previously stored LB calibration results to the appropriate ProSLIC
+ * RAM locations.
+ *
+ * @param[in] pProslic - which channel to program the values
+ * @param[in] result1 - values to be written
+ * @param[in] result2 - values to be written
+ * @param[in] result3 - values to be written
+ * @param[in] result4 - values to be written
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_LBCal ProSLIC_LoadPreviousLBCalPacked ProSLIC_LBCal ProSLIC_GetLBCalResult ProSLIC_GetLBCalResultPacked
+*/
+
+int ProSLIC_LoadPreviousLBCal (proslicChanType *pProslic,int32 result1,
+ int32 result2,int32 result3,int32 result4);
+
+/**
+ * @brief
+ * This function returns the results of the last LB calibration packed into single int32.
+ *
+ * @param[in] pProslic - which channel to retrieve the values from.
+ * @param[out] result - results - where to store the value
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_LBCal ProSLIC_LoadPreviousLBCal ProSLIC_LoadPreviousLBCalPacked ProSLIC_LBCal
+*/
+
+int ProSLIC_GetLBCalResultPacked (proslicChanType *pProslic,int32 *result);
+
+/**
+ * @brief
+ * This function loads previously stored LB calibration results that are in the packed format.
+ *
+ * @param[in] pProslic - which channel to retrieve the values from.
+ * @param[in] result - results read from @ref ProSLIC_GetLBCalResultPacked
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+* @sa ProSLIC_LBCal ProSLIC_LoadPreviousLBCal ProSLIC_LBCal ProSLIC_GetLBCalResultPacked
+*
+*/
+
+int ProSLIC_LoadPreviousLBCalPacked (proslicChanType *pProslic,int32 *result);
+
+/** @} PROSLIC_LB_CALIBRATION */
+
+
+/*****************************************************************************/
+/** @addtogroup DIAGNOSTICS
+ * @{
+ */
+
+/**
+ * @brief
+ * This function can be used to verify that the SPI interface is functioning
+ * properly by performing a series of read back tests. This test DOES modify
+ * certain registers, so a reinitialization will be required. This test is
+ * recommended only for development use.
+ *
+ * @param[in] pProslic - This should point to the channel that is to be verified.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error amd will typically return back
+ * @ref RC_SPI_FAIL if a SPI failure occured.
+ */
+
+int ProSLIC_VerifyControlInterface (proslicChanType_ptr pProslic);
+
+/** @addtogroup PSTN_CHECK PSTN Check
+ * @{
+ */
+
+/**
+ * @brief
+ * Allocates memory for a PSTN check object. One channel object is needed per
+ * ProSLIC channel.
+ *
+ * @param[in,out] pstnCheckObj - pointer to the object that is to be initialized.
+ * @param[in] num_objs - number of objects to allocate
+ *
+ * @retval 0 = OK
+ */
+
+int ProSLIC_CreatePSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj,
+ unsigned int num_objs);
+#define ProSLIC_CreatePSTNCheckObj(PTRPTR) ProSLIC_CreatePSTNCheckObjs((PTRPTR), 1)
+
+/**
+ * @brief
+ * Allocates memory for a differential PSTN check object. One channel object is needed per
+ * ProSLIC channel.
+ *
+ * @param[in,out] pstnCheckObj - pointer to the object that is to be initialized.
+ * @param[in] num_objs - number of objects to allocate
+ *
+ * @retval 0 = OK
+ */
+
+int ProSLIC_CreateDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
+ *pstnCheckObj, unsigned int num_objs);
+#define ProSLIC_CreateDiffPSTNCheckObj(PTRPTR) ProSLIC_CreateDiffPSTNCheckObjs((PTRPTR), 1)
+
+/**
+ * @brief
+ * Destroys a PSTN check object and deallocates memory.
+ *
+ * @param[in] pstnCheckObj - object to deallocate.
+ *
+ * @retval 0 = OK
+ */
+
+#define ProSLIC_DestroyPSTNCheckObj ProSLIC_DestroyPSTNCheckObjs
+int ProSLIC_DestroyPSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj);
+
+/**
+ * @brief
+ * Destroys a differential PSTN check object and deallocates memory.
+ *
+ * @param[in] pstnCheckObj - object to deallocate.
+ *
+ * @retval 0 = OK
+ */
+
+#define ProSLIC_DestroyDiffPSTNCheckObj ProSLIC_DestroyDiffPSTNCheckObjs
+int ProSLIC_DestroyDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
+ *pstnCheckObj);
+
+/**
+ * @brief
+ * Initialize pstnCheckObj structure members
+ *
+ * @param[in] pstnCheckObj - which object to initialize
+ * @param[in] avgThresh - Average current threshold that indicates a PSTN is present (uA).
+ * @param[in] singleThresh - Single current threshold that indicates a PSTN is present (uA).
+ * @param[in] samples - number of samples to collect
+ * @retval 0 = OK
+ */
+
+int ProSLIC_InitPSTNCheckObj(proslicPSTNCheckObjType_ptr pstnCheckObj,
+ int32 avgThresh, int32 singleThresh, uInt8 samples);
+
+/**
+ * @brief
+ * This function initializes a differential PSTN detection object.
+ *
+ * @param[in,out] pstnDiffCheckObj - object to be initialized
+ * @param[in] preset1 - DC Feed preset to be used for first loop I/V measurement
+ * @param[in] preset2 - DC Feed preset to be used for second loop I/V measurement
+ * @param[in] entry_preset - restore_preset DC Feed preset that is restored after PSTN check is complete.
+ * @param[in] femf_enable - Flag to enable OPEN state hazardous voltage measurement (0 = disabled, 1 = enabled)
+ * @retval 0 = OK
+ */
+
+int ProSLIC_InitDiffPSTNCheckObj(proslicDiffPSTNCheckObjType_ptr
+ pstnDiffCheckObj, int preset1, int preset2, int entry_preset, int femf_enable);
+
+/**
+ * @brief
+ * This function monitors longitudinal current (average and single sample) to quickly identify
+ * the presence of a live PSTN line. Sufficient polling needs to occur in order to quickly determine
+ * if a PSTN line is preset or not.
+ *
+ * @param[in] pProslic - which channel to run this test on.
+ * @param[in] pPSTNCheck - the initialized data structure that contains the intermediate results of this test.
+ * @retval 0 = no PSTN detected/thresholds have not been exceeded, 1 = PSTN detected, state machine reset.
+ *
+ * @note
+ * If wanting to restart the test, one will need to call @ref ProSLIC_InitPSTNCheckObj again. However, if the
+ * number of samples exceeds the buffer then the function will "wrap".
+ */
+
+int ProSLIC_PSTNCheck(proslicChanType *pProslic,
+ proslicPSTNCheckObjType *pPSTNCheck);
+
+/**
+ * @brief
+ * This function monitors for a foreign voltage (if enabled) and measures the differential I/V
+ * characteristics of the loop at 2 unique settings to detect a foreign PSTN. It is assumed that polling will
+ * occur at the configured value found in @ref PSTN_DET_POLL_RATE.
+ *
+ * @param[in] pProslic - channel to be monitored
+ * @param[in,out] pPSTNCheck - pointer to an initialized structure that is used by the function to
+ * store state information.
+ * @retval int @ref RC_NONE - test is in progress, @ref RC_COMPLETE_NO_ERR - test complete, no errors, @ref RC_PSTN_OPEN_FEMF - detected foreign voltage, RC_CHANNEL_TYPE_ERR = a non-ProSLIC device was called to perform this function
+ */
+int ProSLIC_DiffPSTNCheck(proslicChanType *pProslic,
+ proslicDiffPSTNCheckObjType *pPSTNCheck);
+
+/** @} PSTN_CHECK */
+/** @} DIAGNOSTICS*/
+
+/*****************************************************************************/
+/** @defgroup PROSLIC_DCFEED DC Feed Setup and control
+ * @{
+ */
+
+/**
+ * @brief
+ * Configures the DC feed from a preset.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] preset - the preset to use
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be disabled by @ref DISABLE_DCFEED_SETUP
+ */
+
+int ProSLIC_DCFeedSetup (proslicChanType_ptr hProslic,int preset);
+
+/**
+ * @brief
+ * Configures the DC feed from a preset.
+ *
+ * @param[in] hProslic - which channel to configure
+ * @param[in] cfg - pointer to preset storage structure
+ * @param[in] preset - the preset to use
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @note This function can be disabled by @ref DISABLE_DCFEED_SETUP
+ */
+int ProSLIC_DCFeedSetupCfg (proslicChanType_ptr hProslic,
+ ProSLIC_DCfeed_Cfg *cfg, int preset);
+
+/**
+ * @brief
+ * This function allows one to adjust the DC open circuit voltage level dynamically. Boundary checking is done.
+ *
+ * @note This function does NOT modify the register sets needed, it calculates the correct values and stores
+ * them in the correct preset. Use @ref ProSLIC_DCFeedSetup to program the device with the new values.
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] v_vlim_val - absolute voltage level
+ * @param[in] preset - DC Feed preset to be modified.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_dbgSetDCFeedIloop ProSLIC_DCFeedSetup
+ */
+
+int ProSLIC_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
+ int32 preset);
+
+/**
+ * @brief
+ * This function allows one to adjust the loop current level dynamically. Boundary checking is done.
+ *
+ * @note This function does NOT modify the register sets needed, it calculates the correct values and stores
+ * them in the correct preset. Use @ref ProSLIC_DCFeedSetup to program the device with the new values.
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] i_ilim_val - loop current level
+ * @param[in] preset - DC Feed preset to be modified.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_dbgSetDCFeedVopen ProSLIC_DCFeedSetup
+ */
+
+int ProSLIC_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
+ int32 preset);
+
+/**
+ * @brief
+ * This function allows one to enable/disable power savings mode found on some of the chipsets. This allows one
+ * to change the default value set in the GUI config tool.
+ *
+ * @param[in] pProslic - which channel to configure
+ * @param[in] pwrsave - power savings mode enabled or disabled - value expected: @ref PWRSAVE_DISABLE or @ref PWRSAVE_ENABLE
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int ProSLIC_SetPowersaveMode(proslicChanType *pProslic, int pwrsave);
+
+/** @} PROSLIC_DCFEED */
+
+/*****************************************************************************/
+/** @defgroup MESSAGE_WAITING Message Waiting Indicator routines
+ * @{
+ */
+
+/**
+ * @brief
+ * Configure optional MWI voltage settings. Default value is 95v.
+ *
+ * @details
+ * Set MWI flashing voltage level (Vpk).
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] hProslic - channel to modify
+ * @param[in] vpk_mag - MWI voltage level (vpk) (no change is made if 0)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_MWISetV (proslicChanType_ptr hProslic,uInt16 vpk_mag);
+
+/**
+ * @brief
+ * Enables message waiting indicator feature
+ *
+ * @details
+ * Message waiting (neon flashing) enabled if device is in the onhook state.
+ * Otherwise, function will not execute and return RC_MWI_ENABLE_FAIL. This
+ * function must be called to ENABLE MWI prior to calling ProSLIC_MWI to toggle
+ * the voltage level on TIP-RING.
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] hProslic - channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_MWIEnable (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * Disables message waiting indicator feature
+ *
+ * @details
+ * Message waiting (neon flashing) disable. Turns off flashing and disabled
+ * MWI feature.
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] hProslic - channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_MWIDisable (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * Implements message waiting indicator
+ *
+ * @details
+ * Message waiting (neon flashing) state toggling. If MWI feature has not been
+ * enabled by calling ProSLIC_SetMWIEnable(), then this function will return
+ * RC_MWI_NOT_ENABLED
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] hProslic - channel to modify
+ * @param[in] flash_on - 0 = lamp off, 1 = lamp on.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_SetMWIState(proslicChanType_ptr hProslic,uInt8 flash_on);
+
+/**
+ * @brief
+ * Intializes message waiting indicator with ramp configurability
+ *
+ * @details
+ * Message waiting (neon flashing) initialization. If MWI feature has not been
+ * enabled by calling ProSLIC_SetMWIEnable(), then this function will return
+ * RC_MWI_NOT_ENABLED
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] pProslic - channel to modify
+ * @param[in] steps - number of steps in ramp, tick duration is time of one step
+ * @param[in] onTime - number of ticks MWI is in the ON state
+ * @param[in] offTime - number of ticks MWI is in the OFF state
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_MWIRampStart(proslicChanType_ptr pProslic, uInt32 steps, uInt32 onTime, uInt32 offTime);
+
+/**
+ * @brief
+ * Implements message waiting indicator with ramp between ON and OFF states
+ *
+ * @details
+ * Message waiting (neon flashing) polling function. If MWI feature has not been
+ * enabled by calling ProSLIC_SetMWIEnable(), then this function will return
+ * RC_MWI_NOT_ENABLED
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] pProslic - channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_MWIRampPoll(proslicChanType_ptr pProslic);
+
+/**
+ * @brief
+ * Restores ramping message waiting indicator state
+ *
+ * @details
+ * Message waiting (neon flashing) stop function. If MWI feature has not been
+ * enabled by calling ProSLIC_SetMWIEnable(), then this function will return
+ * RC_MWI_NOT_ENABLED
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] pProslic - channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_MWIRampStop(proslicChanType_ptr pProslic);
+
+/**
+ * @brief
+ * Read MWI output state
+ *
+ * @details
+ * Message waiting (neon flashing) state read. If MWI feature has not been
+ * enabled by calling ProSLIC_SetMWIEnable(), then this function will return
+ * RC_MWI_NOT_ENABLED
+ *
+ * @note
+ * Proper patch must be loaded for this feature to work properly. Code does not
+ * automatically verify that this patch is loaded.
+ *
+ * @param[in] hProslic - channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_GetMWIState(proslicChanType_ptr hProslic);
+
+/** @} MESSAGE_WAITING */
+
+/*****************************************************************************/
+/** @defgroup MISC MISC. routines
+ * @{
+ */
+
+/**
+ * @brief
+ * This function initiates PLL free run mode.
+ *
+ * @param[in] hProslic - which channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_PLLFreeRunStart (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function terminates PLL free run mode.
+ *
+ * @param[in] hProslic - which channel to modify
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_PLLFreeRunStop (proslicChanType_ptr hProslic);
+
+/**
+ * @brief
+ * This function returns PLL free run status.
+ *
+ * @param[in] hProslic - which channel to report upon.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int ProSLIC_GetPLLFreeRunStatus (proslicChanType_ptr hProslic);
+
+/**
+ *
+ * @brief
+ * Sets the ProSLIC into User Access Mode (UAM) on parts that support this. This is mainly
+ * used internally within the API.
+ *
+ * @param[in] pProslic - which channel to modify
+ * @param[in] isEnabled - is the User Access Mode enabled (NOTE: once enabled, it can not be disabled)
+ * @param[in] isBcast - is this a broadcast on the daisychain
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_SetUserMode(proslicChanType *pProslic,BOOLEAN isEnabled,
+ BOOLEAN isBcast);
+
+/*
+** @brief
+** Checks for improper ring exit (this is used internally by the API) and
+** not all chipsets need to call this.
+**
+** @param[in] pProslic - which ProSLIC to check.
+** Returns:
+** RC_NONE - Reinit not required
+** RC_REINIT_REQUIRED - Corrupted state machine - reinit required
+**
+*/
+int ProSLIC_isReinitRequired(proslicChanType *pProslic);
+
+/** @} MISC */
+/** @} */
+
+/* Hopefully customer's code will never call this function... */
+int ProSLIC_UnsupportedFeatureNoArg(proslicChanType_ptr pProslic,
+ const char *function_name);
+
+/* Helper function used by PSTN routines */
+#ifdef PSTN_DET_ENABLE
+void ProSLIC_PSTN_delay_poll(proslicTestStateType *pState, uInt16 delay);
+#endif
+
+#if defined(SI3218X) || defined(SI3226X) || defined(SI3228X) || defined(SI3217X) || defined(SI3219X)
+int ProSLIC_Calibrate(proslicChanType_ptr *hProslic, int maxChan, uInt8 *calr,
+ int maxTime);
+#endif
+/**
+ * @brief determine if the given channel is a ProSLIC or DAA
+ *
+ * @param[in,out] pProslic - channel to be probed.
+ * @retval PROSLIC | DAA | UNKNOWN
+ */
+int ProSLIC_identifyChannelType(proslicChanType *pProslic);
+
+/* The following functions are used as part of the chipset init functions, not meant to be called
+ outside this scope.
+*/
+int ProSLIC_ReInit_helper(proslicChanType_ptr *pProslic, int size,
+ initOptionsType init_option, int numChanPerDevice);
+int ProSLIC_VerifyMasterStat(proslicChanType_ptr);
+
+void ProSLIC_LoadSupportRAM(proslicChanType *pProslic, uInt8 channel,
+ const uInt16 *address, const ramData *data);
+
+#endif /*end ifdef PROSLIC_H*/
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/proslic_tstin.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/proslic_tstin.h
new file mode 100644
index 0000000..0283473
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/proslic_tstin.h
@@ -0,0 +1,437 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Author(s):
+ * cdp
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the header file for the inward test implementations.
+ *
+ */
+#ifndef PROSLIC_TSTIN_H
+#define PROSLIC_TSTIN_H
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "proslic.h"
+
+/** @addtogroup DIAGNOSTICS
+ * @{
+ */
+/** @defgroup PROSLIC_TSTIN ProSLIC Inward Tests (Test-In)
+ * This section documents functions and data structures related to the
+ * ProSLIC/FXS inward test implementations.
+ * @{
+ */
+
+#define MIN_RINGING_SAMPLES 16 /**< Minimum number of ringing samples for measuring ring amplitude */
+#define MAX_RINGING_SAMPLES 255 /**< Maximum number of ringing samples for measuring ring amplitude */
+#define MIN_RINGING_SAMPLE_INTERVAL 1 /**< Minimum sample interval for measuring ring amplitude */
+#define MAX_RINGING_SAMPLE_INTERVAL 10 /**< Maximum sample interval for measuring ring amplitude */
+
+/**
+* Test-In results status
+*/
+enum
+{
+ TSTIN_RESULTS_INVALID,
+ TSTIN_RESULTS_VALID
+};
+
+/**
+* PCM format options
+*/
+enum
+{
+ PCM_8BIT,
+ PCM_16BIT
+};
+
+/**
+* Abort if Line-in-use option
+*/
+enum
+{
+ ABORT_LIU_DISABLED,
+ ABORT_LIU_ENABLED
+};
+
+/**
+* Check for loop closure option
+*/
+enum
+{
+ LCR_CHECK_DISABLED,
+ LCR_CHECK_ENABLED
+};
+
+/**
+* Check for ringtrip option
+*/
+enum
+{
+ RTP_CHECK_DISABLED,
+ RTP_CHECK_ENABLED
+};
+
+
+/**
+ * Defines generic test limit/value/status structure
+ */
+typedef struct
+{
+ int32 lowerLimit; /**< Lower test limit */
+ int32 upperLimit; /**< Upper test limit */
+ int32 value; /**< Numeric test result */
+ uInt8 testResult; /**< 0 - Fail, 1 - pass */
+} proslicTestObj;
+
+/**
+ * Defines structure for PCM Loopback Test
+ */
+typedef struct
+{
+ BOOLEAN testEnable; /**< Gate execution/updating of results with this flag */
+ BOOLEAN pcmLpbkEnabled; /**< Indicates if test data is valid (1) or stale (0) */
+ BOOLEAN pcm8BitLinear; /**< Set to use 8 bit linear mode (used if normally using ulaw or alaw) */
+ uInt8 pcmModeSave; /**< Store entry PCMMODE value */
+ uInt8 testResult; /**< OR of all test results in this structure */
+} proslicPcmLpbkTest;
+
+
+/**
+ * Defines structure for DC Feed Test
+ */
+typedef struct
+{
+ BOOLEAN testEnable; /**< Gate execution/updating of results with this flag */
+ BOOLEAN testDataValid; /**< Indicates if test data is valid (1) or stale (0) */
+ BOOLEAN abortIfLineInUse; /**< Abort test if LCR set at the start of test. Leaves results invalid */
+ BOOLEAN applyLcrThresh; /**< Apply alternate LCR thresholds to ensure LCR event occurs */
+ uInt32
+ altLcrOffThresh; /**< Optional LCROFFHK threshold to apply during test */
+ uInt32 altLcrOnThresh; /**< Optional LCRONHK threshold to apply during test */
+ BOOLEAN lcrStatus; /**< Indicates LCR status after applying test load */
+ proslicTestObj dcfeedVtipOnhook; /**< On-hook VTIP test results */
+ proslicTestObj dcfeedVringOnhook; /**< On-hook VRING test results */
+ proslicTestObj dcfeedVloopOnhook; /**< On-hook VLOOP test results */
+ proslicTestObj dcfeedVbatOnhook; /**< On-hook VBAT test results */
+ proslicTestObj dcfeedItipOnhook; /**< On-hook ITIP test results */
+ proslicTestObj dcfeedIringOnhook; /**< On-hook IRING test results */
+ proslicTestObj dcfeedIloopOnhook; /**< On-hook ILOOP test results */
+ proslicTestObj dcfeedIlongOnhook; /**< On-hook ILONG test results */
+ proslicTestObj dcfeedVtipOffhook; /**< Off-hook VTIP test results */
+ proslicTestObj dcfeedVringOffhook; /**< Off-hook VRING test results */
+ proslicTestObj dcfeedVloopOffhook; /**< Off-hook VLOOP test results */
+ proslicTestObj dcfeedVbatOffhook; /**< Off-hook VBAT test results */
+ proslicTestObj dcfeedItipOffhook; /**< Off-hook ITIP test results */
+ proslicTestObj dcfeedIringOffhook; /**< Off-hook IRING test results */
+ proslicTestObj dcfeedIloopOffhook; /**< Off-hook ILOOP test results */
+ proslicTestObj dcfeedIlongOffhook; /**< Off-hook ILONG test results */
+ uInt8 testResult; /**< OR of all test results in this structure */
+} proslicDcFeedTest;
+
+
+/**
+ * Defines structure for Ringing Test
+ */
+typedef struct
+{
+ BOOLEAN testEnable; /**< Gate execution/updating of results with this flag */
+ BOOLEAN testDataValid; /**< Indicates if test data is valid (1) or stale (0) */
+ BOOLEAN abortIfLineInUse; /**< Abort test if LCR set at the start of test. Leaves results invalid */
+ uInt16 numSamples; /**< Number of samples taken */
+ uInt8
+ sampleInterval; /**< Sample interval (in ms - range 1 to 100) */
+ BOOLEAN ringtripTestEnable; /**< Enable ringtrip test */
+ BOOLEAN rtpStatus; /**< RTP Bit */
+ proslicTestObj ringingVac; /**< Ringing AC Voltage test results */
+ proslicTestObj ringingVdc; /**< Ringing DC Voltage test results */
+ uInt8 testResult; /**< OR of all test results in this structure */
+} proslicRingingTest;
+
+/**
+ * Defines structure for Battery Test
+ */
+typedef struct
+{
+ BOOLEAN testEnable; /**< Gate execution/updating of results with this flag */
+ BOOLEAN testDataValid; /**< Indicates if test data is valid (1) or stale (0) */
+ proslicTestObj vbat; /**< VBAT test results */
+ uInt8 testResult; /**< OR of all test results in this structure */
+} proslicBatteryTest;
+
+/**
+ * Defines structure for Audio Test
+ */
+typedef struct
+{
+ BOOLEAN testEnable; /**< Gate execution/updating of results with this flag */
+ BOOLEAN testDataValid; /**< Indicates if test data is valid (1) or stale (0) */
+ BOOLEAN abortIfLineInUse; /**< Abort test if LCR set at the start of test. Leaves results invalid */
+ int32
+ zerodBm_mVpk; /**< 0dBm voltage (in mVpk) of ref impedance */
+ proslicTestObj txGain; /**< TX path gain test results */
+ proslicTestObj rxGain; /**< RX path gain test results */
+ uInt8 testResult; /**< OR of all test results in this structure */
+} proslicAudioTest;
+
+
+/**
+ * Defines structure for all tests
+ */
+typedef struct
+{
+ proslicPcmLpbkTest pcmLpbkTest;
+ proslicDcFeedTest dcFeedTest;
+ proslicRingingTest ringingTest;
+ proslicBatteryTest batteryTest;
+ proslicAudioTest audioTest;
+} proslicTestInObjType;
+
+typedef proslicTestInObjType *proslicTestInObjType_ptr;
+
+
+/**
+ * @brief
+ * Allocate memory and initialize the given structure.
+ *
+ * @param[in,out] *pTstin - the structure to initialize
+ * @param[in] num_objs - number of Testin structures to allocate.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa ProSLIC_DestroyTestInObjs
+ */
+int ProSLIC_createTestInObjs(proslicTestInObjType_ptr *pTstin, uInt32 num_objs);
+#define ProSLIC_createTestInObj(X) ProSLIC_createTestInObjs((X),1)
+
+/**
+ * @brief
+ * Free memory reserved by the given structure.
+ *
+ * @param[in,out] *pTstin - the structure to initialize
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_destroyTestInObjs(proslicTestInObjType_ptr *pTstin);
+#define ProSLIC_destroyTestInObj ProSLIC_destroyTestInObjs
+
+/**
+ * @brief
+ * Enable PCM loopback.
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in,out] pTstin - all control, limits, and results
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInPCMLpbkEnable(proslicChanType_ptr pProslic,
+ proslicTestInObjType_ptr pTstin);
+
+
+/**
+ * @brief
+ * Disable PCM loopback.
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in,out] pTstin - all control, limits, and results
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInPCMLpbkDisable(proslicChanType_ptr pProslic,
+ proslicTestInObjType_ptr pTstin);
+
+
+/**
+ * @brief
+ * DC Feed Test - the pTstin->dcFeedTest contains control, limits and test result information.
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in,out] pTstin - all control, limits, and results
+ *
+ * @retval int - error from @ref errorCodeType
+ * @retval RC_TEST_PASSED indicates test completed and passed
+ * @retval RC_TEST_FAILED indicates test completed and failed
+ * @retval RC_UNSUPPORTED_FEATURE indicates feature not supported on this device
+ * @retval RC_TEST_DISABLED indicates test has not been initialized/enabled
+ * @retval RC_LINE_IN_USE indicates LCS already set
+ *
+ */
+int ProSLIC_testInDCFeed(proslicChanType_ptr pProslic,
+ proslicTestInObjType_ptr pTstin);
+
+
+/**
+ * @brief
+ * Ringing and Ringtrip Test
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in,out] pTstin - all control, limits, and results
+ *
+ * @retval int - error from @ref errorCodeType
+ * @retval RC_TEST_PASSED indicates test completed and passed
+ * @retval RC_TEST_FAILED indicates test completed and failed
+ * @retval RC_UNSUPPORTED_FEATURE indicates feature not supported on this device
+ * @retval RC_TEST_DISABLED indicates test has not been initialized/enabled
+ * @retval RC_LINE_IN_USE indicates LCS already set
+ *
+ */
+int ProSLIC_testInRinging(proslicChanType_ptr pProslic,
+ proslicTestInObjType_ptr pTstin);
+
+/**
+ * @brief
+ * Battery Test -
+ * pTstin contains both the configuration data and test results.
+ * See **pTstin->batteryTest.testResult - Pass/Fail result
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in,out] pTstin - configuration and test results
+ *
+ * @retval int - error from @ref errorCodeType
+ * @retval RC_TEST_PASSED indicates test completed and passed
+ * @retval RC_TEST_FAILED indicates test completed and failed
+ * @retval RC_UNSUPPORTED_FEATURE indicates feature not supported on this device
+ * @retval RC_TEST_DISABLED indicates test has not been initialized/enabled
+ *
+ */
+int ProSLIC_testInBattery(proslicChanType_ptr pProslic,
+ proslicTestInObjType_ptr pTstin);
+
+/**
+ * @brief
+ * Audio level inward test. pTstin->audioTest contains all control, limits and results.
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in,out] pTstin - all control, limits, and results
+ *
+ * @retval int - error from @ref errorCodeType
+ * @retval RC_TEST_PASSED indicates test completed and passed
+ * @retval RC_TEST_FAILED indicates test completed and failed
+ * @retval RC_UNSUPPORTED_FEATURE indicates feature not supported on this device
+ * @retval RC_TEST_DISABLED indicates test has not been initialized/enabled
+ * @retval RC_LINE_IN_USE indicates LCS already set
+ *
+ */
+int ProSLIC_testInAudio(proslicChanType_ptr pProslic,
+ proslicTestInObjType_ptr pTstin);
+
+/**
+ * @brief
+ * Initialize/Enable PCM Loopback Test. Links test config/limits
+ * to inward test data structure.
+ *
+ * @param[in,out] pTstin->pcmLpbkTest - all control, limits, and results
+ * @param[in] pcmLpbkTest - test config and limits to link to pTstin->pcmLpbkTest
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInPcmLpbkSetup(proslicTestInObjType *pTstin,
+ proslicPcmLpbkTest *pcmLpbkTest);
+
+/**
+ * @brief
+ * Initialize/Enable DC Feed Test. Links test config/limits
+ * to inward test data structure.
+ *
+ * @param[in,out] pTstin->dcFeedTest - all control, limits, and results
+ * @param[in] dcFeedTest - test config and limits to link to pTstin->dcFeedTest
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInDcFeedSetup(proslicTestInObjType *pTstin,
+ proslicDcFeedTest *dcFeedTest);
+
+/**
+ * @brief
+ * Initialize/Enable Ringing Test. Links test config/limits
+ * to inward test data structure.
+ *
+ * @param[in,out] pTstin->ringingTest - all control, limits, and results
+ * @param[in] ringingTest - test config and limits to link to pTstin->ringingTest
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInRingingSetup(proslicTestInObjType *pTstin,
+ proslicRingingTest *ringingTest);
+
+/**
+ * @brief
+ * Initialize/Enable Battery Test. Links test config/limits
+ * to inward test data structure.
+ *
+ * @param[in,out] pTstin->batteryTest - all control, limits, and results
+ * @param[in] batteryTest - test config and limits to link to pTstin->batteryTest
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInBatterySetup(proslicTestInObjType *pTstin,
+ proslicBatteryTest *batteryTest);
+
+/**
+ * @brief
+ * Initialize/Enable Audio Test. Links test config/limits
+ * to inward test data structure.
+ *
+ * @param[in,out] pTstin->audioTest - all control, limits, and results
+ * @param[in] audioTest - test config and limits to link to pTstin->audioTest
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+int ProSLIC_testInAudioSetup(proslicTestInObjType *pTstin,
+ proslicAudioTest *audioTest);
+
+
+/**
+ * @brief
+ * Debug utility to log presently loaded test limits
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in] pTstin - inward test data structure
+ *
+ * @retval int - error from @ref errorCodeType
+ * @retval RC_NONE indicates no error.
+ * @retval RC_UNSUPPORTED_FEATURE indicates feature not supported on this device
+ */
+int ProSLIC_testInPrintLimits(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin);
+
+/**
+ * @brief
+ * Provide a simulated offhook using the ProSLIC test load. You would call
+ * this function twice: once to enable the simulated test load
+ * (is_testStart = TRUE) and check if the upper layer correctly detected
+ * the hook state change and possibly pass some audio. After you have
+ * completed this test/check, you would call the same function again to
+ * restore the system to normal state (is_testStart = FALSE).
+ *
+ * @note This test can only be executed one at a time. Running this on
+ * multiple channels that have different DC Feed and digital control
+ * settings will cause problems. If the all the channels have the
+ * same settings, this restriction can be loosened.
+ *
+ *
+ * @param[in] pProslic - channel data structure
+ * @param[in] is_testStart - is the the start or end of test.
+ * @param[in] timeDelayMsec - how may mSec to delay prior to returning from
+ the function.
+ *
+ * @retval int - error from @ref errorCodeType
+ * @retval RC_NONE indicates no error.
+ * @retval RC_UNSUPPORTED_FEATURE indicates feature not supported on this device
+ */
+
+int ProSLIC_testLoadTest(
+ SiVoiceChanType_ptr pProslic,
+ BOOLEAN is_testStart,
+ uint32_t timeDelayMsec);
+
+/** @} PROSLIC_TSTIN */
+/** @} DIAGNOSTICS */
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x.h
new file mode 100644
index 0000000..e2fd9d2
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x.h
@@ -0,0 +1,305 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ */
+
+#ifndef SI3218XH_H
+#define SI3218XH_H
+
+#include "proslic.h"
+
+#define SI3218X_CHAN_PER_DEVICE 1
+
+
+/*
+** Calibration Constants
+*/
+
+#define SI3218X_CAL_STD_CALR1 0xC0
+#define SI3218X_CAL_STD_CALR2 0x18
+
+/* Timeouts in 10s of ms */
+#define SI3218X_TIMEOUT_DCDC_UP 200
+#define SI3218X_TIMEOUT_DCDC_DOWN 200
+
+
+/*
+** SI3218X DataTypes/Function Definitions
+*/
+
+
+typedef ProSLIC_DCfeed_Cfg Si3218x_DCfeed_Cfg;
+
+/*
+** Si3218x General Parameter Struct
+*/
+typedef struct
+{
+ /* Flags */
+ uInt8 device_key;
+ bomOptionsType bom_option;
+ vdcRangeType vdc_range;
+ autoZcalType zcal_en;
+ pmBomType pm_bom;
+ /* Raw Parameters */
+ ramData i_oithresh_lo;
+ ramData i_oithresh_hi;
+ ramData v_ovthresh;
+ ramData v_uvthresh;
+ ramData v_uvhyst;
+ /* RAM Updates */
+ ramData dcdc_fsw_vthlo;
+ ramData dcdc_fsw_vhyst;
+ ramData p_th_hvic;
+ ramData coef_p_hvic;
+ ramData bat_hyst;
+ ramData
+ vbath_expect; /* default - this is overwritten by dc feed preset */
+ ramData
+ vbatr_expect; /* default - this is overwritten by ring preset */
+ ramData pwrsave_timer;
+ ramData pwrsave_ofhk_thresh;
+ ramData vbat_track_min; /* Same as DCDC_VREF_MIN */
+ ramData vbat_track_min_rng; /* Same as DCDC_VREF_MIN_RNG */
+ ramData dcdc_ana_scale;
+ ramData therm_dbi;
+ ramData vov_dcdc_slope;
+ ramData vov_dcdc_os;
+ ramData vov_ring_bat_dcdc;
+ ramData vov_ring_bat_max;
+ ramData dcdc_verr;
+ ramData dcdc_verr_hyst;
+ ramData pd_uvlo;
+ ramData pd_ovlo;
+ ramData pd_oclo;
+ ramData pd_swdrv;
+ ramData dcdc_uvpol;
+ ramData dcdc_rngtype;
+ ramData dcdc_ana_toff;
+ ramData dcdc_ana_tonmin;
+ ramData dcdc_ana_tonmax;
+ uInt8 irqen1;
+ uInt8 irqen2;
+ uInt8 irqen3;
+ uInt8 irqen4;
+ uInt8 enhance;
+ uInt8 auto_reg;
+} Si3218x_General_Cfg;
+
+/*
+** Defines structure for configuring pcm
+*/
+typedef struct
+{
+ uInt8 pcmFormat;
+ uInt8 widebandEn;
+ uInt8 pcm_tri;
+ uInt8 tx_edge;
+ uInt8 alaw_inv;
+} Si3218x_PCM_Cfg;
+
+/*
+** Defines structure for configuring pulse metering
+*/
+typedef struct
+{
+ ramData pm_amp_thresh;
+ uInt8 pmFreq;
+ uInt8 pmAuto;
+ ramData pmActive;
+ ramData pmInactive;
+} Si3218x_PulseMeter_Cfg;
+/*
+** Defines structure for configuring FSK generation
+*/
+typedef ProSLIC_FSK_Cfg Si3218x_FSK_Cfg;
+
+
+/*
+** Defines structure for configuring impedance synthesis
+*/
+typedef struct
+{
+ ramData zsynth_b0;
+ ramData zsynth_b1;
+ ramData zsynth_b2;
+ ramData zsynth_a1;
+ ramData zsynth_a2;
+ uInt8 ra;
+} Si3218x_Zsynth_Cfg;
+
+/*
+** Defines structure for configuring hybrid
+*/
+typedef struct
+{
+ ramData ecfir_c2;
+ ramData ecfir_c3;
+ ramData ecfir_c4;
+ ramData ecfir_c5;
+ ramData ecfir_c6;
+ ramData ecfir_c7;
+ ramData ecfir_c8;
+ ramData ecfir_c9;
+ ramData ecfir_b0;
+ ramData ecfir_b1;
+ ramData ecfir_a1;
+ ramData ecfir_a2;
+} Si3218x_hybrid_Cfg;
+
+/*
+** Defines structure for configuring GCI CI bits
+*/
+typedef struct
+{
+ uInt8 gci_ci;
+} Si3218x_CI_Cfg;
+
+/*
+** Defines structure for configuring audio eq
+*/
+
+typedef struct
+{
+ ramData txaceq_c0;
+ ramData txaceq_c1;
+ ramData txaceq_c2;
+ ramData txaceq_c3;
+
+ ramData rxaceq_c0;
+ ramData rxaceq_c1;
+ ramData rxaceq_c2;
+ ramData rxaceq_c3;
+} Si3218x_audioEQ_Cfg;
+
+/*
+** Defines structure for configuring audio gain
+*/
+typedef ProSLIC_audioGain_Cfg Si3218x_audioGain_Cfg;
+
+
+
+typedef struct
+{
+ Si3218x_audioEQ_Cfg audioEQ;
+ Si3218x_hybrid_Cfg hybrid;
+ Si3218x_Zsynth_Cfg zsynth;
+ ramData txgain;
+ ramData rxgain;
+ ramData rxachpf_b0_1;
+ ramData rxachpf_b1_1;
+ ramData rxachpf_a1_1;
+ int16 txgain_db; /*overall gain associated with this configuration*/
+ int16 rxgain_db;
+} Si3218x_Impedance_Cfg;
+
+
+
+/*
+** Defines structure for configuring tone generator
+*/
+typedef ProSLIC_Tone_Cfg Si3218x_Tone_Cfg;
+
+/*
+** Defines structure for configuring ring generator
+*/
+typedef struct
+{
+ ramData rtper;
+ ramData freq;
+ ramData amp;
+ ramData phas;
+ ramData offset;
+ ramData slope_ring;
+ ramData iring_lim;
+ ramData rtacth;
+ ramData rtdcth;
+ ramData rtacdb;
+ ramData rtdcdb;
+ ramData vov_ring_bat;
+ ramData vov_ring_gnd;
+ ramData vbatr_expect;
+ uInt8 talo;
+ uInt8 tahi;
+ uInt8 tilo;
+ uInt8 tihi;
+ ramData adap_ring_min_i;
+ ramData counter_iring_val;
+ ramData counter_vtr_val;
+ ramData ar_const28;
+ ramData ar_const32;
+ ramData ar_const38;
+ ramData ar_const46;
+ ramData rrd_delay;
+ ramData rrd_delay2;
+ ramData dcdc_vref_min_rng;
+ uInt8 ringcon;
+ uInt8 userstat;
+ ramData vcm_ring;
+ ramData vcm_ring_fixed;
+ ramData delta_vcm;
+ ramData dcdc_rngtype;
+} Si3218x_Ring_Cfg;
+
+
+
+
+
+/*
+** Function: Si3218x_RevC_GenParamUpdate
+**
+** Description:
+** Update Si3218x general parameters and other required modifications
+** to default reg/ram values
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_GenParamUpdate(proslicChanType_ptr hProslic,initSeqType seq);
+
+
+/*
+** Function: Si3217x_RevC_SelectPatch
+**
+** Description:
+** Select appropriate patch based on general parameters
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_SelectPatch(proslicChanType_ptr hProslic,
+ const proslicPatch **patch);
+
+/*
+** Function: Si3217x_RevC_ConverterSetup
+**
+** Description:
+** Program revision specific settings before powering converter
+**
+** Specifically, from general parameters and knowledge that this
+** is Rev C, setup dcff drive, gate drive polarity, and charge pump.
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_ConverterSetup(proslicChanType_ptr pProslic);
+
+/*
+** Function: Si3217x_RevC_PulseMeterSetup
+**
+** Description:
+** configure pulse metering
+*/
+int Si3218x_PulseMeterSetup (proslicChanType_ptr hProslic, int preset);
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x_intf.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x_intf.h
new file mode 100644
index 0000000..af9b057
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x_intf.h
@@ -0,0 +1,479 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Si3218x ProSLIC interface header file
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the header file for the ProSLIC driver.
+ *
+ *
+ */
+
+#ifndef SI3218X_INTF_H
+#define SI3218X_INTF_H
+#include "si3218x.h"
+
+/* The following macros are for backward compatibility */
+#define Si3218x_LoadPatch ProSLIC_LoadPatch
+#define Si3218x_ReadHookStatus ProSLIC_ReadHookStatus
+#define Si3218x_DCFeedSetup(PCHAN, NDX) Si3218x_DCFeedSetupCfg((PCHAN),Si3218x_DCfeed_Presets, (NDX))
+#define Si3218x_VerifyPatch ProSLIC_VerifyPatch
+#define Si3218x_SetPowersaveMode ProSLIC_SetPowersaveMode
+#define Si3218x_Init(PCHAN, SZ) Si3218x_Init_with_Options((PCHAN), (SZ), INIT_NO_OPT)
+#define Si3218x_LoadRegTables ProSLIC_LoadRegTables
+#define Si3218x_VerifyControlInterface ProSLIC_VefifyControlInterface
+#define Si3218x_ShutdownChannel ProSLIC_PowerDownConverter
+#define Si3218x_PowerDownConverter ProSLIC_PowerDownConverter
+#define Si3218x_Calibrate ProSLIC_Calibrate
+#define Si3218x_SetLinefeedStatusBroadcast ProSLIC_SetLinefeedStatusBroadcast
+#define Si3218x_SetLinefeedStatus ProSLIC_SetLinefeedStatus
+#define Si3218x_MWIEnable ProSLIC_MWIEnable
+#define Si3218x_MWIDisable ProSLIC_MWIDisable
+#define Si3218x_SetMWIState ProSLIC_SetMWIState
+#define Si3218x_GetMWIState ProSLIC_GetMWIState
+#define Si3218x_MWISetup(PCHAN,VPK,LCR) ProSLIC_MWISetV(PCHAN,VPK)
+
+/* DC Feed */
+#ifndef DISABLE_DCFEED_SETUP
+extern Si3218x_DCfeed_Cfg Si3218x_DCfeed_Presets[];
+#endif
+
+/*
+**
+** PROSLIC INITIALIZATION FUNCTIONS
+**
+*/
+
+/*
+** Function: PROSLIC_Init_MultiBOM
+**
+** Description:
+** Initializes the ProSLIC w/ selected general parameters
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object
+** size: number of channels
+** preset: General configuration preset
+**
+** Return:
+** none
+*/
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+int Si3218x_Init_MultiBOM (proslicChanType_ptr *hProslic,int size,int preset);
+#endif
+
+/*
+** Function: Si3218x_Init_with_Options
+**
+** Description:
+** Initializes the ProSLIC with an option.
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object
+** size - number of continuous channels to initialize
+** init_opt - which initialization type to do.
+**
+** Return:
+** none
+*/
+int Si3218x_Init_with_Options (proslicChanType_ptr *pProslic, int size,
+ initOptionsType init_opt);
+
+/*
+** Function: PROSLIC_VerifyControlInterface
+**
+** Description:
+** Verify SPI port read capabilities
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object
+**
+** Return:
+** none
+*/
+int Si3218x_VerifyControlInterface (proslicChanType_ptr hProslic);
+
+/*
+** Function: Si3218x_PowerUpConverter
+**
+** Description:
+** Powers all DC/DC converters sequentially with delay to minimize
+** peak power draw on VDC.
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_PowerUpConverter(proslicChanType_ptr hProslic);
+
+/*
+** Function: Si3218x_PowerDownConverter
+**
+** Description:
+** Power down DCDC converter (selected channel only)
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_PowerDownConverter(proslicChanType_ptr hProslic);
+
+/*
+** Function: PROSLIC_EnableInterrupts
+**
+** Description:
+** Enables interrupts
+**
+** Input Parameters:
+** hProslic: pointer to Proslic object
+**
+** Return:
+**
+*/
+int Si3218x_EnableInterrupts (proslicChanType_ptr hProslic);
+
+/*
+**
+** PROSLIC CONFIGURATION FUNCTIONS
+**
+*/
+
+/*
+** Function: PROSLIC_RingSetup
+**
+** Description:
+** configure ringing
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** pRingSetup: pointer to ringing config structure
+**
+** Return:
+** none
+*/
+int Si3218x_RingSetup (proslicChanType *pProslic, int preset);
+
+/*
+** Function: PROSLIC_ZsynthSetup
+**
+** Description:
+** configure impedance synthesis
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** pZynth: pointer to zsynth config structure
+**
+** Return:
+** none
+*/
+int Si3218x_ZsynthSetup (proslicChanType *pProslic, int preset);
+
+/*
+** Function: PROSLIC_AudioGainSetup
+**
+** Description:
+** configure audio gains
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** preset: impedance preset to scale
+**
+** Return:
+** none
+*/
+int Si3218x_TXAudioGainSetup (proslicChanType *pProslic, int preset);
+int Si3218x_RXAudioGainSetup (proslicChanType *pProslic, int preset);
+#define Si3218x_AudioGainSetup ProSLIC_AudioGainSetup
+
+/*
+** Function: PROSLIC_TXAudioGainScale
+**
+** Description:
+** configure audio gains
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** preset: pointer to audio gains config structure
+** pga_scale: pga_scaling constant
+** eq_scale: equalizer scaling constant
+**
+** Return:
+** none
+*/
+int Si3218x_TXAudioGainScale (proslicChanType *pProslic, int preset,
+ uInt32 pga_scale, uInt32 eq_scale);
+
+/*
+** Function: PROSLIC_RXAudioGainScale
+**
+** Description:
+** configure audio gains
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** preset: pointer to audio gains config structure
+** pga_scale: pga_scaling constant
+** eq_scale: equalizer scaling constant
+**
+** Return:
+** none
+*/
+int Si3218x_RXAudioGainScale (proslicChanType *pProslic, int preset,
+ uInt32 pga_scale, uInt32 eq_scale);
+
+/*
+** Function: PROSLIC_AudioEQSetup
+**
+** Description:
+** configure audio equalizers
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** pAudioEQ: pointer to ringing config structure
+**
+** Return:
+** none
+*/
+int Si3218x_AudioEQSetup (proslicChanType *pProslic, int preset);
+
+/*
+** Function: PROSLIC_DCFeedSetup
+**
+** Description:
+** configure dc feed
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** pDcFeed: pointer to dc feed config structure
+**
+** Return:
+** none
+*/
+int Si3218x_DCFeedSetupCfg (proslicChanType *pProslic, ProSLIC_DCfeed_Cfg *cfg,
+ int preset);
+
+/*
+** Function: PROSLIC_PCMSetup
+**
+** Description:
+** configure pcm
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** pPcm: pointer to pcm config structure
+**
+** Return:
+** none
+*/
+int Si3218x_PCMSetup(proslicChanType *pProslic, int preset);
+
+/*
+**
+** PROSLIC CONTROL FUNCTIONS
+**
+*/
+
+/*
+** Function: PROSLIC_GetInterrupts
+**
+** Description:
+** Enables interrupts
+**
+** Input Parameters:
+** hProslic: pointer to Proslic object
+** pIntData: pointer to interrupt info retrieved
+**
+** Return:
+**
+*/
+int Si3218x_GetInterrupts (proslicChanType_ptr hProslic,
+ proslicIntType *pIntData);
+
+/*
+** Function: PROSLIC_PulseMeterSetup
+**
+** Description:
+** configure pulse metering
+**
+** Input Parameters:
+** pProslic: pointer to Proslic object
+** pPulseCfg: pointer to pulse metering config structure
+**
+** Return:
+** none
+*/
+int Si3218x_PulseMeterSetup (proslicChanType *pProslic, int preset);
+
+/*
+** Function: PROSLIC_dbgSetDCFeed
+**
+** Description:
+** provision function for setting up
+** dcfeed given desired open circuit voltage
+** and loop current.
+*/
+int Si3218x_dbgSetDCFeed (proslicChanType *pProslic, uInt32 v_vlim_val,
+ uInt32 i_ilim_val, int32 preset);
+
+/*
+** Function: PROSLIC_dbgSetDCFeedVopen
+**
+** Description:
+** provision function for setting up
+** dcfeed given desired open circuit voltage
+** and loop current.
+*/
+int Si3218x_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
+ int32 preset);
+
+
+/*
+** Function: PROSLIC_dbgSetDCFeedIloop
+**
+** Description:
+** provision function for setting up
+** dcfeed given desired open circuit voltage
+** and loop current.
+*/
+int Si3218x_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
+ int32 preset);
+
+
+/*
+** Function: PROSLIC_dbgRingingSetup
+**
+** Description:
+** Provision function for setting up
+** Ring type, frequency, amplitude and dc offset.
+** Main use will be by peek/poke applications.
+*/
+int Si3218x_dbgSetRinging (proslicChanType *pProslic,
+ ProSLIC_dbgRingCfg *ringCfg, int preset);
+
+/*
+** Function: PROSLIC_dbgSetRXGain
+**
+** Description:
+** Provision function for setting up
+** RX path gain.
+*/
+int Si3218x_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset);
+
+/*
+** Function: PROSLIC_dbgSetTXGain
+**
+** Description:
+** Provision function for setting up
+** TX path gain.
+*/
+int Si3218x_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset);
+
+
+/*
+** Function: PROSLIC_LineMonitor
+**
+** Description:
+** Monitor line voltages and currents
+*/
+int Si3218x_LineMonitor(proslicChanType *pProslic, proslicMonitorType *monitor);
+
+
+/*
+** Function: PROSLIC_PSTNCheck
+**
+** Description:
+** Continuous monitor of ilong to detect hot pstn line
+*/
+int Si3218x_PSTNCheck(proslicChanType *pProslic,
+ proslicPSTNCheckObjType *pstnCheckObj);
+
+
+/*
+** Function: PROSLIC_PSTNCheck
+**
+** Description:
+** Continuous monitor of ilong to detect hot pstn line
+*/
+int Si3218x_DiffPSTNCheck(proslicChanType *pProslic,
+ proslicDiffPSTNCheckObjType *pstnCheckObj);
+
+/*
+** Function: PROSLIC_ReadMADCScaled
+**
+** Description:
+** Read MADC (or other sensed voltages/currents) and
+** return scaled value in int32 format
+*/
+int32 Si3218x_ReadMADCScaled(proslicChanType_ptr pProslic, uInt16 addr,
+ int32 scale);
+
+/*
+** Function: Si3218x_GenParamUpdate
+**
+** Description:
+** Update Si3218x general parameters and other required modifications
+** to default reg/ram values
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_GenParamUpdate(proslicChanType_ptr hProslic,initSeqType seq);
+
+
+/*
+** Function: Si3218x_SelectPatch
+**
+** Description:
+** Select appropriate patch based on general parameters
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_SelectPatch(proslicChanType_ptr hProslic,
+ const proslicPatch **patch);
+
+/*
+** Function: Si3218x_ConverterSetup
+**
+** Description:
+** Program revision specific settings before powering converter
+**
+** Specifically, from general parameters and knowledge that this
+** is Rev C, setup dcff drive, gate drive polarity, and charge pump.
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_ConverterSetup(proslicChanType_ptr pProslic);
+
+/*
+** Function: Si3218x8_PulseMeterSetup
+**
+** Description:
+** configure pulse metering
+*/
+int Si3218x_PulseMeterSetup (proslicChanType_ptr hProslic, int preset);
+
+
+/*
+** Function: Si3218x_GetChipInfo
+** Description: Returns the specific chipset in the Si3218x family.
+** Input parameters: channel pointer
+** output: either RC_SPI_FAIL or RC_NONE. channel pointer deviceId will be updated.
+**/
+int Si3218x_GetChipInfo(proslicChanType_ptr pProslic);
+
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x_registers.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x_registers.h
new file mode 100644
index 0000000..2812803
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si3218x_registers.h
@@ -0,0 +1,1518 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ */
+
+#ifndef SI3218X_REGS_H
+#define SI3218X_REGS_H
+
+/*
+** SI3218X SPI Registers
+*/
+enum SI3218X_REG
+{
+ SI3218X_REG_ID = 0,
+ SI3218X_REG_RESET = 1,
+ SI3218X_REG_MSTREN = 2,
+ SI3218X_REG_MSTRSTAT = 3,
+ SI3218X_REG_RAMSTAT = 4,
+ SI3218X_REG_RAM_ADDR_HI = 5,
+ SI3218X_REG_RAM_DATA_B0 = 6,
+ SI3218X_REG_RAM_DATA_B1 = 7,
+ SI3218X_REG_RAM_DATA_B2 = 8,
+ SI3218X_REG_RAM_DATA_B3 = 9,
+ SI3218X_REG_RAM_ADDR_LO = 10,
+ SI3218X_REG_PCMMODE = 11,
+ SI3218X_REG_PCMTXLO = 12,
+ SI3218X_REG_PCMTXHI = 13,
+ SI3218X_REG_PCMRXLO = 14,
+ SI3218X_REG_PCMRXHI = 15,
+ SI3218X_REG_IRQ = 16,
+ SI3218X_REG_IRQ0 = 17,
+ SI3218X_REG_IRQ1 = 18,
+ SI3218X_REG_IRQ2 = 19,
+ SI3218X_REG_IRQ3 = 20,
+ SI3218X_REG_IRQ4 = 21,
+ SI3218X_REG_IRQEN1 = 22,
+ SI3218X_REG_IRQEN2 = 23,
+ SI3218X_REG_IRQEN3 = 24,
+ SI3218X_REG_IRQEN4 = 25,
+ SI3218X_REG_CALR0 = 26,
+ SI3218X_REG_CALR1 = 27,
+ SI3218X_REG_CALR2 = 28,
+ SI3218X_REG_CALR3 = 29,
+ SI3218X_REG_LINEFEED = 30,
+ SI3218X_REG_POLREV = 31,
+ SI3218X_REG_SPEEDUP_DIS = 32,
+ SI3218X_REG_SPEEDUP = 33,
+ SI3218X_REG_LCRRTP = 34,
+ SI3218X_REG_OFFLOAD = 35,
+ SI3218X_REG_BATSELMAP = 36,
+ SI3218X_REG_BATSEL = 37,
+ SI3218X_REG_RINGCON = 38,
+ SI3218X_REG_RINGTALO = 39,
+ SI3218X_REG_RINGTAHI = 40,
+ SI3218X_REG_RINGTILO = 41,
+ SI3218X_REG_RINGTIHI = 42,
+ SI3218X_REG_LOOPBACK = 43,
+ SI3218X_REG_DIGCON = 44,
+ SI3218X_REG_RA = 45,
+ SI3218X_REG_ZCAL_EN = 46,
+ SI3218X_REG_ENHANCE = 47,
+ SI3218X_REG_OMODE = 48,
+ SI3218X_REG_OCON = 49,
+ SI3218X_REG_O1TALO = 50,
+ SI3218X_REG_O1TAHI = 51,
+ SI3218X_REG_O1TILO = 52,
+ SI3218X_REG_O1TIHI = 53,
+ SI3218X_REG_O2TALO = 54,
+ SI3218X_REG_O2TAHI = 55,
+ SI3218X_REG_O2TILO = 56,
+ SI3218X_REG_O2TIHI = 57,
+ SI3218X_REG_FSKDAT = 58,
+ SI3218X_REG_FSKDEPTH = 59,
+ SI3218X_REG_TONDTMF = 60,
+ SI3218X_REG_TONDET = 61,
+ SI3218X_REG_TONEN = 62,
+ SI3218X_REG_GCI_CI = 63,
+ SI3218X_REG_GLOBSTAT1 = 64,
+ SI3218X_REG_GLOBSTAT2 = 65,
+ SI3218X_REG_USERSTAT = 66,
+ SI3218X_REG_GPIO_CFG1 = 68,
+ SI3218X_REG_DIAG1 = 71,
+ SI3218X_REG_DIAG2 = 72,
+ SI3218X_REG_CM_CLAMP = 73,
+ SI3218X_REG_DIAG3 = 74,
+ SI3218X_REG_PMCON = 75,
+ SI3218X_REG_PCLK_FAULT_CNTL = 76,
+ SI3218X_REG_AUTO = 80,
+ SI3218X_REG_JMPEN = 81,
+ SI3218X_REG_JMP0LO = 82,
+ SI3218X_REG_JMP0HI = 83,
+ SI3218X_REG_JMP1LO = 84,
+ SI3218X_REG_JMP1HI = 85,
+ SI3218X_REG_JMP2LO = 86,
+ SI3218X_REG_JMP2HI = 87,
+ SI3218X_REG_JMP3LO = 88,
+ SI3218X_REG_JMP3HI = 89,
+ SI3218X_REG_JMP4LO = 90,
+ SI3218X_REG_JMP4HI = 91,
+ SI3218X_REG_JMP5LO = 92,
+ SI3218X_REG_JMP5HI = 93,
+ SI3218X_REG_JMP6LO = 94,
+ SI3218X_REG_JMP6HI = 95,
+ SI3218X_REG_JMP7LO = 96,
+ SI3218X_REG_JMP7HI = 97,
+ SI3218X_REG_PDN = 98,
+ SI3218X_REG_PDN_STAT = 99,
+ SI3218X_REG_PDN2 = 100,
+ SI3218X_REG_PDN2_STAT = 101,
+ SI3218X_REG_M1_OSC_LO = 112,
+ SI3218X_REG_M1_OSC_HI = 113,
+ SI3218X_REG_BITCNT_LO = 114,
+ SI3218X_REG_BITCNT_HI = 115,
+ SI3218X_REG_PCLK_MULT = 116,
+ SI3218X_REG_RAM_DATA_16 = 117,
+ SI3218X_REG_BYPASS_ADDR_LO = 118,
+ SI3218X_REG_BYPASS_ADDR_HI = 119,
+ SI3218X_REG_PC_LO = 120,
+ SI3218X_REG_PC_HI = 121,
+ SI3218X_REG_PC_SHAD_LO = 122,
+ SI3218X_REG_PC_SHAD_HI = 123,
+ SI3218X_REG_PASS_LO = 124,
+ SI3218X_REG_PASS_HI = 125,
+ SI3218X_REG_TEST_CNTL = 126,
+ SI3218X_REG_TEST_MODE = 127,
+};
+
+/*
+** SI3218X_RAM
+*/
+enum SI3218X_RAM
+{
+ SI3218X_RAM_IRNGNG_SENSE = 0,
+ SI3218X_RAM_MADC_VTIPC = 1,
+ SI3218X_RAM_MADC_VRINGC = 2,
+ SI3218X_RAM_MADC_VBAT = 3,
+ SI3218X_RAM_MADC_VLONG = 4,
+ SI3218X_RAM_UNUSED5 = 5,
+ SI3218X_RAM_MADC_VDC = 6,
+ SI3218X_RAM_MADC_ILONG = 7,
+ SI3218X_RAM_MADC_ITIP = 8,
+ SI3218X_RAM_MADC_IRING = 9,
+ SI3218X_RAM_MADC_ILOOP = 10,
+ SI3218X_RAM_VDIFF_SENSE = 11,
+ SI3218X_RAM_VTIP = 12,
+ SI3218X_RAM_VRING = 13,
+ SI3218X_RAM_P_Q1_D = 14,
+ SI3218X_RAM_INIT_GUESS = 15,
+ SI3218X_RAM_Y1 = 16,
+ SI3218X_RAM_Y2 = 17,
+ SI3218X_RAM_Y3 = 18,
+ SI3218X_RAM_UNUSED19 = 19,
+ SI3218X_RAM_P_Q1 = 20,
+ SI3218X_RAM_DIAG_EX1 = 21,
+ SI3218X_RAM_DIAG_EX2 = 22,
+ SI3218X_RAM_DIAG_LPF_MADC = 23,
+ SI3218X_RAM_DIAG_DMM_I = 24,
+ SI3218X_RAM_DIAG_DMM_V = 25,
+ SI3218X_RAM_OSC1FREQ = 26,
+ SI3218X_RAM_OSC1AMP = 27,
+ SI3218X_RAM_OSC1PHAS = 28,
+ SI3218X_RAM_OSC2FREQ = 29,
+ SI3218X_RAM_OSC2AMP = 30,
+ SI3218X_RAM_OSC2PHAS = 31,
+ SI3218X_RAM_TESTB0_1 = 32,
+ SI3218X_RAM_TESTB1_1 = 33,
+ SI3218X_RAM_TESTB2_1 = 34,
+ SI3218X_RAM_TESTA1_1 = 35,
+ SI3218X_RAM_TESTA2_1 = 36,
+ SI3218X_RAM_TESTB0_2 = 37,
+ SI3218X_RAM_TESTB1_2 = 38,
+ SI3218X_RAM_TESTB2_2 = 39,
+ SI3218X_RAM_TESTA1_2 = 40,
+ SI3218X_RAM_TESTA2_2 = 41,
+ SI3218X_RAM_TESTB0_3 = 42,
+ SI3218X_RAM_TESTB1_3 = 43,
+ SI3218X_RAM_TESTB2_3 = 44,
+ SI3218X_RAM_TESTA1_3 = 45,
+ SI3218X_RAM_TESTA2_3 = 46,
+ SI3218X_RAM_TESTPKO = 47,
+ SI3218X_RAM_TESTABO = 48,
+ SI3218X_RAM_TESTWLN = 49,
+ SI3218X_RAM_TESTAVBW = 50,
+ SI3218X_RAM_TESTPKFL = 51,
+ SI3218X_RAM_TESTAVFL = 52,
+ SI3218X_RAM_TESTPKTH = 53,
+ SI3218X_RAM_TESTAVTH = 54,
+ SI3218X_RAM_DAC_IN_SYNC1 = 55,
+ SI3218X_RAM_BYPASS_REG = 56,
+ SI3218X_RAM_LCRMASK_CNT = 57,
+ SI3218X_RAM_DAC_IN_SYNC = 58,
+ SI3218X_RAM_TEMP = 59,
+ SI3218X_RAM_TEMP_ISR = 60,
+ SI3218X_RAM_P_Q2 = 61,
+ SI3218X_RAM_P_Q3 = 62,
+ SI3218X_RAM_P_Q4 = 63,
+ SI3218X_RAM_P_Q5 = 64,
+ SI3218X_RAM_P_Q6 = 65,
+ SI3218X_RAM_ILOOP_FILT = 66,
+ SI3218X_RAM_ILONG_FILT = 67,
+ SI3218X_RAM_VBAT_FILT = 68,
+ SI3218X_RAM_VDIFF_FILT = 69,
+ SI3218X_RAM_VCM_FILT = 70,
+ SI3218X_RAM_VBAT_CNT = 71,
+ SI3218X_RAM_V_VLIM_SCALED = 72,
+ SI3218X_RAM_V_VLIM_TRACK = 73,
+ SI3218X_RAM_V_VLIM_MODFEED = 74,
+ SI3218X_RAM_DIAG_P_OUT = 75,
+ SI3218X_RAM_DIAG_COUNT = 76,
+ SI3218X_RAM_ROW0_MAG = 77,
+ SI3218X_RAM_ROW1_MAG = 78,
+ SI3218X_RAM_ROW2_MAG = 79,
+ SI3218X_RAM_ROW3_MAG = 80,
+ SI3218X_RAM_COL0_MAG = 81,
+ SI3218X_RAM_COL1_MAG = 82,
+ SI3218X_RAM_COL2_MAG = 83,
+ SI3218X_RAM_COL3_MAG = 84,
+ SI3218X_RAM_ROW0_2ND_Y1 = 85,
+ SI3218X_RAM_ROW1_2ND_Y1 = 86,
+ SI3218X_RAM_ROW2_2ND_Y1 = 87,
+ SI3218X_RAM_ROW3_2ND_Y1 = 88,
+ SI3218X_RAM_COL0_2ND_Y1 = 89,
+ SI3218X_RAM_COL1_2ND_Y1 = 90,
+ SI3218X_RAM_COL2_2ND_Y1 = 91,
+ SI3218X_RAM_COL3_2ND_Y1 = 92,
+ SI3218X_RAM_ROW0_2ND_Y2 = 93,
+ SI3218X_RAM_ROW1_2ND_Y2 = 94,
+ SI3218X_RAM_ROW2_2ND_Y2 = 95,
+ SI3218X_RAM_ROW3_2ND_Y2 = 96,
+ SI3218X_RAM_COL0_2ND_Y2 = 97,
+ SI3218X_RAM_COL1_2ND_Y2 = 98,
+ SI3218X_RAM_COL2_2ND_Y2 = 99,
+ SI3218X_RAM_COL3_2ND_Y2 = 100,
+ SI3218X_RAM_DTMF_IN = 101,
+ SI3218X_RAM_DTMFDTF_D2_1 = 102,
+ SI3218X_RAM_DTMFDTF_D1_1 = 103,
+ SI3218X_RAM_DTMFDTF_OUT_1 = 104,
+ SI3218X_RAM_DTMFDTF_D2_2 = 105,
+ SI3218X_RAM_DTMFDTF_D1_2 = 106,
+ SI3218X_RAM_DTMFDTF_OUT_2 = 107,
+ SI3218X_RAM_DTMFDTF_D2_3 = 108,
+ SI3218X_RAM_DTMFDTF_D1_3 = 109,
+ SI3218X_RAM_DTMFDTF_OUT_3 = 110,
+ SI3218X_RAM_DTMFDTF_OUT = 111,
+ SI3218X_RAM_DTMFLPF_D2_1 = 112,
+ SI3218X_RAM_DTMFLPF_D1_1 = 113,
+ SI3218X_RAM_DTMFLPF_OUT_1 = 114,
+ SI3218X_RAM_DTMFLPF_D2_2 = 115,
+ SI3218X_RAM_DTMFLPF_D1_2 = 116,
+ SI3218X_RAM_DTMFLPF_OUT_2 = 117,
+ SI3218X_RAM_DTMF_ROW = 118,
+ SI3218X_RAM_DTMFHPF_D2_1 = 119,
+ SI3218X_RAM_DTMFHPF_D1_1 = 120,
+ SI3218X_RAM_DTMFHPF_OUT_1 = 121,
+ SI3218X_RAM_DTMFHPF_D2_2 = 122,
+ SI3218X_RAM_DTMFHPF_D1_2 = 123,
+ SI3218X_RAM_DTMFHPF_OUT_2 = 124,
+ SI3218X_RAM_DTMF_COL = 125,
+ SI3218X_RAM_ROW_POWER = 126,
+ SI3218X_RAM_COL_POWER = 127,
+ SI3218X_RAM_GP_TIMER = 128,
+ SI3218X_RAM_SPR_INTERP_DIF = 129,
+ SI3218X_RAM_SPR_INTERP_DIF_OUT = 130,
+ SI3218X_RAM_SPR_INTERP_INT = 131,
+ SI3218X_RAM_SPR_CNT = 132,
+ SI3218X_RAM_ROW0_Y1 = 133,
+ SI3218X_RAM_ROW0_Y2 = 134,
+ SI3218X_RAM_ROW1_Y1 = 135,
+ SI3218X_RAM_ROW1_Y2 = 136,
+ SI3218X_RAM_ROW2_Y1 = 137,
+ SI3218X_RAM_ROW2_Y2 = 138,
+ SI3218X_RAM_ROW3_Y1 = 139,
+ SI3218X_RAM_ROW3_Y2 = 140,
+ SI3218X_RAM_COL0_Y1 = 141,
+ SI3218X_RAM_COL0_Y2 = 142,
+ SI3218X_RAM_COL1_Y1 = 143,
+ SI3218X_RAM_COL1_Y2 = 144,
+ SI3218X_RAM_COL2_Y1 = 145,
+ SI3218X_RAM_COL2_Y2 = 146,
+ SI3218X_RAM_COL3_Y1 = 147,
+ SI3218X_RAM_COL3_Y2 = 148,
+ SI3218X_RAM_ROWMAX_MAG = 149,
+ SI3218X_RAM_COLMAX_MAG = 150,
+ SI3218X_RAM_ROW0_2ND_MAG = 151,
+ SI3218X_RAM_COL0_2ND_MAG = 152,
+ SI3218X_RAM_ROW_THR = 153,
+ SI3218X_RAM_COL_THR = 154,
+ SI3218X_RAM_OSC1_Y = 155,
+ SI3218X_RAM_OSC2_Y = 156,
+ SI3218X_RAM_OSC1_X = 157,
+ SI3218X_RAM_OSC1_COEFF = 158,
+ SI3218X_RAM_OSC2_X = 159,
+ SI3218X_RAM_OSC2_COEFF = 160,
+ SI3218X_RAM_RXACIIR_D2_1 = 161,
+ SI3218X_RAM_RXACIIR_OUT_1 = 162,
+ SI3218X_RAM_RXACIIR_D2_2 = 163,
+ SI3218X_RAM_RXACIIR_D1_2 = 164,
+ SI3218X_RAM_RXACIIR_OUT_2 = 165,
+ SI3218X_RAM_RXACIIR_D2_3 = 166,
+ SI3218X_RAM_RXACIIR_D1_3 = 167,
+ SI3218X_RAM_RXACIIR_OUT = 168,
+ SI3218X_RAM_RXACIIR_OUT_3 = 169,
+ SI3218X_RAM_TXACCOMB_D1 = 170,
+ SI3218X_RAM_TXACCOMB_D2 = 171,
+ SI3218X_RAM_TXACCOMB_D3 = 172,
+ SI3218X_RAM_TXACSINC_OUT = 173,
+ SI3218X_RAM_TXACHPF_D1_2 = 174,
+ SI3218X_RAM_TXACHPF_D2_1 = 175,
+ SI3218X_RAM_TXACHPF_D2_2 = 176,
+ SI3218X_RAM_TXACHPF_OUT = 177,
+ SI3218X_RAM_TXACHPF_OUT_1 = 178,
+ SI3218X_RAM_TXACHPF_OUT_2 = 179,
+ SI3218X_RAM_TXACIIR_D2_1 = 180,
+ SI3218X_RAM_TXACIIR_OUT_1 = 181,
+ SI3218X_RAM_TXACIIR_D2_2 = 182,
+ SI3218X_RAM_TXACIIR_D1_2 = 183,
+ SI3218X_RAM_TXACIIR_OUT_2 = 184,
+ SI3218X_RAM_TXACIIR_D2_3 = 185,
+ SI3218X_RAM_TXACIIR_D1_3 = 186,
+ SI3218X_RAM_TXACIIR_OUT_3 = 187,
+ SI3218X_RAM_TXACIIR_OUT = 188,
+ SI3218X_RAM_ECIIR_D1 = 189,
+ SI3218X_RAM_ECIIR_D2 = 190,
+ SI3218X_RAM_EC_DELAY1 = 191,
+ SI3218X_RAM_EC_DELAY2 = 192,
+ SI3218X_RAM_EC_DELAY3 = 193,
+ SI3218X_RAM_EC_DELAY4 = 194,
+ SI3218X_RAM_EC_DELAY5 = 195,
+ SI3218X_RAM_EC_DELAY6 = 196,
+ SI3218X_RAM_EC_DELAY7 = 197,
+ SI3218X_RAM_EC_DELAY8 = 198,
+ SI3218X_RAM_EC_DELAY9 = 199,
+ SI3218X_RAM_EC_DELAY10 = 200,
+ SI3218X_RAM_EC_DELAY11 = 201,
+ SI3218X_RAM_ECHO_EST = 202,
+ SI3218X_RAM_EC_OUT = 203,
+ SI3218X_RAM_TESTFILT_OUT_1 = 204,
+ SI3218X_RAM_TESTFILT_D1_1 = 205,
+ SI3218X_RAM_TESTFILT_D2_1 = 206,
+ SI3218X_RAM_TESTFILT_OUT_2 = 207,
+ SI3218X_RAM_TESTFILT_D1_2 = 208,
+ SI3218X_RAM_TESTFILT_D2_2 = 209,
+ SI3218X_RAM_TESTFILT_OUT_3 = 210,
+ SI3218X_RAM_TESTFILT_D1_3 = 211,
+ SI3218X_RAM_TESTFILT_D2_3 = 212,
+ SI3218X_RAM_TESTFILT_PEAK = 213,
+ SI3218X_RAM_TESTFILT_ABS = 214,
+ SI3218X_RAM_TESTFILT_MEANACC = 215,
+ SI3218X_RAM_TESTFILT_COUNT = 216,
+ SI3218X_RAM_TESTFILT_NO_OFFSET = 217,
+ SI3218X_RAM_RING_X = 218,
+ SI3218X_RAM_RING_Y = 219,
+ SI3218X_RAM_RING_INT = 220,
+ SI3218X_RAM_RING_Y_D1 = 221,
+ SI3218X_RAM_RING_DIFF = 222,
+ SI3218X_RAM_RING_DELTA = 223,
+ SI3218X_RAM_WTCHDOG_CNT = 224,
+ SI3218X_RAM_RING_WAVE = 225,
+ SI3218X_RAM_UNUSED226 = 226,
+ SI3218X_RAM_ONEKHZ_COUNT = 227,
+ SI3218X_RAM_TX2100_Y1 = 228,
+ SI3218X_RAM_TX2100_Y2 = 229,
+ SI3218X_RAM_TX2100_MAG = 230,
+ SI3218X_RAM_RX2100_Y1 = 231,
+ SI3218X_RAM_RX2100_Y2 = 232,
+ SI3218X_RAM_RX2100_MAG = 233,
+ SI3218X_RAM_TX2100_POWER = 234,
+ SI3218X_RAM_RX2100_POWER = 235,
+ SI3218X_RAM_TX2100_IN = 236,
+ SI3218X_RAM_RX2100_IN = 237,
+ SI3218X_RAM_RINGTRIP_COUNT = 238,
+ SI3218X_RAM_RINGTRIP_DC1 = 239,
+ SI3218X_RAM_RINGTRIP_DC2 = 240,
+ SI3218X_RAM_RINGTRIP_AC1 = 241,
+ SI3218X_RAM_RINGTRIP_AC2 = 242,
+ SI3218X_RAM_RINGTRIP_AC_COUNT = 243,
+ SI3218X_RAM_RINGTRIP_DC_COUNT = 244,
+ SI3218X_RAM_RINGTRIP_AC_RESULT = 245,
+ SI3218X_RAM_RINGTRIP_DC_RESULT = 246,
+ SI3218X_RAM_RINGTRIP_ABS = 247,
+ SI3218X_RAM_TXACEQ_OUT = 248,
+ SI3218X_RAM_LCR_DBI_CNT = 249,
+ SI3218X_RAM_BAT_DBI_CNT = 250,
+ SI3218X_RAM_LONG_DBI_CNT = 251,
+ SI3218X_RAM_TXACEQ_DELAY3 = 252,
+ SI3218X_RAM_TXACEQ_DELAY2 = 253,
+ SI3218X_RAM_TXACEQ_DELAY1 = 254,
+ SI3218X_RAM_RXACEQ_DELAY3 = 255,
+ SI3218X_RAM_RXACEQ_DELAY2 = 256,
+ SI3218X_RAM_RXACEQ_DELAY1 = 257,
+ SI3218X_RAM_RXACEQ_IN = 258,
+ SI3218X_RAM_TXDCCOMB_D1 = 259,
+ SI3218X_RAM_TXDCCOMB_D2 = 260,
+ SI3218X_RAM_TXDCSINC_OUT = 261,
+ SI3218X_RAM_RXACDIFF_D1 = 262,
+ SI3218X_RAM_DC_NOTCH_1 = 263,
+ SI3218X_RAM_DC_NOTCH_2 = 264,
+ SI3218X_RAM_DC_NOTCH_OUT = 265,
+ SI3218X_RAM_DC_NOTCH_SCALED = 266,
+ SI3218X_RAM_V_FEED_IN = 267,
+ SI3218X_RAM_I_TAR = 268,
+ SI3218X_RAM_CONST_VLIM = 269,
+ SI3218X_RAM_UNITY = 270,
+ SI3218X_RAM_TXACNOTCH_1 = 271,
+ SI3218X_RAM_TXACNOTCH_2 = 272,
+ SI3218X_RAM_TXACNOTCH_OUT = 273,
+ SI3218X_RAM_ZSYNTH_1 = 274,
+ SI3218X_RAM_ZSYNTH_2 = 275,
+ SI3218X_RAM_ZSYNTH_OUT_1 = 276,
+ SI3218X_RAM_TXACD2_1_0 = 277,
+ SI3218X_RAM_TXACD2_1_1 = 278,
+ SI3218X_RAM_TXACD2_1_2 = 279,
+ SI3218X_RAM_TXACD2_1_3 = 280,
+ SI3218X_RAM_TXACD2_1_4 = 281,
+ SI3218X_RAM_TXACD2_1_5 = 282,
+ SI3218X_RAM_TXACD2_1_OUT = 283,
+ SI3218X_RAM_TXACD2_2_0 = 284,
+ SI3218X_RAM_TXACD2_2_1 = 285,
+ SI3218X_RAM_TXACD2_2_2 = 286,
+ SI3218X_RAM_TXACD2_2_3 = 287,
+ SI3218X_RAM_TXACD2_2_4 = 288,
+ SI3218X_RAM_TXACD2_2_5 = 289,
+ SI3218X_RAM_TXACD2_2_OUT = 290,
+ SI3218X_RAM_TXACD2_3_0 = 291,
+ SI3218X_RAM_TXACD2_3_1 = 292,
+ SI3218X_RAM_TXACD2_3_2 = 293,
+ SI3218X_RAM_TXACD2_3_3 = 294,
+ SI3218X_RAM_TXACD2_3_4 = 295,
+ SI3218X_RAM_TXACD2_3_5 = 296,
+ SI3218X_RAM_TXACD2_3_OUT = 297,
+ SI3218X_RAM_RXACI2_1_1 = 298,
+ SI3218X_RAM_RXACI2_1_2 = 299,
+ SI3218X_RAM_RXACI2_1_3 = 300,
+ SI3218X_RAM_RXACI2_1_4 = 301,
+ SI3218X_RAM_RXACI2_1_OUT = 302,
+ SI3218X_RAM_RXACI2_2_1 = 303,
+ SI3218X_RAM_RXACI2_2_2 = 304,
+ SI3218X_RAM_RXACI2_2_3 = 305,
+ SI3218X_RAM_RXACI2_2_4 = 306,
+ SI3218X_RAM_RXACI2_2_OUT = 307,
+ SI3218X_RAM_RXACI2_3_1 = 308,
+ SI3218X_RAM_RXACI2_3_2 = 309,
+ SI3218X_RAM_RXACI2_3_3 = 310,
+ SI3218X_RAM_RXACI2_3_4 = 311,
+ SI3218X_RAM_RXACI2_3_OUT = 312,
+ SI3218X_RAM_TXACCOMP1 = 313,
+ SI3218X_RAM_TXACCOMP_OUT = 314,
+ SI3218X_RAM_RXACCOMP1 = 315,
+ SI3218X_RAM_RXACCOMP_OUT = 316,
+ SI3218X_RAM_RXACHPF_D1_2 = 317,
+ SI3218X_RAM_RXACHPF_D2_1 = 318,
+ SI3218X_RAM_RXACHPF_D2_2 = 319,
+ SI3218X_RAM_RXACHPF_OUT = 320,
+ SI3218X_RAM_RXACHPF_OUT_1 = 321,
+ SI3218X_RAM_RXACHPF_OUT_2 = 322,
+ SI3218X_RAM_RXACEQ_OUT = 323,
+ SI3218X_RAM_METER_I_1 = 324,
+ SI3218X_RAM_METER_I_OUT = 325,
+ SI3218X_RAM_METER_LPF_1 = 326,
+ SI3218X_RAM_METER_LPF_2 = 327,
+ SI3218X_RAM_METER_LPF_OUT = 328,
+ SI3218X_RAM_METER_BP_1 = 329,
+ SI3218X_RAM_METER_BP_2 = 330,
+ SI3218X_RAM_METER_BP_OUT = 331,
+ SI3218X_RAM_METER_SRC_OUT = 332,
+ SI3218X_RAM_UNUSED333 = 333,
+ SI3218X_RAM_UNUSED334 = 334,
+ SI3218X_RAM_RING_LPF_1 = 335,
+ SI3218X_RAM_RING_LPF_2 = 336,
+ SI3218X_RAM_RING_LPF_OUT = 337,
+ SI3218X_RAM_RING_INTERP_DIFF = 338,
+ SI3218X_RAM_RING_INTERP_DIFF_OUT = 339,
+ SI3218X_RAM_RING_INTERP_INT = 340,
+ SI3218X_RAM_RING_INTERP_INT_OUT = 341,
+ SI3218X_RAM_V_ILIM_TRACK = 342,
+ SI3218X_RAM_V_RFEED_TRACK = 343,
+ SI3218X_RAM_LF_SPEEDUP_CNT = 344,
+ SI3218X_RAM_DC_SPEEDUP_CNT = 345,
+ SI3218X_RAM_AC_SPEEDUP_CNT = 346,
+ SI3218X_RAM_LCR_SPEEDUP_CNT = 347,
+ SI3218X_RAM_CM_SPEEDUP_CNT = 348,
+ SI3218X_RAM_DC_SPEEDUP_MASK = 349,
+ SI3218X_RAM_ZSYNTH_IN = 350,
+ SI3218X_RAM_I_TAR_SAVE = 351,
+ SI3218X_RAM_UNUSED352 = 352,
+ SI3218X_RAM_UNUSED353 = 353,
+ SI3218X_RAM_COUNTER_VTR = 354,
+ SI3218X_RAM_I_RING_AVG = 355,
+ SI3218X_RAM_COUNTER_IRING = 356,
+ SI3218X_RAM_COMP_RATIO = 357,
+ SI3218X_RAM_MADC_VBAT_DIV2 = 358,
+ SI3218X_RAM_VDIFF_PK_T = 359,
+ SI3218X_RAM_PEAK_CNT = 360,
+ SI3218X_RAM_CM_DBI_CNT = 361,
+ SI3218X_RAM_VCM_LAST = 362,
+ SI3218X_RAM_VBATL_SENSE = 363,
+ SI3218X_RAM_VBATH_SENSE = 364,
+ SI3218X_RAM_VBATR_SENSE = 365,
+ SI3218X_RAM_BAT_SETTLE_CNT = 366,
+ SI3218X_RAM_VBAT_TGT = 367,
+ SI3218X_RAM_VBAT_REQ = 368,
+ SI3218X_RAM_VCM_HIRES = 369,
+ SI3218X_RAM_VCM_LORES = 370,
+ SI3218X_RAM_ILOOP1 = 371,
+ SI3218X_RAM_ILONG2 = 372,
+ SI3218X_RAM_ITIP1 = 373,
+ SI3218X_RAM_IRING1 = 374,
+ SI3218X_RAM_CAL_TEMP1 = 375,
+ SI3218X_RAM_CAL_TEMP2 = 376,
+ SI3218X_RAM_CAL_TEMP3 = 377,
+ SI3218X_RAM_CAL_TEMP4 = 378,
+ SI3218X_RAM_CAL_TEMP5 = 379,
+ SI3218X_RAM_CAL_TEMP6 = 380,
+ SI3218X_RAM_CAL_TEMP7 = 381,
+ SI3218X_RAM_CMRR_DIVISOR = 382,
+ SI3218X_RAM_CMRR_REMAINDER = 383,
+ SI3218X_RAM_CMRR_Q_PTR = 384,
+ SI3218X_RAM_I_SOURCE1 = 385,
+ SI3218X_RAM_I_SOURCE2 = 386,
+ SI3218X_RAM_VTR1 = 387,
+ SI3218X_RAM_VTR2 = 388,
+ SI3218X_RAM_STOP_TIMER1 = 389,
+ SI3218X_RAM_STOP_TIMER2 = 390,
+ SI3218X_RAM_UNUSED391 = 391,
+ SI3218X_RAM_UNUSED392 = 392,
+ SI3218X_RAM_CAL_ONHK_Z = 393,
+ SI3218X_RAM_CAL_LB_SETTLE = 394,
+ SI3218X_RAM_CAL_DECLPF_V0 = 395,
+ SI3218X_RAM_CAL_DECLPF_V1 = 396,
+ SI3218X_RAM_CAL_DECLPF_V2 = 397,
+ SI3218X_RAM_CAL_GOERTZEL_V0 = 398,
+ SI3218X_RAM_CAL_GOERTZEL_V1 = 399,
+ SI3218X_RAM_CAL_DECLPF_Y = 400,
+ SI3218X_RAM_CAL_GOERTZEL_Y = 401,
+ SI3218X_RAM_P_HVIC = 402,
+ SI3218X_RAM_VBATL_MIRROR = 403,
+ SI3218X_RAM_VBATH_MIRROR = 404,
+ SI3218X_RAM_VBATR_MIRROR = 405,
+ SI3218X_RAM_DIAG_EX1_OUT = 406,
+ SI3218X_RAM_DIAG_EX2_OUT = 407,
+ SI3218X_RAM_DIAG_DMM_V_OUT = 408,
+ SI3218X_RAM_DIAG_DMM_I_OUT = 409,
+ SI3218X_RAM_DIAG_P = 410,
+ SI3218X_RAM_DIAG_LPF_V = 411,
+ SI3218X_RAM_DIAG_LPF_I = 412,
+ SI3218X_RAM_DIAG_TONE_FLAG = 413,
+ SI3218X_RAM_ILOOP1_LAST = 414,
+ SI3218X_RAM_RING_ENTRY_VOC = 415,
+ SI3218X_RAM_UNUSED416 = 416,
+ SI3218X_RAM_OSC1_X_SAVE = 417,
+ SI3218X_RAM_EZSYNTH_1 = 418,
+ SI3218X_RAM_EZSYNTH_2 = 419,
+ SI3218X_RAM_ZSYNTH_OUT = 420,
+ SI3218X_RAM_UNUSED421 = 421,
+ SI3218X_RAM_CAL_SUBSTATE = 422,
+ SI3218X_RAM_DIAG_EX1_DC_OUT = 423,
+ SI3218X_RAM_DIAG_EX1_DC = 424,
+ SI3218X_RAM_EZSYNTH_B1 = 425,
+ SI3218X_RAM_EZSYNTH_B2 = 426,
+ SI3218X_RAM_EZSYNTH_A1 = 427,
+ SI3218X_RAM_EZSYNTH_A2 = 428,
+ SI3218X_RAM_ILOOP1_FILT = 429,
+ SI3218X_RAM_AC_PU_DELTA1_CNT = 430,
+ SI3218X_RAM_AC_PU_DELTA2_CNT = 431,
+ SI3218X_RAM_UNUSED432 = 432,
+ SI3218X_RAM_UNUSED433 = 433,
+ SI3218X_RAM_UNUSED434 = 434,
+ SI3218X_RAM_AC_DAC_GAIN_SAVE = 435,
+ SI3218X_RAM_RING_FLUSH_CNT = 436,
+ SI3218X_RAM_UNUSED437 = 437,
+ SI3218X_RAM_DIAG_VAR_OUT = 438,
+ SI3218X_RAM_I_VBAT = 439,
+ SI3218X_RAM_UNUSED440 = 440,
+ SI3218X_RAM_CALTMP_LOOPCNT = 441,
+ SI3218X_RAM_CALTMP_LOOPINC = 442,
+ SI3218X_RAM_UNUSED443 = 443,
+ SI3218X_RAM_CALTMP_CODEINC = 444,
+ SI3218X_RAM_CALTMP_TAUINC = 445,
+ SI3218X_RAM_CALTMP_TAU = 446,
+ SI3218X_RAM_CAL_TEMP8 = 447,
+ SI3218X_RAM_PATCHID = 448,
+ SI3218X_RAM_UNUSED449 = 449,
+ SI3218X_RAM_UNUSED450 = 450,
+ SI3218X_RAM_UNUSED451 = 451,
+ SI3218X_RAM_CAL_LB_OFFSET_FWD = 452,
+ SI3218X_RAM_CAL_LB_OFFSET_RVS = 453,
+ SI3218X_RAM_COUNT_SPEEDUP = 454,
+ SI3218X_RAM_SWEEP_COUNT = 455,
+ SI3218X_RAM_AMP_RAMP = 456,
+ SI3218X_RAM_DIAG_LPF_MADC_D = 457,
+ SI3218X_RAM_DIAG_HPF_MADC = 458,
+ SI3218X_RAM_UNUSED459 = 459,
+ SI3218X_RAM_TXDEC_OUT = 460,
+ SI3218X_RAM_TXDEC_D1 = 461,
+ SI3218X_RAM_TXDEC_D2 = 462,
+ SI3218X_RAM_RXDEC_D1 = 463,
+ SI3218X_RAM_RXDEC_D2 = 464,
+ SI3218X_RAM_OSCINT1_D2_1 = 465,
+ SI3218X_RAM_OSCINT1_D1_1 = 466,
+ SI3218X_RAM_OSCINT1_OUT_1 = 467,
+ SI3218X_RAM_OSCINT1_D2_2 = 468,
+ SI3218X_RAM_OSCINT1_D1_2 = 469,
+ SI3218X_RAM_OSCINT1_OUT = 470,
+ SI3218X_RAM_OSCINT2_D2_1 = 471,
+ SI3218X_RAM_OSCINT2_D1_1 = 472,
+ SI3218X_RAM_OSCINT2_OUT_1 = 473,
+ SI3218X_RAM_OSCINT2_D2_2 = 474,
+ SI3218X_RAM_OSCINT2_D1_2 = 475,
+ SI3218X_RAM_OSCINT2_OUT = 476,
+ SI3218X_RAM_OSC1_Y_SAVE = 477,
+ SI3218X_RAM_OSC2_Y_SAVE = 478,
+ SI3218X_RAM_PWRSAVE_CNT = 479,
+ SI3218X_RAM_VBATR_PK = 480,
+ SI3218X_RAM_SPEEDUP_MASK_CNT = 481,
+ SI3218X_RAM_VCM_RING_FIXED = 482,
+ SI3218X_RAM_DELTA_VCM = 483,
+ SI3218X_RAM_MADC_VTIPC_DIAG_OS = 484,
+ SI3218X_RAM_MADC_VRINGC_DIAG_OS = 485,
+ SI3218X_RAM_MADC_VLONG_DIAG_OS = 486,
+ SI3218X_RAM_UNUSED487 = 487,
+ SI3218X_RAM_UNUSED488 = 488,
+ SI3218X_RAM_UNUSED489 = 489,
+ SI3218X_RAM_UNUSED490 = 490,
+ SI3218X_RAM_UNUSED491 = 491,
+ SI3218X_RAM_PWRSAVE_DBI_CNT = 492,
+ SI3218X_RAM_COMP_RATIO_SAVE = 493,
+ SI3218X_RAM_CAL_TEMP9 = 494,
+ SI3218X_RAM_CAL_TEMP10 = 495,
+ SI3218X_RAM_DAC_OFFSET_TEMP = 496,
+ SI3218X_RAM_CAL_DAC_CODE = 497,
+ SI3218X_RAM_DCDAC_OFFSET = 498,
+ SI3218X_RAM_VDIFF_COARSE = 499,
+ SI3218X_RAM_RXACIIR_OUT_4 = 500,
+ SI3218X_RAM_CAL_TEMP11 = 501,
+ SI3218X_RAM_METER_RAMP = 502,
+ SI3218X_RAM_METER_RAMP_DIR = 503,
+ SI3218X_RAM_METER_ON_T = 504,
+ SI3218X_RAM_METER_PK_DET = 505,
+ SI3218X_RAM_METER_PK_DET_T = 506,
+ SI3218X_RAM_THERM_CNT = 507,
+ SI3218X_RAM_VDIFF_SENSE_DELAY = 508,
+ SI3218X_RAM_RING_INTERP_DIFF_SYNC = 509,
+ SI3218X_RAM_CPUMP_DEB_CNT = 510,
+ SI3218X_RAM_UNUSED511 = 511,
+ SI3218X_RAM_MINUS_ONE = 512,
+ SI3218X_RAM_ILOOPLPF = 513,
+ SI3218X_RAM_ILONGLPF = 514,
+ SI3218X_RAM_BATLPF = 515,
+ SI3218X_RAM_VDIFFLPF = 516,
+ SI3218X_RAM_VCMLPF = 517,
+ SI3218X_RAM_TXACIIR_B0_1 = 518,
+ SI3218X_RAM_TXACIIR_B1_1 = 519,
+ SI3218X_RAM_TXACIIR_A1_1 = 520,
+ SI3218X_RAM_TXACIIR_B0_2 = 521,
+ SI3218X_RAM_TXACIIR_B1_2 = 522,
+ SI3218X_RAM_TXACIIR_B2_2 = 523,
+ SI3218X_RAM_TXACIIR_A1_2 = 524,
+ SI3218X_RAM_TXACIIR_A2_2 = 525,
+ SI3218X_RAM_TXACIIR_B0_3 = 526,
+ SI3218X_RAM_TXACIIR_B1_3 = 527,
+ SI3218X_RAM_TXACIIR_B2_3 = 528,
+ SI3218X_RAM_TXACIIR_A1_3 = 529,
+ SI3218X_RAM_TXACIIR_A2_3 = 530,
+ SI3218X_RAM_TXACHPF_B0_1 = 531,
+ SI3218X_RAM_TXACHPF_B1_1 = 532,
+ SI3218X_RAM_TXACHPF_A1_1 = 533,
+ SI3218X_RAM_TXACHPF_B0_2 = 534,
+ SI3218X_RAM_TXACHPF_B1_2 = 535,
+ SI3218X_RAM_TXACHPF_B2_2 = 536,
+ SI3218X_RAM_TXACHPF_A1_2 = 537,
+ SI3218X_RAM_TXACHPF_A2_2 = 538,
+ SI3218X_RAM_TXACHPF_GAIN = 539,
+ SI3218X_RAM_TXACEQ_C0 = 540,
+ SI3218X_RAM_TXACEQ_C1 = 541,
+ SI3218X_RAM_TXACEQ_C2 = 542,
+ SI3218X_RAM_TXACEQ_C3 = 543,
+ SI3218X_RAM_TXACGAIN = 544,
+ SI3218X_RAM_RXACGAIN = 545,
+ SI3218X_RAM_RXACEQ_C0 = 546,
+ SI3218X_RAM_RXACEQ_C1 = 547,
+ SI3218X_RAM_RXACEQ_C2 = 548,
+ SI3218X_RAM_RXACEQ_C3 = 549,
+ SI3218X_RAM_RXACIIR_B0_1 = 550,
+ SI3218X_RAM_RXACIIR_B1_1 = 551,
+ SI3218X_RAM_RXACIIR_A1_1 = 552,
+ SI3218X_RAM_RXACIIR_B0_2 = 553,
+ SI3218X_RAM_RXACIIR_B1_2 = 554,
+ SI3218X_RAM_RXACIIR_B2_2 = 555,
+ SI3218X_RAM_RXACIIR_A1_2 = 556,
+ SI3218X_RAM_RXACIIR_A2_2 = 557,
+ SI3218X_RAM_RXACIIR_B0_3 = 558,
+ SI3218X_RAM_RXACIIR_B1_3 = 559,
+ SI3218X_RAM_RXACIIR_B2_3 = 560,
+ SI3218X_RAM_RXACIIR_A1_3 = 561,
+ SI3218X_RAM_RXACIIR_A2_3 = 562,
+ SI3218X_RAM_ECFIR_C2 = 563,
+ SI3218X_RAM_ECFIR_C3 = 564,
+ SI3218X_RAM_ECFIR_C4 = 565,
+ SI3218X_RAM_ECFIR_C5 = 566,
+ SI3218X_RAM_ECFIR_C6 = 567,
+ SI3218X_RAM_ECFIR_C7 = 568,
+ SI3218X_RAM_ECFIR_C8 = 569,
+ SI3218X_RAM_ECFIR_C9 = 570,
+ SI3218X_RAM_ECIIR_B0 = 571,
+ SI3218X_RAM_ECIIR_B1 = 572,
+ SI3218X_RAM_ECIIR_A1 = 573,
+ SI3218X_RAM_ECIIR_A2 = 574,
+ SI3218X_RAM_DTMFDTF_B0_1 = 575,
+ SI3218X_RAM_DTMFDTF_B1_1 = 576,
+ SI3218X_RAM_DTMFDTF_B2_1 = 577,
+ SI3218X_RAM_DTMFDTF_A1_1 = 578,
+ SI3218X_RAM_DTMFDTF_A2_1 = 579,
+ SI3218X_RAM_DTMFDTF_B0_2 = 580,
+ SI3218X_RAM_DTMFDTF_B1_2 = 581,
+ SI3218X_RAM_DTMFDTF_B2_2 = 582,
+ SI3218X_RAM_DTMFDTF_A1_2 = 583,
+ SI3218X_RAM_DTMFDTF_A2_2 = 584,
+ SI3218X_RAM_DTMFDTF_B0_3 = 585,
+ SI3218X_RAM_DTMFDTF_B1_3 = 586,
+ SI3218X_RAM_DTMFDTF_B2_3 = 587,
+ SI3218X_RAM_DTMFDTF_A1_3 = 588,
+ SI3218X_RAM_DTMFDTF_A2_3 = 589,
+ SI3218X_RAM_DTMFDTF_GAIN = 590,
+ SI3218X_RAM_DTMFLPF_B0_1 = 591,
+ SI3218X_RAM_DTMFLPF_B1_1 = 592,
+ SI3218X_RAM_DTMFLPF_B2_1 = 593,
+ SI3218X_RAM_DTMFLPF_A1_1 = 594,
+ SI3218X_RAM_DTMFLPF_A2_1 = 595,
+ SI3218X_RAM_DTMFLPF_B0_2 = 596,
+ SI3218X_RAM_DTMFLPF_B1_2 = 597,
+ SI3218X_RAM_DTMFLPF_B2_2 = 598,
+ SI3218X_RAM_DTMFLPF_A1_2 = 599,
+ SI3218X_RAM_DTMFLPF_A2_2 = 600,
+ SI3218X_RAM_DTMFLPF_GAIN = 601,
+ SI3218X_RAM_DTMFHPF_B0_1 = 602,
+ SI3218X_RAM_DTMFHPF_B1_1 = 603,
+ SI3218X_RAM_DTMFHPF_B2_1 = 604,
+ SI3218X_RAM_DTMFHPF_A1_1 = 605,
+ SI3218X_RAM_DTMFHPF_A2_1 = 606,
+ SI3218X_RAM_DTMFHPF_B0_2 = 607,
+ SI3218X_RAM_DTMFHPF_B1_2 = 608,
+ SI3218X_RAM_DTMFHPF_B2_2 = 609,
+ SI3218X_RAM_DTMFHPF_A1_2 = 610,
+ SI3218X_RAM_DTMFHPF_A2_2 = 611,
+ SI3218X_RAM_DTMFHPF_GAIN = 612,
+ SI3218X_RAM_POWER_GAIN = 613,
+ SI3218X_RAM_GOERTZEL_GAIN = 614,
+ SI3218X_RAM_MODEM_GAIN = 615,
+ SI3218X_RAM_HOTBIT1 = 616,
+ SI3218X_RAM_HOTBIT0 = 617,
+ SI3218X_RAM_ROW0_C1 = 618,
+ SI3218X_RAM_ROW1_C1 = 619,
+ SI3218X_RAM_ROW2_C1 = 620,
+ SI3218X_RAM_ROW3_C1 = 621,
+ SI3218X_RAM_COL0_C1 = 622,
+ SI3218X_RAM_COL1_C1 = 623,
+ SI3218X_RAM_COL2_C1 = 624,
+ SI3218X_RAM_COL3_C1 = 625,
+ SI3218X_RAM_ROW0_C2 = 626,
+ SI3218X_RAM_ROW1_C2 = 627,
+ SI3218X_RAM_ROW2_C2 = 628,
+ SI3218X_RAM_ROW3_C2 = 629,
+ SI3218X_RAM_COL0_C2 = 630,
+ SI3218X_RAM_COL1_C2 = 631,
+ SI3218X_RAM_COL2_C2 = 632,
+ SI3218X_RAM_COL3_C2 = 633,
+ SI3218X_RAM_SLOPE_VLIM = 634,
+ SI3218X_RAM_SLOPE_RFEED = 635,
+ SI3218X_RAM_SLOPE_ILIM = 636,
+ SI3218X_RAM_SLOPE_RING = 637,
+ SI3218X_RAM_SLOPE_DELTA1 = 638,
+ SI3218X_RAM_SLOPE_DELTA2 = 639,
+ SI3218X_RAM_V_VLIM = 640,
+ SI3218X_RAM_V_RFEED = 641,
+ SI3218X_RAM_V_ILIM = 642,
+ SI3218X_RAM_CONST_RFEED = 643,
+ SI3218X_RAM_CONST_ILIM = 644,
+ SI3218X_RAM_I_VLIM = 645,
+ SI3218X_RAM_DC_DAC_GAIN = 646,
+ SI3218X_RAM_VDIFF_TH = 647,
+ SI3218X_RAM_TXDEC_B0 = 648,
+ SI3218X_RAM_TXDEC_B1 = 649,
+ SI3218X_RAM_TXDEC_B2 = 650,
+ SI3218X_RAM_TXDEC_A1 = 651,
+ SI3218X_RAM_TXDEC_A2 = 652,
+ SI3218X_RAM_ZSYNTH_B0 = 653,
+ SI3218X_RAM_ZSYNTH_B1 = 654,
+ SI3218X_RAM_ZSYNTH_B2 = 655,
+ SI3218X_RAM_ZSYNTH_A1 = 656,
+ SI3218X_RAM_ZSYNTH_A2 = 657,
+ SI3218X_RAM_RXACHPF_B0_1 = 658,
+ SI3218X_RAM_RXACHPF_B1_1 = 659,
+ SI3218X_RAM_RXACHPF_A1_1 = 660,
+ SI3218X_RAM_RXACHPF_B0_2 = 661,
+ SI3218X_RAM_RXACHPF_B1_2 = 662,
+ SI3218X_RAM_RXACHPF_B2_2 = 663,
+ SI3218X_RAM_RXACHPF_A1_2 = 664,
+ SI3218X_RAM_RXACHPF_A2_2 = 665,
+ SI3218X_RAM_RXACHPF_GAIN = 666,
+ SI3218X_RAM_MASK7LSB = 667,
+ SI3218X_RAM_RXDEC_B0 = 668,
+ SI3218X_RAM_RXDEC_B1 = 669,
+ SI3218X_RAM_RXDEC_B2 = 670,
+ SI3218X_RAM_RXDEC_A1 = 671,
+ SI3218X_RAM_RXDEC_A2 = 672,
+ SI3218X_RAM_OSCINT1_B0_1 = 673,
+ SI3218X_RAM_OSCINT1_B1_1 = 674,
+ SI3218X_RAM_OSCINT1_B2_1 = 675,
+ SI3218X_RAM_OSCINT1_A1_1 = 676,
+ SI3218X_RAM_OSCINT1_A2_1 = 677,
+ SI3218X_RAM_OSCINT1_B0_2 = 678,
+ SI3218X_RAM_OSCINT1_B1_2 = 679,
+ SI3218X_RAM_OSCINT1_B2_2 = 680,
+ SI3218X_RAM_OSCINT1_A1_2 = 681,
+ SI3218X_RAM_OSCINT1_A2_2 = 682,
+ SI3218X_RAM_OSCINT2_B0_1 = 683,
+ SI3218X_RAM_OSCINT2_B1_1 = 684,
+ SI3218X_RAM_OSCINT2_B2_1 = 685,
+ SI3218X_RAM_OSCINT2_A1_1 = 686,
+ SI3218X_RAM_OSCINT2_A2_1 = 687,
+ SI3218X_RAM_OSCINT2_B0_2 = 688,
+ SI3218X_RAM_OSCINT2_B1_2 = 689,
+ SI3218X_RAM_OSCINT2_B2_2 = 690,
+ SI3218X_RAM_OSCINT2_A1_2 = 691,
+ SI3218X_RAM_OSCINT2_A2_2 = 692,
+ SI3218X_RAM_UNUSED693 = 693,
+ SI3218X_RAM_UNUSED694 = 694,
+ SI3218X_RAM_UNUSED695 = 695,
+ SI3218X_RAM_RING_LPF_B0 = 696,
+ SI3218X_RAM_RING_LPF_B1 = 697,
+ SI3218X_RAM_RING_LPF_B2 = 698,
+ SI3218X_RAM_RING_LPF_A1 = 699,
+ SI3218X_RAM_RING_LPF_A2 = 700,
+ SI3218X_RAM_LCRDBI = 701,
+ SI3218X_RAM_LONGDBI = 702,
+ SI3218X_RAM_VBAT_TIMER = 703,
+ SI3218X_RAM_LF_SPEEDUP_TIMER = 704,
+ SI3218X_RAM_DC_SPEEDUP_TIMER = 705,
+ SI3218X_RAM_AC_SPEEDUP_TIMER = 706,
+ SI3218X_RAM_LCR_SPEEDUP_TIMER = 707,
+ SI3218X_RAM_CM_SPEEDUP_TIMER = 708,
+ SI3218X_RAM_VCM_TH = 709,
+ SI3218X_RAM_AC_SPEEDUP_TH = 710,
+ SI3218X_RAM_SPR_SIG_0 = 711,
+ SI3218X_RAM_SPR_SIG_1 = 712,
+ SI3218X_RAM_SPR_SIG_2 = 713,
+ SI3218X_RAM_SPR_SIG_3 = 714,
+ SI3218X_RAM_SPR_SIG_4 = 715,
+ SI3218X_RAM_SPR_SIG_5 = 716,
+ SI3218X_RAM_SPR_SIG_6 = 717,
+ SI3218X_RAM_SPR_SIG_7 = 718,
+ SI3218X_RAM_SPR_SIG_8 = 719,
+ SI3218X_RAM_SPR_SIG_9 = 720,
+ SI3218X_RAM_SPR_SIG_10 = 721,
+ SI3218X_RAM_SPR_SIG_11 = 722,
+ SI3218X_RAM_SPR_SIG_12 = 723,
+ SI3218X_RAM_SPR_SIG_13 = 724,
+ SI3218X_RAM_SPR_SIG_14 = 725,
+ SI3218X_RAM_SPR_SIG_15 = 726,
+ SI3218X_RAM_SPR_SIG_16 = 727,
+ SI3218X_RAM_SPR_SIG_17 = 728,
+ SI3218X_RAM_SPR_SIG_18 = 729,
+ SI3218X_RAM_COUNTER_VTR_VAL = 730,
+ SI3218X_RAM_CONST_028 = 731,
+ SI3218X_RAM_CONST_032 = 732,
+ SI3218X_RAM_CONST_038 = 733,
+ SI3218X_RAM_CONST_046 = 734,
+ SI3218X_RAM_COUNTER_IRING_VAL = 735,
+ SI3218X_RAM_GAIN_RING = 736,
+ SI3218X_RAM_RING_HYST = 737,
+ SI3218X_RAM_COMP_Z = 738,
+ SI3218X_RAM_CONST_115 = 739,
+ SI3218X_RAM_CONST_110 = 740,
+ SI3218X_RAM_CONST_105 = 741,
+ SI3218X_RAM_CONST_100 = 742,
+ SI3218X_RAM_CONST_095 = 743,
+ SI3218X_RAM_CONST_090 = 744,
+ SI3218X_RAM_CONST_085 = 745,
+ SI3218X_RAM_V_RASUM_IDEAL = 746,
+ SI3218X_RAM_CONST_ONE = 747,
+ SI3218X_RAM_VCM_OH = 748,
+ SI3218X_RAM_VCM_RING = 749,
+ SI3218X_RAM_VCM_HYST = 750,
+ SI3218X_RAM_VOV_GND = 751,
+ SI3218X_RAM_VOV_BAT = 752,
+ SI3218X_RAM_VOV_RING_BAT = 753,
+ SI3218X_RAM_CM_DBI = 754,
+ SI3218X_RAM_RTPER = 755,
+ SI3218X_RAM_P_TH_HVIC = 756,
+ SI3218X_RAM_UNUSED757 = 757,
+ SI3218X_RAM_UNUSED758 = 758,
+ SI3218X_RAM_COEF_P_HVIC = 759,
+ SI3218X_RAM_UNUSED760 = 760,
+ SI3218X_RAM_UNUSED761 = 761,
+ SI3218X_RAM_UNUSED762 = 762,
+ SI3218X_RAM_UNUSED763 = 763,
+ SI3218X_RAM_BAT_HYST = 764,
+ SI3218X_RAM_BAT_DBI = 765,
+ SI3218X_RAM_VBATL_EXPECT = 766,
+ SI3218X_RAM_VBATH_EXPECT = 767,
+ SI3218X_RAM_VBATR_EXPECT = 768,
+ SI3218X_RAM_BAT_SETTLE = 769,
+ SI3218X_RAM_VBAT_IRQ_TH = 770,
+ SI3218X_RAM_MADC_VTIPC_OS = 771,
+ SI3218X_RAM_MADC_VRINGC_OS = 772,
+ SI3218X_RAM_MADC_VBAT_OS = 773,
+ SI3218X_RAM_MADC_VLONG_OS = 774,
+ SI3218X_RAM_UNUSED775 = 775,
+ SI3218X_RAM_MADC_VDC_OS = 776,
+ SI3218X_RAM_MADC_ILONG_OS = 777,
+ SI3218X_RAM_UNUSED778 = 778,
+ SI3218X_RAM_UNUSED779 = 779,
+ SI3218X_RAM_MADC_ILOOP_OS = 780,
+ SI3218X_RAM_MADC_ILOOP_SCALE = 781,
+ SI3218X_RAM_UNUSED782 = 782,
+ SI3218X_RAM_UNUSED783 = 783,
+ SI3218X_RAM_DC_ADC_OS = 784,
+ SI3218X_RAM_CAL_UNITY = 785,
+ SI3218X_RAM_UNUSED786 = 786,
+ SI3218X_RAM_UNUSED787 = 787,
+ SI3218X_RAM_ACADC_OFFSET = 788,
+ SI3218X_RAM_ACDAC_OFFSET = 789,
+ SI3218X_RAM_CAL_DCDAC_CODE = 790,
+ SI3218X_RAM_CAL_DCDAC_15MA = 791,
+ SI3218X_RAM_UNUSED792 = 792,
+ SI3218X_RAM_UNUSED793 = 793,
+ SI3218X_RAM_UNUSED794 = 794,
+ SI3218X_RAM_UNUSED795 = 795,
+ SI3218X_RAM_UNUSED796 = 796,
+ SI3218X_RAM_UNUSED797 = 797,
+ SI3218X_RAM_UNUSED798 = 798,
+ SI3218X_RAM_UNUSED799 = 799,
+ SI3218X_RAM_UNUSED800 = 800,
+ SI3218X_RAM_CAL_LB_TSQUELCH = 801,
+ SI3218X_RAM_CAL_LB_TCHARGE = 802,
+ SI3218X_RAM_CAL_LB_TSETTLE0 = 803,
+ SI3218X_RAM_CAL_GOERTZEL_DLY = 804,
+ SI3218X_RAM_CAL_GOERTZEL_ALPHA = 805,
+ SI3218X_RAM_CAL_DECLPF_K = 806,
+ SI3218X_RAM_CAL_DECLPF_B1 = 807,
+ SI3218X_RAM_CAL_DECLPF_B2 = 808,
+ SI3218X_RAM_CAL_DECLPF_A1 = 809,
+ SI3218X_RAM_CAL_DECLPF_A2 = 810,
+ SI3218X_RAM_CAL_ACADC_THRL = 811,
+ SI3218X_RAM_CAL_ACADC_THRH = 812,
+ SI3218X_RAM_CAL_ACADC_TSETTLE = 813,
+ SI3218X_RAM_DTROW0TH = 814,
+ SI3218X_RAM_DTROW1TH = 815,
+ SI3218X_RAM_DTROW2TH = 816,
+ SI3218X_RAM_DTROW3TH = 817,
+ SI3218X_RAM_DTCOL0TH = 818,
+ SI3218X_RAM_DTCOL1TH = 819,
+ SI3218X_RAM_DTCOL2TH = 820,
+ SI3218X_RAM_DTCOL3TH = 821,
+ SI3218X_RAM_DTFTWTH = 822,
+ SI3218X_RAM_DTRTWTH = 823,
+ SI3218X_RAM_DTROWRTH = 824,
+ SI3218X_RAM_DTCOLRTH = 825,
+ SI3218X_RAM_DTROW2HTH = 826,
+ SI3218X_RAM_DTCOL2HTH = 827,
+ SI3218X_RAM_DTMINPTH = 828,
+ SI3218X_RAM_DTHOTTH = 829,
+ SI3218X_RAM_RXPWR = 830,
+ SI3218X_RAM_TXPWR = 831,
+ SI3218X_RAM_RXMODPWR = 832,
+ SI3218X_RAM_TXMODPWR = 833,
+ SI3218X_RAM_FSKFREQ0 = 834,
+ SI3218X_RAM_FSKFREQ1 = 835,
+ SI3218X_RAM_FSKAMP0 = 836,
+ SI3218X_RAM_FSKAMP1 = 837,
+ SI3218X_RAM_FSK01 = 838,
+ SI3218X_RAM_FSK10 = 839,
+ SI3218X_RAM_VOCDELTA = 840,
+ SI3218X_RAM_VOCLTH = 841,
+ SI3218X_RAM_VOCHTH = 842,
+ SI3218X_RAM_RINGOF = 843,
+ SI3218X_RAM_RINGFR = 844,
+ SI3218X_RAM_RINGAMP = 845,
+ SI3218X_RAM_RINGPHAS = 846,
+ SI3218X_RAM_RTDCTH = 847,
+ SI3218X_RAM_RTACTH = 848,
+ SI3218X_RAM_RTDCDB = 849,
+ SI3218X_RAM_RTACDB = 850,
+ SI3218X_RAM_RTCOUNT = 851,
+ SI3218X_RAM_LCROFFHK = 852,
+ SI3218X_RAM_LCRONHK = 853,
+ SI3218X_RAM_LCRMASK = 854,
+ SI3218X_RAM_LCRMASK_POLREV = 855,
+ SI3218X_RAM_LCRMASK_STATE = 856,
+ SI3218X_RAM_LCRMASK_LINECAP = 857,
+ SI3218X_RAM_LONGHITH = 858,
+ SI3218X_RAM_LONGLOTH = 859,
+ SI3218X_RAM_IRING_LIM = 860,
+ SI3218X_RAM_AC_PU_DELTA1 = 861,
+ SI3218X_RAM_AC_PU_DELTA2 = 862,
+ SI3218X_RAM_DIAG_LPF_8K = 863,
+ SI3218X_RAM_DIAG_LPF_128K = 864,
+ SI3218X_RAM_DIAG_INV_N = 865,
+ SI3218X_RAM_DIAG_GAIN = 866,
+ SI3218X_RAM_DIAG_G_CAL = 867,
+ SI3218X_RAM_DIAG_OS_CAL = 868,
+ SI3218X_RAM_SPR_GAIN_TRIM = 869,
+ SI3218X_RAM_UNUSED870 = 870,
+ SI3218X_RAM_AC_DAC_GAIN = 871,
+ SI3218X_RAM_UNUSED872 = 872,
+ SI3218X_RAM_UNUSED873 = 873,
+ SI3218X_RAM_AC_DAC_GAIN0 = 874,
+ SI3218X_RAM_EZSYNTH_B0 = 875,
+ SI3218X_RAM_UNUSED876 = 876,
+ SI3218X_RAM_UNUSED877 = 877,
+ SI3218X_RAM_UNUSED878 = 878,
+ SI3218X_RAM_UNUSED879 = 879,
+ SI3218X_RAM_AC_ADC_GAIN = 880,
+ SI3218X_RAM_ILOOP1LPF = 881,
+ SI3218X_RAM_RING_FLUSH_TIMER = 882,
+ SI3218X_RAM_ALAW_BIAS = 883,
+ SI3218X_RAM_MADC_VTRC_SCALE = 884,
+ SI3218X_RAM_UNUSED885 = 885,
+ SI3218X_RAM_MADC_VBAT_SCALE = 886,
+ SI3218X_RAM_MADC_VLONG_SCALE = 887,
+ SI3218X_RAM_MADC_VLONG_SCALE_RING = 888,
+ SI3218X_RAM_UNUSED889 = 889,
+ SI3218X_RAM_MADC_VDC_SCALE = 890,
+ SI3218X_RAM_MADC_ILONG_SCALE = 891,
+ SI3218X_RAM_UNUSED892 = 892,
+ SI3218X_RAM_UNUSED893 = 893,
+ SI3218X_RAM_VDIFF_SENSE_SCALE = 894,
+ SI3218X_RAM_VDIFF_SENSE_SCALE_RING = 895,
+ SI3218X_RAM_VOV_RING_GND = 896,
+ SI3218X_RAM_DIAG_GAIN_DC = 897,
+ SI3218X_RAM_CAL_LB_OSC1_FREQ = 898,
+ SI3218X_RAM_CAL_DCDAC_9TAU = 899,
+ SI3218X_RAM_CAL_MADC_9TAU = 900,
+ SI3218X_RAM_ADAP_RING_MIN_I = 901,
+ SI3218X_RAM_SWEEP_STEP = 902,
+ SI3218X_RAM_SWEEP_STEP_SAVE = 903,
+ SI3218X_RAM_SWEEP_REF = 904,
+ SI3218X_RAM_AMP_STEP = 905,
+ SI3218X_RAM_RXACGAIN_SAVE = 906,
+ SI3218X_RAM_AMP_RAMP_INIT = 907,
+ SI3218X_RAM_DIAG_HPF_GAIN = 908,
+ SI3218X_RAM_DIAG_HPF_8K = 909,
+ SI3218X_RAM_DIAG_ADJ_STEP = 910,
+ SI3218X_RAM_UNUSED911 = 911,
+ SI3218X_RAM_UNUSED912 = 912,
+ SI3218X_RAM_MADC_SCALE_INV = 913,
+ SI3218X_RAM_UNUSED914 = 914,
+ SI3218X_RAM_PWRSAVE_TIMER = 915,
+ SI3218X_RAM_OFFHOOK_THRESH = 916,
+ SI3218X_RAM_SPEEDUP_MASK_TIMER = 917,
+ SI3218X_RAM_UNUSED918 = 918,
+ SI3218X_RAM_VBAT_TRACK_MIN = 919,
+ SI3218X_RAM_VBAT_TRACK_MIN_RNG = 920,
+ SI3218X_RAM_UNUSED921 = 921,
+ SI3218X_RAM_UNUSED922 = 922,
+ SI3218X_RAM_UNUSED923 = 923,
+ SI3218X_RAM_UNUSED924 = 924,
+ SI3218X_RAM_UNUSED925 = 925,
+ SI3218X_RAM_UNUSED926 = 926,
+ SI3218X_RAM_DC_HOLD_DAC_OS = 927,
+ SI3218X_RAM_UNUSED928 = 928,
+ SI3218X_RAM_NOTCH_B0 = 929,
+ SI3218X_RAM_NOTCH_B1 = 930,
+ SI3218X_RAM_NOTCH_B2 = 931,
+ SI3218X_RAM_NOTCH_A1 = 932,
+ SI3218X_RAM_NOTCH_A2 = 933,
+ SI3218X_RAM_METER_LPF_B0 = 934,
+ SI3218X_RAM_METER_LPF_B1 = 935,
+ SI3218X_RAM_METER_LPF_B2 = 936,
+ SI3218X_RAM_METER_LPF_A1 = 937,
+ SI3218X_RAM_METER_LPF_A2 = 938,
+ SI3218X_RAM_METER_SIG_0 = 939,
+ SI3218X_RAM_METER_SIG_1 = 940,
+ SI3218X_RAM_METER_SIG_2 = 941,
+ SI3218X_RAM_METER_SIG_3 = 942,
+ SI3218X_RAM_METER_SIG_4 = 943,
+ SI3218X_RAM_METER_SIG_5 = 944,
+ SI3218X_RAM_METER_SIG_6 = 945,
+ SI3218X_RAM_METER_SIG_7 = 946,
+ SI3218X_RAM_METER_SIG_8 = 947,
+ SI3218X_RAM_METER_SIG_9 = 948,
+ SI3218X_RAM_METER_SIG_10 = 949,
+ SI3218X_RAM_METER_SIG_11 = 950,
+ SI3218X_RAM_METER_SIG_12 = 951,
+ SI3218X_RAM_METER_SIG_13 = 952,
+ SI3218X_RAM_METER_SIG_14 = 953,
+ SI3218X_RAM_METER_SIG_15 = 954,
+ SI3218X_RAM_METER_BP_B0 = 955,
+ SI3218X_RAM_METER_BP_B1 = 956,
+ SI3218X_RAM_METER_BP_B2 = 957,
+ SI3218X_RAM_METER_BP_A1 = 958,
+ SI3218X_RAM_METER_BP_A2 = 959,
+ SI3218X_RAM_PM_AMP_THRESH = 960,
+ SI3218X_RAM_METER_GAIN = 961,
+ SI3218X_RAM_PWRSAVE_DBI = 962,
+ SI3218X_RAM_DCDC_ANA_SCALE = 963,
+ SI3218X_RAM_VOV_BAT_PWRSAVE_LO = 964,
+ SI3218X_RAM_VOV_BAT_PWRSAVE_HI = 965,
+ SI3218X_RAM_AC_ADC_GAIN0 = 966,
+ SI3218X_RAM_SCALE_KAUDIO = 967,
+ SI3218X_RAM_METER_GAIN_TEMP = 968,
+ SI3218X_RAM_METER_RAMP_STEP = 969,
+ SI3218X_RAM_THERM_DBI = 970,
+ SI3218X_RAM_LPR_SCALE = 971,
+ SI3218X_RAM_LPR_CM_OS = 972,
+ SI3218X_RAM_VOV_DCDC_SLOPE = 973,
+ SI3218X_RAM_VOV_DCDC_OS = 974,
+ SI3218X_RAM_VOV_RING_BAT_MAX = 975,
+ SI3218X_RAM_SLOPE_VLIM1 = 976,
+ SI3218X_RAM_SLOPE_RFEED1 = 977,
+ SI3218X_RAM_SLOPE_ILIM1 = 978,
+ SI3218X_RAM_V_VLIM1 = 979,
+ SI3218X_RAM_V_RFEED1 = 980,
+ SI3218X_RAM_V_ILIM1 = 981,
+ SI3218X_RAM_CONST_RFEED1 = 982,
+ SI3218X_RAM_CONST_ILIM1 = 983,
+ SI3218X_RAM_I_VLIM1 = 984,
+ SI3218X_RAM_SLOPE_VLIM2 = 985,
+ SI3218X_RAM_SLOPE_RFEED2 = 986,
+ SI3218X_RAM_SLOPE_ILIM2 = 987,
+ SI3218X_RAM_V_VLIM2 = 988,
+ SI3218X_RAM_V_RFEED2 = 989,
+ SI3218X_RAM_V_ILIM2 = 990,
+ SI3218X_RAM_CONST_RFEED2 = 991,
+ SI3218X_RAM_CONST_ILIM2 = 992,
+ SI3218X_RAM_I_VLIM2 = 993,
+ SI3218X_RAM_DIAG_V_TAR = 994,
+ SI3218X_RAM_DIAG_V_TAR2 = 995,
+ SI3218X_RAM_STOP_TIMER1_VAL = 996,
+ SI3218X_RAM_STOP_TIMER2_VAL = 997,
+ SI3218X_RAM_DIAG_VCM1_TAR = 998,
+ SI3218X_RAM_DIAG_VCM_STEP = 999,
+ SI3218X_RAM_LKG_DNT_HIRES = 1000,
+ SI3218X_RAM_LKG_DNR_HIRES = 1001,
+ SI3218X_RAM_LINEAR_OS = 1002,
+ SI3218X_RAM_CPUMP_DEB = 1003,
+ SI3218X_RAM_DCDC_VERR = 1004,
+ SI3218X_RAM_DCDC_VERR_HYST = 1005,
+ SI3218X_RAM_DCDC_OITHRESH_LO = 1006,
+ SI3218X_RAM_DCDC_OITHRESH_HI = 1007,
+ SI3218X_RAM_HV_BIAS_ONHK = 1008,
+ SI3218X_RAM_HV_BIAS_OFFHK = 1009,
+ SI3218X_RAM_UNUSED1010 = 1010,
+ SI3218X_RAM_UNUSED1011 = 1011,
+ SI3218X_RAM_UNUSED1012 = 1012,
+ SI3218X_RAM_UNUSED1013 = 1013,
+ SI3218X_RAM_ILONG_RT_THRESH = 1014,
+ SI3218X_RAM_VOV_RING_BAT_DCDC = 1015,
+ SI3218X_RAM_UNUSED1016 = 1016,
+ SI3218X_RAM_LKG_LB_OFFSET = 1017,
+ SI3218X_RAM_LKG_OFHK_OFFSET = 1018,
+ SI3218X_RAM_SWEEP_FREQ_TH = 1019,
+ SI3218X_RAM_AMP_MOD_G = 1020,
+ SI3218X_RAM_AMP_MOD_OS = 1021,
+ SI3218X_RAM_UNUSED1022 = 1022,
+ SI3218X_RAM_UNUSED1023 = 1023,
+ SI3218X_RAM_UNUSED_REG256 = 1280,
+ SI3218X_RAM_DAC_IN = 1281,
+ SI3218X_RAM_ADC_OUT = 1282,
+ SI3218X_RAM_PASS1 = 1283,
+ SI3218X_RAM_TX_AC_INT = 1284,
+ SI3218X_RAM_RX_AC_DIFF = 1285,
+ SI3218X_RAM_INDIRECT_WR = 1286,
+ SI3218X_RAM_INDIRECT_RD = 1287,
+ SI3218X_RAM_BYPASS_OUT = 1288,
+ SI3218X_RAM_ACC = 1289,
+ SI3218X_RAM_INDIRECT_RAM_A = 1290,
+ SI3218X_RAM_INDIRECT_RAM_B = 1291,
+ SI3218X_RAM_HOT_BIT1 = 1292,
+ SI3218X_RAM_HOT_BIT0 = 1293,
+ SI3218X_RAM_PASS0_ROW_PWR = 1294,
+ SI3218X_RAM_PASS0_COL_PWR = 1295,
+ SI3218X_RAM_PASS0_ROW = 1296,
+ SI3218X_RAM_PASS0_COL = 1297,
+ SI3218X_RAM_PASS0_ROW_REL = 1298,
+ SI3218X_RAM_PASS0_COL_REL = 1299,
+ SI3218X_RAM_PASS0_ROW_2ND = 1300,
+ SI3218X_RAM_PASS0_COL_2ND = 1301,
+ SI3218X_RAM_PASS0_REV_TW = 1302,
+ SI3218X_RAM_PASS0_FWD_TW = 1303,
+ SI3218X_RAM_DAA_ADC_OUT = 1304,
+ SI3218X_RAM_CAL_CM_BAL_TEST = 1305,
+ SI3218X_RAM_UNUSED_REG282 = 1306,
+ SI3218X_RAM_TONE1 = 1307,
+ SI3218X_RAM_TONE2 = 1308,
+ SI3218X_RAM_RING_TRIG = 1309,
+ SI3218X_RAM_VCM_DAC = 1310,
+ SI3218X_RAM_UNUSED_REG287 = 1311,
+ SI3218X_RAM_RING_DAC = 1312,
+ SI3218X_RAM_VRING_CROSSING = 1313,
+ SI3218X_RAM_UNUSED_REG290 = 1314,
+ SI3218X_RAM_LINEFEED_SHADOW = 1315,
+ SI3218X_RAM_UNUSED_REG292 = 1316,
+ SI3218X_RAM_UNUSED_REG293 = 1317,
+ SI3218X_RAM_UNUSED_REG294 = 1318,
+ SI3218X_RAM_ROW_DIGIT = 1319,
+ SI3218X_RAM_COL_DIGIT = 1320,
+ SI3218X_RAM_UNUSED_REG297 = 1321,
+ SI3218X_RAM_PQ1_IRQ = 1322,
+ SI3218X_RAM_PQ2_IRQ = 1323,
+ SI3218X_RAM_PQ3_IRQ = 1324,
+ SI3218X_RAM_PQ4_IRQ = 1325,
+ SI3218X_RAM_PQ5_IRQ = 1326,
+ SI3218X_RAM_PQ6_IRQ = 1327,
+ SI3218X_RAM_LCR_SET = 1328,
+ SI3218X_RAM_LCR_CLR = 1329,
+ SI3218X_RAM_RTP_SET = 1330,
+ SI3218X_RAM_LONG_SET = 1331,
+ SI3218X_RAM_LONG_CLR = 1332,
+ SI3218X_RAM_VDIFF_IRQ = 1333,
+ SI3218X_RAM_MODFEED_SET = 1334,
+ SI3218X_RAM_MODFEED_CLR = 1335,
+ SI3218X_RAM_LF_SPEEDUP_SET = 1336,
+ SI3218X_RAM_LF_SPEEDUP_CLR = 1337,
+ SI3218X_RAM_DC_SPEEDUP_SET = 1338,
+ SI3218X_RAM_DC_SPEEDUP_CLR = 1339,
+ SI3218X_RAM_AC_SPEEDUP_SET = 1340,
+ SI3218X_RAM_AC_SPEEDUP_CLR = 1341,
+ SI3218X_RAM_LCR_SPEEDUP_SET = 1342,
+ SI3218X_RAM_LCR_SPEEDUP_CLR = 1343,
+ SI3218X_RAM_CM_SPEEDUP_SET = 1344,
+ SI3218X_RAM_CM_SPEEDUP_CLR = 1345,
+ SI3218X_RAM_MODEMPASS0 = 1346,
+ SI3218X_RAM_RX2100_PASS1_PWR = 1347,
+ SI3218X_RAM_RX2100_PASS1_THR = 1348,
+ SI3218X_RAM_TX2100_PASS1_PWR = 1349,
+ SI3218X_RAM_TX2100_PASS1_THR = 1350,
+ SI3218X_RAM_TXMDM_TRIG = 1351,
+ SI3218X_RAM_RXMDM_TRIG = 1352,
+ SI3218X_RAM_UNUSED_REG329 = 1353,
+ SI3218X_RAM_TX_FILT_CLR = 1354,
+ SI3218X_RAM_TX_DC_INT = 1355,
+ SI3218X_RAM_RX_DC_MOD_IN = 1356,
+ SI3218X_RAM_DSP_ACCESS = 1357,
+ SI3218X_RAM_PRAM_ADDR = 1358,
+ SI3218X_RAM_PRAM_DATA = 1359,
+ SI3218X_RAM_IND_RAM_A_BASE = 1360,
+ SI3218X_RAM_IND_RAM_A_ADDR = 1361,
+ SI3218X_RAM_IND_RAM_A_MOD = 1362,
+ SI3218X_RAM_IND_RAM_B_BASE = 1363,
+ SI3218X_RAM_IND_RAM_B_ADDR = 1364,
+ SI3218X_RAM_IND_RAM_B_MOD = 1365,
+ SI3218X_RAM_UNUSED_REG342 = 1366,
+ SI3218X_RAM_UNUSED_REG343 = 1367,
+ SI3218X_RAM_UNUSED_REG344 = 1368,
+ SI3218X_RAM_USER_B0 = 1369,
+ SI3218X_RAM_USER_B1 = 1370,
+ SI3218X_RAM_USER_B2 = 1371,
+ SI3218X_RAM_USER_B3 = 1372,
+ SI3218X_RAM_USER_B4 = 1373,
+ SI3218X_RAM_USER_B5 = 1374,
+ SI3218X_RAM_USER_B6 = 1375,
+ SI3218X_RAM_USER_B7 = 1376,
+ SI3218X_RAM_FLUSH_AUDIO_CLR = 1377,
+ SI3218X_RAM_FLUSH_DC_CLR = 1378,
+ SI3218X_RAM_SPR_CLR = 1379,
+ SI3218X_RAM_GPI0 = 1380,
+ SI3218X_RAM_GPI1 = 1381,
+ SI3218X_RAM_GPI2 = 1382,
+ SI3218X_RAM_GPI3 = 1383,
+ SI3218X_RAM_GPO0 = 1384,
+ SI3218X_RAM_GPO1 = 1385,
+ SI3218X_RAM_GPO2 = 1386,
+ SI3218X_RAM_GPO3 = 1387,
+ SI3218X_RAM_GPO0_OE = 1388,
+ SI3218X_RAM_GPO1_OE = 1389,
+ SI3218X_RAM_GPO2_OE = 1390,
+ SI3218X_RAM_GPO3_OE = 1391,
+ SI3218X_RAM_BATSEL_L_SET = 1392,
+ SI3218X_RAM_BATSEL_H_SET = 1393,
+ SI3218X_RAM_BATSEL_R_SET = 1394,
+ SI3218X_RAM_BATSEL_CLR = 1395,
+ SI3218X_RAM_VBAT_IRQ = 1396,
+ SI3218X_RAM_MADC_VTIPC_RAW = 1397,
+ SI3218X_RAM_MADC_VRINGC_RAW = 1398,
+ SI3218X_RAM_MADC_VBAT_RAW = 1399,
+ SI3218X_RAM_MADC_VLONG_RAW = 1400,
+ SI3218X_RAM_UNUSED_REG377 = 1401,
+ SI3218X_RAM_MADC_VDC_RAW = 1402,
+ SI3218X_RAM_MADC_ILONG_RAW = 1403,
+ SI3218X_RAM_UNUSED_REG380 = 1404,
+ SI3218X_RAM_UNUSED_REG381 = 1405,
+ SI3218X_RAM_MADC_ILOOP_RAW = 1406,
+ SI3218X_RAM_MADC_DIAG_RAW = 1407,
+ SI3218X_RAM_UNUSED_REG384 = 1408,
+ SI3218X_RAM_UNUSED_REG385 = 1409,
+ SI3218X_RAM_CALR3_DSP = 1410,
+ SI3218X_RAM_PD_MADC = 1411,
+ SI3218X_RAM_UNUSED_REG388 = 1412,
+ SI3218X_RAM_PD_BIAS = 1413,
+ SI3218X_RAM_PD_DC_ADC = 1414,
+ SI3218X_RAM_PD_DC_DAC = 1415,
+ SI3218X_RAM_PD_DC_SNS = 1416,
+ SI3218X_RAM_PD_DC_COARSE_SNS = 1417,
+ SI3218X_RAM_PD_VBAT_SNS = 1418,
+ SI3218X_RAM_PD_DC_BUF = 1419,
+ SI3218X_RAM_PD_AC_ADC = 1420,
+ SI3218X_RAM_PD_AC_DAC = 1421,
+ SI3218X_RAM_PD_AC_SNS = 1422,
+ SI3218X_RAM_PD_CM_SNS = 1423,
+ SI3218X_RAM_PD_CM = 1424,
+ SI3218X_RAM_UNUSED_REG401 = 1425,
+ SI3218X_RAM_UNUSED_REG402 = 1426,
+ SI3218X_RAM_PD_SUM = 1427,
+ SI3218X_RAM_PD_LKGDAC = 1428,
+ SI3218X_RAM_UNUSED_REG405 = 1429,
+ SI3218X_RAM_PD_HVIC = 1430,
+ SI3218X_RAM_UNUSED_REG407 = 1431,
+ SI3218X_RAM_CMDAC_CHEN_B = 1432,
+ SI3218X_RAM_SUM_CHEN_B = 1433,
+ SI3218X_RAM_TRNRD_CHEN_B = 1434,
+ SI3218X_RAM_UNUSED_REG411 = 1435,
+ SI3218X_RAM_DC_BUF_CHEN_B = 1436,
+ SI3218X_RAM_AC_SNS_CHEN_B = 1437,
+ SI3218X_RAM_DC_SNS_CHEN_B = 1438,
+ SI3218X_RAM_LB_MUX_CHEN_B = 1439,
+ SI3218X_RAM_UNUSED_REG416 = 1440,
+ SI3218X_RAM_CMDAC_EN_B = 1441,
+ SI3218X_RAM_RA_EN_B = 1442,
+ SI3218X_RAM_RD_EN_B = 1443,
+ SI3218X_RAM_VCTL = 1444,
+ SI3218X_RAM_UNUSED_REG421 = 1445,
+ SI3218X_RAM_UNUSED_REG422 = 1446,
+ SI3218X_RAM_HVIC_STATE = 1447,
+ SI3218X_RAM_HVIC_STATE_OBSERVE = 1448,
+ SI3218X_RAM_HVIC_STATE_MAN = 1449,
+ SI3218X_RAM_HVIC_STATE_READ = 1450,
+ SI3218X_RAM_UNUSED_REG427 = 1451,
+ SI3218X_RAM_VCMDAC_SCALE_MAN = 1452,
+ SI3218X_RAM_CAL_ACADC_CNTL = 1453,
+ SI3218X_RAM_CAL_ACDAC_CNTL = 1454,
+ SI3218X_RAM_UNUSED_REG431 = 1455,
+ SI3218X_RAM_CAL_DCDAC_CNTL = 1456,
+ SI3218X_RAM_CAL_TRNRD_CNTL = 1457,
+ SI3218X_RAM_CAL_TRNRD_DACT = 1458,
+ SI3218X_RAM_CAL_TRNRD_DACR = 1459,
+ SI3218X_RAM_LKG_UPT_ACTIVE = 1460,
+ SI3218X_RAM_LKG_UPR_ACTIVE = 1461,
+ SI3218X_RAM_LKG_DNT_ACTIVE = 1462,
+ SI3218X_RAM_LKG_DNR_ACTIVE = 1463,
+ SI3218X_RAM_LKG_UPT_OHT = 1464,
+ SI3218X_RAM_LKG_UPR_OHT = 1465,
+ SI3218X_RAM_LKG_DNT_OHT = 1466,
+ SI3218X_RAM_LKG_DNR_OHT = 1467,
+ SI3218X_RAM_CAL_LKG_EN_CNTL = 1468,
+ SI3218X_RAM_CAL_PUPD_CNTL = 1469,
+ SI3218X_RAM_UNUSED_REG446 = 1470,
+ SI3218X_RAM_CAL_AC_RCAL = 1471,
+ SI3218X_RAM_CAL_DC_RCAL = 1472,
+ SI3218X_RAM_KAC_MOD = 1473,
+ SI3218X_RAM_KAC_SEL = 1474,
+ SI3218X_RAM_SEL_RING = 1475,
+ SI3218X_RAM_CMDAC_FWD = 1476,
+ SI3218X_RAM_CMDAC_RVS = 1477,
+ SI3218X_RAM_CAL_INC_STATE = 1478,
+ SI3218X_RAM_CAL_DCDAC_COMP = 1479,
+ SI3218X_RAM_BAT_SWITCH = 1480,
+ SI3218X_RAM_CH_IRQ = 1481,
+ SI3218X_RAM_ILOOP_CROSSING = 1482,
+ SI3218X_RAM_VOC_FAILSAFE = 1483,
+ SI3218X_RAM_UNUSED_REG460 = 1484,
+ SI3218X_RAM_UNUSED_REG461 = 1485,
+ SI3218X_RAM_GENERIC_0 = 1486,
+ SI3218X_RAM_GENERIC_1 = 1487,
+ SI3218X_RAM_GENERIC_2 = 1488,
+ SI3218X_RAM_GENERIC_3 = 1489,
+ SI3218X_RAM_GENERIC_4 = 1490,
+ SI3218X_RAM_GENERIC_5 = 1491,
+ SI3218X_RAM_GENERIC_6 = 1492,
+ SI3218X_RAM_GENERIC_7 = 1493,
+ SI3218X_RAM_UNUSED_REG470 = 1494,
+ SI3218X_RAM_UNUSED_REG471 = 1495,
+ SI3218X_RAM_QHI_SET = 1496,
+ SI3218X_RAM_QHI_CLR = 1497,
+ SI3218X_RAM_UNUSED_REG474 = 1498,
+ SI3218X_RAM_RDC_SUM = 1499,
+ SI3218X_RAM_UNUSED_REG476 = 1500,
+ SI3218X_RAM_UNUSED_REG477 = 1501,
+ SI3218X_RAM_UNUSED_REG478 = 1502,
+ SI3218X_RAM_UNUSED_REG479 = 1503,
+ SI3218X_RAM_UNUSED_REG480 = 1504,
+ SI3218X_RAM_UNUSED_REG481 = 1505,
+ SI3218X_RAM_FLUSH_AUDIO_MAN = 1506,
+ SI3218X_RAM_FLUSH_DC_MAN = 1507,
+ SI3218X_RAM_TIP_RING_CNTL = 1508,
+ SI3218X_RAM_SQUELCH_SET = 1509,
+ SI3218X_RAM_SQUELCH_CLR = 1510,
+ SI3218X_RAM_CAL_STATE_MAN = 1511,
+ SI3218X_RAM_UNUSED_REG488 = 1512,
+ SI3218X_RAM_UNUSED_REG489 = 1513,
+ SI3218X_RAM_RINGING_BW = 1514,
+ SI3218X_RAM_AUDIO_MAN = 1515,
+ SI3218X_RAM_HVIC_STATE_SPARE = 1516,
+ SI3218X_RAM_RINGING_FAST_MAN = 1517,
+ SI3218X_RAM_VCM_DAC_MAN = 1518,
+ SI3218X_RAM_UNUSED_REG495 = 1519,
+ SI3218X_RAM_UNUSED_REG496 = 1520,
+ SI3218X_RAM_UNUSED_REG497 = 1521,
+ SI3218X_RAM_GENERIC_8 = 1522,
+ SI3218X_RAM_GENERIC_9 = 1523,
+ SI3218X_RAM_GENERIC_10 = 1524,
+ SI3218X_RAM_GENERIC_11 = 1525,
+ SI3218X_RAM_UNUSED_REG502 = 1526,
+ SI3218X_RAM_GENERIC_12 = 1527,
+ SI3218X_RAM_GENERIC_13 = 1528,
+ SI3218X_RAM_UNUSED_REG505 = 1529,
+ SI3218X_RAM_DC_HOLD_DAC = 1530,
+ SI3218X_RAM_OFFHOOK_CMP = 1531,
+ SI3218X_RAM_PWRSAVE_SET = 1532,
+ SI3218X_RAM_PWRSAVE_CLR = 1533,
+ SI3218X_RAM_PD_WKUP = 1534,
+ SI3218X_RAM_SPEEDUP_MASK_SET = 1535,
+ SI3218X_RAM_SPEEDUP_MASK_CLR = 1536,
+ SI3218X_RAM_UNUSED_REG513 = 1537,
+ SI3218X_RAM_PD_DCDC = 1538,
+ SI3218X_RAM_UNUSED_REG515 = 1539,
+ SI3218X_RAM_PD_UVLO = 1540,
+ SI3218X_RAM_PD_OVLO = 1541,
+ SI3218X_RAM_PD_OCLO = 1542,
+ SI3218X_RAM_PD_SWDRV = 1543,
+ SI3218X_RAM_UNUSED_REG520 = 1544,
+ SI3218X_RAM_DCDC_UVHYST = 1545,
+ SI3218X_RAM_DCDC_UVTHRESH = 1546,
+ SI3218X_RAM_DCDC_OVTHRESH = 1547,
+ SI3218X_RAM_DCDC_OITHRESH = 1548,
+ SI3218X_RAM_UNUSED_REG525 = 1549,
+ SI3218X_RAM_UNUSED_REG526 = 1550,
+ SI3218X_RAM_DCDC_STATUS = 1551,
+ SI3218X_RAM_UNUSED_REG528 = 1552,
+ SI3218X_RAM_DCDC_SWDRV_POL = 1553,
+ SI3218X_RAM_DCDC_UVPOL = 1554,
+ SI3218X_RAM_DCDC_CPUMP = 1555,
+ SI3218X_RAM_UNUSED_REG532 = 1556,
+ SI3218X_RAM_DCDC_VREF_MAN = 1557,
+ SI3218X_RAM_DCDC_VREF_CTRL = 1558,
+ SI3218X_RAM_UNUSED_REG535 = 1559,
+ SI3218X_RAM_DCDC_RNGTYPE = 1560,
+ SI3218X_RAM_DCDC_DIN_FILT = 1561,
+ SI3218X_RAM_UNUSED_REG538 = 1562,
+ SI3218X_RAM_DCDC_DOUT = 1563,
+ SI3218X_RAM_UNUSED_REG540 = 1564,
+ SI3218X_RAM_DCDC_OIMASK = 1565,
+ SI3218X_RAM_UNUSED_REG542 = 1566,
+ SI3218X_RAM_UNUSED_REG543 = 1567,
+ SI3218X_RAM_DCDC_SC_SET = 1568,
+ SI3218X_RAM_WAKE_HOLD = 1569,
+ SI3218X_RAM_PD_AC_SQUELCH = 1570,
+ SI3218X_RAM_PD_REF_OSC = 1571,
+ SI3218X_RAM_UNUSED_REG548 = 1572,
+ SI3218X_RAM_PWRSAVE_MAN = 1573,
+ SI3218X_RAM_PWRSAVE_SEL = 1574,
+ SI3218X_RAM_PWRSAVE_CTRL_LO = 1575,
+ SI3218X_RAM_PWRSAVE_CTRL_HI = 1576,
+ SI3218X_RAM_PWRSAVE_HVIC_LO = 1577,
+ SI3218X_RAM_PWRSAVE_HVIC_HI = 1578,
+ SI3218X_RAM_DSP_PROM_MISR = 1579,
+ SI3218X_RAM_DSP_CROM_MISR = 1580,
+ SI3218X_RAM_DAA_PROM_MISR = 1581,
+ SI3218X_RAM_DAA_CROM_MISR = 1582,
+ SI3218X_RAM_RAMBIST_ERROR = 1583,
+ SI3218X_RAM_DCDC_ANA_VREF = 1584,
+ SI3218X_RAM_DCDC_ANA_GAIN = 1585,
+ SI3218X_RAM_DCDC_ANA_TOFF = 1586,
+ SI3218X_RAM_DCDC_ANA_TONMIN = 1587,
+ SI3218X_RAM_DCDC_ANA_TONMAX = 1588,
+ SI3218X_RAM_DCDC_ANA_DSHIFT = 1589,
+ SI3218X_RAM_DCDC_ANA_LPOLY = 1590,
+ SI3218X_RAM_DCDC_ANA_PSKIP = 1591,
+ SI3218X_RAM_PD_DCDC_ANA = 1592,
+ SI3218X_RAM_UNUSED_REG569 = 1593,
+ SI3218X_RAM_UNUSED_REG570 = 1594,
+ SI3218X_RAM_PWRPEND_SET = 1595,
+ SI3218X_RAM_PD_CM_BUF = 1596,
+ SI3218X_RAM_JMP8 = 1597,
+ SI3218X_RAM_JMP9 = 1598,
+ SI3218X_RAM_JMP10 = 1599,
+ SI3218X_RAM_JMP11 = 1600,
+ SI3218X_RAM_JMP12 = 1601,
+ SI3218X_RAM_JMP13 = 1602,
+ SI3218X_RAM_JMP14 = 1603,
+ SI3218X_RAM_JMP15 = 1604,
+ SI3218X_RAM_METER_TRIG = 1605,
+ SI3218X_RAM_PM_ACTIVE = 1606,
+ SI3218X_RAM_PM_INACTIVE = 1607,
+ SI3218X_RAM_HVIC_VERSION = 1608,
+ SI3218X_RAM_THERM_OFF = 1609,
+ SI3218X_RAM_THERM_HI = 1610,
+ SI3218X_RAM_TEST_LOAD = 1611,
+ SI3218X_RAM_DC_HOLD_MAN = 1612,
+ SI3218X_RAM_DC_HOLD_DAC_MAN = 1613,
+ SI3218X_RAM_UNUSED_REG590 = 1614,
+ SI3218X_RAM_DCDC_CPUMP_LP = 1615,
+ SI3218X_RAM_DCDC_CPUMP_LP_MASK = 1616,
+ SI3218X_RAM_DCDC_CPUMP_PULLDOWN = 1617,
+ SI3218X_RAM_BOND_STATUS = 1618,
+ SI3218X_RAM_BOND_MAN = 1619,
+ SI3218X_RAM_BOND_VAL = 1620,
+ SI3218X_RAM_REF_DEBOUNCE_PCLK = 1633,
+ SI3218X_RAM_REF_DEBOUNCE_FSYNC = 1634,
+ SI3218X_RAM_DCDC_LIFT_EN = 1635,
+ SI3218X_RAM_DCDC_CPUMP_PGOOD = 1636,
+ SI3218X_RAM_DCDC_CPUMP_PGOOD_WKEN = 1637,
+ SI3218X_RAM_DCDC_CPUMP_PGOOD_FRC = 1638,
+ SI3218X_RAM_DCDC_CPUMP_LP_MASK_SH = 1639,
+ SI3218X_RAM_DCDC_UV_MAN = 1640,
+ SI3218X_RAM_DCDC_UV_DEBOUNCE = 1641,
+ SI3218X_RAM_DCDC_OV_MAN = 1642,
+ SI3218X_RAM_DCDC_OV_DEBOUNCE = 1643,
+ SI3218X_RAM_ANALOG3_TEST_MUX = 1644,
+};
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice.h
new file mode 100644
index 0000000..fe03c58
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice.h
@@ -0,0 +1,949 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the main header file for the ProSLIC API software.
+ *
+ *
+ */
+
+#ifndef SI_VOICE_H
+#define SI_VOICE_H
+
+#include "../config_inc/proslic_api_config.h"
+#include "si_voice_ctrl.h"
+#include "si_voice_timer_intf.h"
+
+/* The following macros are in place so that if the customer did not define them, the "safe" default is not disable the functionality.*/
+#ifndef ENABLE_DEBUG
+#define DEBUG_PRINT(...)
+#define DEBUG_ENABLED(X) 0
+#endif
+
+#ifndef ENABLE_TRACES
+#define TRACE_ENABLED(X) 0
+#define TRACEPRINT(...)
+#define TRACEPRINT_NOCHAN(...)
+#endif
+
+#ifndef LOGPRINT
+#define LOGPRINT(...)
+#endif
+
+#define SILABS_UNREFERENCED_PARAMETER(param) (void)param
+
+/** @defgroup SIVOICE SiVoice definitions
+
+ * @{
+ */
+/*****************************************************************************/
+/** @defgroup CHIPFAM Chip family definitions
+ * @{
+ */
+#define SI3217X_TYPE 4 /**< Single channel chipset*/
+#define SI3226X_TYPE 5 /**< Dual channel chipset */
+#define SI3218X_TYPE 6 /**< Single channel chipset*/
+#define SI3228X_TYPE 7 /**< Dual channel chipset */
+#define SI3228X_TYPE 7 /**< Dual channel chipset */
+#define SI3219X_TYPE 8 /**< Single channel chipset*/
+#define SI3050_TYPE 20 /**< Single channel FXO chipset */
+
+/** @} CHIPFAM */
+/*****************************************************************************/
+
+
+/*
+* Workaroud for building on windows systems
+*/
+
+#ifdef RC_NONE
+#undef RC_NONE
+#endif
+
+#define SIVOICE_RC_NONE RC_NONE
+
+/**
+* This is the main Silicon Labs control interface object. do not access directly!
+*/
+typedef struct
+{
+ void *hCtrl; /**< user provided SPI/GCI structure */
+ ctrl_Reset_fptr Reset_fptr; /**< user provided reset function */
+ ctrl_WriteRegister_fptr
+ WriteRegister_fptr; /**< user provided SPI/GCI write register function */
+ ctrl_ReadRegister_fptr
+ ReadRegister_fptr; /**< user provided SPI/GI read register function */
+ ctrl_WriteRAM_fptr
+ WriteRAM_fptr; /**< ProSLIC only - user provided SPI/GCI read RAM/Indirect register function */
+ ctrl_ReadRAM_fptr ReadRAM_fptr; /**< ProSLIC only */
+ ctrl_Semaphore_fptr Semaphore_fptr; /**< ProSLIC only */
+ void *hTimer; /**< user provided Timer data structure */
+ system_delay_fptr
+ Delay_fptr; /**< user supplied mSec delay function */
+ system_timeElapsed_fptr
+ timeElapsed_fptr; /**< user provided mSec time elapsed function */
+ system_getTime_fptr
+ getTime_fptr; /**< user provided timestamp function */
+} SiVoiceControlInterfaceType;
+
+/* MAINTAINER NOTE: if this changes, update deubg.c in the API demo */
+typedef enum
+{
+ SI32171, /* '170 is the HV version of this part */
+ SI32172, /* '173 is the HV version of this part */
+ SI32174,
+ SI32175,
+ SI32176,
+ SI32177,
+ SI32178,
+ SI32179,
+ SI32260,
+ SI32261,
+ SI32262,
+ SI32263,
+ SI32264,
+ SI32265,
+ SI32266,
+ SI32267,
+ SI32268,
+ SI32269,
+ SI32360,
+ SI32361,
+ SI32180,
+ SI32181,
+ SI32182,
+ SI32183,
+ SI32184,
+ SI32185,
+ SI32186,
+ SI32187,
+ SI32188,
+ SI32189, /* Place holder */
+ SI32280,
+ SI32281,
+ SI32282,
+ SI32283,
+ SI32284,
+ SI32285,
+ SI32286,
+ SI32287,
+ SI32289, /* Place holder */
+ SI32190, /* NOT all parts numbers are used at this time and are placeholders */
+ SI32191,
+ SI32192,
+ SI32193,
+ SI32194,
+ SI32195,
+ SI32196,
+ SI32197,
+ SI32198,
+ SI32199,
+ SI3050 = 100,
+ UNSUPPORTED_PART_NUM = 255
+} partNumberType;
+
+#define IS_SI3219X(SI_DEVPTR) ( ( (SI_DEVPTR)->chipType >= SI32190) && ( (SI_DEVPTR)->chipType <= SI32199) )
+
+/**
+* Chip revision definition for easier readability in the source code
+*/
+typedef enum
+{
+ A,
+ B,
+ C,
+ D,
+ E,
+ F,
+ G
+} revisionType ;
+
+
+typedef enum
+{
+ UNKNOWN, /**< Channel type has not been initialized or is still unknown */
+ PROSLIC, /**< Channel type is a ProSLIC/FXS */
+ DAA /**< Channel type is a DAA/FXO */
+} channelTypeType;
+
+/**
+* These are the error codes for ProSLIC failures
+*/
+typedef enum
+{
+ RC_IGNORE = 0,
+ RC_NONE= 0, /**< Means the function did not encounter an error */
+ RC_TEST_PASSED = 0,
+ RC_TEST_FAILED = 1,
+ RC_COMPLETE_NO_ERR = 1, /**< A test completed, no error detected */
+ RC_POWER_ALARM_Q1,
+ RC_POWER_ALARM_Q2,
+ RC_POWER_ALARM_Q3,
+ RC_POWER_ALARM_Q4,
+ RC_POWER_ALARM_Q5,
+ RC_POWER_ALARM_Q6,
+ RC_SPI_FAIL, /**< SPI Communications failure */
+ RC_POWER_LEAK,
+ RC_VBAT_UP_TIMEOUT,
+ RC_VBAT_OUT_OF_RANGE,
+ RC_VBAT_DOWN_TIMEOUT,
+ RC_TG_RG_SHORT,
+ RC_CM_CAL_ERR,
+ RC_RING_FAIL_INT,
+ RC_CAL_TIMEOUT,
+ RC_PATCH_ERR,
+ RC_BROADCAST_FAIL, /**< Broadcast unavailable for requested operation */
+ RC_UNSUPPORTED_FEATURE, /**< Feature is not supported by the chipset*/
+ RC_CHANNEL_TYPE_ERR, /**< Channel type does not support called function */
+ RC_GAIN_DELTA_TOO_LARGE, /**< Requested gain delta too large */
+ RC_GAIN_OUT_OF_RANGE, /**< Gain requested exceeds range */
+ RC_POWER_ALARM_HVIC, /**< Power alarm on HVIC */
+ RC_POWER_ALARM_OFFLD, /**< Power alarm on offload transistor */
+ RC_THERMAL_ALARM_HVIC, /**< Thermal alarm detected */
+ RC_NO_MEM, /**< Out of memory */
+ RC_INVALID_GEN_PARAM, /**< Invalid general parameter */
+ RC_LINE_IN_USE, /**< Line is in use (LCS detected) */
+ RC_RING_V_LIMITED, /**< Ringer voltage limited - signal may be clipped */
+ RC_PSTN_CHECK_SINGLE_FAIL, /**< PSTN detect single current exceeds limit */
+ RC_PSTN_CHECK_AVG_FAIL, /**< PSTN detect average current exceeds limit */
+ RC_VDAA_ILOOP_OVLD, /**< Overload detected */
+ RC_UNSUPPORTED_OPTION, /**< Function parameter is not supported at this time */
+ RC_FDT_TIMEOUT, /**< Timeout waiting for valid frame detect */
+ RC_PSTN_OPEN_FEMF, /**< Detected FEMF, device left in open state */
+ RC_VDAA_PAR_HANDSET_DET, /**< Parallel handset detected */
+ RC_VDAA_PAR_HANDSET_NOT_DET, /**< Parallel handset not detected */
+ RC_PATCH_RAM_VERIFY_FAIL, /**< Patch RAM verification failure */
+ RC_PATCH_ENTRY_VERIFY_FAIL, /**< Patch entry table verification failure */
+ RC_UNSUPPORTED_DEVICE_REV, /**< Device revision not supported */
+ RC_INVALID_PATCH, /**< No patch for selected options */
+ RC_INVALID_PRESET, /**< Invalid Preset value */
+ RC_TEST_DISABLED, /**< Test Not enabled */
+ RC_RING_START_FAIL, /**< Ringing failed to start */
+ RC_MWI_ENABLE_FAIL, /**< Failed to enable MWI feature */
+ RC_MWI_IN_USE, /**< MWI active and unable to be modified */
+ RC_MWI_NOT_ENABLED, /**< MWI not enabled */
+ RC_DCDC_SETUP_ERR, /**< DCDC not properly initialized prior to powerup */
+ RC_PLL_FREERUN_ACTIVE, /**< PLL In Freerun Mode */
+ RC_UNSUPPORTED_VDC_RANGE, /**< VDC Range Unsupported */
+ RC_NON_FATAL_INIT_ERR, /**< Generic error to indicate a non-fatal error during init */
+ RSPI_CONNECTION_FAILED, /**< Client disconnected from server or vice versa */
+ RC_REINIT_REQUIRED = 255 /**< Soft Reset Required */
+} errorCodeType;
+
+/**********************************************************************/
+/**
+ * @defgroup PROLSIC_BRD_DESIGN Board design settings
+ * @{
+ */
+/**
+* BOM Option Tag - refer to hardware design
+*/
+
+typedef enum
+{
+ DEFAULT, /**< DCDC: Unspecified */
+ BO_DCDC_FLYBACK, /**< DCDC: flyback design */
+ BO_DCDC_LCQC_7P6W, /**< DCDC: quasi-cuk design */
+ BO_DCDC_QCUK = BO_DCDC_LCQC_7P6W, /**< @deprecated DCDC: quasi-cuk design (deprecated name, use BO_DCDC_LCQC_7P6W) */
+ BO_DCDC_BUCK_BOOST, /**< DCDC: BJT buck-boost design */
+ BO_DCDC_LCQC_3W, /**< DCDC: low-cost quasi-cuk design */
+ BO_DCDC_LCQCUK = BO_DCDC_LCQC_3W, /**< DCDC: low-cost quasi-cuk design */
+ BO_DCDC_P_BUCK_BOOST_5V, /**< @deprecated DCDC: PMOS buck-boost 5v design */
+ BO_DCDC_P_BUCK_BOOST_12V, /**< @deprecated DCDC: PMOS buck-boost 12v design */
+ BO_DCDC_P_BUCK_BOOST_12V_HV, /**< @deprecated DCDC: PMOS buck-boost 12v design, high voltage */
+ BO_DCDC_CUK, /**< DCDC: full cuk design */
+ BO_DCDC_PMOS_BUCK_BOOST, /**< @deprecated DCDC: PMOS buck-boost design */
+ BO_DCDC_LCQC_6W, /**< DCDC: low cost quasi-cuk design, 6W capability */
+ BO_DCDC_LCQC_5W, /**< DCDC: low cost quasi-cuk design, 5W capability - '180 & '280 parts */
+ BO_DCDC_LCCB, /**< DCDC: low cost capacitive boost design - '180 & '280 parts */
+ BO_DCDC_LCUB,
+ BO_DCDC_LCCB110,
+ BO_DCDC_LCFB
+} bomOptionsType;
+
+/**
+* VDC input voltage range option tags - please refer hardware design
+*/
+typedef enum
+{
+ VDC_3P0_6P0,
+ VDC_4P5_16P0,
+ VDC_4P5_27P0,
+ VDC_7P0_20P0,
+ VDC_8P0_16P0,
+ VDC_9P0_15P0,
+ VDC_9P0_16P0,
+ VDC_9P0_24P0,
+ VDC_10P8_20P0,
+ VDC_27P0_42P0,
+ VDC_10P8_13P2
+} vdcRangeType;
+
+/**
+* Battery Rail option tags - please refer hardware design
+*/
+typedef enum
+{
+ BO_DCDC_TSS, /**< Used for Fixed Rail DC-DC supplies */
+ BO_DCDC_TRACKING, /**< Used for Tracking DC-DC supplies */
+ BO_DCDC_EXTERNAL, /**< Used for external fixed rail supplies */
+ BO_DCDC_TSS_ISO, /**< Used for isolated TSS supplies */
+ BO_DCDC_QSS, /**< Used for QSS Designs */
+ BO_DCDC_FIXED_RAIL = BO_DCDC_TSS /**< Fixed rail replaced by TSS */
+#ifndef SIVOICE_CFG_NEWTYPES_ONLY
+ ,FIXED = BO_DCDC_FIXED_RAIL /**< @deprecated use BO_DCDC_FIXED_RAIL */
+ ,TRACKING = BO_DCDC_TRACKING /**< @deprecated use BO_DCDC_TRACKING */
+#endif
+ ,BO_DCDC_UNKNOWN
+} batRailType;
+
+/**
+* FET Gate Driver option tags
+*/
+
+typedef enum
+{
+ BO_GDRV_NOT_INSTALLED = 0,
+ BO_GDRV_INSTALLED = 1
+} gateDriveType;
+
+/**
+* Auto ZCAL Enable option tags
+*/
+
+typedef enum
+{
+ AUTO_ZCAL_DISABLED = 0,
+ AUTO_ZCAL_ENABLED = 1
+} autoZcalType;
+
+/**
+* VDAA Support option tags
+*/
+typedef enum
+{
+ VDAA_DISABLED = 0,
+ VDAA_ENABLED = 1
+} vdaaSupportType;
+
+/**
+* PM BOM Support option tags
+*/
+
+typedef enum
+{
+ BO_STD_BOM,
+ BO_PM_BOM
+} pmBomType;
+
+/**
+* Initialization options to allow init flow and/or content to be
+* altered at runtime
+*/
+typedef enum
+{
+ INIT_NO_OPT, /**< No initialization option */
+ INIT_REINIT, /**< Reinitialization option */
+ INIT_NO_CAL, /**< Skip calibration only - DEBUG use only */
+ INIT_NO_PATCH_LOAD, /**< Skip patch load - DEBUG use only */
+ INIT_SOFTRESET /**< SLIC is running after a SOC reset */
+} initOptionsType;
+
+/**
+** This is the main Voice device object
+*/
+typedef struct
+{
+ SiVoiceControlInterfaceType
+ *ctrlInterface; /**< How do we talk to the system? User supplied functions are connected here */
+ revisionType chipRev; /**< What revision is the chip? */
+ partNumberType chipType; /**< What member of the particular family is this chip? */
+ uInt8 lsRev; /**< DAA: what rev is the line side chip? */
+ uInt8 lsType; /**< DAA: what type is the line side chip */
+} SiVoiceDeviceType;
+
+typedef SiVoiceDeviceType *SiVoiceDeviceType_ptr; /**< Shortcut typedef */
+
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+/*
+** Defines structure for storing MWI params
+*/
+typedef struct
+{
+ ramData ringof;
+ ramData ringamp;
+ ramData vbatr_expect;
+ ramData vov_ring_bat;
+ ramData vov_ring_gnd;
+ ramData rtacth;
+ ramData rtdcth;
+ ramData iring_lim;
+ ramData dcdc_rngtype;
+ ramData slope_ring;
+ ramData rtper;
+ ramData ringfr;
+ ramData rtdcdb;
+ ramData lcrmask;
+ ramData dcdc_oithresh_lo;
+ uInt8 enhance;
+ uInt8 ringcon;
+ uInt8 userstat;
+ uInt8 linefeed;
+} SiVoice_MWI_Store;
+#endif
+
+/* Define a complete ring cadence */
+typedef struct
+{
+ uInt32 steps; /* In ticks */
+ uInt32 onTime;
+ uInt32 offTime; /* "" */
+ uInt32 step_size;
+ uInt32 von;
+ uInt32 voff;
+} SiVoice_MWI_poll_t;
+
+typedef enum
+{
+ PROSLIC_MWI_ON,
+ PROSLIC_MWI_OFF,
+ PROSLIC_MWI_RAMP_ON,
+ PROSLIC_MWI_RAMP_OFF
+} SiVoice_MWIrampStates_t;
+
+typedef struct
+{
+ SiVoice_MWI_poll_t poll;
+ SiVoice_MWIrampStates_t state;
+ uInt32 ticks; /* How many ticks left to next state? */
+} SiVoice_MWIrampState_t;
+
+/**
+** This is the main ProSLIC channel object
+*/
+typedef struct
+{
+ SiVoiceDeviceType_ptr
+ deviceId; /**< Information about the device associated with this channel */
+ uInt8 channel; /**< Which channel is this device? This is a system parameter meaning if you have 2 dual channel devices in your system, this number would then typically go from 0-3 */
+ channelTypeType channelType; /**< Is this a ProSLIC or a DAA */
+ errorCodeType error; /**< Storage for the current error state - used only for APIs that don't return back an error */
+ int debugMode; /**< Are we debugging on this channel? */
+ int channelEnable; /**< is the channel enabled or not? If not, this channel is not initialized */
+ bomOptionsType bomOption; /**< Device/PCB specific */
+ uInt8 dcdc_polarity_invert; /**< Invert DCDC polarity from what is provided in general parameters */
+ uInt8 scratch; /**< Internal use only */
+ uInt8 scratch2; /**< Internal use only */
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+ SiVoice_MWI_Store mwiSave;
+ SiVoice_MWIrampState_t mwiState;
+#endif
+} SiVoiceChanType;
+
+
+typedef SiVoiceChanType *SiVoiceChanType_ptr;
+/** @} */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_IF_CFG SiVoice System control interface functions
+ *
+ * These functions are used by the ProSLIC API to access system resources
+ * such as SPI/GCI access, memory allocation/deallocation and timers.
+ *
+ * @{
+ */
+/*****************************************************************************/
+/** @defgroup SIVOICE_MEMORY_IF SiVoice Memory allocation/deallocation
+ *
+ * These functions dynamically allocate and deallocate memory for the given
+ * structures. malloc() and memset() are called for allocation and free() is
+ * called for deallocation. These functions are typically called during
+ * initialization of the API and at the tear down of the API. If customers
+ * prefer to use statically allocated structures, then they must ensure that
+ * the structure elements are zero'ed out.
+ *
+ * @{
+ */
+
+/**
+ @brief
+ * Allocate memory and initialize the given structure.
+ *
+ * @param[in,out] pCtrlIntf - the structure to initialize
+ * @param[in] interface_count - number of device interfaces present. Typically 1 interface per SPI controller.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_destroyControlInterfaces
+ */
+
+int SiVoice_createControlInterfaces (SiVoiceControlInterfaceType **pCtrlIntf,
+ uInt32 interface_count);
+#define SiVoice_createControlInterface(X) SiVoice_createControlInterfaces((X),1)
+
+/**
+ @brief
+ * Destroys the given structure and deallocates memory.
+ *
+ * @param[in,out] pCtrlIntf - the structure to destroy/deallocate
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_createControlInterfaces
+ */
+
+int SiVoice_destroyControlInterfaces (SiVoiceControlInterfaceType **pCtrlIntf);
+#define SiVoice_destroyControlInterface SiVoice_destroyControlInterfaces
+
+/**
+ @brief
+ * Allocate memory and initialize the given structure.
+ *
+ * @param[in,out] pDev - the structure to initialize
+ * @param[in] device_count - number of devices to allocate.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_destroyDevices
+ */
+
+int SiVoice_createDevices (SiVoiceDeviceType **pDev, uInt32 device_count);
+#define SiVoice_createDevice(X) SiVoice_createDevices((X),1)
+
+/**
+ @brief
+ * Destroys the given structure and deallocates memory.
+ *
+ * @param[in,out] pDev - the structure to destroy/deallocate
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_createDevices
+ */
+
+int SiVoice_destroyDevices (SiVoiceDeviceType **pDev);
+
+#define SiVoice_destroyDevice SiVoice_destroyDevices
+
+/**
+ @brief
+ * Allocate memory and initialize the given structure.
+ *
+ * @param[in,out] pChan - the structure to initialize
+ * @param[in] channel_count - number of channels to allocate.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_destroyChannels
+ */
+
+int SiVoice_createChannels (SiVoiceChanType_ptr *pChan, uInt32 channel_count);
+
+#define SiVoice_createChannel(X) SiVoice_createChannels((X),1)
+
+/**
+ @brief
+ * Destroys the given structure and deallocates memory.
+ *
+ * @param[in,out] pChan - the structure to destroy/deallocate
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_createChannels
+ */
+
+#define SiVoice_destroyChannel SiVoice_destroyChannels
+int SiVoice_destroyChannels (SiVoiceChanType_ptr *pChan);
+/** @} SIVOICE_MEMORY_IF */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_IO SiVoice SPI/GCI access routines
+ * This group of functions are used to associate the transport mechanism (SPI, GCI) functions with the API. The actual
+ * functions being references are normally implemented by the customer for their particular OS and platform.
+ *
+ * @{
+ */
+
+/**
+ @brief
+ * Associate a interface object with a user supplied data structure. This
+ * structure is passed to all the I/O routines that the ProSLIC API calls.
+ *
+ * @param[in,out] pCtrlIntf - which interface to associate
+ * the user supplied structure with.
+ * @param[in] *hCtrl - the user supplied structure that is passed to the IO functions.
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceCtrlObj (SiVoiceControlInterfaceType *pCtrlIntf,
+ void *hCtrl);
+
+/**
+ @brief
+ * Associate a interface object with the reset function.
+ *
+ * @param[in,out] pCtrlIntf - which interface to associate
+ * the user supplied function with.
+ * @param[in] Reset_fptr - the reset function pointer
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceReset (SiVoiceControlInterfaceType *pCtrlIntf,
+ ctrl_Reset_fptr Reset_fptr);
+
+/**
+ @brief
+ * Associate a interface object with the register write function.
+ *
+ * @param[in,out] pCtrlIntf - which interface to associate
+ * the user supplied function with.
+ * @param[in] WriteRegister_fptr - the register write function pointer
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceWriteRegister (SiVoiceControlInterfaceType
+ *pCtrlIntf, ctrl_WriteRegister_fptr WriteRegister_fptr);
+
+/**
+ @brief
+ * Associate a interface object with the register read function.
+ *
+ * @param[in,out] pCtrlIntf - which interface to associate
+ * the user supplied function with.
+ * @param[in] ReadRegister_fptr- the register read function pointer
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceReadRegister (SiVoiceControlInterfaceType
+ *pCtrlIntf, ctrl_ReadRegister_fptr ReadRegister_fptr);
+
+/**
+ @brief
+ * Associate a interface object with the write RAM function.
+ *
+ * @param[in,out] pCtrlIntf - which interface to associate
+ * the user supplied function with.
+ * @param[in] WriteRAM_fptr - the reset function pointer
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceWriteRAM (SiVoiceControlInterfaceType *pCtrlIntf,
+ ctrl_WriteRAM_fptr WriteRAM_fptr);
+
+/**
+ @brief
+ * Associate a interface object with the read RAM function.
+ *
+ * @param[in,out] pCtrlIntf - which interface to associate
+ * the user supplied function with.
+ * @param[in] ReadRAM_fptr - the read RAM function pointer
+ *
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceReadRAM (SiVoiceControlInterfaceType *pCtrlIntf,
+ ctrl_ReadRAM_fptr ReadRAM_fptr);
+/** @} SIVOICE_IO */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_TIMER SiVoice Timer functions
+ *
+ * This group of functions associates the customer supplied timer routines with
+ * the ProSLIC API. Please note, for most applications, only the delay routine
+ * is required. The other routines are needed for the pulse digit API.
+ * @{
+ */
+
+/**
+ @brief
+ * This function associates a timer object - which is user defined, but it is
+ * used with ALL channels of the particular control interface.
+ *
+ * @param[in] pCtrlIntf which control interface to associate the given timer object with.
+ * @param[in] *hTimer - the timer ojbect that is passed to all timer functions.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa SiVoice_setControlInterfaceDelay SiVoice_setControlInterfaceTimeElapsed SiVoice_setControlInterfaceGetTime PROSLIC_TIMER
+ */
+
+int SiVoice_setControlInterfaceTimerObj (SiVoiceControlInterfaceType *pCtrlIntf,
+ void *hTimer);
+
+/**
+ @brief
+ * Associate a timer delay function with a given control interface. The
+ * delay function takes in an argument of the timer object and the time in mSec
+ * and delays the thread/task for at least the time requested.
+ *
+ * @param[in] pCtrlIntf - which control interface to associate the function with.
+ * @param[in] Delay_fptr - the pointer to the delay function.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa SiVoice_setControlInterfaceTimerObj SiVoice_setControlInterfaceTimeElapsed SiVoice_setControlInterfaceGetTime PROSLIC_TIMER
+ */
+
+int SiVoice_setControlInterfaceDelay (SiVoiceControlInterfaceType *pCtrlIntf,
+ system_delay_fptr Delay_fptr);
+
+/**
+ * Description:
+ * Associate a time elapsed function with a given control interface. The
+ * time elapsed function uses the values from the function specified in
+ * @ref SiVoice_setControlInterfaceGetTime and computes the delta time
+ * in mSec.
+ * @param[in] pCtrlIntf - which control interface to associate the function with.
+ * @param[in] timeElapsed_fptr - the pointer to the elapsed time function.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_setControlInterfaceTimerObj SiVoice_setControlInterfaceGetTime SiVoice_setControlInterfaceDelay PROSLIC_TIMER
+ */
+
+int SiVoice_setControlInterfaceTimeElapsed (SiVoiceControlInterfaceType
+ *pCtrlIntf, system_timeElapsed_fptr timeElapsed_fptr);
+
+/**
+ * Description:
+ * Associate a time get function with a given control interface. The
+ * time get function returns a value in a form of a void pointer that
+ * is suitable to be used with the function specified in @ref SiVoice_setControlInterfaceTimeElapsed .
+ * This is typically used as a timestamp of when an event started. The resolution needs to be in terms
+ * of mSec.
+ *
+ * @param[in] pCtrlIntf - which control interface to associate the function with.
+ * @param[in] getTime_fptr - the pointer to the get time function.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa SiVoice_setControlInterfaceTimerObj SiVoice_setControlInterfaceTimeElapsed SiVoice_setControlInterfaceDelay PROSLIC_TIMER
+ */
+
+int SiVoice_setControlInterfaceGetTime (SiVoiceControlInterfaceType *pCtrlIntf,
+ system_getTime_fptr getTime_fptr);
+
+/** @} SIVOICE_TIMER */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_PROC_CONTROL SiVoice Process control
+ * @{
+ */
+
+/**
+ @brief
+ * This function associates a user defined semaphore/critical section
+ * function with the given interface.
+ *
+ * @param[in,out] pCtrlIntf the interface to associate the function with.
+ * @param[in] semaphore_fptr - the function pointer for semaphore control.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int SiVoice_setControlInterfaceSemaphore (SiVoiceControlInterfaceType
+ *pCtrlIntf, ctrl_Semaphore_fptr semaphore_fptr);
+
+/** @} SIVOICE_PROC_CONTROL */
+/*****************************************************************************/
+/** @} SIVOICE_IF_CFG*/
+/*****************************************************************************/
+/** @defgroup SIVOICE_INIT Initialization routines
+ * @{
+ */
+
+/**
+ @brief
+ * This function initializes the various channel structure elements.
+ * This function does not access the chipset directly, so SPI/GCI
+ * does not need to be up during this function call.
+ *
+ * @param[in,out] hProslic - which channel to initialize.
+ * @param[in] channel - Which channel index is this. For example, for a 4 channel system, this would typically range from 0 to 3.
+ * @param[in] chipType - chipset family type for example @ref SI3217X_TYPE or @ref SI3217X_TYPE
+ * @param[in] pDeviceObj - Device structure pointer associated with this channel
+ * @param[in] pCtrlIntf - Control interface associated with this channel
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_SWInitChan
+ */
+
+int SiVoice_SWInitChan (SiVoiceChanType_ptr hProslic,int channel,int chipType,
+ SiVoiceDeviceType *pDeviceObj, SiVoiceControlInterfaceType *pCtrlIntf);
+
+/**
+ @brief
+ * This function calls the user supplied reset function to put and take out the channel from reset. This is
+ * typically done during initialization and may be assumed to be a "global" reset - that is 1 reset per
+ * daisychain vs. 1 per device.
+ *
+ * @note This function can take more than 500 mSec to complete.
+ *
+ * @param[in] pChan - which channel to reset, if a "global reset", then any channel on the daisy chain is sufficient.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int SiVoice_Reset (SiVoiceChanType_ptr pChan);
+
+/** @} SIVOICE_INIT */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_DEBUG Debug
+ * @{
+ */
+
+/**
+ @brief
+ * This function enables or disables the debug mode, assuming @ref ENABLE_DEBUG is set in the configuration file.
+ *
+ * @param[in] pChan - which channel to set the debug flag.
+ * @param[in] debugEn - 0 = Not set, 1 = set.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int SiVoice_setSWDebugMode (SiVoiceChanType_ptr pChan, int debugEn);
+
+/**
+ @brief
+ * This function enables or disables the debug mode, assuming @ref ENABLE_TRACES is set in the configuration file.
+ *
+ * @param[in] pChan - which channel to set the debug flag.
+ * @param[in] traceEn - 0 = Not set, 1 = set.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int SiVoice_setTraceMode (SiVoiceChanType_ptr pChan, int traceEn);
+
+/**
+ * @brief
+ * This function allows access to SPI read register function pointer from interface
+ *
+ * @param[in] hProslic - pointer to channel structure
+ * @param[in] addr - address to read
+ * @retval uInt8 - register contents
+ *
+ */
+
+uInt8 SiVoice_ReadReg (SiVoiceChanType_ptr hProslic, uInt8 addr);
+
+/**
+ * @brief
+ * This function allows access to SPI write register function pointer from interface
+ *
+ * @param[in] pProslic - pointer to channel structure
+ * @param[in] addr - address to write
+ * @param[in] data to be written
+ * @retval int - @ref RC_NONE
+ *
+ */
+int SiVoice_WriteReg (SiVoiceChanType_ptr pProslic, uInt8 addr, uInt8 data);
+
+/** @} SIVOICE_DEBUG */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_ERROR Return code functions
+ * @{
+ */
+
+/**
+ @brief
+ * This function returns the error flag that may be set by some function in where
+ * @ref errorCodeType is not returned.
+ *
+ * @note For functions that DO return errorCodeType, the return value here is undefined.
+ *
+ * @param[in] pChan - which channel to clear the error flag
+ * @param[in,out] *error - The current value of error flag.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa SiVoice_clearErrorFlag
+ */
+
+int SiVoice_getErrorFlag (SiVoiceChanType_ptr pChan, int *error);
+
+/**
+ @brief
+ * This function clears the error flag that may be set by some function in where
+ * @ref errorCodeType is not returned.
+ *
+ * @param[in,out] pChan - which channel to clear the error flag
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa SiVoice_getErrorFlag
+ */
+
+int SiVoice_clearErrorFlag (SiVoiceChanType_ptr pChan);
+
+/** @} SIVOICE_ERROR */
+
+/*****************************************************************************/
+/** @defgroup SIVOICE_ENABLE Enable/disable channels (for init)
+ * @{
+ */
+/**
+ @brief
+ * This function sets the channel enable status. If NOT set, then when
+ * the various initialization routines such as @ref SiVoice_SWInitChan is called,
+ * then this particular channel will NOT be initialized.
+ *
+ * This function does not access the chipset directly, so SPI/GCI
+ * does not need to be up during this function call.
+ *
+ * @param[in,out] pChan - which channel to return the status.
+ * @param[in] chanEn - The new value of the channel enable field. 0 = NOT enabled, 1 = enabled.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa SiVoice_getChannelEnable
+ */
+
+int SiVoice_setChannelEnable (SiVoiceChanType_ptr pChan, int chanEn);
+
+/**
+ @brief
+ * This function returns back if the channel is enabled or not.
+ * This function does not access the chipset directly, so SPI/GCI
+ * does not need to be up during this function call.
+ *
+ * @param[in] pChan - which channel to return the status.
+ * @param[in,out] chanEn* - The current value of if the channel is enabled. 0 = NOT enabled, 1 = enabled.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa SiVoice_setChannelEnable
+ */
+
+int SiVoice_getChannelEnable (SiVoiceChanType_ptr pChan, int *chanEn);
+
+/** @} SIVOICE_ENABLE */
+/** @defgroup SIVOICE_MISC Other functions that don't fit into other categories
+ * @{
+ */
+/**
+ @brief
+ * This function returns the current version of the ProSLIC API release as
+ * a NULL terminated string.
+ * @retval char * - string containing the API release string.
+ */
+char *SiVoice_Version(void);
+
+/**
+ * @brief
+ * This function probes an array of channel pointers to determine the number of
+ * ProSLIC's,if not NULL and DAA's, if not NULL. Should only be called after a reset.
+ * @param[in,out] pProslic - an array of channel pointers to iterate through. ChannelType is modified.
+ * @param[in] size - number of channels to pobe.
+ * @param[out] slicCount - if not NULL, the number of SLIC's detected.
+ * @param[out] daaCount - if not NULL, the number of DAA's detected.
+ * @retval RC_NONE if successful.
+ */
+int SiVoice_IdentifyChannels(SiVoiceChanType_ptr *pProslic, int size,
+ int *slicCount, int *daaCount);
+
+/** @} SIVOICE_MISC */
+
+/*****************************************************************************/
+/** @} SIVOICE */
+#endif
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice_ctrl.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice_ctrl.h
new file mode 100644
index 0000000..4eb5178
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice_ctrl.h
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * si_voice_ctrl.h
+ * SPI driver header file
+ *
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * File Description:
+ * This is the header file for the control driver used
+ * in the ProSLIC demonstration code.
+ *
+ *
+ */
+
+#ifndef CTRL_H
+#define CTRL_H
+
+/** @defgroup PROSLIC_CUSTOMER_APIS Customer implemented functions
+ * This section has documentation related to APIs that the customer
+ * needs to implement to allow the ProSLIC API to function correctly.
+ *
+ * @note Please note, in addition to the functions mentioned here, the
+ * customer will need to review/modify si_voice_datatypes.h to match
+ * the native datatypes of their system.
+ *
+ * @{
+ */
+/*****************************************************************************/
+/** @defgroup PROSLIC_CUSTOMER_CONTROL Customer implemented control functions
+ * This group of function pointer prototypes need to be implemented by the
+ * customer in order for the ProSLIC API to function correctly. These functions
+ * need to be associated with the API by the functions documented in @ref SIVOICE_IO
+ * @{
+ */
+
+/**
+* @brief
+* Sets/clears the reset pin of all the ProSLICs/VDAAs
+*
+* @param[in] *hCtrl - which interface to reset (this is a customer supplied structure)
+* @param[in] in_reset - 0 = Take the device out of reset, 1 = place the device(s) in reset
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*/
+
+typedef int (*ctrl_Reset_fptr) (void *hCtrl, int in_reset);
+
+/**
+* @brief
+* Register write function pointer
+*
+* @param[in] *hCtrl - which interface to communicate through (this is a customer supplied structure)
+* @param[in] channel - ProSLIC channel to write to (this is the value passed is the same as found in @ref SiVoice_SWInitChan)
+* @param[in] regAddr - Address of register to write
+* @param[in] data - data to write to register
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+*/
+
+typedef int (*ctrl_WriteRegister_fptr) (void *hCtrl, uInt8 channel,
+ uInt8 regAddr, uInt8 data);
+
+/**
+* @brief
+* RAM write function pointer
+*
+* @param[in] *hCtrl - which interface to communicate through (this is a customer supplied structure)
+* @param[in] channel - ProSLIC channel to write to (this is the value passed is the same as found in @ref SiVoice_SWInitChan)
+* @param[in] ramAddr - Address of the RAM location to write
+* @param[in] ramData - data to write to the RAM location
+* @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*
+*/
+
+typedef int (*ctrl_WriteRAM_fptr) (void *hCtrl, uInt8 channel, uInt16 ramAddr,
+ ramData data);
+
+/**
+* @brief
+* Register read function pointer
+*
+* @param[in] *hCtrl - which interface to communicate through (this is a customer supplied structure)
+* @param[in] channel - ProSLIC channel to read from (this is the value passed is the same as found in @ref SiVoice_SWInitChan)
+* @param[in] regAddr - Address of register to read from
+* @retval uInt8 - the value read. If an error occurs, this value is undefined.
+*/
+
+typedef uInt8 (*ctrl_ReadRegister_fptr) (void *hCtrl, uInt8 channel,
+ uInt8 regAddr);
+
+/**
+* @brief
+* RAM read function pointer
+*
+* @param[in] *hCtrl - which interface to communicate through (this is a customer supplied structure)
+* @param[in] channel - ProSLIC channel to read from (this is the value passed is the same as found in @ref SiVoice_SWInitChan)
+* @param[in] ramAddr - Address of the RAM location to read from
+* @retval ramData - the value read. If an error occurs, this value is undefined.
+*/
+
+typedef ramData (*ctrl_ReadRAM_fptr) (void *hCtrl, uInt8 channel,
+ uInt16 ramAddr);
+
+/**
+ * @brief
+ * Critical Section/Semaphore function pointer
+ *
+* @param[in] *hCtrl - which interface to communicate through (this is a customer supplied structure)
+* @param[in] in_critical_section - request to lock the critical section 1 = lock, 0 = unlock
+* @retval 1 = success, 0 = failed
+*/
+
+typedef int (*ctrl_Semaphore_fptr) (void *hCtrl, int in_critical_section);
+
+/** @} PROSLIC_CUSTOMER_CONTROL */
+/** @} */
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice_timer_intf.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice_timer_intf.h
new file mode 100644
index 0000000..b4be48f
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/si_voice_timer_intf.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * System specific functions header file
+ *
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * File Description:
+ * This is the header file for the system specific functions like timer functions.
+ *
+ *
+ */
+
+#ifndef TIMER_INTF_H
+#define TIMER_INTF_H
+
+/** @addtogroup PROSLIC_CUSTOMER_APIS
+ * @{
+ * @defgroup PROSLIC_CUSTOMER_TIMER Customer implemented timer functions
+ * This section has documentation related to timers: delays and timestamps. The void * is a customer
+ * supplied timer data structure that the user specifies in @ref SiVoice_setControlInterfaceTimerObj.
+ * These functions need to be associated with the functions documented in @ref SIVOICE_TIMER
+ *
+ * @note For the majority of implementations, the only function that is required is the delay function.
+ *
+ * @{
+ */
+
+/**
+ * @brief
+ * System time delay function pointer
+ *
+ * @param[in] hTimer - the system timer object
+ * @param[in] timeInMS - number of mSec to suspend the task/thread executing.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+*/
+
+typedef int (*system_delay_fptr) (void *hTimer, int timeInMs);
+
+/**
+ * @brief
+ * System time elapsed function pointer
+ *
+ * @details
+ * This function combined with @ref system_getTime_fptr function allow one to determine
+ * the time elapsed between the two event times.
+ *
+ * The example pseudo code below shows how one may see this function used in conjunction with
+ * the function pointed by @ref system_getTime_fptr to do some processing while waiting
+ * for a time to expire.
+ *
+ * @code
+ * my_timer_obj time_now;
+ *
+ * getTime(my_prosclic_obj->timer_obj_ptr, (void *)(&time_now));
+ *
+ * Some events occur here...
+ *
+ * do
+ * {
+ * time_elapsed(my_proslic_obj->timer_obj_ptr,(void *)(&time_now), &elapsed_time_mSec);
+ *
+ * Do something here...
+ *
+ * }while(elapsed_time_mSec < Desired delay);
+ *
+ * Change state...
+ *
+ * @endcode
+ *
+ * @param[in] *hTimer - the system timer object
+ * @param[in] *startTime - the time object returned by @ref system_getTime_fptr - the "start time" of the event.
+ * @param[out] *timeInMs - the time in mSec between the "start time" and the current time.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa system_getTime_fptr
+*/
+
+typedef int (*system_timeElapsed_fptr) (void *hTimer, void *startTime,
+ int *timeInMs);
+
+/**
+ * @brief
+ * Retrieve system time in mSec resolution.
+ *
+ * @details
+ * This function combined with @ref system_timeElapsed_fptr function allow one to determine
+ * the time elapsed between the two event times.
+ *
+ * @param[in] *hTimer - the system timer object
+ * @param[in] *time - the time stamp object needed by @ref system_timeElapsed_fptr
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa system_timeElapsed_fptr
+*/
+
+typedef int (*system_getTime_fptr) (void *hTimer, void *time);
+
+/** @}
+ * @} */
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/vdaa.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/vdaa.h
new file mode 100644
index 0000000..91ae85c
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/vdaa.h
@@ -0,0 +1,1144 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Vdaa VoiceDAA interface header file
+ *
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the header file for the main VoiceDAA API and is used
+ * in the VoiceDAA demonstration code.
+ *
+ *
+ */
+
+#ifndef VDAA_INTF_H
+#define VDAA_INTF_H
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "si_voice.h"
+/*****************************************************************************/
+/** @defgroup VDAA_API VDAA API
+ * This section covers APIs and definitions related to the VDAA/FXO.
+ * @{
+ */
+
+/*
+** Constants
+*/
+#define BROADCAST 0xff
+#define LCS_SCALE_NUM 33 /* Line Current Status Scale */
+#define LCS_SCALE_DEN 10 /* Line Current Status Scale */
+
+/* Macro substitution from Vdaa legacy API's to SiVoice API's */
+#define Vdaa_createControlInterface SiVoice_createControlInterface
+#define Vdaa_destroyControlInterface SiVoice_destroyControlInterface
+#define Vdaa_createDevice SiVoice_createDevice
+#define Vdaa_destroyDevice SiVoice_destroyDevice
+#define Vdaa_createChannel SiVoice_createChannel
+#define Vdaa_destroyChannel SiVoice_destroyChannel
+
+#define Vdaa_setControlInterfaceCtrlObj SiVoice_setControlInterfaceCtrlObj
+#define Vdaa_setControlInterfaceReset SiVoice_setControlInterfaceReset
+#define Vdaa_setControlInterfaceWriteRAM SiVoice_setControlInterfaceWriteRAM
+#define Vdaa_setControlInterfaceReadRAM SiVoice_setControlInterfaceReadRAM
+#define Vdaa_setControlInterfaceWriteRegister SiVoice_setControlInterfaceWriteRegister
+#define Vdaa_setControlInterfaceReadRegister SiVoice_setControlInterfaceReadRegister
+#define Vdaa_setControlInterfaceTimerObj SiVoice_setControlInterfaceTimerObj
+#define Vdaa_setControlInterfaceDelay SiVoice_setControlInterfaceDelay
+#define Vdaa_setControlInterfaceSemaphore SiVoice_setControlInterfaceSemaphore
+#define Vdaa_setControlInterfaceTimeElapsed SiVoice_setControlInterfaceTimeElapsed
+#define Vdaa_setControlInterfaceGetTime SiVoice_setControlInterfaceGetTime
+
+#define Vdaa_SWInitChan SiVoice_SWInitChan
+
+#define Vdaa_setSWDebugMode SiVoice_setSWDebugMode
+#define Vdaa_getErrorFlag SiVoice_getErrorFlag
+#define Vdaa_clearErrorFlag SiVoice_clearErrorFlag
+
+#define Vdaa_setChannelEnable SiVoice_setChannelEnable
+#define Vdaa_getChannelEnable SiVoice_getChannelEnable
+
+#define Vdaa_Reset SiVoice_Reset
+#define Vdaa_Version SiVoice_Version
+
+#define SI3050_CHAN_PER_DEVICE 1
+
+/*
+**
+** VDAA Initialization/Configuration Parameter Options
+**
+*/
+/*
+** This defines names for the PCM Data Format
+*/
+typedef enum
+{
+ A_LAW = 0, /**< 00 = A-Law. Signed magnitude data format */
+ U_LAW = 1, /**< 01 = u-Law. Signed magnitude data format */
+ LINEAR_16_BIT = 3 /**< 11 = 16-bit linear (2s complement data format) */
+} tPcmFormat;
+
+/*
+** This defines names for the phcf bits
+*/
+typedef enum
+{
+ PCLK_1_PER_BIT = 0,
+ PCLK_2_PER_BIT = 1
+} tPHCF;
+
+
+/*
+** This defines names for the tri bit
+*/
+typedef enum
+{
+ TRI_POS_EDGE = 0,
+ TRI_NEG_EDGE = 1
+} tTRI;
+
+
+/**
+** This defines names for the AC impedance range
+*/
+typedef enum
+{
+ AC_600, /**< 600 Ohms */
+ AC_900, /**< 900 O */
+ AC_270__750_150, /**< 270 O + (750 O || 150 nF) and 275 O + (780 O || 150 nF) */
+ AC_220__820_120, /**< 220 O + (820 O || 120 nF) and 220 O + (820 O || 115 nF) */
+ AC_370__620_310, /**< 370 O + (620 O || 310 nF) */
+ AC_320__1050_230, /**< 320 O + (1050 O || 230 nF) */
+ AC_370__820_110, /**< 370 O + (820 O || 110 nF) */
+ AC_275__780_115, /**< 275 O + (780 O || 115 nF) */
+ AC_120__820_110, /**< 120 O + (820 O || 110 nF) */
+ AC_350__1000_210, /**< 350 O + (1000 O || 210 nF) */
+ AC_200__680_100, /**< 200 O + (680 O || 100 nF) */
+ AC_600__2160, /**< 600 O + 2.16 uF */
+ AC_900__1000, /**< 900 O + 1 uF */
+ AC_900__2160, /**< 900 O + 2.16 uF */
+ AC_600__1000, /**< 600 O + 1 uF */
+ AC_Global_impedance /**< Global impedance */
+} tAC_Z;
+
+/**
+** This defines names for the DC impedance range
+*/
+typedef enum
+{
+ DC_50, /**< 50 Ohms dc termination is selected */
+ DC_800 /**< 800 Ohms dc termination is selected */
+
+} tDC_Z;
+
+/**
+** This defines names for the ringer impedance range
+*/
+typedef enum
+{
+ RZ_MAX = 0,
+ RZ_SYNTH = 1
+} tRZ;
+
+/**
+** This defines names for the dc voltage adjust
+*/
+typedef enum
+{
+ DCV3_1 = 0,
+ DCV3_2 = 1,
+ DCV3_35 = 2,
+ DCV3_5 = 3
+} tDCV;
+
+/**
+** This defines names for the minimum loop current
+*/
+typedef enum
+{
+ MINI_10MA = 0,
+ MINI_12MA = 1,
+ MINI_14MA = 2,
+ MINI_16MA = 3
+} tMINI;
+
+/**
+** This defines names for the current limiting enable bit
+*/
+typedef enum
+{
+ ILIM_DISABLED = 0,
+ ILIM_ENABLED = 1
+} tILIM;
+
+/**
+** This defines names for the ring detect interupt mode
+*/
+typedef enum
+{
+ RDI_BEG_BURST = 0,
+ RDI_BEG_END_BURST = 1
+} tRDI;
+
+/**
+** This defines names for the on hook speed / spark quenching
+*/
+typedef enum
+{
+ OHS_LESS_THAN_0_5MS = 0,
+ OHS_3MS = 1,
+ OHS_26MS = 0xE
+} tOHS;
+
+/**
+** This defines names for the hbe bit
+*/
+typedef enum
+{
+ HYBRID_DISABLED = 0,
+ HYBRID_ENABLED = 1
+} tHBE;
+
+
+/**
+** Gain/Attenuation Select
+*/
+typedef enum
+{
+ XGA_GAIN,
+ XGA_ATTEN
+} tXGA;
+
+/**
+** MUTE Control Options
+*/
+typedef enum
+{
+ MUTE_DISABLE_ALL,
+ MUTE_DISABLE_RX,
+ MUTE_DISABLE_TX,
+ MUTE_ENABLE_RX,
+ MUTE_ENABLE_TX,
+ MUTE_ENABLE_ALL
+} tMUTE;
+
+/**
+** This defines names for the ring delay setting
+*/
+typedef enum
+{
+ RDLY_0MS = 0,
+ RDLY_256MS = 1,
+ RDLY_512MS = 2,
+ RDLY_768MS = 3,
+ RDLY_1024MS = 4,
+ RDLY_1280MS = 5,
+ RDLY_1536MS = 6,
+ RDLY_1792MS = 7
+} tRDLY;
+
+/**
+** This defines names for the ring timeouts
+*/
+typedef enum
+{
+ RTO_128MS = 1,
+ RTO_256MS = 2,
+ RTO_384MS = 3,
+ RTO_512MS = 4,
+ RTO_640MS = 5,
+ RTO_768MS = 6,
+ RTO_896MS = 7,
+ RTO_1024MS = 8,
+ RTO_1152MS = 9,
+ RTO_1280MS = 10,
+ RTO_1408MS = 11,
+ RTO_1536MS = 12,
+ RTO_1664MS = 13,
+ RTO_1792MS = 14,
+ RTO_1920MS = 15
+} tRTO;
+
+/**
+** This defines names for the ring timeouts
+*/
+typedef enum
+{
+ RCC_100MS = 0,
+ RCC_150MS = 1,
+ RCC_200MS = 2,
+ RCC_256MS = 3,
+ RCC_384MS = 4,
+ RCC_512MS = 5,
+ RCC_640MS = 6,
+ RCC_1024MS = 7
+} tRCC;
+
+/**
+** This defines names for the ring validation modes
+*/
+typedef enum
+{
+ RNGV_DISABLED = 0,
+ RNGV_ENABLED = 1
+} tRNGV;
+
+/**
+** This defines names for the rfwe bit
+*/
+typedef enum
+{
+ RFWE_HALF_WAVE = 0,
+ RFWE_FULL_WAVE = 1,
+ RFWE_RNGV_RING_ENV = 0,
+ RFWE_RNGV_THRESH_CROSS = 1
+} tRFWE;
+
+/**
+** This defines names for the rt and rt2 bit
+*/
+typedef enum
+{
+ RT__13_5VRMS_16_5VRMS = 0,
+ RT__19_35VRMS_23_65VRMS = 2,
+ RT__40_5VRMS_49_5VRMS = 3
+} tRT;
+
+/**
+** This defines names for the rt and rt2 bit
+*/
+typedef enum
+{
+ RGDT_ACTIVE_LOW = 0,
+ RGDT_ACTIVE_HI = 1
+} tRPOL;
+
+
+/**
+** This defines names for the interrupts
+*/
+typedef enum
+{
+ POLI,
+ TGDI,
+ LCSOI,
+ DODI,
+ BTDI,
+ FTDI,
+ ROVI,
+ RDTI,
+ CVI /**< Current/Voltage Interrupt REGISTER#44 */
+} vdaaInt;
+
+/**
+** Interrupt Bitmask Fields
+*/
+typedef enum
+{
+ POLM = 1,
+ TGDM = 2, /**< Si3050 Only */
+ LCSOM = 4,
+ DODM = 8,
+ BTDM = 16,
+ FDTM = 32,
+ ROVM = 64,
+ RDTM = 128
+} vdaaIntMask;
+
+
+/**
+** This defines names for the idl bit (obsolete)
+*/
+typedef enum
+{
+ IDL_DISABLED = 0,
+ IDL_ENABLED = 1
+} tIDL;
+
+/**
+** This defines names for the ddl bit (obsolete)
+*/
+typedef enum
+{
+ DDL_NORMAL_OPERATION = 0,
+ DDL_PCM_LOOPBACK = 1
+} tDDL;
+
+/**
+** Loopback Modes
+*/
+typedef enum
+{
+ LPBK_NONE = 0,
+ LPBK_IDL = 1,
+ LPBK_DDL = 2,
+ LPBK_PCML = 3
+} tLpbkMode;
+
+/**
+** Loopback Status
+*/
+typedef enum
+{
+ LPBK_DISABLED = 0,
+ LPBK_ENABLED = 1
+} tLpbkStatus;
+
+/**
+** This defines names for the interrupt pin modes
+*/
+typedef enum
+{
+ INTE_DISABLED = 0,
+ INTE_ENABLED = 1
+} tInte;
+
+/**
+** This defines names for the interrupt pin polarities
+*/
+typedef enum
+{
+ INTE_ACTIVE_LOW = 0,
+ INTE_ACTIVE_HIGH = 1
+} tIntePol;
+
+/**
+** This defines names for the pwm settings
+*/
+typedef enum
+{
+ PWM_DELTA_SIGMA = 0,
+ PWM_CONVENTIONAL_16KHZ = 1,
+ PWM_CONVENTIONAL_32KHZ = 2
+} tPwmMode;
+
+/**
+** PWME
+*/
+typedef enum
+{
+ PWM_DISABLED = 0,
+ PWM_ENABLED
+} tPWME;
+
+/**
+** RCALD control
+*/
+typedef enum
+{
+ RES_CAL_ENABLED = 0,
+ RES_CAL_DISABLED
+} tRCALD;
+
+/**
+** Voice DAA Hook states
+*/
+enum
+{
+ VDAA_DIG_LOOPBACK = 1,
+ VDAA_ONHOOK = 2,
+ VDAA_OFFHOOK = 3,
+ VDAA_ONHOOK_MONITOR = 4
+};
+
+/**
+** FDT Monitoring Options
+*/
+enum
+{
+ FDT_MONITOR_OFF = 0,
+ FDT_MONITOR_ON
+};
+
+
+/**
+** Offhook Speed Select
+*/
+typedef enum
+{
+ FOH_512,
+ FOH_128,
+ FOH_64,
+ FOH_8
+} tFOH;
+
+/**
+** Sample Rate Control
+*/
+typedef enum
+{
+ FS_8KHZ,
+ FS_16KHZ
+} tHSSM;
+
+/**
+** Line Voltage Force Disable
+*/
+typedef enum
+{
+ LVS_FORCE_ENABLED = 0,
+ LVS_FORCE_DISABLED
+} tLVFD;
+
+/**
+** Current/Voltage Monitor Select
+*/
+typedef enum
+{
+ CVS_CURRENT,
+ CVS_VOLTAGE
+} tCVS;
+
+/**
+** Current/Voltage Interrupt Polarity
+*/
+typedef enum
+{
+ CVP_BELOW,
+ CVP_ABOVE
+} tCVP;
+
+/**
+** Guarded Clear
+*/
+typedef enum
+{
+ GCE_DISABLED = 0,
+ GCE_ENABLED
+} tGCE;
+
+/**
+** SPI Mode (Si3050 Only)
+*/
+typedef enum
+{
+ SPIM_TRI_CS,
+ SPIM_TRI_SCLK
+} tSPIM;
+
+/**
+** FILT
+*/
+typedef enum
+{
+ FILT_HPF_5HZ,
+ FILT_HPF_200HZ
+} tFILT;
+
+/**
+** IIRE
+*/
+typedef enum
+{
+ IIR_DISABLED = 0,
+ IIR_ENABLED
+} tIIRE;
+
+/**
+** FULL2
+*/
+typedef enum
+{
+ FULL2_DISABLED = 0,
+ FULL2_ENABLED
+} tFULL2;
+
+/**
+** FULL
+*/
+typedef enum
+{
+ FULL_DISABLED = 0,
+ FULL_ENABLED
+} tFULL;
+
+/**
+** RG1
+*/
+typedef enum
+{
+ RG1_DISABLED = 0,
+ RG1_ENABLED
+} tRG1;
+
+
+/**
+** -----------------------------
+** CONFIGURATION DATA STRUCTURES
+** -----------------------------
+*/
+
+/**
+** (Updated) Structure for General Parameters
+*/
+typedef struct
+{
+ tInte inte; /* INTE */
+ tIntePol intp; /* INTP */
+ tRCALD rcald; /* RCALD */
+ tHSSM hssm; /* HSSM */
+ tFOH foh; /* FOH */
+ tLVFD lvfd; /* LVFD */
+ tCVS cvs; /* CVS */
+ tCVP cvp; /* CVP */
+ tGCE gce; /* GCE */
+ tIIRE iire; /* IIRE */
+ tFULL2 full2; /* FULL2 */
+ tFULL full; /* FULL */
+ tFILT filt; /* FILT */
+ tRG1 rg1; /* RG1 */
+ tPwmMode pwmm; /* PWMM Si3050 Only */
+ tPWME pwmEnable; /* PWME Si3050 Only */
+ tSPIM spim; /* SPIM Si3050 Only */
+} vdaa_General_Cfg;
+
+
+/**
+** (NEW) Structure for Country Presets
+*/
+typedef struct
+{
+ tRZ rz;
+ tDC_Z dcr;
+ tAC_Z acim;
+ tDCV dcv;
+ tMINI mini;
+ tILIM ilim;
+ tOHS ohs_sq;
+ tHBE hbe;
+} vdaa_Country_Cfg;
+
+/**
+** (NEW) Structure for Hybrid Presets
+*/
+typedef struct
+{
+ uInt8 hyb1;
+ uInt8 hyb2;
+ uInt8 hyb3;
+ uInt8 hyb4;
+ uInt8 hyb5;
+ uInt8 hyb6;
+ uInt8 hyb7;
+ uInt8 hyb8;
+} vdaa_Hybrid_Cfg;
+
+/**
+** Structure for PCM configuration presets
+*/
+typedef struct
+{
+ tPcmFormat pcmFormat;
+ tPHCF pcmHwy;
+ tTRI pcm_tri;
+} vdaa_PCM_Cfg;
+
+/** @addtogroup VDAA_AUDIO
+ * @{
+ */
+/** @addtogroup VDAA_GAIN_CONTROL
+ * @{
+ */
+/*
+** (Updated) Structure for Audio path gain preset
+*/
+typedef struct
+{
+ uInt8 mute;
+ tXGA xga2;
+ uInt8 acgain2;
+ tXGA xga3;
+ uInt8 acgain3;
+ uInt8 callProgress;
+ BOOLEAN cpEn;
+} vdaa_audioGain_Cfg;
+
+/** @} VDAA_GAIN_CONTROL*/
+/** @} */
+/*
+** Structure for configuring ring detect config
+*/
+
+typedef struct
+{
+ tRDLY rdly;
+ tRT rt;
+ uInt8 rmx;
+ tRTO rto;
+ tRCC rcc;
+ tRNGV rngv;
+ uInt8 ras;
+ tRFWE rfwe;
+ tRDI rdi;
+ tRPOL rpol;
+} vdaa_Ring_Detect_Cfg;
+
+
+/*
+** Defines structure of interrupt data
+*/
+typedef struct
+{
+ vdaaInt *irqs;
+ uInt8 number;
+} vdaaIntType;
+
+/*
+** Defines structure for configuring Loop Back
+*/
+typedef struct
+{
+ tIDL isoDigLB;
+ tDDL digDataLB;
+} vdaa_Loopback_Cfg;
+
+
+/*
+** Generic Flag
+*/
+typedef enum
+{
+ VDAA_BIT_SET = 1,
+ VDAA_BIT_CLEAR = 0
+} tVdaaBit;
+
+/*
+** Defines structure for daa current status (ring detect/hook stat)
+*/
+typedef struct
+{
+ tVdaaBit ringDetectedNeg;
+ tVdaaBit ringDetectedPos;
+ tVdaaBit ringDetected;
+ tVdaaBit offhook;
+ tVdaaBit onhookLineMonitor;
+} vdaaRingDetectStatusType;
+
+
+typedef SiVoiceControlInterfaceType vdaaControlInterfaceType;
+typedef SiVoiceDeviceType vdaaDeviceType;
+typedef SiVoiceChanType vdaaChanType;
+
+/*
+** This is the main VoiceDAA interface object pointer
+*/
+typedef vdaaChanType *vdaaChanType_ptr;
+
+/*
+** Defines initialization data structures
+*/
+typedef struct
+{
+ uInt8 address;
+ uInt8 initValue;
+} vdaaRegInit;
+
+
+typedef enum
+{
+ PAR_HANDSET_NOT_DETECTED = 0,
+ PAR_HANDSET_DETECTED = 1
+} vdaaPHDStatus;
+
+/*
+** Line In Use Configuration Structure
+*/
+typedef struct
+{
+ vdaaPHDStatus status;
+ int8 min_onhook_vloop;
+ int8 min_offhook_vloop;
+ int16 min_offhook_iloop;
+ int8 measured_vloop;
+ int16 measured_iloop;
+} vdaa_LIU_Config;
+
+/*
+** Function Declarations
+*/
+
+/*****************************************************************************/
+/** @defgroup VDAA_AUDIO Audio
+ * @{
+ */
+/** @defgroup VDAA_GAIN_CONTROL Gain Control
+ * This section covers functions that allow one to adjust the audio
+ * gains - with TX toward the network/SOC/DSP and RX toward the tip/ring.
+ *
+ * @{
+ */
+
+/**
+ * @brief
+ * Sets the TX audio gain (toward the network).
+ *
+ * @param[in] pVdaa - which channel to configure
+ * @param[in] preset - which preset to use (this may be from the constants file)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_TXAudioGainSetup (vdaaChanType *pVdaa,int32 preset);
+
+/**
+ * @brief
+ * Sets the RX audio gain (toward the tip/ring).
+ *
+ * @param[in] pVdaa - which channel to configure
+ * @param[in] preset - which preset to use (this may be from the constants file)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_RXAudioGainSetup (vdaaChanType *pVdaa,int32 preset);
+
+/** @} VDAA_GAIN_CONTROL */
+
+/*****************************************************************************/
+/** @defgroup VDAA_AUDIO_CONTROL Audio control/configuration
+ * This group of functions is used to configure and control the PCM bus. It is essential that @ref Vdaa_PCMSetup,
+ * @ref Vdaa_PCMTimeSlotSetup and @ref Vdaa_PCMStart are called prior to any audio processing.
+ * @{
+ */
+
+/**
+ * @brief
+ * This configures the PCM bus with parameters such as companding and data latching timing.
+ *
+ * @param[in] pVdaa - which channel should be configured
+ * @param[in] preset - which preset to use from the constants file (see configuration tool, PCM dialog box)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa Vdaa_PCMTimeSlotSetup ProSLIC_PCMStart
+ */
+
+int Vdaa_PCMSetup (vdaaChanType *pVdaa,int32 preset);
+
+/**
+ * @brief
+ * This configures the ProSLIC to latch and send the PCM data at a particular timeslot in terms of PCM clocks (PCLK).
+ *
+ * Typically, for aLaw and uLaw, one can use the following calculation to set the rxcount and txcount parameters:
+ *
+ * rxcount = txcount = (channel_number)*8;
+ *
+ * For 16 bit linear, one can do the following:
+ *
+ * rxcount = txcount = (channel_number)*16;
+ *
+ * where channel_number = which ProSLIC channel on the PCM bus. For example, if one were to have 2 dual channel
+ * VDAA's on the same PCM bus, this value would range from 0 to 3.
+ *
+ * @param[in] pVdaa - which channel should be configured
+ * @param[in] rxcount - how many clocks until reading data from the PCM bus
+ * @param[in] txcount - how many clocks until writing data to the PCM bus.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa Vdaa_PCMSetup Vdaa_PCMStart
+ */
+
+int Vdaa_PCMTimeSlotSetup (vdaaChanType *pVdaa, uInt16 rxcount, uInt16 txcount);
+
+/**
+ * @brief
+ * This enables PCM transfer on the given ProSLIC channel.
+ *
+ * @param[in] pVdaa - - which channel should be enabled
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa ProSLIC_PCMSetup ProSLIC_PCMTimeSlotSetup ProSLIC_PCMStop
+ */
+
+int Vdaa_PCMStart (vdaaChanType *pVdaa);
+
+/**
+ * @brief
+ * This disables PCM transfer on the given VDAA channel. Typically, this is called for debugging
+ * purposes only.
+ *
+ * @param[in] pVdaa - - which channel should be disabled
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ * @sa Vdaa_PCMSetup Vdaa_PCMTimeSlotSetup Vdaa_PCMStart
+ */
+
+int Vdaa_PCMStop (vdaaChanType *pVdaa);
+
+/**
+ * @brief
+ * Program desired mute mode for the given channel.
+ *
+ * @param[in] pVdaa - which channel should be modified
+ * @param[in] mute - what is the desired mode.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int Vdaa_SetAudioMute(vdaaChanType *pVdaa, tMUTE mute);
+
+/**
+ * @brief
+ * Program desired loopback test mode for the given channel.
+ *
+ * @param[in] pVdaa - which channel should be modified
+ * @param[in] lpbk_mode - what is the desired loopback mode.
+ * @param[in] lpbk_status - is this to enable or disable the loopback mode.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int Vdaa_SetLoopbackMode(vdaaChanType_ptr pVdaa, tLpbkMode lpbk_mode,
+ tLpbkStatus lpbk_status);
+
+/*****************************************************************************/
+/** @} VDAA_AUDIO */
+/** @} */
+/** @defgroup VDAA_RING Ring detection
+ * @{
+ */
+
+/**
+ * @brief This function configures ringing detect for the Vdaa.
+ * @param[in] pVdaa - which channel to program
+ * @param[in] preset - Index of predefined ring detect setup configuration
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_RingDetectSetup (vdaaChanType *pVdaa,int32 preset);
+
+
+/**
+ * @brief This function reads ring detect/hook status and populates the structure passed via pStatus.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @param[out] pStatus - updated ring status.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_ReadRingDetectStatus (vdaaChanType *pVdaa,
+ vdaaRingDetectStatusType *pStatus);
+
+/** @} VDAA_RING */
+
+/*****************************************************************************/
+/** @defgroup VDAA_LINE_STATE Line state
+ * @{
+ */
+
+
+/**
+ * @brief This function sets the Voice DAA hook status
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @param[in] newHookStatus - new hook state (VDAA_ONHOOK, VDAA_OFFHOOK, VDAA_DIG_LOOPBACK or VDAA_ONHOOK_MONITOR)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_SetHookStatus (vdaaChanType *pVdaa,uInt8 newHookStatus);
+
+/**
+ * @brief This function powers up the Voice DAA lineside device.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_PowerupLineside(vdaaChanType_ptr pVdaa);
+
+/**
+ * @brief This function powers down the Voice DAA line side device.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_PowerdownLineside(vdaaChanType_ptr pVdaa);
+
+/**
+ * @brief Read VDAA Hook Status
+ * @param[in] pVdaa - which channel to return the hook status.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+uInt8 Vdaa_GetHookStatus (vdaaChanType *pVdaa);
+
+/** @} VDAA_LINE_STATE */
+
+/*****************************************************************************/
+/** @defgroup VDAA_DIAG Diagnostics
+ * @{
+ */
+
+/**
+ * @brief This function returns the Voice DAA linefeed status.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @param[in,out] vloop - Pointer to loop voltage variable (set by this function) - in Volts
+ * @param[in,out] iloop - Pointer to loop current variable (set by this function) - in mA
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_ReadLinefeedStatus (vdaaChanType *pVdaa,int8 *vloop, int16 *iloop);
+
+/**
+ * @brief This function initializes the vdaa_LIU_Config datastructure for line in use feature
+ * @param[in,out] liuCfg - Pointer to vdaa_LIU_Config structure (user allocates)
+ * @param[in] minOnV - minimum onhook loop voltage that indicates no parallel handset is present (V)
+ * @param[in] minOffV - minimum offhook loop voltage that indicates no parallel handset is present (V)
+ * @param[in] minOffI - minimum offhook loop current that indicates no parallel handset is preset (mA)
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa Vdaa_CheckForLineInUse
+ */
+
+int Vdaa_InitLineInUseCheck(vdaa_LIU_Config *liuCfg,int8 minOnV,int8 minOffV,
+ int16 minOffI );
+
+/**
+ * @brief Monitor LVCS to detect intrusion or parallel handset
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @param[in,out] liuCfg - Pointer to vdaa_LIU_Config structure
+ * @retval VDAA_ONHOOK or VDAA_OFFHOOK (in use)
+ * @sa Vdaa_InitLineInUseCheck
+ */
+
+uInt8 Vdaa_CheckForLineInUse(vdaaChanType *pVdaa, vdaa_LIU_Config *liuCfg);
+
+/**
+ * @brief This function returns the status of the Frame Detect (FDT) bit.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @retval int - 0 - Frame NOT detected, 1 = Frame detected
+ */
+
+int Vdaa_ReadFDTStatus(vdaaChanType_ptr pVdaa);
+
+/** @} VDAA_DIAG */
+
+/*****************************************************************************/
+/** @defgroup VDAA_INTERRUPTS Interrupts
+ * @{
+ */
+
+
+/**
+ * @brief Enables interrupts based on passed 9-bit bitmask. Bit values defined by vdaaIntMask enum.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @param[in] bitmask - a logical or of @ref vdaaIntMask enum
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_SetInterruptMask(vdaaChanType *pVdaa, vdaaIntMask bitmask);
+
+/**
+ * @brief Returns the current interrupt status.
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @param[out] pIntData - interrupt mask showing which interrupts are set.
+ * @retval int - the number of interrupts set or RC_IGNORE
+ */
+
+int Vdaa_GetInterrupts (vdaaChanType *pVdaa,vdaaIntType *pIntData);
+
+/**
+ * @brief Clears ALL interrupts
+ * @param[in] pVdaa - Pointer to Voice DAA channel structure
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_ClearInterrupts (vdaaChanType *pVdaa);
+
+/** @} VDAA_INTERRUPTS */
+
+/*****************************************************************************/
+/** @defgroup VDAA_INIT Initialization
+ * @{
+ */
+
+/*****************************************************************************/
+/** @defgroup VDAA_HW_INIT Hardware/line initialization
+ * @{
+ */
+
+/**
+ * @brief
+ * This function configures the Voice DAA with a predefined country configuration preset.
+ *
+ * @param[in] pVdaa - which channel to initialize
+ * @param[in] preset - The preset to use to configure the VDAA with.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int Vdaa_CountrySetup (vdaaChanType *pVdaa,int32 preset);
+
+/**
+ * @brief
+ * This function configures the Voice DAA digital hybrid with a predefined preset.
+ *
+ * @param[in] pVdaa - which channel to initialize
+ * @param[in] preset - Index of predefined digital hybrid preset
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ * @sa Vdaa_SetHybridEnable
+ */
+
+int Vdaa_HybridSetup (vdaaChanType *pVdaa,int32 preset);
+
+/**
+ * @brief
+ * This function fully initializes and loads the general config parameters to all Vdaa devices
+ * a given daisychain up to a given number.
+ *
+ * @param[in] pVdaa - which channel to initialize or start from if size>1
+ * @param[in] size - the number of channels to initialize, should be at least 1
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int Vdaa_Init (vdaaChanType_ptr *pVdaa,int size);
+
+/**
+ * @brief
+ * This function calibrates the ADC (analog to digital converter) of the Vdaa device(s).
+ *
+ * @param[in] pVdaa - which channel to calibrate or starting channel if size>1
+ * @param[in] size - the number of channels to calibrate.
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int Vdaa_ADCCal (vdaaChanType_ptr pVdaa, int32 size);
+
+/**
+ * @brief
+ * This function controls the Voice DAA digital hybrid.
+ *
+ * @param[in] pVdaa - which channel to set/unset
+ * @param[in] enable - TRUE: enable digital hybrid, FALSE: disable digital hybrid
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ *
+ */
+
+int Vdaa_SetHybridEnable(vdaaChanType_ptr pVdaa, int enable);
+
+/** @} VDAA_HW_INIT */
+/*****************************************************************************/
+
+
+/**
+ * @brief Enables watchdog timer
+ * @param[in] pVdaa - the channel to enable the watchdog
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_EnableWatchdog(vdaaChanType_ptr pVdaa);
+
+/**
+ * @brief Execute a soft reset on a given channel.
+ * @param[in] pVdaa - the channel to reset
+ * @retval int - error from @ref errorCodeType @ref RC_NONE indicates no error.
+ */
+
+int Vdaa_SoftReset(vdaaChanType_ptr pVdaa);/** @} VDAA_INIT */
+
+/** @} MISC */
+
+/** @} VDAA_API */
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/vdaa_registers.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/vdaa_registers.h
new file mode 100644
index 0000000..2d48e3d
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/inc/vdaa_registers.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ */
+
+#ifndef SI3050REGS_H
+#define SI3050REGS_H
+
+
+enum REGISTERS
+{
+ CTRL1 = 1, /* Control */
+ CTRL2 = 2, /* Control */
+ INTE_MSK = 3, /* Interrupt Mask */
+ INTE_SRC = 4, /* Interrupt Source */
+ DAA_CTRL1 = 5, /* DAA Control 1 */
+ DAA_CTRL2 = 6, /* DAA Control 2 */
+ SMPL_CTRL = 7, /* Sample Rate Control */
+ RESVD8 = 8, /* Reserved */
+ RESVD9 = 9, /* Reserved */
+ DAA_CTRL3 = 10, /* DAA Control 3 */
+ SYS_LINE_DEV_REV = 11, /* System- and Line-Side Device Revision */
+ LSIDE_STAT = 12, /* Line-Side Device Status */
+ LSIDE_REV = 13, /* Line-Side Device Revision */
+ DAA_CTRL4 = 14, /* DAA Control 4 RPOL */
+ TXRX_GN_CTRL = 15, /* TX/RX Gain Control 1 */
+ INTL_CTRL1 = 16, /* International Control 1 */
+ INTL_CTRL2 = 17, /* International Control 2 */
+ INTL_CTRL3 = 18, /* International Control 3 */
+ INTL_CTRL4 = 19, /* International Control 4 */
+ RXCALL_PROG_ATTEN = 20, /* Call Progress RX Attenuation */
+ TXCALL_PROG_ATTEN = 21, /* Call Progress TX Attenuation */
+ RNG_VLD_CTRL1 = 22, /* Ring Validation Control 1 */
+ RNG_VLD_CTRL2 = 23, /* Ring Validation Control 2 */
+ RNG_VLD_CTRL3 = 24, /* ing Validation Control 3 */
+ RES_CALIB = 25, /* Resistor Calibration */
+ DC_TERM_CTRL = 26, /* DC Termination Control */
+ RESVD27 = 27, /* Reserved */
+ LP_CRNT_STAT = 28, /* Loop Current Status */
+ LINE_VOLT_STAT = 29, /* Line Voltage Status */
+ AC_TERM_CTRL = 30, /* AC Termination Control */
+ DAA_CTRL5 = 31, /* DAA Control 5 */
+ GND_STRT_CTRL = 32, /* Ground Start Control */
+ PCM_SPI_CTRL = 33, /* PCM/SPI Mode Select */
+ PCMTX_CNT_LO = 34, /* PCM Transmit Start Count - Low Byte */
+ PCMTX_CNT_HI = 35, /* PCM Transmit Start Count - High Byte */
+ PCMRX_CNT_LO = 36, /* PCM Receive Start Count - Low Byte */
+ PCMRX_CNT_HI = 37, /* PCM Receive Start Count - High Byte */
+ TX_GN_CTRL2 = 38, /* TX Gain Control 2 */
+ RX_GN_CTRL2 = 39, /* RX Gain Control 2 */
+ TX_GN_CTRL3 = 40, /* TX Gain Control 3 */
+ RX_GN_CTRL3 = 41, /* RX Gain Control 3 */
+ GCI_CTRL = 42, /* GCI Control */
+ LN_VI_THRESH_INTE = 43, /* Line Current/Voltage Threshold Interrupt */
+ LN_VI_THRESH_INTE_CTRL=44, /* Line Current/Voltage Threshold Interrupt Control */
+ HYB1 = 45, /* Programmable Hybrid Register 1 */
+ HYB2 = 46, /* Programmable Hybrid Register 2 */
+ HYB3 = 47, /* Programmable Hybrid Register 3 */
+ HYB4 = 48, /* Programmable Hybrid Register 4 */
+ HYB5 = 49, /* Programmable Hybrid Register 5 */
+ HYB6 = 50, /* Programmable Hybrid Register 6 */
+ HYB7 = 51, /* Programmable Hybrid Register 7 */
+ HYB8 = 52, /* Programmable Hybrid Register 8 */
+ RESVD53 = 53, /* Reserved 53 */
+ RESVD54 = 54, /* Reserved 54 */
+ RESVD55 = 55, /* Reserved 55 */
+ RESVD56 = 56, /* Reserved 56 */
+ RESVD57 = 57, /* Reserved 57 */
+ RESVD58 = 58, /* Reserved 58 */
+ SPRK_QNCH_CTRL = 59 /* Spark Quenching Control */
+
+};
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/mipsregs.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/mipsregs.h
new file mode 100644
index 0000000..b4d10e9
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/mipsregs.h
@@ -0,0 +1,1473 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_MIPSREGS_H
+#define _ASM_MIPSREGS_H
+
+//#include <linux/linkage.h>
+//#include <asm/hazards.h>
+#define CONFIG_PAGE_SIZE_4KB
+/*
+ * The following macros are especially useful for __asm__
+ * inline assembler.
+ */
+#ifndef __STR
+#define __STR(x) #x
+#endif
+#ifndef STR
+#define STR(x) __STR(x)
+#endif
+
+/*
+ * Configure language
+ */
+#ifdef __ASSEMBLY__
+#define _ULCAST_
+#else
+#define _ULCAST_ (unsigned long)
+#endif
+
+/*
+ * Coprocessor 0 register names
+ */
+#define CP0_INDEX $0
+#define CP0_RANDOM $1
+#define CP0_ENTRYLO0 $2
+#define CP0_ENTRYLO1 $3
+#define CP0_CONF $3
+#define CP0_CONTEXT $4
+#define CP0_PAGEMASK $5
+#define CP0_WIRED $6
+#define CP0_INFO $7
+#define CP0_BADVADDR $8
+#define CP0_COUNT $9
+#define CP0_ENTRYHI $10
+#define CP0_COMPARE $11
+#define CP0_STATUS $12
+#define CP0_CAUSE $13
+#define CP0_EPC $14
+#define CP0_PRID $15
+#define CP0_CONFIG $16
+#define CP0_LLADDR $17
+#define CP0_WATCHLO $18
+#define CP0_WATCHHI $19
+#define CP0_XCONTEXT $20
+#define CP0_FRAMEMASK $21
+#define CP0_DIAGNOSTIC $22
+#define CP0_DEBUG $23
+#define CP0_DEPC $24
+#define CP0_PERFORMANCE $25
+#define CP0_ECC $26
+#define CP0_CACHEERR $27
+#define CP0_TAGLO $28
+#define CP0_TAGHI $29
+#define CP0_ERROREPC $30
+#define CP0_DESAVE $31
+
+/*
+ * R4640/R4650 cp0 register names. These registers are listed
+ * here only for completeness; without MMU these CPUs are not useable
+ * by Linux. A future ELKS port might take make Linux run on them
+ * though ...
+ */
+#define CP0_IBASE $0
+#define CP0_IBOUND $1
+#define CP0_DBASE $2
+#define CP0_DBOUND $3
+#define CP0_CALG $17
+#define CP0_IWATCH $18
+#define CP0_DWATCH $19
+
+/*
+ * Coprocessor 0 Set 1 register names
+ */
+#define CP0_S1_DERRADDR0 $26
+#define CP0_S1_DERRADDR1 $27
+#define CP0_S1_INTCONTROL $20
+
+/*
+ * Coprocessor 0 Set 2 register names
+ */
+#define CP0_S2_SRSCTL $12 /* MIPSR2 */
+
+/*
+ * Coprocessor 0 Set 3 register names
+ */
+#define CP0_S3_SRSMAP $12 /* MIPSR2 */
+
+/*
+ * TX39 Series
+ */
+#define CP0_TX39_CACHE $7
+
+/*
+ * Coprocessor 1 (FPU) register names
+ */
+#define CP1_REVISION $0
+#define CP1_STATUS $31
+
+/*
+ * FPU Status Register Values
+ */
+/*
+ * Status Register Values
+ */
+
+#define FPU_CSR_FLUSH 0x01000000 /* flush denormalised results to 0 */
+#define FPU_CSR_COND 0x00800000 /* $fcc0 */
+#define FPU_CSR_COND0 0x00800000 /* $fcc0 */
+#define FPU_CSR_COND1 0x02000000 /* $fcc1 */
+#define FPU_CSR_COND2 0x04000000 /* $fcc2 */
+#define FPU_CSR_COND3 0x08000000 /* $fcc3 */
+#define FPU_CSR_COND4 0x10000000 /* $fcc4 */
+#define FPU_CSR_COND5 0x20000000 /* $fcc5 */
+#define FPU_CSR_COND6 0x40000000 /* $fcc6 */
+#define FPU_CSR_COND7 0x80000000 /* $fcc7 */
+
+/*
+ * X the exception cause indicator
+ * E the exception enable
+ * S the sticky/flag bit
+*/
+#define FPU_CSR_ALL_X 0x0003f000
+#define FPU_CSR_UNI_X 0x00020000
+#define FPU_CSR_INV_X 0x00010000
+#define FPU_CSR_DIV_X 0x00008000
+#define FPU_CSR_OVF_X 0x00004000
+#define FPU_CSR_UDF_X 0x00002000
+#define FPU_CSR_INE_X 0x00001000
+
+#define FPU_CSR_ALL_E 0x00000f80
+#define FPU_CSR_INV_E 0x00000800
+#define FPU_CSR_DIV_E 0x00000400
+#define FPU_CSR_OVF_E 0x00000200
+#define FPU_CSR_UDF_E 0x00000100
+#define FPU_CSR_INE_E 0x00000080
+
+#define FPU_CSR_ALL_S 0x0000007c
+#define FPU_CSR_INV_S 0x00000040
+#define FPU_CSR_DIV_S 0x00000020
+#define FPU_CSR_OVF_S 0x00000010
+#define FPU_CSR_UDF_S 0x00000008
+#define FPU_CSR_INE_S 0x00000004
+
+/* rounding mode */
+#define FPU_CSR_RN 0x0 /* nearest */
+#define FPU_CSR_RZ 0x1 /* towards zero */
+#define FPU_CSR_RU 0x2 /* towards +Infinity */
+#define FPU_CSR_RD 0x3 /* towards -Infinity */
+
+
+/*
+ * Values for PageMask register
+ */
+#ifdef CONFIG_CPU_VR41XX
+
+/* Why doesn't stupidity hurt ... */
+
+#define PM_1K 0x00000000
+#define PM_4K 0x00001800
+#define PM_16K 0x00007800
+#define PM_64K 0x0001f800
+#define PM_256K 0x0007f800
+
+#else
+
+#define PM_4K 0x00000000
+#define PM_16K 0x00006000
+#define PM_64K 0x0001e000
+#define PM_256K 0x0007e000
+#define PM_1M 0x001fe000
+#define PM_4M 0x007fe000
+#define PM_16M 0x01ffe000
+#define PM_64M 0x07ffe000
+#define PM_256M 0x1fffe000
+
+#endif
+
+/*
+ * Default page size for a given kernel configuration
+ */
+#ifdef CONFIG_PAGE_SIZE_4KB
+#define PM_DEFAULT_MASK PM_4K
+#elif defined(CONFIG_PAGE_SIZE_16KB)
+#define PM_DEFAULT_MASK PM_16K
+#elif defined(CONFIG_PAGE_SIZE_64KB)
+#define PM_DEFAULT_MASK PM_64K
+#else
+#error Bad page size configuration!
+#endif
+
+
+/*
+ * Values used for computation of new tlb entries
+ */
+#define PL_4K 12
+#define PL_16K 14
+#define PL_64K 16
+#define PL_256K 18
+#define PL_1M 20
+#define PL_4M 22
+#define PL_16M 24
+#define PL_64M 26
+#define PL_256M 28
+
+/*
+ * R4x00 interrupt enable / cause bits
+ */
+#define IE_SW0 (_ULCAST_(1) << 8)
+#define IE_SW1 (_ULCAST_(1) << 9)
+#define IE_IRQ0 (_ULCAST_(1) << 10)
+#define IE_IRQ1 (_ULCAST_(1) << 11)
+#define IE_IRQ2 (_ULCAST_(1) << 12)
+#define IE_IRQ3 (_ULCAST_(1) << 13)
+#define IE_IRQ4 (_ULCAST_(1) << 14)
+#define IE_IRQ5 (_ULCAST_(1) << 15)
+
+/*
+ * R4x00 interrupt cause bits
+ */
+#define C_SW0 (_ULCAST_(1) << 8)
+#define C_SW1 (_ULCAST_(1) << 9)
+#define C_IRQ0 (_ULCAST_(1) << 10)
+#define C_IRQ1 (_ULCAST_(1) << 11)
+#define C_IRQ2 (_ULCAST_(1) << 12)
+#define C_IRQ3 (_ULCAST_(1) << 13)
+#define C_IRQ4 (_ULCAST_(1) << 14)
+#define C_IRQ5 (_ULCAST_(1) << 15)
+
+/*
+ * Bitfields in the R4xx0 cp0 status register
+ */
+#define ST0_IE 0x00000001
+#define ST0_EXL 0x00000002
+#define ST0_ERL 0x00000004
+#define ST0_KSU 0x00000018
+# define KSU_USER 0x00000010
+# define KSU_SUPERVISOR 0x00000008
+# define KSU_KERNEL 0x00000000
+#define ST0_UX 0x00000020
+#define ST0_SX 0x00000040
+#define ST0_KX 0x00000080
+#define ST0_DE 0x00010000
+#define ST0_CE 0x00020000
+
+/*
+ * Setting c0_status.co enables Hit_Writeback and Hit_Writeback_Invalidate
+ * cacheops in userspace. This bit exists only on RM7000 and RM9000
+ * processors.
+ */
+#define ST0_CO 0x08000000
+
+/*
+ * Bitfields in the R[23]000 cp0 status register.
+ */
+#define ST0_IEC 0x00000001
+#define ST0_KUC 0x00000002
+#define ST0_IEP 0x00000004
+#define ST0_KUP 0x00000008
+#define ST0_IEO 0x00000010
+#define ST0_KUO 0x00000020
+/* bits 6 & 7 are reserved on R[23]000 */
+#define ST0_ISC 0x00010000
+#define ST0_SWC 0x00020000
+#define ST0_CM 0x00080000
+
+/*
+ * Bits specific to the R4640/R4650
+ */
+#define ST0_UM (_ULCAST_(1) << 4)
+#define ST0_IL (_ULCAST_(1) << 23)
+#define ST0_DL (_ULCAST_(1) << 24)
+
+/*
+ * Enable the MIPS MDMX and DSP ASEs
+ */
+#define ST0_MX 0x01000000
+
+/*
+ * Bitfields in the TX39 family CP0 Configuration Register 3
+ */
+#define TX39_CONF_ICS_SHIFT 19
+#define TX39_CONF_ICS_MASK 0x00380000
+#define TX39_CONF_ICS_1KB 0x00000000
+#define TX39_CONF_ICS_2KB 0x00080000
+#define TX39_CONF_ICS_4KB 0x00100000
+#define TX39_CONF_ICS_8KB 0x00180000
+#define TX39_CONF_ICS_16KB 0x00200000
+
+#define TX39_CONF_DCS_SHIFT 16
+#define TX39_CONF_DCS_MASK 0x00070000
+#define TX39_CONF_DCS_1KB 0x00000000
+#define TX39_CONF_DCS_2KB 0x00010000
+#define TX39_CONF_DCS_4KB 0x00020000
+#define TX39_CONF_DCS_8KB 0x00030000
+#define TX39_CONF_DCS_16KB 0x00040000
+
+#define TX39_CONF_CWFON 0x00004000
+#define TX39_CONF_WBON 0x00002000
+#define TX39_CONF_RF_SHIFT 10
+#define TX39_CONF_RF_MASK 0x00000c00
+#define TX39_CONF_DOZE 0x00000200
+#define TX39_CONF_HALT 0x00000100
+#define TX39_CONF_LOCK 0x00000080
+#define TX39_CONF_ICE 0x00000020
+#define TX39_CONF_DCE 0x00000010
+#define TX39_CONF_IRSIZE_SHIFT 2
+#define TX39_CONF_IRSIZE_MASK 0x0000000c
+#define TX39_CONF_DRSIZE_SHIFT 0
+#define TX39_CONF_DRSIZE_MASK 0x00000003
+
+/*
+ * Status register bits available in all MIPS CPUs.
+ */
+#define ST0_IM 0x0000ff00
+#define STATUSB_IP0 8
+#define STATUSF_IP0 (_ULCAST_(1) << 8)
+#define STATUSB_IP1 9
+#define STATUSF_IP1 (_ULCAST_(1) << 9)
+#define STATUSB_IP2 10
+#define STATUSF_IP2 (_ULCAST_(1) << 10)
+#define STATUSB_IP3 11
+#define STATUSF_IP3 (_ULCAST_(1) << 11)
+#define STATUSB_IP4 12
+#define STATUSF_IP4 (_ULCAST_(1) << 12)
+#define STATUSB_IP5 13
+#define STATUSF_IP5 (_ULCAST_(1) << 13)
+#define STATUSB_IP6 14
+#define STATUSF_IP6 (_ULCAST_(1) << 14)
+#define STATUSB_IP7 15
+#define STATUSF_IP7 (_ULCAST_(1) << 15)
+#define STATUSB_IP8 0
+#define STATUSF_IP8 (_ULCAST_(1) << 0)
+#define STATUSB_IP9 1
+#define STATUSF_IP9 (_ULCAST_(1) << 1)
+#define STATUSB_IP10 2
+#define STATUSF_IP10 (_ULCAST_(1) << 2)
+#define STATUSB_IP11 3
+#define STATUSF_IP11 (_ULCAST_(1) << 3)
+#define STATUSB_IP12 4
+#define STATUSF_IP12 (_ULCAST_(1) << 4)
+#define STATUSB_IP13 5
+#define STATUSF_IP13 (_ULCAST_(1) << 5)
+#define STATUSB_IP14 6
+#define STATUSF_IP14 (_ULCAST_(1) << 6)
+#define STATUSB_IP15 7
+#define STATUSF_IP15 (_ULCAST_(1) << 7)
+#define ST0_CH 0x00040000
+#define ST0_SR 0x00100000
+#define ST0_TS 0x00200000
+#define ST0_BEV 0x00400000
+#define ST0_RE 0x02000000
+#define ST0_FR 0x04000000
+#define ST0_CU 0xf0000000
+#define ST0_CU0 0x10000000
+#define ST0_CU1 0x20000000
+#define ST0_CU2 0x40000000
+#define ST0_CU3 0x80000000
+#define ST0_XX 0x80000000 /* MIPS IV naming */
+
+/*
+ * Bitfields and bit numbers in the coprocessor 0 cause register.
+ *
+ * Refer to your MIPS R4xx0 manual, chapter 5 for explanation.
+ */
+#define CAUSEB_EXCCODE 2
+#define CAUSEF_EXCCODE (_ULCAST_(31) << 2)
+#define CAUSEB_IP 8
+#define CAUSEF_IP (_ULCAST_(255) << 8)
+#define CAUSEB_IP0 8
+#define CAUSEF_IP0 (_ULCAST_(1) << 8)
+#define CAUSEB_IP1 9
+#define CAUSEF_IP1 (_ULCAST_(1) << 9)
+#define CAUSEB_IP2 10
+#define CAUSEF_IP2 (_ULCAST_(1) << 10)
+#define CAUSEB_IP3 11
+#define CAUSEF_IP3 (_ULCAST_(1) << 11)
+#define CAUSEB_IP4 12
+#define CAUSEF_IP4 (_ULCAST_(1) << 12)
+#define CAUSEB_IP5 13
+#define CAUSEF_IP5 (_ULCAST_(1) << 13)
+#define CAUSEB_IP6 14
+#define CAUSEF_IP6 (_ULCAST_(1) << 14)
+#define CAUSEB_IP7 15
+#define CAUSEF_IP7 (_ULCAST_(1) << 15)
+#define CAUSEB_IV 23
+#define CAUSEF_IV (_ULCAST_(1) << 23)
+#define CAUSEB_CE 28
+#define CAUSEF_CE (_ULCAST_(3) << 28)
+#define CAUSEB_BD 31
+#define CAUSEF_BD (_ULCAST_(1) << 31)
+
+/*
+ * Bits in the coprocessor 0 config register.
+ */
+/* Generic bits. */
+#define CONF_CM_CACHABLE_NO_WA 0
+#define CONF_CM_CACHABLE_WA 1
+#define CONF_CM_UNCACHED 2
+#define CONF_CM_CACHABLE_NONCOHERENT 3
+#define CONF_CM_CACHABLE_CE 4
+#define CONF_CM_CACHABLE_COW 5
+#define CONF_CM_CACHABLE_CUW 6
+#define CONF_CM_CACHABLE_ACCELERATED 7
+#define CONF_CM_CMASK 7
+#define CONF_BE (_ULCAST_(1) << 15)
+
+/* Bits common to various processors. */
+#define CONF_CU (_ULCAST_(1) << 3)
+#define CONF_DB (_ULCAST_(1) << 4)
+#define CONF_IB (_ULCAST_(1) << 5)
+#define CONF_DC (_ULCAST_(7) << 6)
+#define CONF_IC (_ULCAST_(7) << 9)
+#define CONF_EB (_ULCAST_(1) << 13)
+#define CONF_EM (_ULCAST_(1) << 14)
+#define CONF_SM (_ULCAST_(1) << 16)
+#define CONF_SC (_ULCAST_(1) << 17)
+#define CONF_EW (_ULCAST_(3) << 18)
+#define CONF_EP (_ULCAST_(15)<< 24)
+#define CONF_EC (_ULCAST_(7) << 28)
+#define CONF_CM (_ULCAST_(1) << 31)
+
+/* Bits specific to the R4xx0. */
+#define R4K_CONF_SW (_ULCAST_(1) << 20)
+#define R4K_CONF_SS (_ULCAST_(1) << 21)
+#define R4K_CONF_SB (_ULCAST_(3) << 22)
+
+/* Bits specific to the R5000. */
+#define R5K_CONF_SE (_ULCAST_(1) << 12)
+#define R5K_CONF_SS (_ULCAST_(3) << 20)
+
+/* Bits specific to the RM7000. */
+#define RM7K_CONF_SE (_ULCAST_(1) << 3)
+#define RM7K_CONF_TE (_ULCAST_(1) << 12)
+#define RM7K_CONF_CLK (_ULCAST_(1) << 16)
+#define RM7K_CONF_TC (_ULCAST_(1) << 17)
+#define RM7K_CONF_SI (_ULCAST_(3) << 20)
+#define RM7K_CONF_SC (_ULCAST_(1) << 31)
+
+/* Bits specific to the R10000. */
+#define R10K_CONF_DN (_ULCAST_(3) << 3)
+#define R10K_CONF_CT (_ULCAST_(1) << 5)
+#define R10K_CONF_PE (_ULCAST_(1) << 6)
+#define R10K_CONF_PM (_ULCAST_(3) << 7)
+#define R10K_CONF_EC (_ULCAST_(15)<< 9)
+#define R10K_CONF_SB (_ULCAST_(1) << 13)
+#define R10K_CONF_SK (_ULCAST_(1) << 14)
+#define R10K_CONF_SS (_ULCAST_(7) << 16)
+#define R10K_CONF_SC (_ULCAST_(7) << 19)
+#define R10K_CONF_DC (_ULCAST_(7) << 26)
+#define R10K_CONF_IC (_ULCAST_(7) << 29)
+
+/* Bits specific to the VR41xx. */
+#define VR41_CONF_CS (_ULCAST_(1) << 12)
+#define VR41_CONF_P4K (_ULCAST_(1) << 13)
+#define VR41_CONF_BP (_ULCAST_(1) << 16)
+#define VR41_CONF_M16 (_ULCAST_(1) << 20)
+#define VR41_CONF_AD (_ULCAST_(1) << 23)
+
+/* Bits specific to the R30xx. */
+#define R30XX_CONF_FDM (_ULCAST_(1) << 19)
+#define R30XX_CONF_REV (_ULCAST_(1) << 22)
+#define R30XX_CONF_AC (_ULCAST_(1) << 23)
+#define R30XX_CONF_RF (_ULCAST_(1) << 24)
+#define R30XX_CONF_HALT (_ULCAST_(1) << 25)
+#define R30XX_CONF_FPINT (_ULCAST_(7) << 26)
+#define R30XX_CONF_DBR (_ULCAST_(1) << 29)
+#define R30XX_CONF_SB (_ULCAST_(1) << 30)
+#define R30XX_CONF_LOCK (_ULCAST_(1) << 31)
+
+/* Bits specific to the TX49. */
+#define TX49_CONF_DC (_ULCAST_(1) << 16)
+#define TX49_CONF_IC (_ULCAST_(1) << 17) /* conflict with CONF_SC */
+#define TX49_CONF_HALT (_ULCAST_(1) << 18)
+#define TX49_CONF_CWFON (_ULCAST_(1) << 27)
+
+/* Bits specific to the MIPS32/64 PRA. */
+#define MIPS_CONF_MT (_ULCAST_(7) << 7)
+#define MIPS_CONF_AR (_ULCAST_(7) << 10)
+#define MIPS_CONF_AT (_ULCAST_(3) << 13)
+#define MIPS_CONF_M (_ULCAST_(1) << 31)
+
+/*
+ * Bits in the MIPS32/64 PRA coprocessor 0 config registers 1 and above.
+ */
+#define MIPS_CONF1_FP (_ULCAST_(1) << 0)
+#define MIPS_CONF1_EP (_ULCAST_(1) << 1)
+#define MIPS_CONF1_CA (_ULCAST_(1) << 2)
+#define MIPS_CONF1_WR (_ULCAST_(1) << 3)
+#define MIPS_CONF1_PC (_ULCAST_(1) << 4)
+#define MIPS_CONF1_MD (_ULCAST_(1) << 5)
+#define MIPS_CONF1_C2 (_ULCAST_(1) << 6)
+#define MIPS_CONF1_DA (_ULCAST_(7) << 7)
+#define MIPS_CONF1_DL (_ULCAST_(7) << 10)
+#define MIPS_CONF1_DS (_ULCAST_(7) << 13)
+#define MIPS_CONF1_IA (_ULCAST_(7) << 16)
+#define MIPS_CONF1_IL (_ULCAST_(7) << 19)
+#define MIPS_CONF1_IS (_ULCAST_(7) << 22)
+#define MIPS_CONF1_TLBS (_ULCAST_(63)<< 25)
+
+#define MIPS_CONF2_SA (_ULCAST_(15)<< 0)
+#define MIPS_CONF2_SL (_ULCAST_(15)<< 4)
+#define MIPS_CONF2_SS (_ULCAST_(15)<< 8)
+#define MIPS_CONF2_SU (_ULCAST_(15)<< 12)
+#define MIPS_CONF2_TA (_ULCAST_(15)<< 16)
+#define MIPS_CONF2_TL (_ULCAST_(15)<< 20)
+#define MIPS_CONF2_TS (_ULCAST_(15)<< 24)
+#define MIPS_CONF2_TU (_ULCAST_(7) << 28)
+
+#define MIPS_CONF3_TL (_ULCAST_(1) << 0)
+#define MIPS_CONF3_SM (_ULCAST_(1) << 1)
+#define MIPS_CONF3_MT (_ULCAST_(1) << 2)
+#define MIPS_CONF3_SP (_ULCAST_(1) << 4)
+#define MIPS_CONF3_VINT (_ULCAST_(1) << 5)
+#define MIPS_CONF3_VEIC (_ULCAST_(1) << 6)
+#define MIPS_CONF3_LPA (_ULCAST_(1) << 7)
+#define MIPS_CONF3_DSP (_ULCAST_(1) << 10)
+
+/*
+ * Bits in the MIPS32/64 coprocessor 1 (FPU) revision register.
+ */
+#define MIPS_FPIR_S (_ULCAST_(1) << 16)
+#define MIPS_FPIR_D (_ULCAST_(1) << 17)
+#define MIPS_FPIR_PS (_ULCAST_(1) << 18)
+#define MIPS_FPIR_3D (_ULCAST_(1) << 19)
+#define MIPS_FPIR_W (_ULCAST_(1) << 20)
+#define MIPS_FPIR_L (_ULCAST_(1) << 21)
+#define MIPS_FPIR_F64 (_ULCAST_(1) << 22)
+
+#ifndef __ASSEMBLY__
+
+/*
+ * Functions to access the R10000 performance counters. These are basically
+ * mfc0 and mtc0 instructions from and to coprocessor register with a 5-bit
+ * performance counter number encoded into bits 1 ... 5 of the instruction.
+ * Only performance counters 0 to 1 actually exist, so for a non-R10000 aware
+ * disassembler these will look like an access to sel 0 or 1.
+ */
+#define read_r10k_perf_cntr(counter) \
+({ \
+ unsigned int __res; \
+ __asm__ __volatile__( \
+ "mfpc\t%0, %1" \
+ : "=r" (__res) \
+ : "i" (counter)); \
+ \
+ __res; \
+})
+
+#define write_r10k_perf_cntr(counter,val) \
+do { \
+ __asm__ __volatile__( \
+ "mtpc\t%0, %1" \
+ : \
+ : "r" (val), "i" (counter)); \
+} while (0)
+
+#define read_r10k_perf_event(counter) \
+({ \
+ unsigned int __res; \
+ __asm__ __volatile__( \
+ "mfps\t%0, %1" \
+ : "=r" (__res) \
+ : "i" (counter)); \
+ \
+ __res; \
+})
+
+#define write_r10k_perf_cntl(counter,val) \
+do { \
+ __asm__ __volatile__( \
+ "mtps\t%0, %1" \
+ : \
+ : "r" (val), "i" (counter)); \
+} while (0)
+
+
+/*
+ * Macros to access the system control coprocessor
+ */
+
+#define __read_32bit_c0_register(source, sel) \
+({ int __res; \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __read_64bit_c0_register(source, sel) \
+({ unsigned long long __res; \
+ if (sizeof(unsigned long) == 4) \
+ __res = __read_64bit_c0_split(source, sel); \
+ else if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips3\n\t" \
+ "dmfc0\t%0, " #source "\n\t" \
+ ".set\tmips0" \
+ : "=r" (__res)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmfc0\t%0, " #source ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __write_32bit_c0_register(register, sel, value) \
+do { \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ "mtc0\t%z0, " #register "\n\t" \
+ : : "Jr" ((unsigned int)(value))); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips32\n\t" \
+ "mtc0\t%z0, " #register ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" ((unsigned int)(value))); \
+} while (0)
+
+#define __write_64bit_c0_register(register, sel, value) \
+do { \
+ if (sizeof(unsigned long) == 4) \
+ __write_64bit_c0_split(register, sel, value); \
+ else if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips3\n\t" \
+ "dmtc0\t%z0, " #register "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" (value)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmtc0\t%z0, " #register ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "Jr" (value)); \
+} while (0)
+
+#define __read_ulong_c0_register(reg, sel) \
+ ((sizeof(unsigned long) == 4) ? \
+ (unsigned long) __read_32bit_c0_register(reg, sel) : \
+ (unsigned long) __read_64bit_c0_register(reg, sel))
+
+#define __write_ulong_c0_register(reg, sel, val) \
+do { \
+ if (sizeof(unsigned long) == 4) \
+ __write_32bit_c0_register(reg, sel, val); \
+ else \
+ __write_64bit_c0_register(reg, sel, val); \
+} while (0)
+
+/*
+ * On RM7000/RM9000 these are uses to access cop0 set 1 registers
+ */
+#define __read_32bit_c0_ctrl_register(source) \
+({ int __res; \
+ __asm__ __volatile__( \
+ "cfc0\t%0, " #source "\n\t" \
+ : "=r" (__res)); \
+ __res; \
+})
+
+#define __write_32bit_c0_ctrl_register(register, value) \
+do { \
+ __asm__ __volatile__( \
+ "ctc0\t%z0, " #register "\n\t" \
+ : : "Jr" ((unsigned int)(value))); \
+} while (0)
+
+/*
+ * These versions are only needed for systems with more than 38 bits of
+ * physical address space running the 32-bit kernel. That's none atm :-)
+ */
+#define __read_64bit_c0_split(source, sel) \
+({ \
+ unsigned long long val; \
+ unsigned long flags; \
+ \
+ local_irq_save(flags); \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmfc0\t%M0, " #source "\n\t" \
+ "dsll\t%L0, %M0, 32\n\t" \
+ "dsrl\t%M0, %M0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ ".set\tmips0" \
+ : "=r" (val)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dmfc0\t%M0, " #source ", " #sel "\n\t" \
+ "dsll\t%L0, %M0, 32\n\t" \
+ "dsrl\t%M0, %M0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ ".set\tmips0" \
+ : "=r" (val)); \
+ local_irq_restore(flags); \
+ \
+ val; \
+})
+
+#define __write_64bit_c0_split(source, sel, val) \
+do { \
+ unsigned long flags; \
+ \
+ local_irq_save(flags); \
+ if (sel == 0) \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dsll\t%L0, %L0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ "dsll\t%M0, %M0, 32\n\t" \
+ "or\t%L0, %L0, %M0\n\t" \
+ "dmtc0\t%L0, " #source "\n\t" \
+ ".set\tmips0" \
+ : : "r" (val)); \
+ else \
+ __asm__ __volatile__( \
+ ".set\tmips64\n\t" \
+ "dsll\t%L0, %L0, 32\n\t" \
+ "dsrl\t%L0, %L0, 32\n\t" \
+ "dsll\t%M0, %M0, 32\n\t" \
+ "or\t%L0, %L0, %M0\n\t" \
+ "dmtc0\t%L0, " #source ", " #sel "\n\t" \
+ ".set\tmips0" \
+ : : "r" (val)); \
+ local_irq_restore(flags); \
+} while (0)
+
+#define read_c0_index() __read_32bit_c0_register($0, 0)
+#define write_c0_index(val) __write_32bit_c0_register($0, 0, val)
+
+#define read_c0_entrylo0() __read_ulong_c0_register($2, 0)
+#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val)
+
+#define read_c0_entrylo1() __read_ulong_c0_register($3, 0)
+#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val)
+
+#define read_c0_conf() __read_32bit_c0_register($3, 0)
+#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val)
+
+#define read_c0_context() __read_ulong_c0_register($4, 0)
+#define write_c0_context(val) __write_ulong_c0_register($4, 0, val)
+
+#define read_c0_pagemask() __read_32bit_c0_register($5, 0)
+#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val)
+
+#define read_c0_wired() __read_32bit_c0_register($6, 0)
+#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val)
+
+#define read_c0_info() __read_32bit_c0_register($7, 0)
+
+#define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */
+#define write_c0_cache(val) __write_32bit_c0_register($7, 0, val)
+
+#define read_c0_badvaddr() __read_ulong_c0_register($8, 0)
+#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val)
+
+#define read_c0_count() __read_32bit_c0_register($9, 0)
+#define write_c0_count(val) __write_32bit_c0_register($9, 0, val)
+
+#define read_c0_count2() __read_32bit_c0_register($9, 6) /* pnx8550 */
+#define write_c0_count2(val) __write_32bit_c0_register($9, 6, val)
+
+#define read_c0_count3() __read_32bit_c0_register($9, 7) /* pnx8550 */
+#define write_c0_count3(val) __write_32bit_c0_register($9, 7, val)
+
+#define read_c0_entryhi() __read_ulong_c0_register($10, 0)
+#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val)
+
+#define read_c0_compare() __read_32bit_c0_register($11, 0)
+#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val)
+
+#define read_c0_compare2() __read_32bit_c0_register($11, 6) /* pnx8550 */
+#define write_c0_compare2(val) __write_32bit_c0_register($11, 6, val)
+
+#define read_c0_compare3() __read_32bit_c0_register($11, 7) /* pnx8550 */
+#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
+
+#define read_c0_status() __read_32bit_c0_register($12, 0)
+#ifdef CONFIG_MIPS_MT_SMTC
+#define write_c0_status(val) \
+do { \
+ __write_32bit_c0_register($12, 0, val); \
+ __ehb(); \
+} while (0)
+#else
+/*
+ * Legacy non-SMTC code, which may be hazardous
+ * but which might not support EHB
+ */
+#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
+#endif /* CONFIG_MIPS_MT_SMTC */
+
+#define read_c0_cause() __read_32bit_c0_register($13, 0)
+#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
+
+#define read_c0_epc() __read_ulong_c0_register($14, 0)
+#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val)
+
+#define read_c0_prid() __read_32bit_c0_register($15, 0)
+
+#define read_c0_config() __read_32bit_c0_register($16, 0)
+#define read_c0_config1() __read_32bit_c0_register($16, 1)
+#define read_c0_config2() __read_32bit_c0_register($16, 2)
+#define read_c0_config3() __read_32bit_c0_register($16, 3)
+#define read_c0_config4() __read_32bit_c0_register($16, 4)
+#define read_c0_config5() __read_32bit_c0_register($16, 5)
+#define read_c0_config6() __read_32bit_c0_register($16, 6)
+#define read_c0_config7() __read_32bit_c0_register($16, 7)
+#define write_c0_config(val) __write_32bit_c0_register($16, 0, val)
+#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val)
+#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val)
+#define write_c0_config3(val) __write_32bit_c0_register($16, 3, val)
+#define write_c0_config4(val) __write_32bit_c0_register($16, 4, val)
+#define write_c0_config5(val) __write_32bit_c0_register($16, 5, val)
+#define write_c0_config6(val) __write_32bit_c0_register($16, 6, val)
+#define write_c0_config7(val) __write_32bit_c0_register($16, 7, val)
+
+/*
+ * The WatchLo register. There may be upto 8 of them.
+ */
+#define read_c0_watchlo0() __read_ulong_c0_register($18, 0)
+#define read_c0_watchlo1() __read_ulong_c0_register($18, 1)
+#define read_c0_watchlo2() __read_ulong_c0_register($18, 2)
+#define read_c0_watchlo3() __read_ulong_c0_register($18, 3)
+#define read_c0_watchlo4() __read_ulong_c0_register($18, 4)
+#define read_c0_watchlo5() __read_ulong_c0_register($18, 5)
+#define read_c0_watchlo6() __read_ulong_c0_register($18, 6)
+#define read_c0_watchlo7() __read_ulong_c0_register($18, 7)
+#define write_c0_watchlo0(val) __write_ulong_c0_register($18, 0, val)
+#define write_c0_watchlo1(val) __write_ulong_c0_register($18, 1, val)
+#define write_c0_watchlo2(val) __write_ulong_c0_register($18, 2, val)
+#define write_c0_watchlo3(val) __write_ulong_c0_register($18, 3, val)
+#define write_c0_watchlo4(val) __write_ulong_c0_register($18, 4, val)
+#define write_c0_watchlo5(val) __write_ulong_c0_register($18, 5, val)
+#define write_c0_watchlo6(val) __write_ulong_c0_register($18, 6, val)
+#define write_c0_watchlo7(val) __write_ulong_c0_register($18, 7, val)
+
+/*
+ * The WatchHi register. There may be upto 8 of them.
+ */
+#define read_c0_watchhi0() __read_32bit_c0_register($19, 0)
+#define read_c0_watchhi1() __read_32bit_c0_register($19, 1)
+#define read_c0_watchhi2() __read_32bit_c0_register($19, 2)
+#define read_c0_watchhi3() __read_32bit_c0_register($19, 3)
+#define read_c0_watchhi4() __read_32bit_c0_register($19, 4)
+#define read_c0_watchhi5() __read_32bit_c0_register($19, 5)
+#define read_c0_watchhi6() __read_32bit_c0_register($19, 6)
+#define read_c0_watchhi7() __read_32bit_c0_register($19, 7)
+
+#define write_c0_watchhi0(val) __write_32bit_c0_register($19, 0, val)
+#define write_c0_watchhi1(val) __write_32bit_c0_register($19, 1, val)
+#define write_c0_watchhi2(val) __write_32bit_c0_register($19, 2, val)
+#define write_c0_watchhi3(val) __write_32bit_c0_register($19, 3, val)
+#define write_c0_watchhi4(val) __write_32bit_c0_register($19, 4, val)
+#define write_c0_watchhi5(val) __write_32bit_c0_register($19, 5, val)
+#define write_c0_watchhi6(val) __write_32bit_c0_register($19, 6, val)
+#define write_c0_watchhi7(val) __write_32bit_c0_register($19, 7, val)
+
+#define read_c0_xcontext() __read_ulong_c0_register($20, 0)
+#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val)
+
+#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20)
+#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val)
+
+#define read_c0_framemask() __read_32bit_c0_register($21, 0)
+#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val)
+
+/* RM9000 PerfControl performance counter control register */
+#define read_c0_perfcontrol() __read_32bit_c0_register($22, 0)
+#define write_c0_perfcontrol(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_diag() __read_32bit_c0_register($22, 0)
+#define write_c0_diag(val) __write_32bit_c0_register($22, 0, val)
+
+#define read_c0_diag1() __read_32bit_c0_register($22, 1)
+#define write_c0_diag1(val) __write_32bit_c0_register($22, 1, val)
+
+#define read_c0_diag2() __read_32bit_c0_register($22, 2)
+#define write_c0_diag2(val) __write_32bit_c0_register($22, 2, val)
+
+#define read_c0_diag3() __read_32bit_c0_register($22, 3)
+#define write_c0_diag3(val) __write_32bit_c0_register($22, 3, val)
+
+#define read_c0_diag4() __read_32bit_c0_register($22, 4)
+#define write_c0_diag4(val) __write_32bit_c0_register($22, 4, val)
+
+#define read_c0_diag5() __read_32bit_c0_register($22, 5)
+#define write_c0_diag5(val) __write_32bit_c0_register($22, 5, val)
+
+#define read_c0_debug() __read_32bit_c0_register($23, 0)
+#define write_c0_debug(val) __write_32bit_c0_register($23, 0, val)
+
+#define read_c0_depc() __read_ulong_c0_register($24, 0)
+#define write_c0_depc(val) __write_ulong_c0_register($24, 0, val)
+
+/*
+ * MIPS32 / MIPS64 performance counters
+ */
+#define read_c0_perfctrl0() __read_32bit_c0_register($25, 0)
+#define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val)
+#define read_c0_perfcntr0() __read_32bit_c0_register($25, 1)
+#define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val)
+#define read_c0_perfctrl1() __read_32bit_c0_register($25, 2)
+#define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val)
+#define read_c0_perfcntr1() __read_32bit_c0_register($25, 3)
+#define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val)
+#define read_c0_perfctrl2() __read_32bit_c0_register($25, 4)
+#define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val)
+#define read_c0_perfcntr2() __read_32bit_c0_register($25, 5)
+#define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val)
+#define read_c0_perfctrl3() __read_32bit_c0_register($25, 6)
+#define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val)
+#define read_c0_perfcntr3() __read_32bit_c0_register($25, 7)
+#define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val)
+
+/* RM9000 PerfCount performance counter register */
+#define read_c0_perfcount() __read_64bit_c0_register($25, 0)
+#define write_c0_perfcount(val) __write_64bit_c0_register($25, 0, val)
+
+#define read_c0_ecc() __read_32bit_c0_register($26, 0)
+#define write_c0_ecc(val) __write_32bit_c0_register($26, 0, val)
+
+#define read_c0_derraddr0() __read_ulong_c0_register($26, 1)
+#define write_c0_derraddr0(val) __write_ulong_c0_register($26, 1, val)
+
+#define read_c0_cacheerr() __read_32bit_c0_register($27, 0)
+
+#define read_c0_derraddr1() __read_ulong_c0_register($27, 1)
+#define write_c0_derraddr1(val) __write_ulong_c0_register($27, 1, val)
+
+#define read_c0_taglo() __read_32bit_c0_register($28, 0)
+#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val)
+
+#define read_c0_dtaglo() __read_32bit_c0_register($28, 2)
+#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val)
+
+#define read_c0_taghi() __read_32bit_c0_register($29, 0)
+#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val)
+
+#define read_c0_errorepc() __read_ulong_c0_register($30, 0)
+#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val)
+
+/* MIPSR2 */
+#define read_c0_hwrena() __read_32bit_c0_register($7,0)
+#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val)
+
+#define read_c0_intctl() __read_32bit_c0_register($12, 1)
+#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val)
+
+#define read_c0_srsctl() __read_32bit_c0_register($12, 2)
+#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val)
+
+#define read_c0_srsmap() __read_32bit_c0_register($12, 3)
+#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val)
+
+#define read_c0_ebase() __read_32bit_c0_register($15,1)
+#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
+
+/*
+ * Macros to access the floating point coprocessor control registers
+ */
+#define read_32bit_cp1_register(source) \
+({ int __res; \
+ __asm__ __volatile__( \
+ ".set\tpush\n\t" \
+ ".set\treorder\n\t" \
+ "cfc1\t%0,"STR(source)"\n\t" \
+ ".set\tpop" \
+ : "=r" (__res)); \
+ __res;})
+
+#define rddsp(mask) \
+({ \
+ unsigned int __res; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # rddsp $1, %x1 \n" \
+ " .word 0x7c000cb8 | (%x1 << 16) \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__res) \
+ : "i" (mask)); \
+ __res; \
+})
+
+#define wrdsp(val, mask) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # wrdsp $1, %x1 \n" \
+ " .word 0x7c2004f8 | (%x1 << 11) \n" \
+ " .set pop \n" \
+ : \
+ : "r" (val), "i" (mask)); \
+} while (0)
+
+#if 0 /* Need DSP ASE capable assembler ... */
+#define mflo0() ({ long mflo0; __asm__("mflo %0, $ac0" : "=r" (mflo0)); mflo0;})
+#define mflo1() ({ long mflo1; __asm__("mflo %0, $ac1" : "=r" (mflo1)); mflo1;})
+#define mflo2() ({ long mflo2; __asm__("mflo %0, $ac2" : "=r" (mflo2)); mflo2;})
+#define mflo3() ({ long mflo3; __asm__("mflo %0, $ac3" : "=r" (mflo3)); mflo3;})
+
+#define mfhi0() ({ long mfhi0; __asm__("mfhi %0, $ac0" : "=r" (mfhi0)); mfhi0;})
+#define mfhi1() ({ long mfhi1; __asm__("mfhi %0, $ac1" : "=r" (mfhi1)); mfhi1;})
+#define mfhi2() ({ long mfhi2; __asm__("mfhi %0, $ac2" : "=r" (mfhi2)); mfhi2;})
+#define mfhi3() ({ long mfhi3; __asm__("mfhi %0, $ac3" : "=r" (mfhi3)); mfhi3;})
+
+#define mtlo0(x) __asm__("mtlo %0, $ac0" ::"r" (x))
+#define mtlo1(x) __asm__("mtlo %0, $ac1" ::"r" (x))
+#define mtlo2(x) __asm__("mtlo %0, $ac2" ::"r" (x))
+#define mtlo3(x) __asm__("mtlo %0, $ac3" ::"r" (x))
+
+#define mthi0(x) __asm__("mthi %0, $ac0" ::"r" (x))
+#define mthi1(x) __asm__("mthi %0, $ac1" ::"r" (x))
+#define mthi2(x) __asm__("mthi %0, $ac2" ::"r" (x))
+#define mthi3(x) __asm__("mthi %0, $ac3" ::"r" (x))
+
+#else
+
+#define mfhi0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac0 \n" \
+ " .word 0x00000810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac1 \n" \
+ " .word 0x00200810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac2 \n" \
+ " .word 0x00400810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mfhi3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mfhi %0, $ac3 \n" \
+ " .word 0x00600810 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo0() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac0 \n" \
+ " .word 0x00000812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo1() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac1 \n" \
+ " .word 0x00200812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo2() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac2 \n" \
+ " .word 0x00400812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mflo3() \
+({ \
+ unsigned long __treg; \
+ \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " # mflo %0, $ac3 \n" \
+ " .word 0x00600812 \n" \
+ " move %0, $1 \n" \
+ " .set pop \n" \
+ : "=r" (__treg)); \
+ __treg; \
+})
+
+#define mthi0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac0 \n" \
+ " .word 0x00200011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac1 \n" \
+ " .word 0x00200811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac2 \n" \
+ " .word 0x00201011 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mthi3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mthi $1, $ac3 \n" \
+ " .word 0x00201811 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo0(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac0 \n" \
+ " .word 0x00200013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo1(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac1 \n" \
+ " .word 0x00200813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo2(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac2 \n" \
+ " .word 0x00201013 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#define mtlo3(x) \
+do { \
+ __asm__ __volatile__( \
+ " .set push \n" \
+ " .set noat \n" \
+ " move $1, %0 \n" \
+ " # mtlo $1, $ac3 \n" \
+ " .word 0x00201813 \n" \
+ " .set pop \n" \
+ : \
+ : "r" (x)); \
+} while (0)
+
+#endif
+
+/*
+ * TLB operations.
+ *
+ * It is responsibility of the caller to take care of any TLB hazards.
+ */
+static inline void tlb_probe(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbp\n\t"
+ ".set reorder");
+}
+
+static inline void tlb_read(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbr\n\t"
+ ".set reorder");
+}
+
+static inline void tlb_write_indexed(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbwi\n\t"
+ ".set reorder");
+}
+
+static inline void tlb_write_random(void)
+{
+ __asm__ __volatile__(
+ ".set noreorder\n\t"
+ "tlbwr\n\t"
+ ".set reorder");
+}
+
+/*
+ * Manipulate bits in a c0 register.
+ */
+#ifndef CONFIG_MIPS_MT_SMTC
+/*
+ * SMTC Linux requires shutting-down microthread scheduling
+ * during CP0 register read-modify-write sequences.
+ */
+#define __BUILD_SET_C0(name) \
+static inline unsigned int \
+set_c0_##name(unsigned int set) \
+{ \
+ unsigned int res; \
+ \
+ res = read_c0_##name(); \
+ res |= set; \
+ write_c0_##name(res); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+clear_c0_##name(unsigned int clear) \
+{ \
+ unsigned int res; \
+ \
+ res = read_c0_##name(); \
+ res &= ~clear; \
+ write_c0_##name(res); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+change_c0_##name(unsigned int change, unsigned int new) \
+{ \
+ unsigned int res; \
+ \
+ res = read_c0_##name(); \
+ res &= ~change; \
+ res |= (new & change); \
+ write_c0_##name(res); \
+ \
+ return res; \
+}
+
+#else /* SMTC versions that manage MT scheduling */
+
+#include <linux/irqflags.h>
+
+/*
+ * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with
+ * header file recursion.
+ */
+static inline unsigned int __dmt(void)
+{
+ int res;
+
+ __asm__ __volatile__(
+ " .set push \n"
+ " .set mips32r2 \n"
+ " .set noat \n"
+ " .word 0x41610BC1 # dmt $1 \n"
+ " ehb \n"
+ " move %0, $1 \n"
+ " .set pop \n"
+ : "=r" (res));
+
+ instruction_hazard();
+
+ return res;
+}
+
+#define __VPECONTROL_TE_SHIFT 15
+#define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT)
+
+#define __EMT_ENABLE __VPECONTROL_TE
+
+static inline void __emt(unsigned int previous)
+{
+ if ((previous & __EMT_ENABLE))
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " .word 0x41600be1 # emt \n"
+ " ehb \n"
+ " .set mips0 \n");
+}
+
+static inline void __ehb(void)
+{
+ __asm__ __volatile__(
+ " .set mips32r2 \n"
+ " ehb \n" " .set mips0 \n");
+}
+
+/*
+ * Note that local_irq_save/restore affect TC-specific IXMT state,
+ * not Status.IE as in non-SMTC kernel.
+ */
+
+#define __BUILD_SET_C0(name) \
+static inline unsigned int \
+set_c0_##name(unsigned int set) \
+{ \
+ unsigned int res; \
+ unsigned int omt; \
+ unsigned int flags; \
+ \
+ local_irq_save(flags); \
+ omt = __dmt(); \
+ res = read_c0_##name(); \
+ res |= set; \
+ write_c0_##name(res); \
+ __emt(omt); \
+ local_irq_restore(flags); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+clear_c0_##name(unsigned int clear) \
+{ \
+ unsigned int res; \
+ unsigned int omt; \
+ unsigned int flags; \
+ \
+ local_irq_save(flags); \
+ omt = __dmt(); \
+ res = read_c0_##name(); \
+ res &= ~clear; \
+ write_c0_##name(res); \
+ __emt(omt); \
+ local_irq_restore(flags); \
+ \
+ return res; \
+} \
+ \
+static inline unsigned int \
+change_c0_##name(unsigned int change, unsigned int new) \
+{ \
+ unsigned int res; \
+ unsigned int omt; \
+ unsigned int flags; \
+ \
+ local_irq_save(flags); \
+ \
+ omt = __dmt(); \
+ res = read_c0_##name(); \
+ res &= ~change; \
+ res |= (new & change); \
+ write_c0_##name(res); \
+ __emt(omt); \
+ local_irq_restore(flags); \
+ \
+ return res; \
+}
+#endif
+
+__BUILD_SET_C0(status)
+__BUILD_SET_C0(cause)
+__BUILD_SET_C0(config)
+__BUILD_SET_C0(intcontrol)
+__BUILD_SET_C0(intctl)
+__BUILD_SET_C0(srsmap)
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_MIPSREGS_H */
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/patch_files/Makefile b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/patch_files/Makefile
new file mode 100644
index 0000000..2ea53bb
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/patch_files/Makefile
@@ -0,0 +1,16 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+# platform driver
+ccflags-y += -I../inc
+snd-soc-procslic-patch-objs := si3218x_patch_A_2017MAY25.o
+
+obj-$(CONFIG_SND_SOC_SI3218X) += snd-soc-proslic-patch.o
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/patch_files/si3218x_patch_A_2017MAY25.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/patch_files/si3218x_patch_A_2017MAY25.c
new file mode 100644
index 0000000..ccccb75
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/patch_files/si3218x_patch_A_2017MAY25.c
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Generated from si3218x_patch_A_2017MAY25.dsp_prom
+ * on 05-25-2017 at 15:1:37
+ * Patch ID = 0x05252017L
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ */
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si3218x.h"
+
+static const uInt32 patchData [] = {
+141029L,
+540867L,
+141029L,
+543427L,
+141029L,
+553667L,
+141029L,
+562883L,
+141029L,
+567491L,
+141029L,
+569539L,
+141029L,
+580803L,
+141029L,
+586435L,
+141029L,
+593091L,
+141029L,
+598211L,
+141029L,
+603843L,
+141029L,
+604355L,
+141029L,
+604867L,
+141029L,
+605379L,
+141029L,
+605891L,
+141029L,
+606403L,
+736L,
+492224L,
+452200L,
+141029L,
+491712L,
+558181L,
+410018L,
+539765L,
+142565L,
+551619L,
+355746L,
+539765L,
+142560L,
+548547L,
+767493L,
+356258L,
+407477L,
+142561L,
+551619L,
+767493L,
+539749L,
+743525L,
+119426L,
+141029L,
+925377L,
+387589L,
+558181L,
+388514L,
+387701L,
+142565L,
+561347L,
+524290L,
+144096L,
+559811L,
+524292L,
+141029L,
+560835L,
+524290L,
+437360L,
+671749L,
+437349L,
+141029L,
+21186L,
+560741L,
+524290L,
+143072L,
+565955L,
+141029L,
+122050L,
+694789L,
+141029L,
+789186L,
+408165L,
+408645L,
+141029L,
+950976L,
+524291L,
+144101L,
+571587L,
+199685L,
+666853L,
+574659L,
+431717L,
+197189L,
+136805L,
+198725L,
+408677L,
+262242L,
+524291L,
+144101L,
+577731L,
+408581L,
+666853L,
+873664L,
+136805L,
+407621L,
+141029L,
+873664L,
+9733L,
+136805L,
+116130L,
+524304L,
+660069L,
+440424L,
+9827L,
+660066L,
+524315L,
+141029L,
+674496L,
+694789L,
+828517L,
+119426L,
+267414L,
+829441L,
+828933L,
+694789L,
+118405L,
+788805L,
+725829L,
+119424L,
+141029L,
+230594L,
+492645L,
+252002L,
+524295L,
+517220L,
+144101L,
+596675L,
+517733L,
+827461L,
+141029L,
+745664L,
+466437L,
+558181L,
+410018L,
+519797L,
+142565L,
+601795L,
+385637L,
+466597L,
+524289L,
+141029L,
+27330L,
+524293L,
+524293L,
+524293L,
+524293L,
+524293L,
+524293L,
+0L
+};
+
+static const uInt16 patchEntries [] = {
+951,
+3854,
+4136,
+4333,
+1856,
+1695,
+1316,
+4545,
+1455,
+4148,
+0,
+0,
+0,
+0,
+0,
+0
+};
+
+static const uInt16 patchSupportAddr [] = {
+800,
+694,
+695,
+795,
+914,
+758,
+757,
+798,
+797,
+796,
+226,
+1011,
+1010,
+0
+};
+
+static const uInt32 patchSupportData [] = {
+0x200000L,
+0x80000L,
+0x200000L,
+0x180000L,
+0x07FCFDDAL,
+0x400000L,
+0x0L,
+0x123400L,
+0x123400L,
+0x123400L,
+0x35D540L,
+0x3F00000L,
+0x100000L,
+0x0L
+};
+
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+const proslicPatch si3218xPatchRevALCQC = {
+#else
+const proslicPatch RevAPatch = {
+#endif
+ patchData,
+ patchEntries,
+ 0x05252017L,
+ patchSupportAddr,
+ patchSupportData
+};
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_spi_api.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_spi_api.c
new file mode 100644
index 0000000..77e67d0
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_spi_api.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * spi.h
+ * SPI driver implementation file
+ *
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * File Description:
+ * This is the implementation file for the SPI driver used
+ * in the ProSLIC demonstration code. It calls the library
+ * that initializes and talks to the proslic motherboard.
+ *
+ * Dependancies:
+ *
+ */
+//#include "../iowrapper.h" // This is the motherboard interface library
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include "config_inc/si_voice_datatypes.h"
+#include "inc/si_voice_ctrl.h"
+#include "spi.h"
+#include "proslic_sys.h"
+
+/*
+** Function: SPI_Init
+**
+** Description:
+** Initializes the SPI interface
+**
+** Input Parameters:
+** none
+**
+** Return:
+** none
+*/
+int SPI_Init (ctrl_S *hSpi){
+ int ret;
+
+ ret = proslic_spi_setup();
+
+ return 0;
+}
+
+/*
+** Function: spiGci_ResetWrapper
+**
+** Description:
+** Sets the reset pin of the ProSLIC
+*/
+int ctrl_ResetWrapper (void *hSpiGci, int status){
+
+ printk("ctrl_ResetWrapper");
+ proslic_reset(NULL, status);
+
+ return 0;
+}
+
+/*
+** SPI/GCI register read
+**
+** Description:
+** Reads a single ProSLIC register
+**
+** Input Parameters:
+** channel: ProSLIC channel to read from
+** regAddr: Address of register to read
+** return data: data to read from register
+**
+** Return:
+** none
+*/
+uInt8 ctrl_ReadRegisterWrapper (void *hSpiGci, uInt8 channel, uInt8 regAddr){
+
+
+ return proslic_read_register(hSpiGci,channel,regAddr);
+}
+
+
+/*
+** Function: spiGci_WriteRegisterWrapper
+**
+** Description:
+** Writes a single ProSLIC register
+**
+** Input Parameters:
+** channel: ProSLIC channel to write to
+** address: Address of register to write
+** data: data to write to register
+**
+** Return:
+** none
+*/
+int ctrl_WriteRegisterWrapper (void *hSpiGci, unsigned char channel, unsigned char regAddr, unsigned char data){
+
+ proslic_write_register(hSpiGci,channel,regAddr, data);
+ return 0;
+}
+
+
+/*
+** Function: SPI_ReadRAMWrapper
+**
+** Description:
+** Reads a single ProSLIC RAM location
+**
+** Input Parameters:
+** channel: ProSLIC channel to read from
+** address: Address of RAM location to read
+** pData: data to read from RAM location
+**
+** Return:
+** none
+*/
+ramData ctrl_ReadRAMWrapper (void *hSpiGci, unsigned char channel, unsigned short ramAddr){
+ ramData data;
+
+ data = proslic_read_ram(hSpiGci,channel,ramAddr);
+
+ return data;
+}
+
+
+/*
+** Function: SPI_WriteRAMWrapper
+**
+** Description:
+** Writes a single ProSLIC RAM location
+**
+** Input Parameters:
+** channel: ProSLIC channel to write to
+** address: Address of RAM location to write
+** data: data to write to RAM location
+**
+** Return:
+** none
+*/
+int ctrl_WriteRAMWrapper (void *hSpiGci, unsigned char channel, unsigned short ramAddr, ramData data){
+
+ proslic_write_ram(hSpiGci,channel,ramAddr,data);
+
+ return 0;
+}
+
+
+
+/*
+** $Log: proslic_spi_api.c,v $
+** Revision 1.11 2008/07/24 21:06:16 lajordan
+** no message
+**
+** Revision 1.10 2008/03/19 18:20:09 lajordan
+** no message
+**
+** Revision 1.9 2007/06/04 16:35:51 lajordan
+** added profiling
+**
+** Revision 1.8 2007/02/27 19:25:48 lajordan
+** updated api
+**
+** Revision 1.7 2007/02/05 23:43:27 lajordan
+** fixed register access func
+**
+** Revision 1.6 2006/11/22 21:38:19 lajordan
+** broadcast added
+**
+** Revision 1.5 2006/07/21 20:31:26 lajordan
+** fixed cant connect message
+**
+** Revision 1.4 2006/07/19 18:15:56 lajordan
+** fixed spi init
+**
+** Revision 1.3 2006/07/18 21:50:16 lajordan
+** removed extraneous endif
+**
+** Revision 1.2 2006/07/18 21:48:51 lajordan
+** added 16 bit accesses example code
+**
+** Revision 1.1.1.1 2006/07/13 20:26:08 lajordan
+** no message
+**
+** Revision 1.1.1.1 2006/07/06 22:06:23 lajordan
+** no message
+**
+** Revision 1.3 2006/06/29 19:11:18 laj
+** lpt driver completed
+**
+** Revision 1.2 2006/06/21 23:46:58 laj
+** register reads/writes added
+**
+** Revision 1.1 2006/06/21 23:18:07 laj
+** no message
+**
+** Revision 1.1 2006/06/21 22:42:26 laj
+** new api style
+**
+** Revision 1.3 2005/11/14 17:42:34 laj
+** added SPI_init
+**
+** Revision 1.2 2005/11/07 23:20:54 laj
+** took out extra spaces
+**
+*/
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys.h
new file mode 100644
index 0000000..d629915
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys.h
@@ -0,0 +1,120 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __PROSLIC_SYS_HDR__
+#define __PROSLIC_SYS_HDR__ 1
+#include <linux/types.h>
+#include <linux/time64.h> /* for struct timespec */
+
+#include <linux/spi/spi.h>
+
+#include "proslic_sys_cfg.h"
+
+
+
+/* Do a quick sanity check on channel setting */
+#define SILABS_MAX_CHAN 32
+#if (SILABS_MAX_CHANNELS > SILABS_MAX_CHAN)
+#error "ProSLIC only supports up to 32 channels"
+#endif
+
+#define PROSLIC_BCAST 0xFF
+#define PROSLIC_SPI_OK 0
+#define PROSLIC_SPI_NOK 8 /* This is what the ProSLIC API calls SPI_FAIL */
+#define PROSLIC_TIMER_ERROR 15
+
+/* Debug macros */
+#define PROSLIC_API_HDR "PROSLIC_API "
+
+#define proslic_trace(fmt, arg...) if(proslic_debug_setting & 0x1) printk( KERN_NOTICE PROSLIC_API_HDR "TRC: " fmt "\n", ##arg)
+#define proslic_debug(fmt, arg...) if(proslic_debug_setting & 0x2) printk( KERN_DEBUG PROSLIC_API_HDR "DBG: " fmt "\n", ##arg)
+#define proslic_error(fmt, arg...) if(proslic_debug_setting & 0x4) printk( KERN_ERR PROSLIC_API_HDR "ERR: " fmt "\n", ##arg)
+
+/* Data types compatible with the ProSLIC API system services layer */
+typedef u_int8_t BOOLEAN;
+typedef int8_t int8;
+typedef u_int8_t uInt8;
+typedef uInt8 uChar;
+typedef int16_t int16;
+typedef u_int16_t uInt16;
+typedef int32_t int32;
+typedef u_int32_t uInt32;
+typedef u_int32_t ramData;
+
+
+#ifndef CTRL_H
+/* Function prototypes compatible with the ProSLIC API system services layer */
+typedef int (*ctrl_Reset_fptr) (void *hCtrl, int in_reset);
+
+typedef int (*ctrl_WriteRegister_fptr) (void *hCtrl, uInt8 channel, uInt8 regAddr, uInt8 data);
+typedef int (*ctrl_WriteRAM_fptr) (void *hCtrl, uInt8 channel, uInt16 ramAddr, ramData data);
+
+typedef uInt8 (*ctrl_ReadRegister_fptr) (void *hCtrl, uInt8 channel, uInt8 regAddr);
+typedef ramData (*ctrl_ReadRAM_fptr) (void *hCtrl, uInt8 channel, uInt16 ramAddr);
+
+typedef int (*ctrl_Semaphore_fptr) (void *hCtrl, int in_critical_section);
+#endif
+
+typedef void *(*get_hctrl) (uInt8 channel); /* Get a pointer to the control interface */
+
+typedef int (*system_delay_fptr) (void *hTimer, int timeInMs);
+typedef int (*system_timeElapsed_fptr) (void *hTimer, void *startTime, int *timeInMs);
+typedef int (*system_getTime_fptr) (void *hTimer, void *time);
+typedef void *(get_Timer)(void); /* return a pointer to "the" hTimer */
+
+/* Function table entries to reduce namespace pollution */
+typedef struct
+{
+ ctrl_Reset_fptr reset;
+
+ ctrl_WriteRegister_fptr write_reg;
+ ctrl_WriteRAM_fptr write_ram;
+
+ ctrl_ReadRegister_fptr read_reg;
+ ctrl_ReadRAM_fptr read_ram;
+
+ ctrl_Semaphore_fptr sem;
+} proslic_spi_fptrs_t;
+
+typedef struct
+{
+ system_delay_fptr slic_delay;
+ system_timeElapsed_fptr elapsed_time;
+ system_getTime_fptr get_time;
+} proslic_timer_fptrs_t;
+
+/* Timer container */
+typedef struct
+{
+ struct timespec64 timerObj;
+} proslic_timeStamp;
+
+extern int proslic_channel_count;
+extern int proslic_debug_setting;
+int proslic_spi_setup(void);
+void proslic_spi_shutdown(void);
+
+typedef enum
+{
+ PROSLIC_IS_UNKNOWN,
+ PROSLIC_IS_PROSLIC,
+ PROSLIC_IS_DAA
+} proslic_dev_t;
+
+/* Exported functions/values */
+extern proslic_timer_fptrs_t proslic_timer_if;
+extern proslic_spi_fptrs_t proslic_spi_if;
+int proslic_reset(void *hCtrl, int in_reset);
+int proslic_write_register(void *hCtrl, uInt8 channel, uInt8 regAddr, uInt8 data);
+int proslic_write_ram(void *hCtrl, uInt8 channel, uInt16 ramAddr, ramData data);
+uInt8 proslic_read_register(void *hCtrl, uInt8 channel, uInt8 regAddr);
+ramData proslic_read_ram(void *hCtrl, uInt8 channel, uInt16 ramAddr);
+
+int proslic_get_channel_count(void);
+proslic_dev_t proslic_get_device_type(uint8_t channel);
+void *proslic_get_hCtrl(uint8_t channel);
+int proslic_spi_probe(struct spi_device *spi, struct spi_driver *spi_drv);
+int proslic_spi_remove(struct spi_device *spi);
+
+
+#endif /* End of __PROSLIC_SYS_HDR__ */
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_cfg.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_cfg.h
new file mode 100644
index 0000000..021a9c6
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_cfg.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __PROSLIC_SYS_CFG_HDR__
+#define __PROSLIC_SYS_CFG_HDR__ 1
+/*
+ * Begin user defined build options
+ *
+ * TODO: move this to a .kconfig option menu
+ */
+
+#define SILABS_BITS_PER_WORD 8 /* MUST be either 8, 16, or 32 */
+#define SILABS_SPI_RATE 4000000 /* In terms of Hz */
+#define SILABS_MAX_RAM_WAIT 1000 /* In terms of loop count */
+#define SILABS_RESET_GPIO 135
+#define SILABS_MAX_CHANNELS 4
+#define SILABS_RAM_BLOCK_ACCESS 1 /* Define this if you wish to use a single block to write to RAM, may not work on all systems */
+#define SILABS_DEFAULT_DBG 7
+#define SILABS_MIN_MSLEEP_TIME 30 /* threshold to call mdelay vs. msleep() */
+#define SILABS_MSLEEP_SLOP 10 /* If the msleep() function is off by a constant value, set this number positive if it's too long or negative number for too short - terms of mSec */
+#define PROSLIC_XFER_BUF 4 /* How many bytes to send in 1 transfer. Either 1,2, or 4. If setting SILABS_BITS_PER_WORD to 16 or 32, you MUST set this either 2 or 4 */
+/* End of user defined section */
+
+#endif /* __PROSLIC_SYS_CFG_HDR__ */
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_main.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_main.c
new file mode 100644
index 0000000..b9243c4
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_main.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include "proslic_sys.h"
+
+#define PROSLIC_SYS_SERVICES_VER "0.0.1"
+#define DRIVER_DESCRIPTION "ProSLIC API compatible system services"
+#define DRIVER_AUTHOR "Silicon Laboratories"
+
+int proslic_debug_setting = SILABS_DEFAULT_DBG;
+int proslic_channel_count = SILABS_MAX_CHANNELS;
+
+module_param(proslic_debug_setting, int, S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP);
+MODULE_PARM_DESC(proslic_debug_setting, "debug mode bitmask, 1 = TRC, 2 = DBG, 4 = ERR");
+module_param(proslic_channel_count, int, S_IRUSR | S_IRGRP );
+MODULE_PARM_DESC(proslic_channel_count, "Number of actual channels on the platform");
+
+/*****************************************************************************************************/
+
+int init_module(void)
+{
+ int rc;
+
+ printk( KERN_INFO "ProSLIC API system services module loaded, version: %s\n", PROSLIC_SYS_SERVICES_VER);
+ printk( KERN_INFO "Debug = 0x%0x\n", proslic_debug_setting);
+
+ if(proslic_channel_count > SILABS_MAX_CHANNELS)
+ {
+ printk( KERN_ERR "proslic_channel_count max is: %d, got: %d\n", SILABS_MAX_CHANNELS, proslic_channel_count);
+ return -EINVAL;
+ }
+
+ rc = proslic_spi_setup();
+
+ if(rc == 0)
+ {
+ /* TODO: any other init we may want tot do here... */
+ }
+ else
+ {
+ printk( KERN_ERR "proslic_spi_setup returned: %d\n", rc);
+ return rc;
+ }
+
+ return 0;
+
+}
+
+void cleanup_module(void)
+{
+ proslic_spi_shutdown();
+ printk( KERN_INFO "ProSLIC API system services module unloaded.\n");
+}
+
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("Dual MPL/GPL");
+
+EXPORT_SYMBOL(proslic_spi_if);
+EXPORT_SYMBOL(proslic_timer_if);
+EXPORT_SYMBOL(proslic_get_channel_count);
+EXPORT_SYMBOL(proslic_get_device_type);
+EXPORT_SYMBOL(proslic_get_hCtrl);
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_spi.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_spi.c
new file mode 100644
index 0000000..101c486
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_spi.c
@@ -0,0 +1,698 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+#include <linux/spinlock.h>
+#include <linux/of_gpio.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include "proslic_sys.h"
+
+/*****************************************************************************************************/
+
+#define PROSLIC_REG_ID 0
+#define PROSLIC_REG_RAM_WAIT 4
+#define PROSLIC_REG_RAM_HI 5
+#define PROSLIC_REG_RAM_D0 6
+#define PROSLIC_REG_RAM_D1 7
+#define PROSLIC_REG_RAM_D2 8
+#define PROSLIC_REG_RAM_D3 9
+#define PROSLIC_REG_RAM_LO 10
+#define PROSLIC_REG_WRVSLIC 12
+#define PROSLIC_REG_WRVDAA 34
+#define PROSLIC_REG_ISDAA 11
+
+#define PROSLIC_CW_BYTE 0
+#define PROSLIC_REG_BYTE 1
+#define RAM_ADR_HIGH_MASK(ADDR) (((ADDR)>>3)&0xE0)
+
+/* Basic register definitions, regardless of chipset ('4x, '2x, '17x, '26x compatible */
+
+#define PROSLIC_CW_RD 0x60
+#define PROSLIC_CW_WR 0x20
+#define PROSLIC_CW_BCAST 0x80
+#define PROSLIC_BCAST 0xFF
+
+#ifndef PROSLIC_XFER_BUF
+#define PROSLIC_XFER_BUF (SILABS_BITS_PER_WORD/8)
+#endif
+
+/* Now do some sanity checks */
+#if (SILABS_BITS_PER_WORD != 32) && (SILABS_BITS_PER_WORD != 16) && (SILABS_BITS_PER_WORD != 8)
+#error "SILABS_BITS_PER_WORD needs to be either 8, 16 or 32"
+#endif
+
+#if (((SILABS_BITS_PER_WORD == 16) && (PROSLIC_XFER_BUF != 2) ) \
+ || ((SILABS_BITS_PER_WORD == 32) && (PROSLIC_XFER_BUF != 4) ) )
+#error "SILABS_BITS_PER_WORD & PROSLIC_XFER_BUF size mismatch"
+#endif
+
+#if (SILABS_BITS_PER_WORD != 8)
+#define SILABS_CW_BYTE 1
+#define SILABS_REG_BYTE 0
+#else
+#define SILABS_CW_BYTE 0
+#define SILABS_REG_BYTE 1
+#endif
+
+typedef struct
+{
+ proslic_dev_t deviceType[SILABS_MAX_CHANNELS];
+ spinlock_t bus_lock;
+ uInt8 channel_count; /* In most cases this is the channel count as well */
+} proslic_spi_data_t;
+
+typedef struct
+{
+ /* Placeholder for now */
+} proslic_spi_pform_t;
+
+/* Chan address is sent in reverse bit order */
+static uInt8 chanAddr[SILABS_MAX_CHAN] =
+{
+ 0x00, 0x10,
+#if (SILABS_MAX_CHAN > 2)
+ 0x08, 0x18,
+#endif
+#if (SILABS_MAX_CHAN > 4)
+ 0x04, 0x14,
+#endif
+#if (SILABS_MAX_CHAN > 6)
+ 0x0C, 0x1C,
+#endif
+#if (SILABS_MAX_CHAN > 8)
+ 0x02, 0x12,
+#endif
+#if (SILABS_MAX_CHAN > 10)
+ 0x0A, 0x1A,
+#endif
+#if (SILABS_MAX_CHAN > 12)
+ 0x06, 0x16,
+#endif
+#if (SILABS_MAX_CHAN > 14)
+ 0x0E, 0x1E,
+#endif
+#if (SILABS_MAX_CHAN > 16)
+ 0x01, 0x11,
+#endif
+#if (SILABS_MAX_CHAN > 18)
+ 0x09, 0x19,
+#endif
+#if (SILABS_MAX_CHAN > 20)
+ 0x05, 0x15,
+#endif
+#if (SILABS_MAX_CHAN > 22)
+ 0x0D, 0x1D,
+#endif
+#if (SILABS_MAX_CHAN > 24)
+ 0x03, 0x13,
+#endif
+#if (SILABS_MAX_CHAN > 26)
+ 0x0B, 0x1B,
+#endif
+#if (SILABS_MAX_CHAN > 28)
+ 0x07,0x17,
+#endif
+#if (SILABS_MAX_CHAN > 30)
+ 0x0F, 0x1F
+#endif
+};
+
+static proslic_spi_data_t *proslic_data;
+static unsigned int proslic_reset_gpio = SILABS_RESET_GPIO;
+struct spi_driver *proslic_spi;
+struct spi_device *proslic_spidev;
+
+/*****************************************************************************************************/
+uInt8 proslic_read_register_private(void *hCtrl, uInt8 channel, uInt8 regAddr)
+{
+ u_int8_t data_stream[4];
+// proslic_spi_data_t *spi_data = (proslic_spi_data_t *)hCtrl;
+ if (proslic_spidev == NULL)
+ printk ("%s : small spi NULL\n",__FUNCTION__);
+
+ if( unlikely(channel >= SILABS_MAX_CHANNELS) )
+ {
+ return PROSLIC_SPI_NOK;
+ }
+ else
+ {
+ data_stream[PROSLIC_CW_BYTE] = PROSLIC_CW_RD | chanAddr[channel];
+ }
+
+ data_stream[PROSLIC_REG_BYTE] = regAddr;
+
+ data_stream[2] = 0xFF; /* Set the register to a non-zero value, just in case */
+#if (PROSLIC_XFER_BUF == 4) || (PROSLIC_XFER_BUF == 2)
+ spi_write_then_read(proslic_spidev, data_stream, 2, &data_stream[2], 2); /* In essence, 2 16 bit ops: 1 to send the request, 1 to get the data, needs to be 32 bit aligned. */
+ proslic_debug("%s(%d): chan = %u reg = %u data = 0x%02X", __FUNCTION__, __LINE__, channel, regAddr, data_stream[2]);
+#else
+ {
+ int i;
+ for(i = 0; i < 2; i++)
+ {
+ spi_write(proslic_spidev, &data_stream[i], 1);
+ }
+ }
+ spi_read(proslic_spidev, &data_stream[2], 1);
+#endif
+
+ return data_stream[2];
+}
+
+/*****************************************************************************************************/
+
+uInt8 proslic_read_register(void *hCtrl, uInt8 channel, uInt8 regAddr)
+{
+ uInt8 data;
+ //unsigned long irqSettings;
+ //proslic_spi_data_t *spi_data = (proslic_spi_data_t *)hCtrl;
+ //spin_lock_irqsave(&spi_data->bus_lock, irqSettings);
+ data = proslic_read_register_private(hCtrl, channel, regAddr);
+ //spin_unlock_irqrestore(&spi_data->bus_lock, irqSettings);
+ proslic_debug("%s(%d): chan = %u reg = %u data = 0x%02X", __FUNCTION__, __LINE__, channel, regAddr, data);
+ return data;
+}
+EXPORT_SYMBOL(proslic_read_register);
+
+
+/*****************************************************************************************************/
+/* ProSLIC API register write function */
+#if PROSLIC_XFER_BUF == 4
+#define proslic_write_register_private proslic_write_register
+#endif
+
+int proslic_write_register_private(void *hCtrl, uInt8 channel, uInt8 regAddr, uInt8 data)
+{
+ u_int8_t data_stream[4];
+ //struct spi_device *spi_data = (struct spi_device *)hCtrl;
+
+#if PROSLIC_XFER_BUF != 4
+ int i;
+#endif
+
+ if( unlikely(channel == PROSLIC_BCAST) )
+ {
+ data_stream[PROSLIC_CW_BYTE] = PROSLIC_CW_BCAST | PROSLIC_CW_WR;
+ }
+ else if( unlikely(channel >= SILABS_MAX_CHANNELS) )
+ {
+ return PROSLIC_SPI_NOK;
+ }
+ else
+ {
+ data_stream[PROSLIC_CW_BYTE] = PROSLIC_CW_WR | chanAddr[channel];
+ }
+
+ proslic_trace("%s(%d): chan = %u reg = %u data = 0x%02X", __FUNCTION__, __LINE__, channel, regAddr, data);
+
+ data_stream[PROSLIC_REG_BYTE] = regAddr;
+
+ data_stream[2] = data_stream[3] = data;
+
+#if PROSLIC_XFER_BUF == 4
+ spi_write(proslic_spidev, data_stream, PROSLIC_XFER_BUF);
+#else
+#if PROSLIC_XFER_BUF == 2 /* 16 bit mode */
+ for(i = 0; i < 4; i+=2)
+#else /* Byte by byte */
+ for(i = 0; i < 3; i++)
+#endif
+ {
+ spi_write(proslic_spidev, &data_stream[i], PROSLIC_XFER_BUF);
+ }
+#endif
+
+ return PROSLIC_SPI_OK;
+}
+/*****************************************************************************************************/
+#if PROSLIC_XFER_BUF != 4
+int proslic_write_register(void *hCtrl, uInt8 channel, uInt8 regAddr, uInt8 data)
+{
+ unsigned long irqSettings;
+ int rc;
+ //proslic_spi_data_t *spi_data = (proslic_spi_data_t *)hCtrl;
+ //spin_lock_irqsave(&spi_data->bus_lock, irqSettings);
+ rc = proslic_write_register_private(hCtrl, channel, regAddr, data);
+ //spin_unlock_irqrestore(&spi_data->bus_lock, irqSettings);
+ return rc;
+}
+EXPORT_SYMBOL(proslic_write_register);
+#endif
+
+/*****************************************************************************************************/
+
+/*
+ * wait for RAM access
+ *
+ * return code 0 = OK
+ *
+ */
+
+static int wait_ram(void *hCtrl, uInt8 channel)
+{
+ unsigned int count = SILABS_MAX_RAM_WAIT;
+ uInt8 data;
+
+ do
+ {
+ data = proslic_read_register_private(hCtrl, channel, PROSLIC_REG_RAM_WAIT) & 0x1;
+ if(unlikely(data))
+ {
+ mdelay(5);
+ }
+ }while((data) && (count--));
+
+ if(likely(count))
+ {
+ return 0;
+ }
+ return -1; /* Timed out */
+}
+
+/*****************************************************************************************************/
+/* RAM Write wrapper */
+int proslic_write_ram(void *hCtrl, uInt8 channel, uInt16 ramAddr, ramData data )
+{
+
+ ramData myData = data;
+ int rc = 0;
+ //unsigned long irqSettings;
+ //struct spi_device *spi_data = (struct spi_device *)hCtrl;
+ hCtrl = proslic_spidev;
+
+ proslic_trace("%s(%d): chan = %u ram = %u data = 0x%08X", __FUNCTION__, __LINE__, channel, ramAddr, data);
+ //spin_lock_irqsave(&spi_data->bus_lock, irqSettings);
+
+ if(wait_ram(hCtrl,channel) != 0)
+ {
+ return PROSLIC_SPI_NOK;
+ }
+
+
+#ifdef SILABS_RAM_BLOCK_ACCESS
+ {
+ uInt8 ramWriteData[24]; /* This encapsulates the 6 reg writes into 1 block */
+ const uInt8 regAddr[6] = {PROSLIC_REG_RAM_HI, PROSLIC_REG_RAM_D0, PROSLIC_REG_RAM_D1,
+ PROSLIC_REG_RAM_D2, PROSLIC_REG_RAM_D3, PROSLIC_REG_RAM_LO};
+ int i;
+ uInt8 scratch;
+
+ /* Setup control word & registers for ALL the reg access */
+ scratch = chanAddr[channel] | PROSLIC_CW_WR;
+
+ for(i = 0; i < 6; i++)
+ {
+ ramWriteData[(i<<2)] = scratch ;
+ ramWriteData[(i<<2)+1] = regAddr[i];
+ }
+
+ /* For the data, we send the same byte twice to keep things 32 bit aligned */
+ ramWriteData[2] = ramWriteData[3] = RAM_ADR_HIGH_MASK(ramAddr);
+
+ ramWriteData[6] = ramWriteData[7] = (uInt8)(myData<<3);
+ myData = myData >> 5;
+
+ ramWriteData[10] = ramWriteData[11] = (uInt8)(myData & 0xFF);
+ myData = myData >> 8;
+
+ ramWriteData[14] = ramWriteData[15] = (uInt8)(myData & 0xFF);
+ myData = myData >> 8;
+
+ ramWriteData[18] = ramWriteData[19] = (uInt8)(myData & 0xFF);
+
+ ramWriteData[22] = ramWriteData[23] = (uInt8)(ramAddr& 0xFF);
+
+ spi_write(hCtrl, ramWriteData, 24);
+
+ }
+#else
+ proslic_write_register_private(hCtrl, channel, RAM_ADDR_HI, RAM_ADR_HIGH_MASK(ramAddr));
+
+ proslic_write_register_private(hCtrl, channel, RAM_DATA_B0, ((unsigned char)(myData<<3)));
+
+ myData = myData >> 5;
+
+ proslic_write_register_private(hCtrl, channel, RAM_DATA_B1, ((unsigned char)(myData & 0xFF)));
+
+ myData = myData >> 8;
+
+ proslic_write_register_private(hCtrl, channel, RAM_DATA_B2, ((unsigned char)(myData & 0xFF)));
+
+ myData = myData >> 8;
+
+ proslic_write_register_private(hCtrl, channel, RAM_DATA_B3, ((unsigned char)(myData & 0xFF)));
+
+ proslic_write_register_private(hCtrl, channel, RAM_ADDR_LO, (unsigned char)(ramAddr & 0xFF));
+#endif
+ if(wait_ram(hCtrl,channel) != 0)
+ {
+ rc = PROSLIC_SPI_NOK;
+ }
+ else
+ {
+ rc = PROSLIC_SPI_OK;
+ }
+ //spin_unlock_irqrestore(&spi_data->bus_lock, irqSettings);
+
+ return rc;
+
+}
+EXPORT_SYMBOL(proslic_write_ram);
+
+/*****************************************************************************************************/
+ramData proslic_read_ram(void *hCtrl, uInt8 channel, uInt16 ramAddr)
+{
+ ramData data;
+ //unsigned long irqSettings;
+ //proslic_spi_data_t *spi_data = (proslic_spi_data_t *)hCtrl;
+ hCtrl = proslic_spidev;
+
+ if(wait_ram(hCtrl,channel) != 0)
+ {
+ return PROSLIC_SPI_NOK;
+ }
+
+ //spin_lock_irqsave(&spi_data->bus_lock, irqSettings);
+ /* TODO: could combine these 2 writes into 1 spi_write call... */
+ proslic_write_register_private(hCtrl, channel, PROSLIC_REG_RAM_HI, RAM_ADR_HIGH_MASK(ramAddr));
+
+ proslic_write_register_private(hCtrl, channel, PROSLIC_REG_RAM_LO, (unsigned char)(ramAddr&0xFF));
+
+ if(wait_ram(hCtrl,channel) != 0)
+ {
+ return PROSLIC_SPI_NOK;
+ }
+
+ data = proslic_read_register_private(hCtrl, channel, PROSLIC_REG_RAM_D3);
+ data = data << 8;
+ data |= proslic_read_register_private(hCtrl, channel, PROSLIC_REG_RAM_D2);
+ data = data << 8;
+ data |= proslic_read_register_private(hCtrl, channel, PROSLIC_REG_RAM_D1);
+ data = data << 8;
+ data |= proslic_read_register_private(hCtrl, channel, PROSLIC_REG_RAM_D0);
+ //spin_unlock_irqrestore(&spi_data->bus_lock, irqSettings);
+
+ data = data >>3;
+
+ proslic_trace("%s(%d): chan = %u ram = %u data = 0x%08X", __FUNCTION__, __LINE__, channel, ramAddr, data);
+
+ return data;
+
+}
+EXPORT_SYMBOL(proslic_read_ram);
+
+/*****************************************************************************************************/
+int proslic_reset(void *hCtrl, int in_reset)
+{
+ proslic_trace("%s(%d): in_reset = %d", __FUNCTION__, __LINE__, in_reset);
+ gpio_direction_output(proslic_reset_gpio, (in_reset == 0) );
+
+ return PROSLIC_SPI_OK;
+}
+EXPORT_SYMBOL(proslic_reset);
+
+/*****************************************************************************************************/
+
+/*
+ * Do a simple write/verify test on a given register. 0 = OK.
+ */
+static int simple_wrv(void *hCtrl, uInt8 channel, uInt8 regAddr)
+{
+ uInt8 data;
+
+ proslic_write_register(hCtrl, channel, regAddr, 0);
+ data = proslic_read_register(hCtrl, channel, regAddr);
+ if(unlikely(data != 0) )
+ {
+ return -1;
+ }
+
+ proslic_write_register(hCtrl, channel, regAddr, 0x5A);
+ data = proslic_read_register(hCtrl, channel, regAddr);
+ if(unlikely(data != 0x5A) )
+ {
+ return -2;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************************************/
+
+/*
+ * Determine if this a ProSLIC or DAA or unknown type - NOT fully tested against ALL chipsets, may not
+ * properly work with Si3218/9 parts.
+ */
+static proslic_dev_t proslic_detect_type(void *hCtrl, uInt8 channel)
+{
+ /* Guess it's a ProSLIC first */
+ uInt8 data;
+
+ data = proslic_read_register(hCtrl, channel, PROSLIC_REG_ISDAA);
+ proslic_debug("%s(%d): channel = %d data = 0x%0X", __FUNCTION__, __LINE__, channel, data);
+
+ /* For ProSLIC ISDAA = 5, for DAA it is not (it is non-zero and not FF */
+
+ if( unlikely((data != 0xFF) && data ))
+ {
+ /* Likely a ProSLIC, let's confirm it by doing a few register write/verify operations */
+ if( data == 5)
+ {
+ if(unlikely(simple_wrv(hCtrl, channel, PROSLIC_REG_WRVSLIC) == 0))
+ {
+ proslic_debug("%s(%d): channel = %d is_proslic", __FUNCTION__, __LINE__, channel);
+ return PROSLIC_IS_PROSLIC;
+ }
+ }
+ else /* Likely a DAA/Si3050 device */
+ {
+ if(unlikely(simple_wrv(hCtrl, channel, PROSLIC_REG_WRVDAA) == 0))
+ {
+ proslic_debug("%s(%d): channel = %d is_daa", __FUNCTION__, __LINE__, channel);
+ return PROSLIC_IS_DAA;
+ }
+ }
+ }
+
+ proslic_debug("%s(%d): channel = %d is_unknown", __FUNCTION__, __LINE__, channel);
+ return PROSLIC_IS_UNKNOWN;
+}
+
+/*****************************************************************************************************/
+/* Pull in any device tree parameters */
+#ifdef CONFIG_OF
+static void proslic_of_probe(struct spi_device *spi)
+{
+ int len;
+ const __be32 *property;
+ u8 scratch;
+
+ printk(KERN_INFO "proslic_of_probe()\n");
+
+ /* see if the user specified number of channels */
+ property = of_get_property( spi->dev.of_node, "channel_count", &len);
+
+ if(property && (len >= sizeof(__be32)) )
+ {
+ scratch = be32_to_cpup(property);
+
+ if(( scratch <= SILABS_MAX_CHANNELS )
+ && (scratch > 0) )
+ {
+ proslic_channel_count = scratch;
+ }
+ }
+
+ /* See if the user specified a debug setting */
+ property = of_get_property( spi->dev.of_node, "debug_level", &len);
+
+ if(property && (len >= sizeof(__be32)) )
+ {
+ scratch = be32_to_cpup(property);
+
+ if(( scratch <= SILABS_DEFAULT_DBG )
+ && (scratch > 0) )
+ {
+ proslic_debug_setting = scratch;
+ printk(KERN_INFO "debug_level = %d\n", proslic_debug_setting);
+ }
+ }
+
+ printk(KERN_INFO "[previous]reset_gpio = %d\n", proslic_reset_gpio);
+ proslic_reset_gpio =
+ of_get_named_gpio(spi->dev.of_node, "reset_gpio", 0);
+
+ printk(KERN_INFO "reset_gpio = %d\n", proslic_reset_gpio);
+}
+#endif
+
+/*****************************************************************************************************/
+int proslic_spi_probe(struct spi_device *spi, struct spi_driver *spi_drv)
+{
+ proslic_spi_pform_t *pform_data;
+ unsigned int channel;
+ int rc;
+
+ printk(KERN_INFO "PROSLIC module being probed\n");
+
+ proslic_spi = spi_drv;
+ pform_data = (proslic_spi_pform_t *) &(spi->dev.platform_data);
+
+#ifdef CONFIG_OF
+ proslic_of_probe(spi);
+#endif
+
+ rc = gpio_request(proslic_reset_gpio,"proslic_reset");
+ if(rc == 0)
+ {
+ printk(KERN_INFO "PROSLIC GPIO registered OK");
+ gpio_export( proslic_reset_gpio, 0);
+ proslic_reset(NULL, 0);
+ }
+ else
+ {
+ printk(KERN_INFO "PROSLIC GPIO registered FAil!! rc = %d", rc);
+ return -ENODEV;
+ }
+
+ if(unlikely(!pform_data))
+ {
+ return -ENODEV;
+ }
+
+ proslic_data = kzalloc(sizeof(*proslic_data), GFP_KERNEL);
+
+ if(unlikely(!proslic_data))
+ {
+ return -ENOMEM;
+ }
+
+ spin_lock_init(&(proslic_data->bus_lock));
+ proslic_spidev = spi;
+#ifdef CONFIG_OF
+ spi->bits_per_word = SILABS_BITS_PER_WORD;
+ spi->max_speed_hz = SILABS_SPI_RATE;
+ spi->mode = SPI_MODE_3;
+ if( spi_setup(spi) != 0)
+ {
+ printk(KERN_ERR PROSLIC_API_HDR "failed to configure spi mode");
+ kfree(proslic_data);
+ return -EIO;
+ }
+#endif
+ spi_set_drvdata(spi, proslic_data);
+
+ /* Probe to determine the number of DAA's or ProSLIC's present */
+ for(channel = 0; channel < proslic_channel_count; channel++)
+ {
+ proslic_data->deviceType[channel] = proslic_detect_type(proslic_spidev, channel);
+ if( proslic_data->deviceType[channel] != PROSLIC_IS_UNKNOWN)
+ {
+ proslic_data->channel_count++;
+ }
+ }
+
+ if(proslic_data->channel_count)
+ {
+ return 0;
+ }
+ else
+ {
+ return -ENXIO;
+ }
+}
+EXPORT_SYMBOL(proslic_spi_probe);
+
+/*****************************************************************************************************/
+int proslic_spi_remove(struct spi_device *spi)
+{
+ void *ptr;
+
+ printk(KERN_INFO "ProSLIC module being removed");
+ /* Just put the device(s) into reset - assumes 1 reset per SPI device */
+ proslic_reset(NULL, 1);
+
+ ptr = spi_get_drvdata(spi);
+ if(ptr != NULL)
+ {
+ kfree(ptr);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(proslic_spi_remove);
+
+/*****************************************************************************************************/
+int proslic_spi_setup()
+{
+ int rc;
+ printk(KERN_INFO "proslic_spi_setup()\n");
+
+ rc = spi_register_driver(proslic_spi);
+
+ if(rc != 0)
+ {
+ proslic_error("%s(%d): spi_register driver returned = %d", __FUNCTION__, __LINE__, rc);
+ }
+ else
+ {
+ proslic_debug("%s(%d): spi driver registered", __FUNCTION__, __LINE__);
+ }
+
+ proslic_trace("%s(%d): completed", __FUNCTION__, __LINE__);
+ return rc;
+}
+
+
+void proslic_spi_shutdown()
+{
+ spi_unregister_driver(proslic_spi);
+ gpio_unexport( proslic_reset_gpio );
+ gpio_free( proslic_reset_gpio );
+}
+/*****************************************************************************************************/
+int proslic_get_channel_count()
+{
+ return proslic_data->channel_count;
+}
+
+proslic_dev_t proslic_get_device_type(uint8_t channel_number)
+{
+ if(channel_number < proslic_data->channel_count)
+ {
+ return proslic_data->deviceType[channel_number];
+ }
+ else
+ {
+ return PROSLIC_IS_UNKNOWN;
+ }
+}
+
+void *proslic_get_hCtrl(uint8_t channel)
+{
+ if(channel < proslic_data->channel_count)
+ {
+ return proslic_data;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+/*****************************************************************************************************/
+proslic_spi_fptrs_t proslic_spi_if =
+{
+ proslic_reset,
+
+ proslic_write_register,
+ proslic_write_ram,
+
+ proslic_read_register,
+ proslic_read_ram,
+
+ NULL, /* semaphore */
+
+};
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_timer.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_timer.c
new file mode 100644
index 0000000..7c1ca1b
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_sys_timer.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/delay.h>
+#include <linux/ktime.h>
+#include <linux/timekeeping.h>
+
+#include "proslic_sys.h"
+
+/*****************************************************************************************************/
+static int proslic_sys_delay(void *hTimer, int timeInMsec)
+{
+ if(likely(timeInMsec < SILABS_MIN_MSLEEP_TIME))
+ {
+ mdelay(timeInMsec);
+ }
+ else
+ {
+ msleep((timeInMsec-SILABS_MSLEEP_SLOP));
+ }
+ return PROSLIC_SPI_OK;
+}
+
+/*****************************************************************************************************/
+/* Code assumes time value has been allocated */
+static int proslic_sys_getTime(void *hTimer, void *time)
+{
+ if(time != NULL)
+ {
+ ktime_get_coarse_real_ts64(&((proslic_timeStamp *)time)->timerObj);
+ return PROSLIC_SPI_OK;
+ }
+ else
+ {
+ return PROSLIC_TIMER_ERROR;
+ }
+}
+/*****************************************************************************************************/
+
+static int proslic_sys_timeElapsed(void *hTimer, void *startTime, int *timeInMsec)
+{
+ if( (startTime != NULL) && (timeInMsec != NULL) )
+ {
+ struct timespec64 now;
+ struct timespec64 ts_delta;
+ ktime_get_coarse_real_ts64(&now);
+ ts_delta = timespec64_sub(now, (((proslic_timeStamp *) startTime)->timerObj));
+ *timeInMsec = (int)( (ts_delta.tv_sec *1000) + (ts_delta.tv_nsec / NSEC_PER_MSEC) );
+ return PROSLIC_SPI_OK;
+ }
+ else
+ {
+ return PROSLIC_TIMER_ERROR;
+ }
+}
+
+
+proslic_timer_fptrs_t proslic_timer_if =
+{
+ proslic_sys_delay,
+ proslic_sys_timeElapsed,
+ proslic_sys_getTime
+};
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_timer_intf_linux.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_timer_intf_linux.c
new file mode 100644
index 0000000..208a0df
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/proslic_timer_intf_linux.c
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * $Id: proslic_timer_intf_win.c 109 2008-10-22 19:45:09Z lajordan@SILABS.COM $
+ *
+ * system.c
+ * System specific functions implementation file
+ *
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * File Description:
+ * This is the implementation file for the system specific functions like timer functions.
+ *
+ * Dependancies:
+ * datatypes.h
+ *
+ */
+#include "config_inc/si_voice_datatypes.h"
+#include "inc/si_voice_timer_intf.h"
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/delay.h>
+#include "timer.h"
+//#include <asm/div64.h>
+#
+/*
+** Function: SYSTEM_TimerInit
+*/
+void TimerInit (systemTimer_S *pTimerObj){
+
+}
+
+
+/*
+** Function: SYSTEM_Delay
+*/
+int time_DelayWrapper (void *hTimer, int timeInMs){
+ mdelay(timeInMs);
+ return 0;
+}
+
+
+/*
+** Function: SYSTEM_TimeElapsed
+*/
+int time_TimeElapsedWrapper (void *hTimer, void *startTime, int *timeInMs){ *timeInMs = 1000;
+ return 0;
+}
+
+/*
+** Function: SYSTEM_GetTime
+*/
+int time_GetTimeWrapper (void *hTimer, void *time){
+// time->timestamp=0;
+ return 0;
+}
+
+/*
+** $Log: proslic_timer_intf_win.c,v $
+** Revision 1.5 2008/07/24 21:06:16 lajordan
+** no message
+**
+** Revision 1.4 2007/03/22 18:53:43 lajordan
+** fixed warningg
+**
+** Revision 1.3 2007/02/26 16:46:16 lajordan
+** cleaned up some warnings
+**
+** Revision 1.2 2007/02/16 23:55:07 lajordan
+** no message
+**
+** Revision 1.1.1.1 2006/07/13 20:26:08 lajordan
+** no message
+**
+** Revision 1.1 2006/07/07 21:38:56 lajordan
+** no message
+**
+** Revision 1.1.1.1 2006/07/06 22:06:23 lajordan
+** no message
+**
+** Revision 1.1 2006/06/29 19:17:21 laj
+** no message
+**
+** Revision 1.1 2006/06/21 22:42:26 laj
+** new api style
+**
+**
+*/
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/si3218x.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/si3218x.c
new file mode 100644
index 0000000..efb6818
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/si3218x.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/module.h>
+#include <linux/init.h>
+
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <linux/regmap.h>
+#include <linux/spi/spi.h>
+
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/tlv.h>
+
+#include "proslic_sys.h"
+#include "si3218x.h"
+#include "inc/proslic.h"
+#include "timer.h"
+
+#include "spi.h"
+
+#ifdef SI3218X
+#include "inc/si3218x.h"
+#include "inc/si3218x_intf.h"
+#endif
+
+#define NUMBER_OF_DEVICES 1
+#if defined(SI3218X)
+#define CHAN_PER_DEVICE 1
+#define NUMBER_OF_CHAN (NUMBER_OF_DEVICES*CHAN_PER_DEVICE)
+#define NUMBER_OF_PROSLIC (NUMBER_OF_CHAN)
+#define PROSLIC_DEVICE_TYPE SI3218X_TYPE
+#endif
+
+static int slic_init = 0;
+
+ctrl_S spiGciObj; /* User¡¦s control interface object */
+systemTimer_S timerObj; /* User¡¦s timer object */
+chanState ports[NUMBER_OF_CHAN]; /* User¡¦s channel object, which has
+ ** a member defined as
+ ** proslicChanType_ptr ProObj;
+ */
+/* Define ProSLIC control interface object */
+controlInterfaceType *ProHWIntf;
+/* Define array of ProSLIC device objects */
+ProslicDeviceType *ProSLICDevices[NUMBER_OF_PROSLIC];
+/* Define array of ProSLIC channel object pointers */
+proslicChanType_ptr arrayOfProslicChans[NUMBER_OF_CHAN];
+
+static int ProSLIC_HWInit(void)
+{
+ int32 i, result= 0;
+
+ printk ("%s()\n",__FUNCTION__);
+ /*
+ ** Step 1: (required)
+ ** Create ProSLIC Control Interface Object
+ */
+ ProSLIC_createControlInterface(&ProHWIntf);
+
+ /*
+ ** Step 2: (required)
+ ** Create ProSLIC Device Objects
+ */
+ for(i=0;i<NUMBER_OF_PROSLIC;i++)
+ {
+ ProSLIC_createDevice(&(ProSLICDevices[i]));
+ }
+
+ /*
+ ** Step 3: (required)
+ ** Create and initialize ProSLIC channel objects
+ ** Also initialize array pointers to user¡¦s proslic channel object
+ ** members to simplify initialization process.
+ */
+ for(i=0;i<NUMBER_OF_CHAN;i++)
+ {
+ ProSLIC_createChannel(&(ports[i].ProObj));
+ ProSLIC_SWInitChan(ports[i].ProObj,i,PROSLIC_DEVICE_TYPE,
+ ProSLICDevices[i/CHAN_PER_DEVICE],ProHWIntf);
+ arrayOfProslicChans[i] = ports[i].ProObj;
+ ProSLIC_setSWDebugMode(ports[i].ProObj,TRUE); /* optional */
+ }
+
+ /*
+ ** Step 4: (required)
+ ** Establish linkage between host objects/functions and
+ ** ProSLIC API
+ */
+ ProSLIC_setControlInterfaceCtrlObj (ProHWIntf, &spiGciObj);
+ ProSLIC_setControlInterfaceReset (ProHWIntf, ctrl_ResetWrapper);
+ ProSLIC_setControlInterfaceWriteRegister (ProHWIntf, ctrl_WriteRegisterWrapper);
+ ProSLIC_setControlInterfaceReadRegister (ProHWIntf, ctrl_ReadRegisterWrapper);
+ ProSLIC_setControlInterfaceWriteRAM (ProHWIntf, ctrl_WriteRAMWrapper);
+ ProSLIC_setControlInterfaceReadRAM (ProHWIntf, ctrl_ReadRAMWrapper);
+ ProSLIC_setControlInterfaceTimerObj (ProHWIntf, &timerObj);
+ ProSLIC_setControlInterfaceDelay (ProHWIntf, time_DelayWrapper);
+ ProSLIC_setControlInterfaceTimeElapsed (ProHWIntf, time_TimeElapsedWrapper);
+ ProSLIC_setControlInterfaceGetTime (ProHWIntf, time_GetTimeWrapper);
+ ProSLIC_setControlInterfaceSemaphore (ProHWIntf, NULL);
+
+ /*
+ ** Step 5: (system dependent)
+ ** Assert hardware Reset ¡V ensure VDD, PCLK, and FSYNC are present and stable
+ ** before releasing reset
+ */
+ ProSLIC_Reset(ports[0].ProObj);
+
+ /*
+ ** Step 6: (required)
+ ** Initialize device (loading of general parameters, calibrations,
+ ** dc-dc powerup, etc.)
+ */
+ ProSLIC_Init(arrayOfProslicChans,NUMBER_OF_CHAN);
+ for(i=0;i<NUMBER_OF_CHAN;i++)
+ {
+ if(arrayOfProslicChans[i]->error!=0)
+ {
+ printk("ProSLIC_Init[%d] ERR=%d\n",i,arrayOfProslicChans[i]->error);
+ return 0;
+ }
+ }
+
+
+ /*
+ ** Step 7: (design dependent)
+ ** Execute longitudinal balance calibration
+ ** or reload coefficients from factory LB cal
+ **
+ ** Note: all batteries should be up and stable prior to
+ ** executing the lb cal
+ */
+ ProSLIC_LBCal(arrayOfProslicChans,NUMBER_OF_CHAN);
+ for(i=0;i<NUMBER_OF_CHAN;i++)
+ {
+ ProSLIC_GetLBCalResultPacked(arrayOfProslicChans[i], &result);
+ printk("LBCal=0x%08X\n",result);
+ }
+
+ /*
+ ** Step 8: (design dependent)
+ ** Load custom configuration presets(generated using
+ ** ProSLIC API Config Tool)
+ */
+ for(i=0;i<NUMBER_OF_CHAN;i++)
+ {
+ ProSLIC_PCMTimeSlotSetup(ports[i].ProObj,0,0);
+ ProSLIC_DCFeedSetup(ports[i].ProObj,DCFEED_48V_20MA);
+ ProSLIC_RingSetup(ports[i].ProObj,RING_F20_45VRMS_0VDC_LPR);
+ ProSLIC_PCMSetup(ports[i].ProObj,PCM_16LIN_WB); /* PCM_DEFAULT_CONFIG */
+ ProSLIC_ZsynthSetup(ports[i].ProObj,ZSYN_600_0_0_30_0);
+ ProSLIC_ToneGenSetup(ports[i].ProObj,TONEGEN_FCC_DIAL);
+ }
+
+ for(i=0;i<NUMBER_OF_CHAN;i++)
+ {
+ ProSLIC_PCMStart(ports[i].ProObj);
+ }
+ for(i=0;i<NUMBER_OF_CHAN;i++)
+ {
+ ProSLIC_SetLinefeedStatus(ports[i].ProObj,LF_FWD_ACTIVE);
+ }
+
+ /*
+ ** Step 9: (required)
+ ** SLIC settings - set TX_START and RX_START to 1 and
+ ** disable Free-Run mode.
+ */
+ ProSLIC_WriteReg(ports[0].ProObj, 12, 1);
+ ProSLIC_WriteReg(ports[0].ProObj, 14, 1);
+ ProSLIC_WriteReg(ports[0].ProObj, 47, 1);
+
+ return 1;
+}
+
+static int si3218x_component_probe(struct snd_soc_component *component)
+{
+ dev_info(component->dev, "%s\n", __func__);
+ return 0;
+}
+
+static void si3218x_component_remove(struct snd_soc_component *component)
+{
+ struct si3218x_chip *chip = snd_soc_component_get_drvdata(component);
+
+ dev_info(component->dev, "%s\n", __func__);
+
+ chip->component = NULL;
+}
+
+static const struct snd_soc_dapm_widget si3218x_component_dapm_widgets[] = {
+ SND_SOC_DAPM_INPUT("VINP"),
+ SND_SOC_DAPM_OUTPUT("VOUTP"),
+};
+
+static const struct snd_soc_dapm_route si3218x_component_dapm_routes[] = {
+ { "VOUTP", NULL, "aif_playback"},
+ { "aif_capture", NULL, "VINP"},
+};
+
+static const char * const slic_control_str[] = {
+ "off", "on"
+};
+
+static const struct soc_enum si3218x_slic_enum[] = {
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(slic_control_str),
+ slic_control_str),
+};
+
+static int si3218x_init_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ ucontrol->value.integer.value[0] = slic_init;
+
+ return 0;
+}
+
+static int si3218x_init_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (ucontrol->value.integer.value[0]) {
+ ProSLIC_HWInit();
+ slic_init = 1;
+ }
+
+ return 0;
+}
+
+static int si3218x_ring_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (!slic_init)
+ return 0;
+
+ ucontrol->value.integer.value[0] =
+ (ProSLIC_ReadReg(ports[0].ProObj,30) == 4) ? 1 : 0;
+ return 0;
+}
+
+static int si3218x_ring_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ if (!slic_init)
+ return 0;
+
+ if (ucontrol->value.integer.value[0])
+ ProSLIC_WriteReg(ports[0].ProObj, 30, 4);
+ else
+ ProSLIC_WriteReg(ports[0].ProObj, 30, 1);
+
+ return 0;
+}
+
+static const struct snd_kcontrol_new si3218x_component_snd_controls[] = {
+ SOC_ENUM_EXT("proslic_init", si3218x_slic_enum[0],
+ si3218x_init_get, si3218x_init_set),
+ SOC_ENUM_EXT("proslic_ring", si3218x_slic_enum[0],
+ si3218x_ring_get, si3218x_ring_set),
+};
+
+static const struct snd_soc_component_driver si3218x_component_driver = {
+ .probe = si3218x_component_probe,
+ .remove = si3218x_component_remove,
+
+ .controls = si3218x_component_snd_controls,
+ .num_controls = ARRAY_SIZE(si3218x_component_snd_controls),
+ .dapm_widgets = si3218x_component_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(si3218x_component_dapm_widgets),
+ .dapm_routes = si3218x_component_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(si3218x_component_dapm_routes),
+
+ .idle_bias_on = false,
+};
+
+static int si3218x_component_aif_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
+{
+ int word_len = params_physical_width(hw_params);
+ int aud_bit = params_width(hw_params);
+
+ dev_dbg(dai->dev, "format: 0x%08x\n", params_format(hw_params));
+ dev_dbg(dai->dev, "rate: 0x%08x\n", params_rate(hw_params));
+ dev_dbg(dai->dev, "word_len: %d, aud_bit: %d\n", word_len, aud_bit);
+ if (word_len > 32 || word_len < 16) {
+ dev_err(dai->dev, "not supported word length\n");
+ return -ENOTSUPP;
+ }
+
+ dev_dbg(dai->dev, "%s: --\n", __func__);
+ return 0;
+}
+
+static const struct snd_soc_dai_ops si3218x_component_aif_ops = {
+ .hw_params = si3218x_component_aif_hw_params,
+};
+
+#define STUB_RATES SNDRV_PCM_RATE_8000_192000
+#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_U16_LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_U24_LE | \
+ SNDRV_PCM_FMTBIT_S32_LE | \
+ SNDRV_PCM_FMTBIT_U32_LE)
+
+static struct snd_soc_dai_driver si3218x_codec_dai = {
+ .name = "proslic_spi-aif",
+ .playback = {
+ .stream_name = "aif_playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = STUB_RATES,
+ .formats = STUB_FORMATS,
+ },
+ .capture = {
+ .stream_name = "aif_capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = STUB_RATES,
+ .formats = STUB_FORMATS,
+ },
+ /* dai properties */
+ .symmetric_rates = 1,
+ .symmetric_channels = 1,
+ .symmetric_samplebits = 1,
+ /* dai operations */
+ .ops = &si3218x_component_aif_ops,
+};
+
+int si3218x_spi_probe(struct spi_device *spi, struct spi_driver *spi_drv)
+{
+ int ret;
+
+ printk(KERN_INFO "PROSLIC si3218x_spi_probe\n");
+
+ ret = proslic_spi_probe(spi,spi_drv);
+
+ return snd_soc_register_component(&spi->dev, &si3218x_component_driver,
+ &si3218x_codec_dai, 1);
+}
+EXPORT_SYMBOL(si3218x_spi_probe);
+
+int si3218x_spi_remove(struct spi_device *spi)
+{
+ proslic_spi_remove(spi);
+ snd_soc_unregister_component(&spi->dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(si3218x_spi_remove);
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/si3218x.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/si3218x.h
new file mode 100644
index 0000000..5fa4d42
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/si3218x.h
@@ -0,0 +1,44 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <linux/spi/spi.h>
+#include "inc/proslic.h"
+#include "timer.h"
+#include "spi.h"
+
+#if 1
+#include "inc/si3218x.h"
+#include "inc/si3218x_intf.h"
+#include "config_inc/si3218x_LCCB_constants.h"
+#endif
+
+typedef struct chanStatus chanState; //forward declaration
+
+typedef void (*procState) (chanState *pState, ProslicInt eInput);
+
+/*
+** structure to hold state information for pbx demo
+*/
+struct chanStatus {
+ proslicChanType *ProObj;
+ SiVoiceChanType_ptr VoiceObj;
+ timeStamp onHookTime;
+ timeStamp offHookTime;
+ procState currentState;
+ uInt16 digitCount;
+ uInt8 digits[20];
+ uInt8 ringCount;
+ uInt16 connectionWith;
+ uInt16 powerAlarmCount;
+ pulseDialType pulseDialData;
+ BOOLEAN eventEnable;
+} __attribute__((aligned(32)));
+
+struct si3218x_chip {
+ struct spi_device *spi;
+ struct device *dev;
+ struct snd_soc_component *component;
+};
+
+/* Export function */
+int si3218x_spi_probe(struct spi_device *spi, struct spi_driver *spi_drv);
+int si3218x_spi_remove(struct spi_device *spi);
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/spi.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/spi.h
new file mode 100644
index 0000000..b720f3f
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/spi.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * $Id: SPI.h 109 2008-10-22 19:45:09Z lajordan@SILABS.COM $
+ *
+ * This file is system specific and should be edited for your hardware platform
+ *
+ * This file is used by proslic_timer_intf.h and proslic_spiGci.h
+ */
+#ifndef SPI_TYPE_H
+#define SPI_TYPE_H
+
+/*
+** SPI/GCI structure
+*/
+typedef struct{
+ unsigned short portID;
+} ctrl_S;
+
+/*
+** Function: SPI_Init
+**
+** Description:
+** Initializes the SPI interface
+*/
+int SPI_Init (ctrl_S *hSpi);
+
+
+/*
+** Function: ctrl_ResetWrapper
+**
+** Description:
+** Sets the reset pin of the ProSLIC
+*/
+int ctrl_ResetWrapper (void *hCtrl, int status);
+
+/*
+** register read
+**
+** Description:
+** Reads ProSLIC registers
+*/
+unsigned char ctrl_ReadRegisterWrapper (void *hCtrl, unsigned char channel, unsigned char regAddr);
+
+/*
+** Function: ctrl_WriteRegisterWrapper
+**
+** Description:
+** Writes ProSLIC registers
+*/
+int ctrl_WriteRegisterWrapper (void *hSpiGci, unsigned char channel, unsigned char regAddr, unsigned char data);
+
+/*
+** Function: ctrl_WriteRAMWrapper
+**
+** Description:
+** Writes ProSLIC RAM
+*/
+int ctrl_WriteRAMWrapper (void *hSpiGci, unsigned char channel, unsigned short ramAddr, ramData data);
+
+/*
+** Function: ctrl_ReadRAMWrapper
+**
+** Description:
+** Reads ProSLIC RAM
+*/
+ramData ctrl_ReadRAMWrapper (void *hSpiGci, unsigned char channel, unsigned short ramAddr);
+
+#endif
+/*
+** $Log: SPI.h,v $
+** Revision 1.2 2007/02/21 16:53:07 lajordan
+** no message
+**
+** Revision 1.1 2007/02/16 23:55:15 lajordan
+** no message
+**
+** Revision 1.2 2007/02/15 23:33:25 lajordan
+** no message
+**
+** Revision 1.1.1.1 2006/07/13 20:26:08 lajordan
+** no message
+**
+*/
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/Makefile b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/Makefile
new file mode 100644
index 0000000..d9063fd
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/Makefile
@@ -0,0 +1,18 @@
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+
+# platform driver
+subdir-ccflags-y += -I../inc
+subdir-ccflags-y += -DSI3218X
+subdir-ccflags-y += -DPROSLIC_LINUX_KERNEL
+snd-soc-procslic-common-objs := proslic.o proslic_tstin.o si_voice.o si_voice_version.o si3218x_intf.o vdaa.o si3217x_intf.o si3217x_revb_intf.o si3217x_revc_intf.o si3219x_intf.o si3226x_intf.o si3228x_intf.o
+
+obj-$(CONFIG_SND_SOC_SI3218X) += snd-soc-proslic-common.o
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic.c
new file mode 100644
index 0000000..7a75cc8
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic.c
@@ -0,0 +1,4651 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the generic interface file for the ProSLIC drivers.
+ *
+ * Customers should be calling this level for ProSLIC specific
+ * functions (vs. chipset specific versions of the code)
+ *
+ */
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si_voice_ctrl.h"
+#include "../inc/si_voice_timer_intf.h"
+#include "../inc/proslic.h"
+#include "../config_inc/proslic_api_config.h"
+
+#ifdef ENABLE_DEBUG
+#define LOGPRINT_PREFIX "ProSLIC:"
+#endif
+
+#ifdef SI3217X
+#include "si3217x.h"
+#include "si3217x_intf.h"
+extern Si3217x_General_Cfg Si3217x_General_Configuration;
+#ifndef DISABLE_FSK_SETUP
+extern ProSLIC_FSK_Cfg Si3217x_FSK_Presets[];
+#endif
+#ifndef DISABLE_TONE_SETUP
+extern ProSLIC_Tone_Cfg Si3217x_Tone_Presets[];
+#endif
+
+#endif /* 17X */
+
+#ifdef SI3218X
+#include "../inc/si3218x.h"
+#include "../inc/si3218x_intf.h"
+extern Si3218x_General_Cfg Si3218x_General_Configuration;
+#ifndef DISABLE_FSK_SETUP
+extern ProSLIC_FSK_Cfg Si3218x_FSK_Presets[];
+#endif
+#ifndef DISABLE_TONE_SETUP
+extern ProSLIC_Tone_Cfg Si3218x_Tone_Presets[];
+#endif
+#endif /* 18X */
+
+#ifdef SI3219X
+#include "si3219x.h"
+#include "si3219x_intf.h"
+extern Si3219x_General_Cfg Si3219x_General_Configuration;
+#ifndef DISABLE_FSK_SETUP
+extern ProSLIC_FSK_Cfg Si3219x_FSK_Presets[];
+#endif
+#ifndef DISABLE_TONE_SETUP
+extern ProSLIC_Tone_Cfg Si3219x_Tone_Presets[];
+#endif
+#endif /* 19X */
+
+#ifdef SI3226X
+#include "si3226x.h"
+#include "si3226x_intf.h"
+extern Si3226x_General_Cfg Si3226x_General_Configuration;
+#ifndef DISABLE_FSK_SETUP
+extern ProSLIC_FSK_Cfg Si3226x_FSK_Presets[];
+#endif
+#ifndef DISABLE_TONE_SETUP
+extern ProSLIC_Tone_Cfg Si3226x_Tone_Presets[];
+#endif
+#endif /* 26X */
+
+#ifdef SI3228X
+#include "si3228x.h"
+#include "si3228x_intf.h"
+extern Si3228x_General_Cfg Si3228x_General_Configuration;
+#ifndef DISABLE_FSK_SETUP
+extern ProSLIC_FSK_Cfg Si3228x_FSK_Presets[];
+#endif
+#ifndef DISABLE_TONE_SETUP
+extern ProSLIC_Tone_Cfg Si3228x_Tone_Presets[];
+#endif
+
+#endif /* 28X */
+
+#define pCtrl(X) (X)->deviceId->ctrlInterface
+#define pProHW(X) pCtrl((X))->hCtrl
+#define WriteRAM(PCHAN, CHANNEL, RAMADDR, RAMDATA) (PCHAN)->deviceId->ctrlInterface->WriteRAM_fptr(pProHW(PCHAN), (CHANNEL), (RAMADDR), (RAMDATA))
+#define ReadRAM(PCHAN, CHANNEL, RAMADDR) (PCHAN)->deviceId->ctrlInterface->ReadRAM_fptr(pProHW(PCHAN), (CHANNEL), (RAMADDR))
+#define SetSemaphore(X) (X)->deviceId->ctrlInterface->Semaphore_fptr
+#define ReadReg(PCHAN, CHANNEL, REGADDR) (PCHAN)->deviceId->ctrlInterface->ReadRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR))
+#define WriteReg(PCHAN, CHANNEL, REGADDR, REGDATA) (PCHAN)->deviceId->ctrlInterface->WriteRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR), (REGDATA))
+
+/*
+** Timers
+*/
+#define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
+#define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
+#define pProTimer pProslic->deviceId->ctrlInterface->hTimer
+#define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
+#define pProTimerX(X) ((X)->deviceId->ctrlInterface->hTimer)
+#define DelayX(X,Y) ((X)->deviceId->ctrlInterface->Delay_fptr(pProTimerX(X),Y))
+
+#define PROSLIC_TIMEOUT_DCDC_DOWN 200 /* Number of 10 mSec ticks */
+
+/*****************************************************************************************************/
+int32 ProSLIC_ReadMADCScaled(proslicChanType_ptr hProslic,uInt16 addr,
+ int32 scale)
+{
+ TRACEPRINT(hProslic,"addr: %u scale: %ld\n", addr, scale);
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_ReadMADCScaled(hProslic,addr,scale);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_ReadMADCScaled(hProslic,addr,scale);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_ReadMADCScaled(hProslic,addr,scale);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_ReadMADCScaled(hProslic,addr,scale);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_ReadMADCScaled(hProslic,addr,scale);
+ }
+#endif
+
+ return -1;
+}
+
+/*****************************************************************************************************/
+ramData ProSLIC_ReadRAM(proslicChanType_ptr hProslic,uInt16 addr)
+{
+ TRACEPRINT(hProslic, "addr: %u\n", addr);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ return (ReadRAM(hProslic, hProslic->channel, addr));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_WriteRAM(proslicChanType_ptr hProslic,uInt16 addr, ramData data)
+{
+ TRACEPRINT(hProslic, "addr: %u data: 0x%04X\n", addr, data);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ return (WriteRAM(hProslic, hProslic->channel, addr,data));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PrintDebugData(proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+#ifdef ENABLE_DEBUG
+ ProSLIC_PrintDebugReg(hProslic);
+ return ProSLIC_PrintDebugRAM(hProslic);
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ return RC_NONE;
+#endif
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PrintDebugReg(proslicChanType_ptr hProslic)
+{
+#ifdef ENABLE_DEBUG
+ uInt8 regAddr;
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ /*
+ NOTE: Not all ProSLICs have defined values after location 99
+ (and have 1 location after that), but for simplicity, we print them anyway...
+ */
+ for(regAddr = 0; regAddr < 127; regAddr++)
+ {
+ LOGPRINT("%sRegister %03u = 0x%02X\n", LOGPRINT_PREFIX, regAddr,
+ ReadReg(hProslic, hProslic->channel, regAddr));
+ }
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+#endif
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+/* NOTE: locations above 1024 are protected, the API disables protection during initialization, but if this
+ function is called prior to initialization, then UAM is not set and will impact the ReadRAM call...
+ Upper limit is based upon chipset type...
+*/
+int ProSLIC_PrintDebugRAM(proslicChanType_ptr hProslic)
+{
+#ifdef ENABLE_DEBUG
+ uInt16 ramAddr;
+ uInt16 maxAddr= 0;
+ TRACEPRINT(hProslic, "\n",NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ maxAddr = 1596;
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ maxAddr = 1644;
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ maxAddr = 1644;
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ maxAddr = 1646;
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ maxAddr = 1646;
+ }
+#endif
+
+ for(ramAddr = 0; ramAddr < maxAddr; ramAddr++)
+ {
+ LOGPRINT("%sRAM %04u = 0x%08X\n", LOGPRINT_PREFIX, ramAddr,
+ (unsigned int)(ReadRAM(hProslic, hProslic->channel, ramAddr)));
+ }
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+#endif /* ENABLE_DEBUG */
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: isVerifiedProslic
+**
+** Description:
+** Determine if DAA or ProSLIC present
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC channel object
+**
+** Return:
+** channelType
+*/
+int ProSLIC_identifyChannelType(proslicChanType *pProslic)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n",NULL);
+ /*
+ ** Register 13 (DAA) always has bits 0:1 set to 0 and bit 6 set to 1
+ ** Register 13 (PROSLIC) can have bits 0:1, and 4 set, while all others are undefined
+ ** Write 0x13 to Reg 13. The following return values are expected -
+ **
+ ** 0x00 or 0xFF : No device present
+ ** 0x4X : DAA
+ ** 0x13 : PROSLIC
+ */
+
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI,0x13);
+ Delay(pProTimer,5);
+
+ /* Now check if the value took */
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI);
+
+ if( data == 0x13)
+ {
+ return PROSLIC;
+ }
+ else if (data == 0x40)
+ {
+ return DAA;
+ }
+ else
+ {
+ return UNKNOWN;
+ }
+}
+
+/*****************************************************************************************************/
+int ProSLIC_VerifyControlInterface(proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n",NULL);
+ if (ProSLIC_identifyChannelType(hProslic) != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ /* Note: ProSLIC_identifyChannelType() did a register w/r test earlier */
+
+ /* Verify RAM rd/wr with innocuous RAM location */
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VERIFY_IO,0x12345678L);
+ if (ReadRAM(hProslic,hProslic->channel, PROSLIC_RAM_VERIFY_IO) != 0x12345678L)
+ {
+ hProslic->error = RC_SPI_FAIL;
+ DEBUG_PRINT(hProslic, "%sProslic %d RAM not communicating. RAM access fail.\n",
+ LOGPRINT_PREFIX, hProslic->channel);
+ return RC_SPI_FAIL;
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_VerifyMasterStat(proslicChanType_ptr pProslic)
+{
+ uInt8 regData;
+
+ TRACEPRINT(pProslic, "\n", NULL);
+ WriteReg(pProslic,pProslic->channel, PROSLIC_REG_MSTRSTAT,
+ 0xFF); /* Clear Master status */
+ regData = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_MSTRSTAT);
+
+ if( regData != 0x1F )
+ {
+ return RC_SPI_FAIL;
+ }
+ else
+ {
+ return RC_NONE;
+ }
+}
+
+/*****************************************************************************************************/
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+int ProSLIC_Init_MultiBOM (proslicChanType_ptr *hProslic,int size, int preset)
+{
+ TRACEPRINT(*hProslic, "size: %d preset: %d\n", size, preset);
+#ifdef SI3217X
+ if ((*hProslic)->deviceId->chipType >= SI32171
+ && (*hProslic)->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_Init_MultiBOM(hProslic,size,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if ((*hProslic)->deviceId->chipType >= SI32180
+ && (*hProslic)->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_Init_MultiBOM(hProslic,size,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X((*hProslic)->deviceId) )
+ {
+ return Si3219x_Init_MultiBOM(hProslic,size,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if ((*hProslic)->deviceId->chipType >= SI32260
+ && (*hProslic)->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_Init_MultiBOM(hProslic,size,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if ((*hProslic)->deviceId->chipType >= SI32280
+ && (*hProslic)->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_Init_MultiBOM(hProslic,size,preset);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+int ProSLIC_Init (proslicChanType_ptr *hProslic,int size)
+{
+ TRACEPRINT(*hProslic, "size: %d\n", size);
+ return ProSLIC_Init_with_Options(hProslic, size, INIT_NO_OPT);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_Reinit (proslicChanType_ptr *hProslic,int size)
+{
+ TRACEPRINT(*hProslic, "size: %d\n", size);
+ return ProSLIC_Init_with_Options(hProslic, size, INIT_REINIT);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_Init_with_Options (proslicChanType_ptr *hProslic,int size,
+ int option)
+{
+ TRACEPRINT(*hProslic, "size: %d option: %d\n", size, option);
+#ifdef SI3226X
+ if ((*hProslic)->deviceId->chipType >= SI32260
+ && (*hProslic)->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_Init_with_Options(hProslic,size, option);
+ }
+#endif
+
+#ifdef SI3228X
+ if ((*hProslic)->deviceId->chipType >= SI32280
+ && (*hProslic)->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_Init_with_Options(hProslic,size, option);
+ }
+#endif
+
+#ifdef SI3217X
+ if ((*hProslic)->deviceId->chipType >= SI32171
+ && (*hProslic)->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_Init_with_Options(hProslic,size, option);
+ }
+#endif
+
+#ifdef SI3218X
+ if ((*hProslic)->deviceId->chipType >= SI32180
+ && (*hProslic)->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_Init_with_Options(hProslic,size, option);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X((*hProslic)->deviceId) )
+ {
+ return Si3219x_Init_with_Options(hProslic,size, option);
+ }
+#endif
+
+ return RC_IGNORE;
+}
+
+/*****************************************************************************************************/
+#if defined(SI3217X) || defined(SI3218X) || defined SI3226X || defined SI3228X || defined(SI3219X)
+/* Check patch data - returns TRUE if no error.*/
+static BOOLEAN ProSLIC_VerifyPatchData(proslicChanType *pProslic,
+ const ramData *data, uInt16 maxCount )
+{
+ int loop;
+ ramData read_data;
+ TRACEPRINT(pProslic, "dataptr: %p, count: %d\n", data, maxCount);
+
+ for(loop = 0; loop < maxCount; loop++)
+ {
+ if(*data)
+ {
+ read_data = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_PRAM_DATA);
+ if( ((*data) << 9) != read_data)
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ break;
+ }
+ data++;
+ }
+ return TRUE;
+}
+
+/* Check if the jump table is written correctly.. */
+static BOOLEAN ProSLIC_VerifyPatchJMPLow(proslicChanType *pProslic,
+ const uInt16 *data)
+{
+ uInt8 address = PATCH_JMPTBL_START_ADDR;
+ int regData;
+
+ TRACEPRINT(pProslic, "dataptr: %p\n", data);
+ for(address = PATCH_JMPTBL_START_ADDR;
+ address < (PATCH_JMPTBL_START_ADDR+(2*PATCH_NUM_LOW_ENTRIES)); address++)
+ {
+ if(*data)
+ {
+ regData = ReadReg(pProslic, pProslic->channel, address);
+ if(regData != ((*data) & 0xFF))
+ {
+ return FALSE;
+ }
+
+ address++;
+
+ regData = ReadReg(pProslic, pProslic->channel, address);
+ if(regData != (((*data)>>8) & 0xFF))
+ {
+ return FALSE;
+ }
+
+ data++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ return TRUE;
+}
+
+#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
+/* For chipsets supporting more than 8 jump entries, verify them */
+static BOOLEAN ProSLIC_VerifyPatchJMPHigh(proslicChanType *pProslic,
+ const uInt16 *data)
+{
+ uInt16 address = PATCH_JMPTBL_HIGH_ADDR;
+ ramData read_data;
+
+ TRACEPRINT(pProslic, "dataptr: %p\n", data);
+ for(address = PATCH_JMPTBL_HIGH_ADDR;
+ address < (PATCH_JMPTBL_HIGH_ADDR+PATCH_NUM_HIGH_ENTRIES); address++)
+ {
+ read_data = (ReadRAM(pProslic, pProslic->channel, address) & 0x1FFFL);
+ if(*data != read_data)
+ {
+ return FALSE;
+
+ }
+ data++;
+ }
+ return TRUE;
+}
+#endif /* SI3226X, SI3228X, SI3218X, SI3219X */
+
+static BOOLEAN ProSLIC_VerifyPatchSupportRAM(proslicChanType *pProslic,
+ const uInt16 *ramAddr, const ramData *ramData)
+{
+ int i;
+
+ for(i = 0; ramAddr[i]; i++)
+ {
+ if( ReadRAM(pProslic, pProslic->channel, ramAddr[i]) != ramData[i])
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/* Load the first 8 jump table entries */
+static void ProSLIC_LoadPatchJMPLow(proslicChanType *pProslic, uInt8 channel,
+ const uInt16 *data)
+{
+ uInt8 address;
+
+ TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
+
+ for(address = PATCH_JMPTBL_START_ADDR;
+ address < (PATCH_JMPTBL_START_ADDR+(2*PATCH_NUM_LOW_ENTRIES)); address++)
+ {
+ WriteReg(pProslic, channel, address,((*data) & 0xFF));
+ address++;
+ WriteReg(pProslic, channel, address,(((*data)>>8) & 0xFF));
+ data++;
+ }
+}
+
+/* Load Patch data */
+static void ProSLIC_LoadPatchData(proslicChanType *pProslic, uInt8 channel,
+ const ramData *data)
+{
+ int loop;
+
+ TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
+ WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_ADDR, 0);
+
+ for(loop = 0; loop < PATCH_MAX_SIZE; loop++)
+ {
+ if(*data)
+ {
+ /* Can we take advantage of auto increment, if not, set the address */
+ if( (pProslic->deviceId->chipRev < 3)
+ && (channel == PROSLIC_CHAN_BROADCAST))
+ {
+ WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_ADDR, loop << 19);
+ }
+
+ WriteRAM(pProslic, channel, PROSLIC_RAM_PRAM_DATA, (*data) << 9);
+ }
+ else
+ {
+ return;
+ }
+ data++;
+ }
+}
+
+/* Load Support RAM - basically RAM address/data pairs to be written as part of the Patch process - do not call directly */
+void ProSLIC_LoadSupportRAM(proslicChanType *pProslic, uInt8 channel,
+ const uInt16 *address, const ramData *data)
+{
+ TRACEPRINT(pProslic, "chan: %d addressptr: %p dataptr: %p\n", channel, address,
+ data);
+ while( *address )
+ {
+ WriteRAM(pProslic, channel, *address, *data);
+ address++;
+ data++;
+ }
+}
+
+#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
+/* Load Jump table high for chipsets supporting more than 8 jump entries */
+static void ProSLIC_LoadJMPHigh(proslicChanType *pProslic, uInt8 channel,
+ const uInt16 *data)
+{
+ uInt16 loop;
+ TRACEPRINT(pProslic, "chan: %d dataptr: %p\n", channel, data);
+ for(loop = PATCH_JMPTBL_HIGH_ADDR;
+ loop < (PATCH_JMPTBL_HIGH_ADDR+PATCH_NUM_HIGH_ENTRIES); loop++)
+ {
+ WriteRAM(pProslic, channel, loop, ((*data) & 0x1FFFL) );
+ data++;
+ }
+}
+#endif /* SI3226X, SI3228X, SI3218X, SI3219X */
+
+/* Code assumes ProSLIC_LoadPatch has verified chip type. This is NOT meant to be called
+ * by the user directly.
+ */
+BOOLEAN ProSLIC_LoadPatch_extended(proslicChanType *pProslic,
+ const proslicPatch *pPatch,
+ BOOLEAN is_broadcast, BOOLEAN is_second_chan)
+{
+ uInt8 channel;
+ const uInt16 jmp_disable[PATCH_NUM_LOW_ENTRIES] = {0,0,0,0,0,0,0,0};
+
+#if defined SI3226X || defined SI3228X || defined SI3218X ||defined SI3219X
+ BOOLEAN hasJmpTableHigh = FALSE;
+ const uInt16 jmphigh_disable[PATCH_NUM_HIGH_ENTRIES] = {0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL};
+#endif
+
+ TRACEPRINT(pProslic, "patchptr: %p bcast: %d\n", pPatch, is_broadcast);
+
+ if(pPatch == NULL)
+ {
+ return RC_NONE;
+ }
+
+ if(is_broadcast == TRUE)
+ {
+ channel = PROSLIC_CHAN_BROADCAST;
+ }
+ else
+ {
+ channel = pProslic->channel;
+ }
+
+ ProSLIC_SetUserMode(pProslic,TRUE, is_broadcast);
+
+ /* Disable Patch */
+ WriteReg(pProslic, channel, PROSLIC_REG_JMPEN, 0);
+ if(is_second_chan == FALSE)
+ {
+ DEBUG_PRINT(pProslic, "%sloading patch: %08lx\n", LOGPRINT_PREFIX,
+ (long unsigned int)pPatch->patchSerial);
+
+ ProSLIC_LoadPatchJMPLow(pProslic, channel, jmp_disable);
+
+#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
+ if( 0
+#ifdef SI3226X
+ || (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+#endif
+#ifdef SI3228X
+ || (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+#endif
+#ifdef SI3218X
+ || (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+#endif
+#ifdef SI3219X
+ || ( IS_SI3219X(pProslic->deviceId) )
+#endif
+ )
+ {
+ hasJmpTableHigh = TRUE;
+ ProSLIC_LoadJMPHigh(pProslic, channel, jmphigh_disable);
+ }
+#endif
+
+ ProSLIC_LoadPatchData(pProslic, channel, pPatch->patchData);
+
+ WriteReg(pProslic, channel, PROSLIC_REG_RAM_ADDR_HI, 0);
+
+ ProSLIC_LoadPatchJMPLow(pProslic, channel, pPatch->patchEntries);
+
+#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
+ if(hasJmpTableHigh == TRUE)
+ {
+ ProSLIC_LoadJMPHigh(pProslic, channel,
+ &(pPatch->patchEntries[PATCH_NUM_LOW_ENTRIES]));
+ }
+#endif
+ WriteRAM(pProslic, channel, PROSLIC_RAM_PATCHID,
+ pPatch->patchSerial); /* write the patch ID */
+ } /* !second channel */
+
+ ProSLIC_LoadSupportRAM(pProslic, channel, pPatch->psRamAddr, pPatch->psRamData);
+
+ return RC_NONE;
+
+}
+
+#endif /* patch helper functions */
+
+int ProSLIC_LoadPatch (proslicChanType_ptr pProslic,const proslicPatch *pPatch)
+{
+ int rc;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ if( (rc = ProSLIC_LoadPatch_extended(pProslic, pPatch, FALSE, FALSE) ) == RC_NONE)
+ {
+#ifdef DISABLE_VERIFY_PATCH
+ return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_JMPEN, 1);
+#endif
+ }
+
+ return rc;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_VerifyPatch (proslicChanType_ptr hProslic,const proslicPatch *pPatch)
+{
+ TRACEPRINT(hProslic, "patchptr: %p\n", pPatch);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ if(pPatch == NULL)
+ {
+ return RC_NONE;
+ }
+
+ WriteReg(hProslic, hProslic->channel, PROSLIC_REG_JMPEN, 0);
+ WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PRAM_ADDR, 0);
+
+ if(ProSLIC_VerifyPatchData(hProslic, pPatch->patchData,
+ PATCH_MAX_SIZE) == FALSE)
+ {
+ DEBUG_PRINT(hProslic, "%sPatch data corrupted: channel %d\n",LOGPRINT_PREFIX,
+ hProslic->channel);
+ WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
+ 0UL); /* Mark patch as invalid */
+ return RC_PATCH_RAM_VERIFY_FAIL;
+ }
+
+ /*zero out RAM_ADDR_HI*/
+ WriteReg (hProslic, hProslic->channel, PROSLIC_REG_RAM_ADDR_HI,0);
+
+ if( ProSLIC_VerifyPatchJMPLow(hProslic, pPatch->patchEntries) == FALSE)
+ {
+ DEBUG_PRINT(hProslic,"%sPatch jumptable corrupted: channel %d\n",
+ LOGPRINT_PREFIX,hProslic->channel);
+ WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
+ 0UL); /* Mark patch as invalid */
+ return RC_PATCH_RAM_VERIFY_FAIL;
+ }
+
+#if defined SI3226X || defined SI3228X || defined SI3218X || defined SI3219X
+ if( 0
+#ifdef SI3226X
+ || (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+#endif
+#ifdef SI3228X
+ || (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+#endif
+#ifdef SI3218X
+ || (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+#endif
+#ifdef SI3219X
+ || ( IS_SI3219X(hProslic->deviceId) )
+#endif
+ )
+
+ {
+ if( ProSLIC_VerifyPatchJMPHigh(hProslic,
+ &(pPatch->patchEntries[PATCH_NUM_LOW_ENTRIES])) == FALSE)
+ {
+ DEBUG_PRINT(hProslic,"%sPatch jumptable high corrupted: channel %d\n",
+ LOGPRINT_PREFIX,hProslic->channel);
+ WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
+ 0UL); /* Mark patch as invalid */
+ return RC_PATCH_ENTRY_VERIFY_FAIL;
+ }
+ }
+
+#endif
+
+ if( ProSLIC_VerifyPatchSupportRAM( hProslic, pPatch->psRamAddr, pPatch->psRamData) == FALSE)
+ {
+ DEBUG_PRINT(hProslic,"%sPatch init data corrupted: channel %d\n",
+ LOGPRINT_PREFIX,hProslic->channel);
+ WriteRAM(hProslic, hProslic->channel, PROSLIC_RAM_PATCHID,
+ 0UL); /* Mark patch as invalid */
+ return RC_PATCH_ENTRY_VERIFY_FAIL;
+ }
+
+ WriteReg (hProslic, hProslic->channel, PROSLIC_REG_JMPEN,
+ 1); /*enable the patch*/
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_SetMuteStatus (proslicChanType_ptr pProslic,
+ ProslicMuteModes muteEn)
+{
+
+ uInt8 regTemp;
+ uInt8 newRegValue;
+ TRACEPRINT(pProslic, "muteEn: %d\n", muteEn);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ regTemp = ReadReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON);
+
+ WriteReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON,regTemp&~(0x3));
+ newRegValue = regTemp &~(0x3);
+
+ if (muteEn & PROSLIC_MUTE_RX)
+ {
+ newRegValue |= 1;
+ }
+
+ if (muteEn & PROSLIC_MUTE_TX)
+ {
+ newRegValue |= 2;
+ }
+
+ if(newRegValue != regTemp)
+ {
+ return WriteReg (pProslic,pProslic->channel,PROSLIC_REG_DIGCON,newRegValue);
+ }
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_SetLoopbackMode (proslicChanType_ptr pProslic,
+ ProslicLoopbackModes newMode)
+{
+ uInt8 regTemp, newValue;
+ TRACEPRINT(pProslic, "mode: %d\n", newMode);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ newValue = regTemp = ReadReg (pProslic,pProslic->channel,PROSLIC_REG_LOOPBACK);
+
+ switch (newMode)
+ {
+ case PROSLIC_LOOPBACK_NONE:
+ newValue &= ~(0x11);
+ break;
+
+ case PROSLIC_LOOPBACK_DIG:
+ newValue |= 1;
+ break;
+
+ case PROSLIC_LOOPBACK_ANA:
+ newValue |= 0x10;
+ break;
+ }
+
+ if(newValue != regTemp)
+ {
+ return WriteReg (pProslic,pProslic->channel,PROSLIC_REG_LOOPBACK, newValue);
+ }
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_EnableInterrupts (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_EnableInterrupts(hProslic);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_EnableInterrupts(hProslic);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_EnableInterrupts(hProslic);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_EnableInterrupts(hProslic);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_EnableInterrupts(hProslic);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+
+/*****************************************************************************************************/
+int ProSLIC_DisableInterrupts (proslicChanType_ptr hProslic)
+{
+#ifdef GCI_MODE
+ uInt8 data;
+#endif
+ uInt8 i;
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ for(i = PROSLIC_REG_IRQEN1; i < PROSLIC_REG_IRQEN4; i++)
+ {
+ /* Disable the interrupts */
+ WriteReg(hProslic, hProslic->channel, i, 0);
+ }
+
+ /* Clear the pending interrupts */
+ for(i = PROSLIC_REG_IRQ1; i < PROSLIC_REG_IRQ4; i++)
+ {
+#ifdef GCI_MODE
+ data = ReadReg(hProslic, hProslic->channel, i);
+ WriteReg( hProslic, hProslic->channel, i, data);
+#else
+ (void)ReadReg(hProslic, hProslic->channel, i);
+#endif
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_RingSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_RING_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_RingSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_RingSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_RingSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_RingSetup(hProslic,preset);
+ }
+#endif
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_RingSetup(hProslic,preset);
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_RING_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_ToneGenSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_TONE_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return ProSLIC_ToneGenSetupPtr(hProslic,&(Si3217x_Tone_Presets[preset]));
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3218x_Tone_Presets[preset]));
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3219x_Tone_Presets[preset]));
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3226x_Tone_Presets[preset]));
+ }
+#endif
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return ProSLIC_ToneGenSetupPtr(hProslic, &(Si3228x_Tone_Presets[preset]));
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_TONE_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_FSKSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_FSK_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return ProSLIC_FSKSetupPtr(hProslic, &Si3217x_FSK_Presets[preset]);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return ProSLIC_FSKSetupPtr(hProslic, &Si3218x_FSK_Presets[preset]);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return ProSLIC_FSKSetupPtr(hProslic, &Si3219x_FSK_Presets[preset]);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return ProSLIC_FSKSetupPtr(hProslic, &Si3226x_FSK_Presets[preset]);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return ProSLIC_FSKSetupPtr(hProslic,&Si3228x_FSK_Presets[preset]);
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_FSK_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_ZsynthSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_ZSYNTH_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_ZsynthSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_ZsynthSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_ZsynthSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_ZsynthSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_ZsynthSetup(hProslic,preset);
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_ZSYNTH_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+#ifndef DISABLE_CI_SETUP
+int ProSLIC_GciCISetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_GciCISetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_GciCISetup(hProslic,preset);
+ }
+#endif
+
+#if !defined(SI3217X) && !defined(SI3226X)
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif /*DISABLE_CI_SETUP*/
+
+/*****************************************************************************************************/
+int ProSLIC_TXAudioGainSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_AUDIOGAIN_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_TXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_TXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_TXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_TXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_TXAudioGainSetup(hProslic,preset);
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+
+#endif /*DISABLE_AUDIOGAIN_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_RXAudioGainSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_AUDIOGAIN_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_RXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_RXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_RXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_RXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_RXAudioGainSetup(hProslic,preset);
+ }
+#endif
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_AUDIOGAIN_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_TXAudioGainScale (proslicChanType_ptr hProslic,int preset,
+ uInt32 pga_scale, uInt32 eq_scale)
+{
+ TRACEPRINT(hProslic, "preset: %d pga_scale: %u eq_scale: %u\n", preset,
+ pga_scale, eq_scale);
+#ifndef DISABLE_AUDIOGAIN_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_TXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_AUDIOGAIN_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_RXAudioGainScale (proslicChanType_ptr hProslic,int preset,
+ uInt32 pga_scale, uInt32 eq_scale)
+{
+ TRACEPRINT(hProslic, "preset: %d pga_scale: %u eq_scale: %u\n", preset,
+ pga_scale, eq_scale);
+#ifndef DISABLE_AUDIOGAIN_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_RXAudioGainScale(hProslic,preset,pga_scale,eq_scale);
+ }
+#endif
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_AUDIOGAIN_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_AudioGainSetup (proslicChanType_ptr pProslic,int32 rxgain,
+ int32 txgain,int preset)
+{
+ int rc;
+#ifndef DISABLE_AUDIOGAIN_SETUP
+ int atx_preset = TXACGAIN_SEL;
+ int arx_preset = RXACGAIN_SEL;
+ TRACEPRINT(pProslic, "rxgain: %d txgain: %d preset: %d\n", rxgain, txgain,
+ preset);
+
+ rc = ProSLIC_dbgSetTXGain(pProslic,txgain,preset,atx_preset);
+
+ if( rc == RC_NONE)
+ {
+ rc = ProSLIC_TXAudioGainSetup(pProslic,TXACGAIN_SEL);
+ }
+
+ if( rc == RC_NONE)
+ {
+ rc = ProSLIC_dbgSetRXGain(pProslic,rxgain,preset,arx_preset);
+ }
+
+ if( rc == RC_NONE)
+ {
+ rc = ProSLIC_RXAudioGainSetup(pProslic,RXACGAIN_SEL);
+ }
+ return rc;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+ return RC_IGNORE;
+#endif /*DISABLE_AUDIOGAIN_SETUP*/
+}
+
+/*****************************************************************************************************/
+int ProSLIC_DCFeedSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset: %d\n", preset);
+#ifndef DISABLE_DCFEED_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_DCFeedSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_DCFeedSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_DCFeedSetupCfg(hProslic, Si3219x_DCfeed_Presets, preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_DCFeedSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_DCFeedSetup(hProslic,preset);
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_DCFEED_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_DCFeedSetupCfg (proslicChanType_ptr hProslic,
+ ProSLIC_DCfeed_Cfg *cfg, int preset)
+{
+ TRACEPRINT(hProslic, "cfgPtr = %p preset = %d\n", cfg, preset);
+#ifndef DISABLE_DCFEED_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_DCFeedSetupCfg(hProslic,cfg,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_DCFeedSetupCfg(hProslic,cfg,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_DCFeedSetupCfg(hProslic,cfg,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_DCFeedSetupCfg(hProslic,cfg,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_DCFeedSetupCfg(hProslic,cfg,preset);
+ }
+#endif
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+ SILABS_UNREFERENCED_PARAMETER(cfg);
+#endif /*DISABLE_DCFEED_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_GPIOSetup (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+#ifndef DISABLE_GPIO_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_GPIOSetup(hProslic);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_GPIOSetup(hProslic);
+ }
+#endif
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+#endif /*DISABLE_GPIO_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+#ifndef DISABLE_PULSEMETERING
+int ProSLIC_PulseMeterSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset = %d\n", preset);
+#ifndef DISABLE_PULSE_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_PulseMeterSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_PulseMeterSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_PulseMeterSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_PulseMeterSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_PulseMeterSetup(hProslic,preset);
+ }
+#endif
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_PULSE_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+int ProSLIC_PCMSetup (proslicChanType_ptr hProslic,int preset)
+{
+ TRACEPRINT(hProslic, "preset = %d\n", preset);
+#ifndef DISABLE_PCM_SETUP
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_PCMSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_PCMSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_PCMSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_PCMSetup(hProslic,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_PCMSetup(hProslic,preset);
+ }
+#endif
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+#endif /*DISABLE_PCM_SETUP*/
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PCMTimeSlotSetup (proslicChanType_ptr pProslic, uInt16 rxcount,
+ uInt16 txcount)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "rx = %u tx = %u\n", rxcount, txcount);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ data = txcount & 0xff;
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXLO,data);
+
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI);
+ data &= 0x10; /* keep TX_EDGE bit */
+ data |= ((txcount >> 8)&0x03) ;
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMTXHI,data);
+
+ data = rxcount & 0xff;
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXLO,data);
+
+ data = (rxcount >> 8) & 0x3; /* PCMRXHI has only 2 bits for timeslot */
+ /* add to the calculated timeslot values the non timeslot bits */
+ data |= (ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXHI) & 0xFC);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMRXHI,data);
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+typedef ProslicInt proslicIntTypeMap[SI_MAX_INTERRUPTS][8];
+
+static int ProSLIC_ReadInterruptsHelper(proslicChanType_ptr pProslic,
+ uInt8 *regData, uInt8 numChannels)
+{
+ uInt8 i;
+ uInt8 intsActive;
+ uInt8 *currentData = regData;
+ SILABS_UNREFERENCED_PARAMETER(numChannels);
+
+ intsActive = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_IRQ0);
+
+#ifdef PROSLIC_OPTIMIZE_INTERRUPTS
+ /* For dual channel devices, we need to shift the upper nibble for the second channel
+ if the caller requested the second channel. We determine this by channel ID being
+ even or odd. If this is NOT true - for example a Si3217x and then a Si3226x chipset
+ configuration on the same daisychain, then this optimization logic will not work */
+#if defined(SI3226X) || defined(SI3228X)
+ if( (numChannels != 0) && ((pProslic->channel) & 0x1))
+ {
+ intsActive = intsActive >> 4;
+ }
+#endif /* Multichannel devices */
+#endif
+
+ /* If there are no interrupts, stop... return back to calling function */
+ if((intsActive &0xF) == 0)
+ {
+ return RC_IGNORE;
+ }
+
+ for(i = PROSLIC_REG_IRQ1; i <= PROSLIC_REG_IRQ4; i++)
+ {
+#ifdef PROSLIC_OPTIMIZE_INTERRUPTS
+ /* Read IRQn Register only if IRQ0 states there was an interrupt pending, otherwise
+ skip it. This eliminates unneeded SPI transactions.
+ */
+ if( (intsActive & (1<<(i-PROSLIC_REG_IRQ1))) == 0)
+ {
+ *currentData++ = 0;
+ continue;
+ }
+#endif
+ *currentData = (uInt8)ReadReg(pProslic, pProslic->channel, i);
+#ifdef GCI_MODDE
+ WriteReg(pProslic, pProslic->channel, i, *current_data);
+#endif
+ currentData++;
+ } /* for loop */
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*
+ Reads IRQ0 to determine if an interrupt has occurred for the particular device,
+ if so, reads the interrupt register(s) that fired the interrupt and then
+ maps the interrupt(s) to the generic interrupt value to return to the caller.
+
+ Code assumes normal chipset/compatibility testing has already been done.
+*/
+static int ProSLIC_GetInterruptHelper(proslicChanType_ptr pProslic,
+ const proslicIntTypeMap intMap, proslicIntType *pIntData, uInt8 numChannels)
+{
+ int i,j;
+ uInt8 intData[SI_MAX_INTERRUPTS];
+ uInt8 *currentData;
+ uInt8 map, intCount;
+ BOOLEAN safetyInt = FALSE;
+
+ /* Initialize interrupt count to 0 */
+ pIntData-> number = 0;
+
+ if( ProSLIC_ReadInterruptsHelper(pProslic, intData, numChannels) == RC_IGNORE)
+ {
+ /* No interrupts for the given channel. */
+ return RC_NONE;
+ }
+
+ /* At this point we've collected all the registers, now decode the data */
+ currentData = intData;
+ intCount = 0;
+
+ for(i = 0; i < SI_MAX_INTERRUPTS; i++)
+ {
+ if(*currentData)
+ {
+ for(j = 0; j < 8; j++)
+ {
+ if( *currentData & (1<<j) )
+ {
+ map = intMap[i][j];
+ pIntData->irqs[intCount] = map;
+
+ if( (map == IRQ_P_HVIC)
+ || (map == IRQ_P_THERM) )
+ {
+ safetyInt = TRUE;
+ }
+
+ intCount++;
+ }
+ }
+ }
+ currentData++;
+ }
+
+ pIntData->number = intCount;
+
+ if( safetyInt == TRUE)
+ {
+ if(ProSLIC_isReinitRequired(pProslic))
+ {
+ return RC_REINIT_REQUIRED;
+ }
+ }
+
+ return pIntData->number;
+}
+
+
+int ProSLIC_GetInterrupts (proslicChanType_ptr hProslic,
+ proslicIntType *pIntData)
+{
+ const proslicIntTypeMap interruptMap =
+ {
+ {IRQ_OSC1_T1, IRQ_OSC1_T2, IRQ_OSC2_T1, IRQ_OSC2_T2, IRQ_RING_T1, IRQ_RING_T2, IRQ_FSKBUF_AVAIL, IRQ_VBAT},
+ {IRQ_RING_TRIP, IRQ_LOOP_STATUS, IRQ_LONG_STAT, IRQ_VOC_TRACK, IRQ_DTMF, IRQ_INDIRECT, IRQ_RXMDM, IRQ_TXMDM},
+ {IRQ_P_HVIC, IRQ_P_THERM, IRQ_PQ3, IRQ_PQ4, IRQ_PQ5, IRQ_PQ6, IRQ_DSP, IRQ_MADC_FS},
+ {IRQ_USER_0, IRQ_USER_1, IRQ_USER_2, IRQ_USER_3, IRQ_USER_4, IRQ_USER_5, IRQ_USER_6, IRQ_USER_7}
+ };
+
+ pIntData->number=0;
+ /* TRACEPRINT(hProslic, "\n", NULL); */
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#if defined (SI3217X) || defined (SI3218X) || defined(SI3219X)
+ if (0
+#ifdef SI3217X
+ || (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+#endif
+#ifdef SI3218X
+ || (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+#endif
+#ifdef SI3219X
+ || ( IS_SI3219X(hProslic->deviceId) )
+#endif
+ )
+ {
+ return ProSLIC_GetInterruptHelper(hProslic, interruptMap, pIntData, 1);
+ }
+#endif
+#if defined (SI3226X) || defined (SI3228X)
+ if( 0
+#ifdef SI3226X
+ || (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+#endif
+#ifdef SI3228X
+ || (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+#endif
+ )
+ {
+ return ProSLIC_GetInterruptHelper(hProslic, interruptMap, pIntData, 2);
+ }
+#endif
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_ReadHookStatus (proslicChanType_ptr pProslic,uInt8 *pHookStat)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+ *pHookStat = PROSLIC_ONHOOK;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ if (ReadReg(pProslic,pProslic->channel,PROSLIC_REG_LCRRTP) & 2)
+ {
+ *pHookStat=PROSLIC_OFFHOOK;
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_SetLinefeedStatus (proslicChanType_ptr pProslic, uInt8 newLinefeed)
+{
+ uInt8 lfState;
+ uInt8 irqen1=0;
+ TRACEPRINT(pProslic, "linefeed = %u\n", newLinefeed);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ /* Get the irqen1 setting - used to determine if vbat interrupt was set... */
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ irqen1 = Si3217x_General_Configuration.irqen1;
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ irqen1 = Si3218x_General_Configuration.irqen1;
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ irqen1 = Si3219x_General_Configuration.irqen1;
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ irqen1 = Si3226x_General_Configuration.irqen1;
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ irqen1 = Si3228x_General_Configuration.irqen1;
+ }
+#endif
+
+ if( (newLinefeed& 0xF) == LF_RINGING )
+ {
+ uInt8 regTemp;
+
+ lfState = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED);
+
+ /* Only change to ringing state if not ringing... */
+ if( (lfState & 0xF) != LF_RINGING )
+ {
+ if(irqen1 & 0x80)
+ {
+ /*disable vbat interrupt during ringing*/
+ regTemp = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_IRQEN1 );
+ WriteReg (pProslic, pProslic->channel, PROSLIC_REG_IRQEN1, regTemp&(~0x80));
+ }
+
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, LF_RINGING);
+ }
+ else
+ {
+ return RC_IGNORE;
+ }
+ }
+ else
+ {
+ uInt8 autord;
+
+ /* Preserve the auto register so we can restore it at the end */
+ autord = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD );
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, (autord & 0xFB) ); /* Disable AutoRD */
+
+ lfState = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED);
+
+ if( (lfState & 0xF) == LF_RINGING )
+ {
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, newLinefeed);
+ }
+ else
+ {
+ /* We are already doing a state transition, abort request */
+ if( ((lfState & 0xF0) == (LF_RINGING << 4) )
+ && ( (lfState & 0xF) != LF_RINGING) )
+ {
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, autord ); /* restore the autord bit */
+ return RC_IGNORE;
+ }
+
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_LINEFEED, newLinefeed);
+ }
+ /* Restore autord */
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_AUTORD, autord );
+
+ /* Restore IRQEN1 to what the user specified - if we changed it.. */
+ if(irqen1 & 0x80)
+ {
+ WriteReg (pProslic, pProslic->channel, PROSLIC_REG_IRQEN1, irqen1);
+ }
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_SetLinefeedStatusBroadcast (proslicChanType_ptr hProslic,
+ uInt8 newLinefeed)
+{
+ TRACEPRINT(hProslic, "linefeed = %u\n", newLinefeed);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteReg(hProslic, PROSLIC_CHAN_BROADCAST, PROSLIC_REG_LINEFEED, newLinefeed);
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PolRev (proslicChanType_ptr pProslic,uInt8 abrupt,
+ uInt8 newPolRevState)
+{
+ uInt8 data = 0;
+ TRACEPRINT(pProslic, "abrupt = %u newPolRevState = %u\n", abrupt,
+ newPolRevState);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ switch (newPolRevState)
+ {
+ case POLREV_STOP:
+ data = 0;
+ break;
+ case POLREV_START:
+ data = 2;
+ break;
+ case WINK_START:
+ data = 6;
+ break;
+ case WINK_STOP:
+ data = 4;
+ break;
+ }
+
+ /* Cannot polrev/wink while low power mode is active */
+ ProSLIC_SetPowersaveMode(pProslic,PWRSAVE_DISABLE);
+
+ if (abrupt)
+ {
+ data |= 1;
+ }
+
+ WriteReg(pProslic, pProslic->channel, PROSLIC_REG_POLREV,data);
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_GPIOControl (proslicChanType_ptr pProslic,uInt8 *pGpioData,
+ uInt8 read)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#if defined(SI3217X) || defined (SI3226X)
+ if( 0
+#ifdef SI3217X
+ || (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+#endif
+#ifdef SI3226X
+ || (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+#endif
+ )
+ {
+ if (read)
+ {
+ *pGpioData = 0xf & ReadReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO);
+ }
+ else
+ {
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO,
+ (*pGpioData)|(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_GPIO)&0xf0));
+ }
+ return RC_NONE;
+ }
+#else
+ SILABS_UNREFERENCED_PARAMETER(read);
+ SILABS_UNREFERENCED_PARAMETER(pGpioData);
+#endif
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+/*
+** Optional Neon Message Waiting Support
+*/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_MWISetV (proslicChanType_ptr hProslic, uInt16 vpk_mag)
+{
+ uInt32 ram_val;
+ uInt8 max;
+
+ TRACEPRINT(hProslic, "vpk_mag = %u\n", vpk_mag);
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ /* Set the maximum MWI voltage according to the chipset */
+#if defined (SI3217X) || defined (SI3226X)
+ if( 0
+#ifdef SI3217X
+ || (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+#endif
+#ifdef SI3226X
+ || (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+#endif
+ )
+ {
+ max = SIL_MWI_VPK_MAX;
+ }
+#endif /*17x/26x */
+
+#if defined (SI3218X) || defined (SI3228X) || defined(SI3219X)
+ if( 0
+#ifdef SI3218X
+ || (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+#endif
+
+#ifdef SI3228X
+ || (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+#endif
+
+#ifdef SI3219X
+ || IS_SI3219X(hProslic->deviceId)
+#endif
+
+#ifdef SI3228X
+ || (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+#endif
+ )
+ {
+ max = SIL_MWI_VPK_MAX_LO;
+ }
+#endif /* 18x, 28x, 19x */
+
+ /* Voltage mod */
+ if(vpk_mag > 0) /* Skip if 0 passed */
+ {
+ /* Clamp supplied value to allowable range */
+ if(vpk_mag > max)
+ {
+ vpk_mag = max;
+ }
+ if(vpk_mag < SIL_MWI_VPK_MIN)
+ {
+ vpk_mag = SIL_MWI_VPK_MIN;
+ }
+ ram_val = vpk_mag * SCALE_R_MADC * 1000L;
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_MWI_V,ram_val);
+ }
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_MWIEnable (proslicChanType_ptr hProslic)
+{
+ uInt8 val;
+ ramData ram_val;
+
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ /*
+ ** Check for conditions that would prevent enabling MWI
+ */
+ ProSLIC_ReadHookStatus(hProslic,&val);
+ if(val != PROSLIC_ONHOOK)
+ {
+ return RC_MWI_ENABLE_FAIL;
+ }
+
+ val = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT);
+
+ /* Check if PROSLIC and disabled MWI, if not, ignore this request. */
+ if( (hProslic->channelType != PROSLIC)
+ || (val & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+
+ /* Save parameters */
+ hProslic->mwiSave.ringof = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF);
+ hProslic->mwiSave.ringamp = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP);
+ hProslic->mwiSave.vbatr_expect = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT);
+ hProslic->mwiSave.vov_ring_bat = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT);
+ hProslic->mwiSave.vov_ring_gnd = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND);
+ hProslic->mwiSave.rtacth = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH);
+ hProslic->mwiSave.rtdcth = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH);
+ hProslic->mwiSave.iring_lim = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM);
+ hProslic->mwiSave.dcdc_rngtype = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE);
+ hProslic->mwiSave.slope_ring = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING);
+ hProslic->mwiSave.rtper = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER);
+ hProslic->mwiSave.ringfr = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR);
+ hProslic->mwiSave.rtdcdb = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB);
+ hProslic->mwiSave.lcrmask = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK);
+ hProslic->mwiSave.dcdc_oithresh_lo = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO);
+ hProslic->mwiSave.enhance = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
+ hProslic->mwiSave.ringcon = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON);
+ hProslic->mwiSave.userstat = val;
+ hProslic->mwiSave.linefeed = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_LINEFEED);
+
+ /* Modify parameters */
+ ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
+ ram_val = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_MWI_V);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF,ram_val);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP,0x0L);
+
+ /* Set the VBATR_EXPECT according to the chipset */
+#if defined (SI3217X) || defined (SI3226X)
+ if( 0
+#ifdef SI3217X
+ || (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+#endif
+#ifdef SI3226X
+ || (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+#endif
+ )
+ {
+ ram_val = 0x7FFFFC2L;
+ }
+#endif
+
+#if defined (SI3218X) || defined (SI3228X) || defined(SI3219X)
+ if( 0
+#ifdef SI3218X
+ || (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+#endif
+
+#ifdef SI3228X
+ || (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+#endif
+
+#ifdef SI3219X
+ || IS_SI3219X(hProslic->deviceId)
+#endif
+ )
+ {
+ ram_val = 0x06866635L;
+ }
+#endif /* 18x,28x, 19x */
+
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT,ram_val);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT,0x0L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND,0x051EB80L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH,0x0FFFFFFFL);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH,0x38E38EL);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM,0x380000L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE,0x100000L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING,0x15E5200EL);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER,0x50000L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR,0x07EFE000L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB,0x0000A000L);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK,0x000F0000L);
+ ram_val = ReadRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_HI);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO,ram_val);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,hProslic->mwiSave.enhance&0xEF);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON,0x00);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT,0x0C);
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_MWIDisable (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
+ if( (hProslic->channelType != PROSLIC)
+ || !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+
+ ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGOF,hProslic->mwiSave.ringof);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGAMP,hProslic->mwiSave.ringamp);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VBATR_EXPECT,hProslic->mwiSave.vbatr_expect);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_BAT,hProslic->mwiSave.vov_ring_bat);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_VOV_RING_GND,hProslic->mwiSave.vov_ring_gnd);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTACTH,hProslic->mwiSave.rtacth);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCTH,hProslic->mwiSave.rtdcth);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_IRING_LIM,hProslic->mwiSave.iring_lim);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_RNGTYPE,hProslic->mwiSave.dcdc_rngtype);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_SLOPE_RING,hProslic->mwiSave.slope_ring);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTPER,hProslic->mwiSave.rtper);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RINGFR,hProslic->mwiSave.ringfr);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_RTDCDB,hProslic->mwiSave.rtdcdb);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_LCRMASK,hProslic->mwiSave.lcrmask);
+ WriteRAM(hProslic,hProslic->channel,PROSLIC_RAM_DCDC_OITHRESH_LO,hProslic->mwiSave.dcdc_oithresh_lo);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,hProslic->mwiSave.enhance);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_RINGCON,hProslic->mwiSave.ringcon);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT,hProslic->mwiSave.userstat);
+ ProSLIC_SetLinefeedStatus(hProslic,hProslic->mwiSave.linefeed);
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_SetMWIState (proslicChanType_ptr hProslic,uInt8 flash_on)
+{
+ TRACEPRINT(hProslic, "flash_on = %u\n", flash_on);
+ /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
+ if( (hProslic->channelType != PROSLIC)
+ || !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+
+ if(flash_on)
+ {
+ ProSLIC_SetLinefeedStatus(hProslic,LF_RINGING);
+ }
+ else
+ {
+ ProSLIC_SetLinefeedStatus(hProslic,LF_FWD_ACTIVE);
+ }
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_GetMWIState (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+ /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
+ if( (hProslic->channelType != PROSLIC)
+ || !(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+
+ if(ReadReg(hProslic,hProslic->channel,PROSLIC_REG_LINEFEED) == 0x44)
+ {
+ return SIL_MWI_FLASH_ON;
+ }
+ else
+ {
+ return SIL_MWI_FLASH_OFF;
+ }
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/******************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_MWIRampPoll(proslicChanType_ptr pProslic)
+{
+ uInt32 mwi_voltage;
+
+ /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
+ if( (pProslic->channelType != PROSLIC)
+ || !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+
+ switch(pProslic->mwiState.state)
+ {
+ case PROSLIC_MWI_RAMP_ON:
+ {
+ if(pProslic->mwiState.ticks == pProslic->mwiState.poll.steps)
+ {
+ mwi_voltage = pProslic->mwiState.poll.voff + pProslic->mwiState.poll.step_size;
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_RINGING);
+ }
+ else if(pProslic->mwiState.ticks == 0)
+ {
+ mwi_voltage = pProslic->mwiState.poll.von;
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
+ pProslic->mwiState.ticks = pProslic->mwiState.poll.onTime+1;
+ pProslic->mwiState.state = PROSLIC_MWI_ON;
+ }
+ else
+ {
+ mwi_voltage = pProslic->mwiState.poll.voff + pProslic->mwiState.poll.step_size*(pProslic->mwiState.poll.steps - pProslic->mwiState.ticks + 1);
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
+ }
+ }
+ break;
+
+ case PROSLIC_MWI_RAMP_OFF:
+ {
+ if(pProslic->mwiState.ticks == 0)
+ {
+ pProslic->mwiState.ticks = pProslic->mwiState.poll.offTime+1;
+ pProslic->mwiState.state = PROSLIC_MWI_OFF;
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ }
+ else
+ {
+ mwi_voltage = pProslic->mwiState.poll.von - (pProslic->mwiState.poll.steps - pProslic->mwiState.ticks + 1)*pProslic->mwiState.poll.step_size;
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_RINGOF,mwi_voltage);
+ }
+ break;
+ }
+
+ case PROSLIC_MWI_ON:
+ if(pProslic->mwiState.ticks == 0)
+ {
+ pProslic->mwiState.ticks = pProslic->mwiState.poll.steps+1;
+ pProslic->mwiState.state = PROSLIC_MWI_RAMP_OFF;
+ }
+ break;
+
+ case PROSLIC_MWI_OFF:
+ if(pProslic->mwiState.ticks == 0)
+ {
+ pProslic->mwiState.ticks = pProslic->mwiState.poll.steps+1;
+ pProslic->mwiState.state = PROSLIC_MWI_RAMP_ON;
+ }
+ break;
+
+ default:
+ /* Do nothing */
+ break;
+ }
+ (pProslic->mwiState.ticks)--;
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/******************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_MWIRampStart(proslicChanType_ptr pProslic, uInt32 steps, uInt32 onTime, uInt32 offTime)
+{
+ /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
+ if( (pProslic->channelType != PROSLIC)
+ || !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+
+ pProslic->mwiState.poll.steps = steps-1;
+ pProslic->mwiState.poll.onTime = onTime;
+ pProslic->mwiState.poll.offTime = offTime;
+
+ pProslic->mwiState.poll.von = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_MWI_V);
+ pProslic->mwiState.poll.voff = (ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_V_VLIM)*5)/6;
+ pProslic->mwiState.poll.step_size = (pProslic->mwiState.poll.von - pProslic->mwiState.poll.voff)/steps;
+
+ pProslic->mwiState.state = PROSLIC_MWI_RAMP_ON;
+ pProslic->mwiState.ticks = pProslic->mwiState.poll.steps;
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/******************************************************************************/
+#ifdef SIVOICE_NEON_MWI_SUPPORT
+int ProSLIC_MWIRampStop(proslicChanType_ptr pProslic)
+{
+ /* Check if PROSLIC and enabled MWI, if not, ignore this request. */
+ if( (pProslic->channelType != PROSLIC)
+ || !(ReadReg(pProslic,pProslic->channel,PROSLIC_REG_USERSTAT) & SIL_MWI_USTAT_SET ) )
+ {
+ return RC_IGNORE;
+ }
+ pProslic->mwiState.state = PROSLIC_MWI_OFF;
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+int ProSLIC_ToneGenStart (proslicChanType_ptr pProslic,uInt8 timerEn)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "timerEn = %u\n", timerEn);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ DEBUG_PRINT(pProslic, "%s%s on channel %d\n",LOGPRINT_PREFIX, __FUNCTION__,
+ pProslic->channel);
+
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OCON);
+ data |= 0x11 + (timerEn ? 0x66 : 0);
+ return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,data);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_ToneGenStop (proslicChanType_ptr pProslic)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ DEBUG_PRINT(pProslic,"%s%s on channel %d\n",LOGPRINT_PREFIX, __FUNCTION__,
+ pProslic->channel);
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OCON);
+ data &= ~(0x77);
+ return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,data);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_RingStart (proslicChanType_ptr pProslic)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+ return(ProSLIC_SetLinefeedStatus(pProslic, LF_RINGING));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_RingStop (proslicChanType_ptr pProslic)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+ return(ProSLIC_SetLinefeedStatus(pProslic, LF_FWD_ACTIVE));
+}
+
+#ifndef DISABLE_FSK_SETUP
+/*****************************************************************************************************/
+int ProSLIC_CheckCIDBuffer (proslicChanType_ptr pProslic, uInt8 *fsk_buf_avail)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ data = ReadReg(pProslic,pProslic->channel, PROSLIC_REG_IRQ1);
+#ifdef GCI_MODE
+ WriteReg(pProslic,pProslic->channel, PROSLIC_REG_IRQ1,data); /*clear (for GCI)*/
+#endif
+ *fsk_buf_avail = (data&0x40) ? 1 : 0;
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_EnableCID (proslicChanType_ptr pProslic)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ DEBUG_PRINT(pProslic, "%sEnableCID on channel %d\n",LOGPRINT_PREFIX,
+ pProslic->channel);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0);
+
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
+ data |= 0xA;
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
+
+ return(WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0x5));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_DisableCID (proslicChanType_ptr pProslic)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ DEBUG_PRINT(pProslic, "%sDisableCID on channel %d\n",LOGPRINT_PREFIX,
+ pProslic->channel);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OCON,0);
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
+ data &= ~(0x8);
+
+ return(WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_SendCID (proslicChanType_ptr pProslic, uInt8 *buffer,
+ uInt8 numBytes)
+{
+ TRACEPRINT(pProslic, "numBytes = %u\n", numBytes);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ DEBUG_PRINT (pProslic, "%sSendCID on channel %d\n",LOGPRINT_PREFIX,
+ pProslic->channel);
+ while (numBytes-- > 0)
+ {
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDAT,*(buffer++));
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_ModifyCIDStartBits(proslicChanType_ptr pProslic,
+ uInt8 enable_startStop)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "enable_startStop = %u\n", enable_startStop);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
+
+ if(enable_startStop == FALSE)
+ {
+ data &= ~0x80;
+ }
+ else
+ {
+ data |= 0x80;
+ }
+
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
+
+ return RC_NONE;
+}
+#endif /* DISABLE_FSK_SETUP */
+/*****************************************************************************************************/
+int ProSLIC_PCMStart (proslicChanType_ptr pProslic)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ DEBUG_PRINT(pProslic, "%sPCMStart\n", LOGPRINT_PREFIX);
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE);
+ data |= 0x10;
+
+ return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE,data);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PCMStop (proslicChanType_ptr pProslic)
+{
+ uInt8 data;
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ DEBUG_PRINT(pProslic, "%sPCMStart\n", LOGPRINT_PREFIX);
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE);
+ data &= ~0x10;
+
+ return WriteReg(pProslic,pProslic->channel,PROSLIC_REG_PCMMODE,data);
+}
+
+#ifndef DISABLE_HOOKCHANGE
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_ResetDialPulseDetect
+**
+** Description:
+** reset dial pulse detection state machine (helper function for
+** ProSLIC_InitializeHookChangeDetect.
+*/
+static void ProSLIC_ResetDialPulseDetect(hookChangeType *pPulse)
+{
+ pPulse->currentPulseDigit = 0;
+ pPulse->lookingForTimeout = 0;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_InitializeHookChangeDetect
+**
+** Description:
+** Initialize dial pulse detection parameters
+*/
+int ProSLIC_InitializeHookChangeDetect(hookChangeType *pPulse,void *hookTime)
+{
+ TRACEPRINT_NOCHAN("\n", NULL);
+ pPulse->hookTime = hookTime;
+ pPulse->last_state_reported = SI_HC_NO_ACTIVITY;
+ ProSLIC_ResetDialPulseDetect(pPulse);
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_HookChangeDetect
+**
+** Description:
+** implements pulse dial detection and should be called at every hook transition
+*/
+uInt8 ProSLIC_HookChangeDetect (proslicChanType *pProslic,
+ hookChange_Cfg *pHookChangeCfg, hookChangeType *pHookChangeData)
+{
+ uInt8 hookStat;
+ int delta_time;
+
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ TimeElapsed(pProTimer,pHookChangeData->hookTime,&delta_time);
+ ProSLIC_ReadHookStatus(pProslic,&hookStat);
+
+ /* Did we have a hook state change? */
+ if(hookStat != pHookChangeData->last_hook_state)
+ {
+ pHookChangeData->last_hook_state = hookStat;
+ getTime(pProTimer,pHookChangeData->hookTime);
+ pHookChangeData->lookingForTimeout = 1;
+ if (hookStat == PROSLIC_OFFHOOK)
+ {
+ if ((delta_time >= (pHookChangeCfg->minOnHook))
+ && (delta_time <= (pHookChangeCfg->maxOnHook)))
+ {
+ pHookChangeData->currentPulseDigit++;
+ }
+ else
+ {
+ /* Did we see a hook flash? */
+ if( (delta_time >= pHookChangeCfg->minHookFlash)
+ && (delta_time <= pHookChangeCfg->maxHookFlash) )
+ {
+ pHookChangeData->last_state_reported = SI_HC_HOOKFLASH;
+ ProSLIC_ResetDialPulseDetect(pHookChangeData);
+ return SI_HC_HOOKFLASH;
+ }
+ }
+ }
+
+ return SI_HC_NEED_MORE_POLLS;
+ }
+
+ if( (pHookChangeData->lookingForTimeout == 1)
+ && (delta_time >= pHookChangeCfg->minInterDigit) )
+ {
+
+ if(delta_time > pHookChangeCfg->minHook)
+ {
+ if(pHookChangeData->last_hook_state == PROSLIC_ONHOOK)
+ {
+ ProSLIC_ResetDialPulseDetect(pHookChangeData);
+ pHookChangeData->last_state_reported = SI_HC_ONHOOK_TIMEOUT;
+ return SI_HC_ONHOOK_TIMEOUT;
+ }
+
+ if(pHookChangeData->last_hook_state == PROSLIC_OFFHOOK)
+ {
+ ProSLIC_ResetDialPulseDetect(pHookChangeData);
+
+ /* Check if we saw either a pulse digit or hook flash prior to this,
+ * if so, we're already offhook, so do not report a offhook event,
+ * just stop polling.
+ */
+ if((pHookChangeData->last_state_reported == SI_HC_ONHOOK_TIMEOUT)
+ || (pHookChangeData->last_state_reported == SI_HC_NO_ACTIVITY) )
+ {
+ pHookChangeData->last_state_reported = SI_HC_OFFHOOK_TIMEOUT;
+ return SI_HC_OFFHOOK_TIMEOUT;
+ }
+ else
+ {
+ return SI_HC_NO_ACTIVITY;
+ }
+ }
+ }
+ else
+ {
+ uInt8 last_digit = pHookChangeData->currentPulseDigit;
+
+ if(last_digit)
+ {
+ pHookChangeData->last_state_reported = last_digit;
+ ProSLIC_ResetDialPulseDetect(pHookChangeData);
+ return last_digit;
+ }
+ }
+ return SI_HC_NEED_MORE_POLLS;
+ }
+
+ return SI_HC_NEED_MORE_POLLS;
+}
+#endif /* DISABLE_HOOKCHANGE */
+
+/*****************************************************************************************************/
+int ProSLIC_DTMFReadDigit (proslicChanType_ptr pProslic,uInt8 *pDigit)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ DEBUG_PRINT(pProslic, "%sDTMFReadDigit on channel %d\n",LOGPRINT_PREFIX,
+ pProslic->channel);
+ *pDigit = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_TONDTMF) & 0xf;
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PLLFreeRunStart (proslicChanType_ptr hProslic)
+{
+ uInt8 tmp;
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ZCAL_EN,0x00);
+ tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
+
+ return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,tmp|0x4));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PLLFreeRunStop (proslicChanType_ptr hProslic)
+{
+ uInt8 tmp;
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
+ WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE,tmp&~(0x4));
+
+ return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_ZCAL_EN,0x04);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_GetPLLFreeRunStatus (proslicChanType_ptr hProslic)
+{
+ uInt8 tmp;
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ tmp = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE);
+
+ if(tmp & 0x02)
+ {
+ return RC_PLL_FREERUN_ACTIVE;
+ }
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+#ifndef DISABLE_PULSEMETERING
+int ProSLIC_PulseMeterEnable (proslicChanType_ptr hProslic)
+{
+ uInt8 widebandEn;
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ widebandEn = ReadReg(hProslic,hProslic->channel,PROSLIC_REG_ENHANCE) & 0x01;
+
+ if (widebandEn)
+ {
+ DEBUG_PRINT (hProslic,
+ "%s Pulse Metering is not supported while Wideband Mode is enabled.\n",
+ LOGPRINT_PREFIX);
+ }
+
+#if defined (SI3217X) || defined (SI3218X) || defined (SI3226X) || defined (SI3228X) || defined(SI3219X)
+ if(!widebandEn && (0
+#ifdef SI3217X
+ || (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+#endif
+#ifdef SI3218X
+ ||(hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+#endif
+#ifdef SI3219X
+ || (IS_SI3219X(hProslic->deviceId) )
+#endif
+#ifdef SI3226X
+ || (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+#endif
+#ifdef SI3228X
+ || (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289 )
+#endif
+ ))
+ {
+ return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
+ hProslic->channel,PROSLIC_REG_PMCON) | (0x01));
+ }
+#endif
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PulseMeterDisable (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
+ hProslic->channel,PROSLIC_REG_PMCON) & ~(0x05)));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PulseMeterStart (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ return WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
+ hProslic->channel,PROSLIC_REG_PMCON) | (0x5));
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PulseMeterStop (proslicChanType_ptr hProslic)
+{
+ TRACEPRINT(hProslic, "\n", NULL);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
+ hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
+ hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return(WriteReg(hProslic,hProslic->channel,PROSLIC_REG_PMCON,ReadReg(hProslic,
+ hProslic->channel,PROSLIC_REG_PMCON) & ~(0x04)));
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return ProSLIC_PulseMeterDisable(hProslic);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return ProSLIC_PulseMeterDisable(hProslic);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif /* DISABLE_PULSEMETERING */
+/*****************************************************************************************************/
+int ProSLIC_SetDCDCInversionFlag (proslicChanType_ptr hProslic, uInt8 flag)
+{
+ TRACEPRINT(hProslic, "flag = %u\n", flag);
+
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ hProslic->dcdc_polarity_invert = flag;
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+
+int ProSLIC_PowerUpConverter (proslicChanType_ptr hProslic)
+{
+ if(hProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (hProslic->deviceId->chipType >= SI32171
+ && hProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_PowerUpConverter(hProslic);
+ }
+#endif
+
+#ifdef SI3218X
+ if (hProslic->deviceId->chipType >= SI32180
+ && hProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_PowerUpConverter(hProslic);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(hProslic->deviceId) )
+ {
+ return Si3219x_PowerUpConverter(hProslic);
+ }
+#endif
+
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_PowerUpConverter(hProslic);
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_PowerUpConverter(hProslic);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+/*****************************************************************************************************/
+static int ProSLIC_GetBatType(proslicChanType_ptr hProslic)
+{
+#ifdef SI3226X
+ if (hProslic->deviceId->chipType >= SI32260
+ && hProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_General_Configuration.batType;
+ }
+#endif
+
+#ifdef SI3228X
+ if (hProslic->deviceId->chipType >= SI32280
+ && hProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_General_Configuration.batType;
+ }
+#endif
+
+#if !defined(SI3226X) && !defined(SI3228X)
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+#endif
+ return BO_DCDC_UNKNOWN;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_PowerDownConverter (proslicChanType_ptr pProslic)
+{
+ errorCodeType error = RC_NONE;
+ int32 vbat;
+ int timer = 0;
+
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ /* Force channel out of powersavings mode and then put it in open state */
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_LINEFEED,LF_FWD_OHT);
+ Delay(pProTimer,10);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_LINEFEED, LF_OPEN);
+ Delay(pProTimer,50);
+
+ /* Don't try to shutdown converter if we're using external supplies or if the
+ converter is already shutdown.
+ */
+ if((ProSLIC_GetBatType(pProslic) == BO_DCDC_EXTERNAL) ||
+ (ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_PD_DCDC) & 0x100000) )
+ {
+ return RC_NONE;
+ }
+
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_PD_DCDC,0x900000L);
+ Delay(pProTimer,50);
+
+ do
+ {
+ vbat = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_MADC_VBAT);
+ if(vbat & 0x10000000L)
+ {
+ vbat |= 0xF0000000L;
+ }
+ Delay(pProTimer,10);
+ }
+ while((vbat > COMP_5V) && (timer++ < PROSLIC_TIMEOUT_DCDC_DOWN));
+
+ DEBUG_PRINT(pProslic, "%s VBAT Down = %d.%d v\n", LOGPRINT_PREFIX,
+ (int)((vbat/SCALE_V_MADC)/1000),
+ SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
+
+ if(timer > PROSLIC_TIMEOUT_DCDC_DOWN)
+ {
+ /* Error handling - shutdown converter, disable channel, set error tag */
+ pProslic->channelEnable = 0;
+ pProslic->error = error = RC_VBAT_DOWN_TIMEOUT;
+ DEBUG_PRINT(pProslic, "%sDCDC Power Down timeout channel %d\n", LOGPRINT_PREFIX,
+ pProslic->channel);
+ }
+ return error;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_LBCal (proslicChanType_ptr *pProslic, int size)
+{
+ int k;
+ int timeout;
+ uInt8 data;
+ uInt8 lfState, enhance_value;
+ TRACEPRINT(*pProslic, "size = %d\n", size);
+
+ if((*pProslic)->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ /* For all channels, save settings, initiate LBCAL */
+ for(k = 0; k < size; k++)
+ {
+ if( (pProslic[k]->channelEnable) && (pProslic[k]->channelType == PROSLIC) )
+ {
+ DEBUG_PRINT(pProslic[k], "%sStarting LB Cal on channel %d\n", LOGPRINT_PREFIX,
+ pProslic[k]->channel);
+ /* Preserve old settings */
+ lfState = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED);
+ enhance_value = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_ENHANCE);
+ ProSLIC_SetPowersaveMode(pProslic[k], PWRSAVE_DISABLE);
+ ProSLIC_SetLinefeedStatus(pProslic[k], LF_FWD_ACTIVE);
+ WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR0, CAL_LB_ALL);
+ WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR3, 0x80);
+ pProslic[k]->error = RC_CAL_TIMEOUT; /* Assume failure */
+
+ timeout = 0;
+ do
+ {
+ data = ReadReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_CALR3);
+ DelayX(*pProslic, 10);
+ timeout++;
+ }
+ while((data & 0x80) && (timeout < TIMEOUT_LB_CAL));
+
+ if( (data & 0x80) )
+ {
+ DEBUG_PRINT(pProslic[k], "%sLB Cal timeout on channel %d\n", LOGPRINT_PREFIX,
+ pProslic[k]->channel);
+ WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED, LF_OPEN);
+ return RC_CAL_TIMEOUT;
+ }
+ else
+ {
+ WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_LINEFEED, lfState);
+ WriteReg(pProslic[k], pProslic[k]->channel, PROSLIC_REG_ENHANCE, enhance_value);
+ pProslic[k]->error = RC_NONE;
+ }
+ }
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+#define PROSLIC_RAM_CMDAC_FWD 1476
+#define PROSLIC_RAM_CMDAC_REV 1477
+#define PROSLIC_RAM_CAL_TRNRD_DACT 1458
+#define PROSLIC_RAM_CAL_TRNRD_DACR 1459
+
+int ProSLIC_GetLBCalResult (proslicChanType *pProslic,int32 *result1,
+ int32 *result2, int32 *result3, int32 *result4)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ *result1 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CMDAC_FWD);
+ *result2 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CMDAC_REV);
+ *result3 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CAL_TRNRD_DACT);
+ *result4 = ReadRAM(pProslic, pProslic->channel, PROSLIC_RAM_CAL_TRNRD_DACR);
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_GetLBCalResultPacked (proslicChanType *pProslic,int32 *result)
+{
+ int32 results[4];
+ int rc;
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ rc = ProSLIC_GetLBCalResult(pProslic, &(results[0]), &(results[1]),
+ &(results[2]), &(results[3]));
+ if(rc == RC_NONE)
+ {
+ /*
+ Bits 31:24 CMDAC_FWD[25:18]
+ Bits 23:16 CMDAC_REV[25:18]
+ Bits 15:8 CAL_TRNRD_DACT[20:13]
+ Bits 7:0 CAL_TRNRD_DACR[20:13]
+ */
+ *result = (results[0]<<6) & 0xff000000L;
+ *result |=(results[1]>>1) & 0x00ff0000L;
+ *result |=(results[2]>>5) & 0x0000ff00L;
+ *result |=(results[3]>>13)& 0x000000ffL;
+ }
+
+ return rc;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_LoadPreviousLBCal (proslicChanType *pProslic,int32 result1,
+ int32 result2,int32 result3,int32 result4)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_FWD,result1);
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_REV,result2);
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACT,result3);
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACR,result4);
+
+#ifdef API_TEST
+ ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CMDAC_FWD);
+ LOGPRINT ("%s UNPACKED CMDAC_FWD = %08x\n", LOGPRINT_PREFIX, ramVal);
+ ramVal = ReadRAM(pProslic, pProslic->channel,PROSLIC_RAM_CMDAC_REV);
+ LOGPRINT ("%s UNPACKED CMDAC_REF = %08x\n", LOGPRINT_PREFIX, ramVal);
+ ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACT);
+ LOGPRINT ("%s UNPACKED CAL_TRNRD_DACT = %08x\n", LOGPRINT_PREFIX, ramVal);
+ ramVal = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_CAL_TRNRD_DACR);
+ LOGPRINT ("%s UNPACKED CAL_TRNRD_DACR = %08x\n", LOGPRINT_PREFIX, ramVal);
+#endif
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_LoadPreviousLBCalPacked (proslicChanType *pProslic,int32 *result)
+{
+ ramData ramVal[4];
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+ ramVal[0] = (*result&0xff000000L)>>6;
+ ramVal[1] = (*result&0x00ff0000L)<<1;
+ ramVal[2] = (*result&0x0000ff00L)<<5;
+ ramVal[3] = (*result&0x000000ffL)<<13;
+
+ return ProSLIC_LoadPreviousLBCal(pProslic, ramVal[0], ramVal[1], ramVal[2],
+ ramVal[3]);
+}
+
+/*****************************************************************************************************/
+int ProSLIC_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
+ int32 preset)
+{
+ TRACEPRINT(pProslic, "v_vlim_val = %u preset = %d\n", v_vlim_val, preset);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_dbgSetDCFeedVopen (pProslic,v_vlim_val,preset);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
+ int32 preset)
+{
+ TRACEPRINT(pProslic, "i_ilim_val = %u preset = %d\n", i_ilim_val, preset);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_dbgSetDCFeedIloop (pProslic,i_ilim_val,preset);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_dbgSetRinging (proslicChanType *pProslic,
+ ProSLIC_dbgRingCfg *ringCfg, int preset)
+{
+ TRACEPRINT(pProslic, "preset = %d\n", preset);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_dbgSetRinging (pProslic,ringCfg,preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_dbgSetRinging (pProslic,ringCfg,preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_dbgSetRinging (pProslic,ringCfg,preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_dbgSetRinging (pProslic,ringCfg,preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_dbgSetRinging (pProslic,ringCfg,preset);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset)
+{
+ TRACEPRINT(pProslic, "gain = %d imp_preset = %d audio_gain_preset = %d\n", gain,
+ impedance_preset, audio_gain_preset);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_dbgSetRXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset)
+{
+ TRACEPRINT(pProslic, "gain = %d imp_preset = %d audio_gain_preset = %d\n", gain,
+ impedance_preset, audio_gain_preset);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_dbgSetTXGain (pProslic,gain,impedance_preset,audio_gain_preset);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_LineMonitor
+**
+** Description:
+** Generic monitoring function
+**
+** Returns:
+** 0
+*/
+
+int ProSLIC_LineMonitor (proslicChanType *pProslic, proslicMonitorType *monitor)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_LineMonitor (pProslic, monitor);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_LineMonitor (pProslic, monitor);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_LineMonitor (pProslic, monitor);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_LineMonitor (pProslic, monitor);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_LineMonitor (pProslic, monitor);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_PSTNCheck
+**
+** Description:
+** Monitor for excessive longitudinal current, which
+** would be present if a live pstn line was connected
+** to the port.
+**
+** Returns:
+** 0 - no pstn detected
+** 1 - pstn detected
+*/
+int ProSLIC_PSTNCheck (proslicChanType *pProslic,
+ proslicPSTNCheckObjType *pPSTNCheck)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_PSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_PSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_PSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_PSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_PSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_DiffPSTNCheck
+**
+** Description:
+** Monitor for excessive longitudinal current, which
+** would be present if a live pstn line was connected
+** to the port.
+**
+** Returns:
+** RC_NONE - test in progress
+** RC_IGNORE - non-ProSLIC channel
+** RC_COMPLETE_NO_ERR - ProSLIC does not support feature.
+** RC_PSTN_OPEN_FEMF | RC_COMPLETE_NO_ERR - test completed.
+**
+*/
+#ifdef PSTN_DET_ENABLE
+int ProSLIC_DiffPSTNCheck (proslicChanType *pProslic,
+ proslicDiffPSTNCheckObjType *pPSTNCheck)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ return Si3217x_DiffPSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3218X
+ if (pProslic->deviceId->chipType >= SI32180
+ && pProslic->deviceId->chipType <= SI32189)
+ {
+ return Si3218x_DiffPSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(pProslic->deviceId) )
+ {
+ return Si3219x_DiffPSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3226X
+ if (pProslic->deviceId->chipType >= SI32260
+ && pProslic->deviceId->chipType <= SI32269)
+ {
+ return Si3226x_DiffPSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+#ifdef SI3228X
+ if (pProslic->deviceId->chipType >= SI32280
+ && pProslic->deviceId->chipType <= SI32289)
+ {
+ return Si3228x_DiffPSTNCheck (pProslic,pPSTNCheck);
+ }
+#endif
+
+ return RC_COMPLETE_NO_ERR;
+}
+#endif
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_CreatePSTNCheckObj
+**
+** Description:
+** Allocate memory for pstnCheckObj
+**
+** Returns:
+** RC_NONE
+** RC_NO_MEM if failed to allocate memory.
+** RC_UNSUPPORTED_FEATER if malloc disabled
+*/
+int ProSLIC_CreatePSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj,
+ unsigned int num_objs)
+{
+ TRACEPRINT_NOCHAN("num_objs = %u\n", num_objs);
+#ifndef DISABLE_MALLOC
+ *pstnCheckObj = SIVOICE_CALLOC(sizeof(proslicPSTNCheckObjType),num_objs);
+ if(*pstnCheckObj == NULL)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
+#endif
+ return RC_NO_MEM;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
+ SILABS_UNREFERENCED_PARAMETER(num_objs);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_CreateDiffPSTNCheckObjs
+**
+** Description:
+** Allocate memory for proslicDiffPstnCheckObjs
+**
+** Returns:
+** RC_NONE
+** RC_NO_MEM if failed to allocate memory.
+** RC_UNSUPPORTED_FEATURE if malloc disabled
+*/
+
+#ifdef PSTN_DET_ENABLE
+int ProSLIC_CreateDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
+ *pstnCheckObj, unsigned int num_objs)
+{
+ TRACEPRINT_NOCHAN("num_objs = %u\n", num_objs);
+
+#ifndef DISABLE_MALLOC
+ *pstnCheckObj = SIVOICE_CALLOC(sizeof(proslicDiffPSTNCheckObjType),num_objs);
+ if(*pstnCheckObj == NULL)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
+#endif
+ return RC_NO_MEM;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
+ SILABS_UNREFERENCED_PARAMETER(num_objs);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+#endif
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_DestroyPSTNCheckObjs
+**
+** Description:
+** Free memory for pstnCheckObj
+**
+** Returns:
+** RC_NONE
+** RC_UNSUPPORTED_FEATER if malloc disabled
+*/
+int ProSLIC_DestroyPSTNCheckObjs(proslicPSTNCheckObjType_ptr *pstnCheckObj)
+{
+ TRACEPRINT_NOCHAN("\n", NULL);
+
+#ifndef DISABLE_MALLOC
+ if(pstnCheckObj)
+ {
+ SIVOICE_FREE((proslicPSTNCheckObjType_ptr)*pstnCheckObj);
+ }
+
+ return RC_NONE;
+
+#else
+ SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_DestroyDiffPSTNCheckObjs
+**
+** Description:
+** Free memory for pstnDiffCheckObj
+**
+** Returns:
+** RC_NONE
+** RC_UNSUPPORTED_FEATER if malloc disabled
+*/
+#ifdef PSTN_DET_ENABLE
+int ProSLIC_DestroyDiffPSTNCheckObjs(proslicDiffPSTNCheckObjType_ptr
+ *pstnCheckObj)
+{
+ TRACEPRINT_NOCHAN("\n", NULL);
+
+#ifndef DISABLE_MALLOC
+ if(pstnCheckObj)
+ {
+ SIVOICE_FREE((proslicDiffPSTNCheckObjType_ptr)*pstnCheckObj);
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pstnCheckObj);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+#endif
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_InitPSTNCheckObj
+**
+** Description:
+** Initialize pstnCheckObj structure members
+**
+** Returns:
+** RC_NONE
+*/
+int ProSLIC_InitPSTNCheckObj(proslicPSTNCheckObjType_ptr pstnCheckObj,
+ int32 avgThresh, int32 singleThresh, uInt8 samples)
+{
+ TRACEPRINT_NOCHAN("avgThres = %d singleThresh = %d samples = %u\n", avgThresh,
+ avgThresh, samples);
+
+ pstnCheckObj->avgThresh = avgThresh;
+ pstnCheckObj->singleThresh = singleThresh;
+ pstnCheckObj->samples = samples;
+ pstnCheckObj->avgIlong = 0;
+ pstnCheckObj->count = 0;
+ pstnCheckObj->buffFull = 0;
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_InitDiffPSTNCheckObj
+**
+** Description:
+** Initialize pstnCheckObj structure members
+**
+** Returns:
+** RC_NONE
+*/
+#ifdef PSTN_DET_ENABLE
+int ProSLIC_InitDiffPSTNCheckObj(proslicDiffPSTNCheckObjType_ptr
+ pstnDiffCheckObj,
+ int preset1,
+ int preset2,
+ int entry_preset,
+ int femf_enable)
+{
+ TRACEPRINT_NOCHAN("p1 = %d p2 = %d ep = %d femf_enable = %d\n", preset1,
+ preset2, entry_preset, femf_enable);
+
+ pstnDiffCheckObj->samples = PSTN_DET_DIFF_SAMPLES;
+ pstnDiffCheckObj->max_femf_vopen = PSTN_DET_MAX_FEMF;
+ pstnDiffCheckObj->entryDCFeedPreset = entry_preset;
+ pstnDiffCheckObj->dcfPreset1 = preset1;
+ pstnDiffCheckObj->dcfPreset2 = preset2;
+ pstnDiffCheckObj->femf_enable = femf_enable;
+ pstnDiffCheckObj->pState.stage = 0;
+ pstnDiffCheckObj->pState.sampleIterations = 0;
+ pstnDiffCheckObj->pState.waitIterations = 0;
+
+ return RC_NONE;
+}
+#endif
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_SetPwrsaveMode
+**
+** Description:
+** Enable or disable powersave mode
+**
+** Returns:
+** RC_NONE
+*/
+#define PROSLIC_REG_ENHANCE 47
+
+int ProSLIC_SetPowersaveMode (proslicChanType *pProslic, int pwrsave)
+{
+ uInt8 regData;
+ TRACEPRINT(pProslic, "pwrsave = %d\n", pwrsave);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ regData = ReadReg(pProslic,pProslic->channel, PROSLIC_REG_ENHANCE);
+
+ if(pwrsave == PWRSAVE_DISABLE)
+ {
+#ifdef SI3217X
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ regData &= 0x27;
+ }
+ else
+ {
+#endif
+ regData &= 0x07;
+#ifdef SI3217X
+ }
+#endif
+ }
+ else
+ {
+ regData |= 0x10;
+ }
+
+ return WriteReg(pProslic,pProslic->channel, PROSLIC_REG_ENHANCE, regData);
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_SetDAAEnable
+**
+** Description:
+** Enable or disable adjacent FXO (Si32178 only)
+**
+** Returns:
+** RC_NONE
+*/
+int ProSLIC_SetDAAEnable (proslicChanType *pProslic, int enable)
+{
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+#ifdef SI3217X
+ return Si3217x_SetDAAEnable (pProslic,enable);
+#else
+ SILABS_UNREFERENCED_PARAMETER(enable);
+ return RC_NONE;
+#endif
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_SetUserMode
+**
+** Description: Enables User Access Mode (UAM) if the part supports it.
+**
+** Returns:
+** RC_NONE if successful.
+*/
+#define PROSLIC_REG_USERMODE_ENABLE 126
+
+int ProSLIC_SetUserMode(proslicChanType *pProslic,BOOLEAN isEnabled,
+ BOOLEAN isBcast)
+{
+ uInt8 data;
+ uInt8 channel;
+
+ TRACEPRINT(pProslic, "enable = %d bcast = %d\n", (int)isEnabled, (int)isBcast);
+
+ if(isEnabled == FALSE)
+ {
+ return RC_NONE;
+ }
+
+ if( pProslic->channelType != PROSLIC )
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ if(isBcast == TRUE)
+ {
+ channel = PROSLIC_CHAN_BROADCAST;
+ }
+ else
+ {
+ channel = pProslic->channel;
+ }
+
+ data = ReadReg(pProslic,pProslic->channel,
+ PROSLIC_REG_USERMODE_ENABLE); /*we check first channel. we assume all channels same user mode state for broadcast */
+
+ if (((data&1) != 0) == isEnabled)
+ {
+ return RC_NONE;
+ }
+
+ WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,2);
+ WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,8);
+ WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,0xe);
+ return WriteReg(pProslic,channel,PROSLIC_REG_USERMODE_ENABLE,0);
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_isReinitRequired
+**
+** Description:
+** Checks for improper ring exit
+**
+** Returns:
+** RC_NONE - Reinit not required
+** RC_REINIT_REQUIRED - Corrupted state machine - reinit required
+**
+*/
+
+int ProSLIC_isReinitRequired(proslicChanType *pProslic)
+{
+ uInt8 lf;
+ ramData rkdc_sum;
+ TRACEPRINT(pProslic, "\n", NULL);
+
+ if( pProslic->channelType != PROSLIC)
+ {
+ return RC_IGNORE;
+ }
+
+ /* Check for improper ring exit which may cause dcfeed corruption */
+
+ lf = ReadReg(pProslic, pProslic->channel,PROSLIC_REG_LINEFEED);
+ rkdc_sum = ReadRAM(pProslic,pProslic->channel,PROSLIC_RAM_RDC_SUM);
+ DEBUG_PRINT(pProslic, "%sisReinitRequired: Linefeed = 0x%02X RDC_SUM = %d\n",
+ LOGPRINT_PREFIX, (int)lf, (int) rkdc_sum);
+ if((rkdc_sum & 0x400000)&&(lf != 0x44))
+ {
+ return RC_REINIT_REQUIRED;
+ }
+ else
+ {
+ return RC_NONE;
+ }
+}
+
+/*****************************************************************************************************/
+/*
+** Function: LoadRegTable
+**
+** Description:
+** Generic function to load register/RAM with predefined addr/value
+*/
+int ProSLIC_LoadRegTable (proslicChanType *pProslic,
+ const ProslicRAMInit *pRamTable,
+ const ProslicRegInit *pRegTable,
+ int broadcast)
+{
+ uInt16 i;
+ uInt8 channel;
+
+ TRACEPRINT(pProslic, "bcast = %d\n", broadcast);
+ /* DAA doesn't have a RAM table.. skip it... */
+ if( (pRamTable != 0)
+ && (pProslic->channelType != PROSLIC) )
+ {
+ return RC_IGNORE;
+ }
+
+ if (broadcast)
+ {
+ channel = PROSLIC_CHAN_BROADCAST;
+ }
+ else
+ {
+ channel = pProslic->channel;
+ }
+
+ i=0;
+ if (pRamTable != 0)
+ {
+ while (pRamTable[i].address != 0xffff)
+ {
+ WriteRAM(pProslic,channel,pRamTable[i].address,pRamTable[i].initValue);
+ i++;
+ }
+ }
+ i=0;
+ if (pRegTable != 0)
+ {
+ while (pRegTable[i].address != 0xff)
+ {
+ WriteReg(pProslic,channel,pRegTable[i].address,pRegTable[i].initValue);
+ i++;
+ }
+ }
+
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: LoadRegTables
+**
+** Description:
+** Generic function to load register/RAM with predefined addr/value
+*/
+
+int ProSLIC_LoadRegTables(proslicChanType_ptr *pProslic,
+ const ProslicRAMInit *pRamTable, const ProslicRegInit *pRegTable, int size)
+{
+ int i;
+ TRACEPRINT(*pProslic, "size = %d\n", size);
+ for (i=0; i<size; i++)
+ {
+ if (pProslic[i]->channelEnable)
+ {
+ ProSLIC_LoadRegTable(pProslic[i],pRamTable,pRegTable,FALSE);
+ }
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_UnsupportedFeatureNoArg(proslicChanType_ptr pProslic,
+ const char *function_name)
+{
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s: unsupported %s was called on channel %d\n", LOGPRINT_PREFIX,
+ function_name, pProslic->channel);
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(function_name);
+#endif
+ return RC_UNSUPPORTED_FEATURE;
+}
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_PSTN_delay_poll
+**
+** Description:
+** Delay function called within PSTN detection functions
+**
+** Return Value:
+** none
+*/
+#ifdef PSTN_DET_ENABLE
+void ProSLIC_PSTN_delay_poll(proslicTestStateType *pState, uInt16 delay)
+{
+ uInt16 delayCount;
+
+ if((delay/PSTN_DET_POLL_RATE) < 2)
+ {
+ delayCount = 0;
+ }
+ else
+ {
+ delayCount = (delay/PSTN_DET_POLL_RATE) - 2;
+ }
+
+ pState->waitIterations++;
+ if((pState->waitIterations == delayCount) || (delayCount == 0))
+ {
+ pState->waitIterations = 0;
+ pState->stage++;
+ }
+}
+#endif
+
+/*****************************************************************************************************/
+/*
+** Function: ProSLIC_Calibrate
+**
+** Description:
+** Performs calibration based on passed ptr to array of
+** desired CALRn settings.
+**
+** Starts calibration on all channels sequentially (not broadcast)
+** and continuously polls for completion. Return error code if
+** CAL_EN does not clear for each enabled channel within the passed
+** timeout period.
+*/
+int ProSLIC_Calibrate(proslicChanType_ptr *pProslic, int maxChan, uInt8 *calr,
+ int maxTime)
+{
+ int i,j, cal_en;
+ int cal_en_chan = 0;
+ int timer = 0;
+
+ TRACEPRINT(*pProslic, "maxChan = %d time = %d\n", maxChan, maxTime );
+
+ if ((*pProslic)->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ for(i = 0; i < maxChan; i++)
+ {
+ if((pProslic[i]->channelEnable)&&(pProslic[i]->channelType == PROSLIC))
+ {
+ for(j = 0; j < 4; j++)
+ {
+ WriteReg(pProslic[i], pProslic[i]->channel, (PROSLIC_REG_CALR0+j), calr[j]);
+ }
+ }
+ }
+
+ /* Wait for calibration to complete */
+ do
+ {
+ cal_en = 0;
+ DelayX(*pProslic, 10);
+ for(i = 0; i < maxChan; i++)
+ {
+ if( (pProslic[i]->channelEnable) && (pProslic[i]->channelType == PROSLIC))
+ {
+ cal_en_chan = ReadReg(pProslic[i], pProslic[i]->channel, PROSLIC_REG_CALR3);
+ if( (cal_en_chan & 0x80) && (timer == maxTime) )
+ {
+ DEBUG_PRINT(pProslic[i], "%sCalibration timed out on channel %d\n",
+ LOGPRINT_PREFIX, pProslic[i]->channel);
+ pProslic[i]->channelEnable = 0;
+ pProslic[i]->error = RC_CAL_TIMEOUT;
+ }
+ cal_en |= cal_en_chan;
+ }
+ }
+ }
+ while( (timer++ <= maxTime) && (cal_en & 0x80) );
+
+ if(timer <= maxTime)
+ {
+ return RC_NONE;
+ }
+ else
+ {
+ return RC_CAL_TIMEOUT;
+ }
+}
+/*****************************************************************************************************/
+/* This function is used by the xxxx_Init_with_Options - do not call this directly... */
+int ProSLIC_ReInit_helper(proslicChanType_ptr *pProslic, int size,
+ initOptionsType init_option, int numChanPerDevice)
+{
+ int i;
+
+ /* Preserve linefeed state.. */
+ for(i = 0; i < size; i++)
+ {
+ pProslic[i]->scratch = ReadReg( pProslic[i], pProslic[i]->channel,
+ PROSLIC_REG_LINEFEED);
+ ProSLIC_PowerDownConverter( pProslic[i] );
+
+ /* Clear MSTRSTAT on a device basis */
+ if( (numChanPerDevice == 1)
+ || ((numChanPerDevice == 2) && ((i&1) == 0) ) )
+ {
+ ProSLIC_WriteReg(pProslic[i], PROSLIC_REG_MSTRSTAT, 0xFF); /* Clear master status register */
+ }
+ }
+
+ DelayX(*pProslic, 10); /* Wait to ensure system is powered down... */
+
+ /* Do a soft reset if reinit is requested...*/
+ if(init_option == INIT_REINIT)
+ {
+ for(i = 0; i < size; i++)
+ {
+ if(numChanPerDevice == 2)
+ {
+ WriteReg(pProslic[i], (pProslic[i])->channel, PROSLIC_REG_RESET,
+ (((pProslic[i])->channel)&1)+1); /* reset 1 channel at a time */
+ }
+ else
+ {
+ WriteReg(pProslic[i], (pProslic[i])->channel, PROSLIC_REG_RESET, 1);
+ }
+
+ pProslic[i]->error = RC_NONE; /* Clear any errors we may have seen in powering down the converter */
+ }
+ DelayX(*pProslic, 100); /* Wait for a soft reset */
+
+ }
+ return RC_NONE;
+}
+
+/*****************************************************************************************************/
+int ProSLIC_SoftReset(proslicChanType_ptr pProslic, uInt16 resetOptions)
+{
+ uInt8 data;
+
+ TRACEPRINT(pProslic, "reset option: %d\n",resetOptions);
+
+ /* We can't use channelType since it may not been set. We assume at least
+ * SWInit was called... */
+ if( pProslic->deviceId->chipType == SI3050 )
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ /* Check if we're in free-run mode, if so abort */
+ data = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_ENHANCE);
+
+ if(data & 0x6)
+ {
+ return RC_PLL_FREERUN_ACTIVE;
+ }
+
+ if(resetOptions & PROSLIC_BCAST_RESET)
+ {
+ return WriteReg(pProslic, PROSLIC_CHAN_BROADCAST, PROSLIC_REG_RESET, (uInt8)(resetOptions & 0xFF));
+ }
+ else
+ {
+ return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_RESET, (uInt8)(resetOptions & 0xFF));
+ }
+}
+
+/*****************************************************************************************************/
+#ifndef DISABLE_TONE_SETUP
+int ProSLIC_ToneGenSetupPtr(proslicChanType_ptr pProslic, ProSLIC_Tone_Cfg *cfg)
+{
+ TRACEPRINT(pProslic, "\n",NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1FREQ, cfg->osc1.freq);
+ WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1AMP, cfg->osc1.amp);
+ WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC1PHAS, cfg->osc1.phas);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TAHI,cfg->osc1.tahi);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TALO,cfg->osc1.talo);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TIHI,cfg->osc1.tihi);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O1TILO,cfg->osc1.tilo);
+
+ WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2FREQ, cfg->osc2.freq);
+ WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2AMP, cfg->osc2.amp);
+ WriteRAM(pProslic, pProslic->channel,PROSLIC_RAM_OSC2PHAS, cfg->osc2.phas);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TAHI,cfg->osc2.tahi);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TALO,cfg->osc2.talo);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TIHI,cfg->osc2.tihi);
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_O2TILO,cfg->osc2.tilo);
+
+
+ WriteReg(pProslic, pProslic->channel,PROSLIC_REG_OMODE,cfg->omode);
+ return RC_NONE;
+}
+#endif /* DISABLE_TONE_SETUP */
+
+/*****************************************************************************************************/
+#ifndef DISABLE_FSK_SETUP
+int ProSLIC_FSKSetupPtr (proslicChanType_ptr pProslic, ProSLIC_FSK_Cfg *cfg)
+{
+ uInt8 data;
+ int i;
+
+ TRACEPRINT(pProslic, "\n",NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDEPTH,
+ 0x08); /* Clear Buffer */
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TAHI,0);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TIHI,0);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TILO,0);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_O1TALO,0x13);
+
+ data = ReadReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE);
+ if (cfg->eightBit)
+ {
+ data |= 0x80;
+ }
+ else
+ {
+ data &= ~(0x80);
+ }
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_FSKDEPTH,cfg->fskdepth);
+ WriteReg(pProslic,pProslic->channel,PROSLIC_REG_OMODE,data);
+
+ for(i = 0; i < 2; i++)
+ {
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSK01+i,cfg->fsk[i]);
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSKAMP0+i,cfg->fskamp[i]);
+ WriteRAM(pProslic,pProslic->channel,PROSLIC_RAM_FSKFREQ0+i,cfg->fskfreq[i]);
+ }
+ return RC_NONE;
+}
+#endif
+
+/*****************************************************************************************************/
+int ProSLIC_EnableFastRingStart(proslicChanType_ptr pProslic, BOOLEAN isEnabled)
+{
+ uInt8 data;
+
+ TRACEPRINT(pProslic, "\n",NULL);
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+#if defined(SI3217X) && !defined(Si3217X_REVC_ONLY)
+ if (pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ if(pProslic->deviceId->chipRev < 2)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+ }
+#endif
+
+ data = ReadReg(pProslic, pProslic->channel, PROSLIC_REG_USERSTAT);
+
+ if( isEnabled )
+ {
+ data |= 8;
+ }
+ else
+ {
+ data &= ~8;
+ }
+
+ return WriteReg(pProslic, pProslic->channel, PROSLIC_REG_USERSTAT, data);
+}
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic_tstin.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic_tstin.c
new file mode 100644
index 0000000..f8f7a99
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/proslic_tstin.c
@@ -0,0 +1,1580 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author(s):
+ * cdp
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the interface file for the ProSLIC test-in functions.
+ *
+ *
+ */
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si_voice_ctrl.h"
+#include "../inc/si_voice_timer_intf.h"
+#include "../inc/proslic.h"
+#include "../config_inc/proslic_api_config.h"
+#include "../inc/proslic_tstin.h"
+
+#ifdef SI3217X
+#include "si3217x.h"
+#include "si3217x_intf.h"
+#endif
+#ifdef SI3218X
+#include "../inc/si3218x.h"
+#include "../inc/si3218x_intf.h"
+#endif
+#ifdef SI3219X
+#include "si3219x.h"
+#include "si3219x_intf.h"
+#endif
+#ifdef SI3226X
+#include "si3226x.h"
+#include "si3226x_intf.h"
+#endif
+#ifdef SI3228X
+#include "si3228x.h"
+#include "si3228x_intf.h"
+#endif
+
+/*
+** Function Pointer Macros
+*/
+#define WriteReg pProslic->deviceId->ctrlInterface->WriteRegister_fptr
+#define ReadReg pProslic->deviceId->ctrlInterface->ReadRegister_fptr
+#define pProHW pProslic->deviceId->ctrlInterface->hCtrl
+#define Reset pProslic->deviceId->ctrlInterface->Reset_fptr
+#define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
+#define pProTimer pProslic->deviceId->ctrlInterface->hTimer
+#define WriteRAM pProslic->deviceId->ctrlInterface->WriteRAM_fptr
+#define ReadRAM pProslic->deviceId->ctrlInterface->ReadRAM_fptr
+#define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
+#define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
+#define SetSemaphore pProslic->deviceId->ctrlInterface->Semaphore_fptr
+
+#define WriteRegX deviceId->ctrlInterface->WriteRegister_fptr
+#define ReadRegX deviceId->ctrlInterface->ReadRegister_fptr
+#define pProHWX deviceId->ctrlInterface->hCtrl
+#define DelayX deviceId->ctrlInterface->Delay_fptr
+#define pProTimerX deviceId->ctrlInterface->hTimer
+#define WriteRAMX deviceId->ctrlInterface->WriteRAM_fptr
+#define ReadRAMX deviceId->ctrlInterface->ReadRAM_fptr
+#define getTimeX deviceId->ctrlInterface->getTime_fptr
+#define TimeElapsedX deviceId->ctrlInterface->timeElapsed_fptr
+
+/*
+* Valid Device Number Ranges
+*/
+
+#define TSTIN_VALID_SI3217X_PART_NUM (pProslic->deviceId->chipType >= SI32171 && pProslic->deviceId->chipType <= SI32179)
+#define TSTIN_VALID_SI3218X_PART_NUM (pProslic->deviceId->chipType >= SI32180 && pProslic->deviceId->chipType <= SI32189)
+#define TSTIN_VALID_SI3219X_PART_NUM (pProslic->deviceId->chipType >= SI32190 && pProslic->deviceId->chipType <= SI32199)
+#define TSTIN_VALID_SI3226X_PART_NUM (pProslic->deviceId->chipType >= SI32260 && pProslic->deviceId->chipType <= SI32269)
+#define TSTIN_VALID_SI3228X_PART_NUM (pProslic->deviceId->chipType >= SI32280 && pProslic->deviceId->chipType <= SI32289)
+
+#define TSTIN_INVALID_PART_NUM !(TSTIN_VALID_SI3217X_PART_NUM ||\
+ TSTIN_VALID_SI3218X_PART_NUM || TSTIN_VALID_SI3219X_PART_NUM ||\
+ TSTIN_VALID_SI3226X_PART_NUM || TSTIN_VALID_SI3228X_PART_NUM)
+
+#define LOGPRINT_PREFIX "ProSLIC:"
+
+ProSLIC_DCfeed_Cfg ringtripTestDCFeedPreset[] =
+{
+ {
+ 0x196038D8L, /* SLOPE_VLIM */
+ 0x1D707651L, /* SLOPE_RFEED */
+ 0x0040A0E0L, /* SLOPE_ILIM */
+ 0x1E07FE48L, /* SLOPE_DELTA1 */
+ 0x1ED62D87L, /* SLOPE_DELTA2 */
+ 0x01A50724L, /* V_VLIM (14.000 v) */
+ 0x016EE54FL, /* V_RFEED (12.200 v) */
+ 0x012CBBF5L, /* V_ILIM (10.000 v) */
+ 0x00AF8C10L, /* CONST_RFEED (10.000 mA) */
+ 0x0045CBBCL, /* CONST_ILIM (15.000 mA) */
+ 0x000D494BL, /* I_VLIM (0.000 mA) */
+ 0x005B0AFBL, /* LCRONHK (10.000 mA) */
+ 0x006D4060L, /* LCROFFHK (12.000 mA) */
+ 0x00008000L, /* LCRDBI (5.000 ms) */
+ 0x0048D595L, /* LONGHITH (8.000 mA) */
+ 0x003FBAE2L, /* LONGLOTH (7.000 mA) */
+ 0x00008000L, /* LONGDBI (5.000 ms) */
+ 0x000F0000L, /* LCRMASK (150.000 ms) */
+ 0x00080000L, /* LCRMASK_POLREV (80.000 ms) */
+ 0x00140000L, /* LCRMASK_STATE (200.000 ms) */
+ 0x00140000L, /* LCRMASK_LINECAP (200.000 ms) */
+ 0x01999999L, /* VCM_OH (25.000 v) */
+ 0x0051EB85L, /* VOV_BAT (5.000 v) */
+ 0x00418937L /* VOV_GND (4.000 v) */
+ }
+};
+
+/*
+** dB lookup table
+*/
+#define DB_TABLE_STEP_SIZE 250
+#define MAX_DB_TABLE 279
+
+static const uInt32 dBTable10_n60 [] =
+{
+ 31623,
+ 30726,
+ 29854,
+ 29007,
+ 28184,
+ 27384,
+ 26607,
+ 25852,
+ 25119,
+ 24406,
+ 23714,
+ 23041,
+ 22387,
+ 21752,
+ 21135,
+ 20535,
+ 19953,
+ 19387,
+ 18836,
+ 18302,
+ 17783,
+ 17278,
+ 16788,
+ 16312,
+ 15849,
+ 15399,
+ 14962,
+ 14538,
+ 14125,
+ 13725,
+ 13335,
+ 12957,
+ 12589,
+ 12232,
+ 11885,
+ 11548,
+ 11220,
+ 10902,
+ 10593,
+ 10292,
+ 10000,
+ 9716,
+ 9441,
+ 9173,
+ 8913,
+ 8660,
+ 8414,
+ 8175,
+ 7943,
+ 7718,
+ 7499,
+ 7286,
+ 7079,
+ 6879,
+ 6683,
+ 6494,
+ 6310,
+ 6131,
+ 5957,
+ 5788,
+ 5623,
+ 5464,
+ 5309,
+ 5158,
+ 5012,
+ 4870,
+ 4732,
+ 4597,
+ 4467,
+ 4340,
+ 4217,
+ 4097,
+ 3981,
+ 3868,
+ 3758,
+ 3652,
+ 3548,
+ 3447,
+ 3350,
+ 3255,
+ 3162,
+ 3073,
+ 2985,
+ 2901,
+ 2818,
+ 2738,
+ 2661,
+ 2585,
+ 2512,
+ 2441,
+ 2371,
+ 2304,
+ 2239,
+ 2175,
+ 2113,
+ 2054,
+ 1995,
+ 1939,
+ 1884,
+ 1830,
+ 1778,
+ 1728,
+ 1679,
+ 1631,
+ 1585,
+ 1540,
+ 1496,
+ 1454,
+ 1413,
+ 1372,
+ 1334,
+ 1296,
+ 1259,
+ 1223,
+ 1189,
+ 1155,
+ 1122,
+ 1090,
+ 1059,
+ 1029,
+ 1000,
+ 972,
+ 944,
+ 917,
+ 891,
+ 866,
+ 841,
+ 818,
+ 794,
+ 772,
+ 750,
+ 729,
+ 708,
+ 688,
+ 668,
+ 649,
+ 631,
+ 613,
+ 596,
+ 579,
+ 562,
+ 546,
+ 531,
+ 516,
+ 501,
+ 487,
+ 473,
+ 460,
+ 447,
+ 434,
+ 422,
+ 410,
+ 398,
+ 387,
+ 376,
+ 365,
+ 355,
+ 345,
+ 335,
+ 325,
+ 316,
+ 307,
+ 299,
+ 290,
+ 282,
+ 274,
+ 266,
+ 259,
+ 251,
+ 244,
+ 237,
+ 230,
+ 224,
+ 218,
+ 211,
+ 205,
+ 200,
+ 194,
+ 188,
+ 183,
+ 178,
+ 173,
+ 168,
+ 163,
+ 158,
+ 154,
+ 150,
+ 145,
+ 141,
+ 137,
+ 133,
+ 130,
+ 126,
+ 122,
+ 119,
+ 115,
+ 112,
+ 109,
+ 106,
+ 103,
+ 100,
+ 97,
+ 94,
+ 92,
+ 89,
+ 87,
+ 84,
+ 82,
+ 79,
+ 77,
+ 75,
+ 73,
+ 71,
+ 69,
+ 67,
+ 65,
+ 63,
+ 61,
+ 60,
+ 58,
+ 56,
+ 55,
+ 53,
+ 52,
+ 50,
+ 49,
+ 47,
+ 46,
+ 45,
+ 43,
+ 42,
+ 41,
+ 40,
+ 39,
+ 38,
+ 37,
+ 35,
+ 34,
+ 33,
+ 33,
+ 32,
+ 31,
+ 30,
+ 29,
+ 28,
+ 27,
+ 27,
+ 26,
+ 25,
+ 24,
+ 24,
+ 23,
+ 22,
+ 22,
+ 21,
+ 21,
+ 20,
+ 19,
+ 19,
+ 18,
+ 18,
+ 17,
+ 17,
+ 16,
+ 16,
+ 15,
+ 15,
+ 15,
+ 14,
+ 14,
+ 13,
+ 13,
+ 13,
+ 12,
+ 12,
+ 12,
+ 11,
+ 11,
+ 11,
+ 10,
+ 10
+};
+
+
+/* *********************************** */
+static int setInternalTestLoad(proslicChanType *pProslic, int connect)
+{
+ ramData ram_save;
+ ramData test_load_addr;
+ ramData test_load_bitmask;
+
+ if(pProslic->deviceId->chipType >= SI32171
+ && pProslic->deviceId->chipType <= SI32179)
+ {
+ test_load_addr = 1516;
+ test_load_bitmask = 0x00800000L; /* bit 23 */
+ }
+ else
+ {
+ test_load_addr = 1611;
+ test_load_bitmask = 0x00040000L; /* bit 18 */
+ }
+
+ ProSLIC_SetUserMode(pProslic,1,0);
+ ram_save = ProSLIC_ReadRAM(pProslic,test_load_addr);
+
+ if(connect)
+ {
+ ram_save |= test_load_bitmask;
+ }
+ else
+ {
+ ram_save &= ~test_load_bitmask;
+ }
+
+ ProSLIC_WriteRAM(pProslic,test_load_addr,ram_save);
+
+ return RC_NONE;
+}
+
+/* *********************************** */
+static void setup1kHzBandpass(proslicChanType *pProslic)
+{
+ /* 1kHz bandpass - Gain = -1.7055 */
+ ProSLIC_WriteRAM(pProslic, 32, 0x180A50L); /* TESTB0_1 */
+ ProSLIC_WriteRAM(pProslic, 33, 0x0L); /* TESTB1_1 */
+ ProSLIC_WriteRAM(pProslic, 34, 0x1FE7F5B0L);/* TESTB2_1 */
+ ProSLIC_WriteRAM(pProslic, 35, 0xB166220L); /* TESTA1_1 */
+ ProSLIC_WriteRAM(pProslic, 36, 0x185119D0L);/* TESTA2_1 */
+ ProSLIC_WriteRAM(pProslic, 37, 0xAF624E0L); /* TESTB0_2 */
+ ProSLIC_WriteRAM(pProslic, 38, 0x0L); /* TESTB1_2 */
+ ProSLIC_WriteRAM(pProslic, 39, 0xAF624E0L); /* TESTB2_2 */
+ ProSLIC_WriteRAM(pProslic, 40, 0x0L); /* TESTA1_2 */
+ ProSLIC_WriteRAM(pProslic, 41, 0x185119D0L);/* TESTA2_2 */
+ ProSLIC_WriteRAM(pProslic, 42, 0x7C6E410L); /* TESTB0_3 */
+ ProSLIC_WriteRAM(pProslic, 43, 0xAFF8B80L); /* TESTB1_3 */
+ ProSLIC_WriteRAM(pProslic, 44, 0x7C6E410L); /* TESTB2_3 */
+ ProSLIC_WriteRAM(pProslic, 45, 0x14E99DE0L);/* TESTA1_3 */
+ ProSLIC_WriteRAM(pProslic, 46, 0x185119D0L);/* TESTA2_3 */
+ ProSLIC_WriteRAM(pProslic, 50, 0x40000L); /* TESTAVBW */
+ ProSLIC_WriteRAM(pProslic, 49, 0x1F40000L); /* TESTWLN */
+ ProSLIC_WriteRAM(pProslic, 54, 0x0L); /* TESTAVTH */
+ ProSLIC_WriteRAM(pProslic, 53, 0x0L); /* TESTPKTH */
+}
+
+/* *********************************** */
+/* Return value in dB*1000 (mdB) */
+static int32 dBLookup(uInt32 number)
+{
+ int i;
+ uInt32 err;
+
+ if(number >= dBTable10_n60[0])
+ {
+ return 10000; /* out of range - clamp at 10dB */
+ }
+
+ for(i=0; i<MAX_DB_TABLE; i++) /* 139 */
+ {
+ if((number < dBTable10_n60[i])&&(number >= dBTable10_n60[i+1]))
+ {
+ /* See which level it is closest to */
+ err = dBTable10_n60[i] - number;
+ if(err < (number - dBTable10_n60[i+1]))
+ {
+ return (10000 - i*DB_TABLE_STEP_SIZE);
+ }
+ else
+ {
+ return (10000 - (i+1)*DB_TABLE_STEP_SIZE);
+ }
+ }
+ }
+ /* No solution found? Return -60dB */
+ return -60000;
+}
+
+/* *********************************** */
+static int32 readAudioDiagLevel(proslicChanType *pProslic,int32 zero_dbm_mvpk)
+{
+ int32 data;
+
+ data = ProSLIC_ReadRAM(pProslic,47); /* TESTPKO */
+ DEBUG_PRINT(pProslic, "TESTPKO = %d\n", (int)data);
+
+ data /= 40145; /* 2^28 * 0.182 * 10^(Gfilt/20) */
+ data *= 1000;
+ data /= zero_dbm_mvpk;
+ data *= 10;
+
+ return(dBLookup(data));
+}
+
+/* *********************************** */
+static char *applyTestLimits(proslicTestObj *test)
+{
+ if((test->value >= test->lowerLimit)&&(test->value <= test->upperLimit))
+ {
+ test->testResult = RC_TEST_PASSED;
+ return ("PASS");
+ }
+ else
+ {
+ test->testResult = RC_TEST_FAILED;
+ return ("FAIL");
+ }
+}
+
+
+
+/* *********************************** */
+static int logTest(proslicChanType *pProslic,proslicTestObj *test,
+ const char *label)
+{
+ char resultStr[10];
+ SIVOICE_STRCPY(resultStr,applyTestLimits(test));
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : %-14s = %-8d :: %s\n", label, (int)(test->value),
+ resultStr);
+#ifndef ENABLE_DEBUG
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(label);
+#endif
+ return test->testResult;
+
+}
+/* *********************************** */
+static int logStatus(proslicChanType *pProslic, int status,const char *label)
+{
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : %-14s = %d\n", label,status);
+#ifndef ENABLE_DEBUG
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(label);
+ SILABS_UNREFERENCED_PARAMETER(status);
+#endif
+ return RC_NONE;
+}
+
+/* *********************************** */
+static uInt32 Isqrt32(uInt32 num)
+{
+ uInt32 one,res,op;
+
+ op=num;
+ res=0;
+ one = 1L << 30;
+ while(one > op)
+ {
+ one >>=2;
+ }
+
+ while(one !=0)
+ {
+ if(op >= res + one)
+ {
+ op = op - (res + one);
+ res = res + 2*one;
+ }
+ res >>= 1;
+ one >>= 2;
+ }
+
+ return (res);
+}
+
+
+/* *********************************** */
+static int storeDCFeedPreset(proslicChanType *pProslic,ProSLIC_DCfeed_Cfg *cfg,uInt8 preset)
+{
+ cfg[preset].slope_vlim = ProSLIC_ReadRAM(pProslic,634);
+ cfg[preset].slope_rfeed = ProSLIC_ReadRAM(pProslic,635);
+ cfg[preset].slope_ilim = ProSLIC_ReadRAM(pProslic,636);
+ cfg[preset].delta1 = ProSLIC_ReadRAM(pProslic,638);
+ cfg[preset].delta2 = ProSLIC_ReadRAM(pProslic,639);
+ cfg[preset].v_vlim = ProSLIC_ReadRAM(pProslic,640);
+ cfg[preset].v_rfeed = ProSLIC_ReadRAM(pProslic,641);
+ cfg[preset].v_ilim = ProSLIC_ReadRAM(pProslic,642);
+ cfg[preset].const_rfeed = ProSLIC_ReadRAM(pProslic,643);
+ cfg[preset].const_ilim = ProSLIC_ReadRAM(pProslic,644);
+ cfg[preset].i_vlim = ProSLIC_ReadRAM(pProslic,645);
+ cfg[preset].lcronhk = ProSLIC_ReadRAM(pProslic,853);
+ cfg[preset].lcroffhk = ProSLIC_ReadRAM(pProslic,852);
+ cfg[preset].lcrdbi = ProSLIC_ReadRAM(pProslic,701);
+ cfg[preset].longhith = ProSLIC_ReadRAM(pProslic,858);
+ cfg[preset].longloth = ProSLIC_ReadRAM(pProslic,859);
+ cfg[preset].longdbi = ProSLIC_ReadRAM(pProslic,702);
+ cfg[preset].lcrmask = ProSLIC_ReadRAM(pProslic,854);
+ cfg[preset].lcrmask_polrev = ProSLIC_ReadRAM(pProslic,855);
+ cfg[preset].lcrmask_state = ProSLIC_ReadRAM(pProslic,856);
+ cfg[preset].lcrmask_linecap = ProSLIC_ReadRAM(pProslic,857);
+ cfg[preset].vcm_oh = ProSLIC_ReadRAM(pProslic,748);
+ cfg[preset].vov_bat = ProSLIC_ReadRAM(pProslic,752);
+ cfg[preset].vov_gnd = ProSLIC_ReadRAM(pProslic,751);
+
+ return RC_NONE;
+}
+
+
+/* *********************************** */
+int ProSLIC_createTestInObjs(proslicTestInObjType_ptr *pTstin, uInt32 num_objs)
+{
+#ifndef DISABLE_MALLOC
+ *pTstin = SIVOICE_CALLOC(sizeof(proslicTestInObjType),num_objs);
+
+ if(*pTstin == NULL)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s: %s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
+#endif
+ return RC_NO_MEM;
+ }
+
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pTstin);
+ SILABS_UNREFERENCED_PARAMETER(num_objs);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+/* *********************************** */
+int ProSLIC_destroyTestInObjs(proslicTestInObjType_ptr *pTstin)
+{
+#ifndef DISABLE_MALLOC
+ SIVOICE_FREE((proslicTestInObjType_ptr) *pTstin);
+ *pTstin = NULL;
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pTstin);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/* *********************************** */
+int ProSLIC_testInPCMLpbkEnable(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin)
+{
+ uInt8 regData;
+
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check if enabled */
+ if(!pTstin->pcmLpbkTest.testEnable)
+ {
+ return RC_TEST_DISABLED;
+ }
+ /* Return if already enabled */
+ if(pTstin->pcmLpbkTest.pcmLpbkEnabled)
+ {
+ return RC_NONE;
+ }
+
+ /* Store PCM Settings */
+ pTstin->pcmLpbkTest.pcmModeSave = ProSLIC_ReadReg(pProslic,11); /* PCMMODE */
+
+
+ /* Disable PCM bus before changing format */
+ regData = pTstin->pcmLpbkTest.pcmModeSave & ~0x10; /* PCM_EN = 0 */
+ ProSLIC_WriteReg(pProslic,11,regData);
+
+ /* Configure for either 8 or 16bit linear */
+ if(pTstin->pcmLpbkTest.pcm8BitLinear == PCM_8BIT)
+ {
+ regData |= 0x02; /* PCM_FMT[1] = 1 */
+ regData &= ~0x01; /* PCM_FMT[0] = 0 */
+ }
+ else /* PCM_16BIT */
+ {
+ regData |= 0x03; /* PCM_FMT[1:0] = 11 */
+ }
+
+ ProSLIC_WriteReg(pProslic,11,regData);
+
+ /* Enable PCM Loopback */
+ ProSLIC_WriteReg(pProslic,43,0x01); /* LOOPBACK */
+
+ /* Re-enable PCM Bus */
+ ProSLIC_WriteReg(pProslic,11,regData|0x10); /* PCMMODE */
+
+ pTstin->pcmLpbkTest.pcmLpbkEnabled = 1;
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : pcmLpbk : ENABLED\n");
+ return RC_NONE;
+}
+
+/* *********************************** */
+int ProSLIC_testInPCMLpbkDisable(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin)
+{
+ uInt8 regData;
+
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check if enabled */
+ if(!pTstin->pcmLpbkTest.testEnable)
+ {
+ return RC_TEST_DISABLED;
+ }
+
+ /* Return if already disabled */
+ if(!pTstin->pcmLpbkTest.pcmLpbkEnabled)
+ {
+ return RC_NONE;
+ }
+
+ /* Disable PCM Bus */
+ regData = ProSLIC_ReadReg(pProslic,11); /* PCMMODE */
+ ProSLIC_WriteReg(pProslic,11,regData &= ~0x10);
+
+ /* Disable PCM Loopback */
+ ProSLIC_WriteReg(pProslic,43,0);
+
+ /* Restore PCMMODE. Force disabled while changing format */
+ ProSLIC_WriteReg(pProslic,11,pTstin->pcmLpbkTest.pcmModeSave &= ~0x10);
+ ProSLIC_WriteReg(pProslic,11,pTstin->pcmLpbkTest.pcmModeSave);
+
+ pTstin->pcmLpbkTest.pcmLpbkEnabled = 0;
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : pcmLpbk : DISABLED\n");
+ return RC_NONE;
+}
+
+/* *************************************************** */
+
+int ProSLIC_testInDCFeed(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin)
+{
+ uInt8 enhanceRegSave;
+ proslicMonitorType monitor;
+ ramData lcroffhk_save = 0;
+ ramData lcronhk_save = 0;
+
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check if enabled */
+ if(!pTstin->dcFeedTest.testEnable)
+ {
+ return RC_TEST_DISABLED;
+ }
+
+ /* Invalidate last test results */
+ pTstin->dcFeedTest.testDataValid = TSTIN_RESULTS_INVALID;
+
+ /* Verify line not in use */
+ if(ProSLIC_ReadReg(pProslic,34) & 0x02) /* LCR */
+ {
+ DEBUG_PRINT(pProslic, "\nProSLIC : TestIn : DC Feed : Line in Use\n");
+
+ if(pTstin->dcFeedTest.abortIfLineInUse==ABORT_LIU_ENABLED)
+ {
+ return RC_LINE_IN_USE;
+ }
+ }
+
+ /* Disable Powersave */
+ enhanceRegSave = ProSLIC_ReadReg(pProslic,47);
+ ProSLIC_WriteReg(pProslic,47,0x20);
+ Delay(pProTimer,10);
+
+ /* Onhook measurement */
+ ProSLIC_LineMonitor(pProslic,&monitor);
+
+ pTstin->dcFeedTest.dcfeedVtipOnhook.value = monitor.vtip;
+ pTstin->dcFeedTest.dcfeedVringOnhook.value = monitor.vring;
+ pTstin->dcFeedTest.dcfeedVloopOnhook.value = monitor.vtr;
+ pTstin->dcFeedTest.dcfeedVbatOnhook.value = monitor.vbat;
+ pTstin->dcFeedTest.dcfeedItipOnhook.value = monitor.itip;
+ pTstin->dcFeedTest.dcfeedIringOnhook.value = monitor.iring;
+ pTstin->dcFeedTest.dcfeedIloopOnhook.value = monitor.itr;
+ pTstin->dcFeedTest.dcfeedIlongOnhook.value = monitor.ilong;
+
+ /* Modify LCR threshold (optional) before connecting test load */
+ if(pTstin->dcFeedTest.applyLcrThresh == LCR_CHECK_ENABLED)
+ {
+ lcroffhk_save = ProSLIC_ReadRAM(pProslic,852);
+ lcronhk_save = ProSLIC_ReadRAM(pProslic,853);
+ ProSLIC_WriteRAM(pProslic,852,pTstin->dcFeedTest.altLcrOffThresh);
+ ProSLIC_WriteRAM(pProslic,853,pTstin->dcFeedTest.altLcrOnThresh);
+ }
+
+ /* Connect internal test load for 2nd dc feed i/v point */
+ setInternalTestLoad(pProslic,1);
+ Delay(pProTimer,50);
+ /* Offhook measurement */
+ ProSLIC_LineMonitor(pProslic,&monitor);
+
+ pTstin->dcFeedTest.dcfeedVtipOffhook.value = monitor.vtip;
+ pTstin->dcFeedTest.dcfeedVringOffhook.value = monitor.vring;
+ pTstin->dcFeedTest.dcfeedVloopOffhook.value = monitor.vtr;
+ pTstin->dcFeedTest.dcfeedVbatOffhook.value = monitor.vbat;
+ pTstin->dcFeedTest.dcfeedItipOffhook.value = monitor.itip;
+ pTstin->dcFeedTest.dcfeedIringOffhook.value = monitor.iring;
+ pTstin->dcFeedTest.dcfeedIloopOffhook.value = monitor.itr;
+ pTstin->dcFeedTest.dcfeedIlongOffhook.value = monitor.ilong;
+
+ pTstin->dcFeedTest.testResult = RC_TEST_PASSED; /* initialize */
+ /* Read LCR */
+ if(ProSLIC_ReadReg(pProslic,34) & 0x07) /* LCRRTP */
+ {
+ pTstin->dcFeedTest.lcrStatus = 1;
+ }
+ else
+ {
+ pTstin->dcFeedTest.lcrStatus = 0;
+ }
+
+ /* Only fail check if enabled */
+ if(pTstin->dcFeedTest.applyLcrThresh == LCR_CHECK_ENABLED)
+ {
+ pTstin->dcFeedTest.testResult |= !pTstin->dcFeedTest.lcrStatus;
+ }
+
+ /* Disconnect Test Load */
+ setInternalTestLoad(pProslic,0);
+
+ /* Restore LCR thresholds */
+ if(pTstin->dcFeedTest.applyLcrThresh == LCR_CHECK_ENABLED)
+ {
+ ProSLIC_WriteRAM(pProslic,852,lcroffhk_save);
+ ProSLIC_WriteRAM(pProslic,853,lcronhk_save);
+ }
+
+ /* Restore enhance reg */
+ ProSLIC_WriteReg(pProslic,47,enhanceRegSave);
+
+ /* Process Results */
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVtipOnhook),"DcFeed : Vtip Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVringOnhook),"DcFeed : Vring Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVloopOnhook),"DcFeed : Vloop Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVbatOnhook),"DcFeed : Vbat Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedItipOnhook),"DcFeed : Itip Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedIringOnhook),"DcFeed : Iring Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedIloopOnhook),"DcFeed : Iloop Onhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedIlongOnhook),"DcFeed : Ilong Onhook");
+
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVtipOffhook),"DcFeed : Vtip Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVringOffhook),"DcFeed : Vring Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVloopOffhook),"DcFeed : Vloop Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedVbatOffhook),"DcFeed : Vbat Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedItipOffhook),"DcFeed : Itip Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedIringOffhook),"DcFeed : Iring Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedIloopOffhook),"DcFeed : Iloop Offhook");
+ pTstin->dcFeedTest.testResult |= logTest(pProslic,
+ &(pTstin->dcFeedTest.dcfeedIlongOffhook),"DcFeed : Ilong Offhook");
+
+ logStatus(pProslic,pTstin->dcFeedTest.lcrStatus,"DcFeed : LCR");
+
+
+ pTstin->dcFeedTest.testDataValid = 1; /* New valid results */
+
+ /* return cumulative pass/fail result */
+
+ return (pTstin->dcFeedTest.testResult);
+}
+
+/* *********************************** */
+int ProSLIC_testInRinging(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin)
+{
+ uInt8 ringcon_save,enhance_save;
+ int32 vtr[MAX_RINGING_SAMPLES];
+ int i;
+ uInt8 lf;
+ uInt32 rtper_save, ringfr_save,ringamp_save,ringof_save,rtacth_save,rtdcth_save;
+ ProSLIC_DCfeed_Cfg dcfeedCfg[1];
+
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check if enabled */
+ if( (!pTstin->ringingTest.testEnable)
+ || (pTstin->ringingTest.numSamples == 0) )
+ {
+ return RC_TEST_DISABLED;
+ }
+
+ /* Verify line not in use */
+ if(ProSLIC_ReadReg(pProslic,34) & 0x02) /* LCR */
+ {
+ DEBUG_PRINT(pProslic, "\nProSLIC : TestIn : Ringing : Line in Use\n");
+
+ if(pTstin->ringingTest.abortIfLineInUse)
+ {
+ return RC_LINE_IN_USE;
+ }
+ }
+
+ /* Invalidate last test results */
+ pTstin->ringingTest.testDataValid = TSTIN_RESULTS_INVALID;
+
+ /* Check sample size/rate */
+ if(pTstin->ringingTest.numSamples > MAX_RINGING_SAMPLES)
+ {
+ pTstin->ringingTest.numSamples = MAX_RINGING_SAMPLES;
+ }
+
+ if(pTstin->ringingTest.sampleInterval > MAX_RINGING_SAMPLE_INTERVAL)
+ {
+ pTstin->ringingTest.sampleInterval = MAX_RINGING_SAMPLE_INTERVAL;
+ }
+
+ if(pTstin->ringingTest.sampleInterval < MIN_RINGING_SAMPLE_INTERVAL)
+ {
+ pTstin->ringingTest.sampleInterval = MIN_RINGING_SAMPLE_INTERVAL;
+ }
+
+ /* Disable Powersave */
+ enhance_save = ProSLIC_ReadReg(pProslic,47);
+ ProSLIC_WriteReg(pProslic,47,0x20);
+ Delay(pProTimer,10);
+
+ /* Disable ring cadencing */
+ ringcon_save = ProSLIC_ReadReg(pProslic,38); /* RINGCON */
+ ProSLIC_WriteReg(pProslic,38,ringcon_save&0xE7); /* RINGCON */
+
+ /* Must enter ringing through active state */
+ lf = ProSLIC_ReadReg(pProslic,30); /* LINEFEED */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ Delay(pProTimer,20); /* settle */
+
+ /* Start ringing */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_RINGING);
+ Delay(pProTimer,500);
+
+ /* Verify Ring Started */
+ if(ProSLIC_ReadReg(pProslic,30) != 0x44)
+ {
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
+ ProSLIC_WriteReg(pProslic,38,ringcon_save);
+ ProSLIC_WriteReg(pProslic,47,enhance_save);
+ ProSLIC_SetLinefeedStatus(pProslic,lf);
+
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : Ringing : Ring Start Fail\n");
+
+ pTstin->ringingTest.testResult = RC_TEST_FAILED;
+ return RC_RING_START_FAIL;
+ }
+
+ /* Capture samples */
+ pTstin->ringingTest.ringingVdc.value = 0;
+ for(i=0; i<pTstin->ringingTest.numSamples; i++)
+ {
+ vtr[i] = ProSLIC_ReadMADCScaled(pProslic,69,0); /* VDIFF_FILT */
+ pTstin->ringingTest.ringingVdc.value += vtr[i];
+
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : Ringing : Vtr[%d] = %d\n",i, (int)(vtr[i]));
+
+ Delay(pProTimer,pTstin->ringingTest.sampleInterval);
+ }
+
+ /* Restore linefeed */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ Delay(pProTimer,20);
+
+ /* Process Results */
+ pTstin->ringingTest.ringingVdc.value /= pTstin->ringingTest.numSamples;
+ for(i=0; i<pTstin->ringingTest.numSamples; i++)
+ {
+ vtr[i] -= pTstin->ringingTest.ringingVdc.value;
+ pTstin->ringingTest.ringingVac.value += ((vtr[i]/100L) * (vtr[i]/100L));
+ }
+
+
+ pTstin->ringingTest.ringingVac.value /= pTstin->ringingTest.numSamples;
+ pTstin->ringingTest.ringingVac.value = Isqrt32(
+ pTstin->ringingTest.ringingVac.value);
+ pTstin->ringingTest.ringingVac.value *= 100L;
+
+ pTstin->ringingTest.testResult = RC_TEST_PASSED;
+ pTstin->ringingTest.testResult |= logTest(pProslic,
+ &(pTstin->ringingTest.ringingVdc),"Ringing : VDC");
+ pTstin->ringingTest.testResult |= logTest(pProslic,
+ &(pTstin->ringingTest.ringingVac),"Ringing : VAC");
+ /*
+ ** Optional Ringtrip Test
+ */
+
+ if(pTstin->ringingTest.ringtripTestEnable == RTP_CHECK_ENABLED)
+ {
+ /* Setup low voltage linefeed so low level ringing may be used */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
+ storeDCFeedPreset(pProslic,&(dcfeedCfg[0]),0);
+ ProSLIC_DCFeedSetupCfg(pProslic,&(ringtripTestDCFeedPreset[0]),0);
+
+ /* Optional Ringtrip Test (modified ringer settings to use test load to trip) */
+ rtper_save = ProSLIC_ReadRAM(pProslic,755);
+ ringfr_save = ProSLIC_ReadRAM(pProslic,844);
+ ringamp_save = ProSLIC_ReadRAM(pProslic,845);
+ ringof_save = ProSLIC_ReadRAM(pProslic,843);
+ rtacth_save = ProSLIC_ReadRAM(pProslic,848);
+ rtdcth_save = ProSLIC_ReadRAM(pProslic,847);
+
+ ProSLIC_WriteRAM(pProslic,755,0x50000L); /* RTPER */
+ ProSLIC_WriteRAM(pProslic,844,0x7EFE000L);/* RINGFR */
+ ProSLIC_WriteRAM(pProslic,845,0xD6307L); /* RINGAMP */
+ ProSLIC_WriteRAM(pProslic,843,0x0L); /* RINGOF */
+ ProSLIC_WriteRAM(pProslic,848,0x7827FL); /* RTACTH */
+ ProSLIC_WriteRAM(pProslic,847,0xFFFFFFFL);/* RTDCTH */
+
+ /* Start ringing from active state */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ Delay(pProTimer,20);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_RINGING);
+ Delay(pProTimer,200);
+
+ /* Verify Ring Started */
+ if(ProSLIC_ReadReg(pProslic,30) != 0x44)
+ {
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
+ ProSLIC_WriteReg(pProslic,38,ringcon_save);
+ ProSLIC_WriteReg(pProslic,47,enhance_save);
+
+ /* Restore DC Feed */
+ ProSLIC_DCFeedSetupCfg(pProslic,&(dcfeedCfg[0]),0);
+
+ /* Restore Ring Settings */
+ ProSLIC_WriteRAM(pProslic,755,rtper_save); /* RTPER */
+ ProSLIC_WriteRAM(pProslic,844,ringfr_save); /*RINGFR */
+ ProSLIC_WriteRAM(pProslic,845,ringamp_save); /* RINGAMP */
+ ProSLIC_WriteRAM(pProslic,843,ringof_save); /* RINGOF */
+ ProSLIC_WriteRAM(pProslic,848,rtacth_save); /* RTACTH */
+ ProSLIC_WriteRAM(pProslic,847,rtdcth_save); /* RTDCTH */
+
+ ProSLIC_SetLinefeedStatus(pProslic,lf);
+
+ DEBUG_PRINT(pProslic, "ProSLIC : TestIn : Ringtrip : Ring Start Fail\n");
+
+ pTstin->ringingTest.testResult=RC_TEST_FAILED;
+ return RC_RING_START_FAIL;
+ }
+
+ /* Connect Test Load to cause ringtrip */
+ setInternalTestLoad(pProslic,1);
+ Delay(pProTimer,200);
+
+ /* Check for RTP */
+ if(ProSLIC_ReadReg(pProslic,34) & 0x01) /* LCRRTP */
+ {
+ pTstin->ringingTest.rtpStatus = 1;
+ pTstin->ringingTest.testResult |= RC_TEST_PASSED;
+ }
+ else
+ {
+ pTstin->ringingTest.rtpStatus = 0;
+ pTstin->ringingTest.testResult |= RC_TEST_FAILED;
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ }
+ setInternalTestLoad(pProslic,0);
+ Delay(pProTimer,20);
+
+ logStatus(pProslic,pTstin->ringingTest.rtpStatus,"Ringing : RTP");
+
+ /* Restore DC Feed */
+ ProSLIC_DCFeedSetupCfg(pProslic,&(dcfeedCfg[0]),0);
+
+ /* Restore Ring Settings */
+ ProSLIC_WriteRAM(pProslic,755,rtper_save);/* RTPER */
+ ProSLIC_WriteRAM(pProslic,844,ringfr_save);/*RINGFR */
+ ProSLIC_WriteRAM(pProslic,845,ringamp_save); /* RINGAMP */
+ ProSLIC_WriteRAM(pProslic,843,ringof_save); /* RINGOF */
+ ProSLIC_WriteRAM(pProslic,848,rtacth_save);/* RTACTH */
+ ProSLIC_WriteRAM(pProslic,847,rtdcth_save);/* RTDCTH */
+
+ }/* end of ringtrip test */
+
+ /* Restore Linefeed */
+ ProSLIC_SetLinefeedStatus(pProslic,lf);
+
+ /* Restore RINGCON and ENHANCE */
+ ProSLIC_WriteReg(pProslic,38,ringcon_save);
+ ProSLIC_WriteReg(pProslic,47,enhance_save);
+
+ pTstin->ringingTest.testDataValid = TSTIN_RESULTS_VALID;
+
+ return (pTstin->ringingTest.testResult);
+}
+
+/* *********************************** */
+int ProSLIC_testInBattery(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin)
+{
+ proslicMonitorType monitor;
+
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check if enabled */
+ if(!pTstin->batteryTest.testEnable)
+ {
+ return RC_TEST_DISABLED;
+ }
+
+ /* Invalidate last test results */
+ pTstin->batteryTest.testDataValid = TSTIN_RESULTS_INVALID;
+
+ /* Measure Battery */
+ ProSLIC_LineMonitor(pProslic,&monitor);
+
+ pTstin->batteryTest.vbat.value = monitor.vbat;
+
+ pTstin->batteryTest.testResult = logTest(pProslic,&(pTstin->batteryTest.vbat),
+ "Battery : VBAT");
+
+ pTstin->batteryTest.testDataValid =
+ TSTIN_RESULTS_VALID; /* New valid results */
+
+ return (pTstin->batteryTest.testResult);
+}
+
+/* *********************************** */
+int ProSLIC_testInAudio(proslicChanType *pProslic, proslicTestInObjType *pTstin)
+{
+ uInt8 enhanceRegSave;
+ uInt8 lf;
+ int32 data;
+ int32 gainMeas1,gainMeas2;
+ int32 gainMeas3 = 0;
+ ProSLIC_audioGain_Cfg gainCfg;
+ int32 Pin = -3980; /* -10dBm + 6.02dB (since OHT w/ no AC load) */
+
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Check if enabled */
+ if(!pTstin->audioTest.testEnable)
+ {
+ return RC_TEST_DISABLED;
+ }
+
+ /* Invalidate last test results */
+ pTstin->audioTest.testDataValid = TSTIN_RESULTS_INVALID;
+
+ /* Verify line not in use */
+ if(ProSLIC_ReadReg(pProslic,34) & 0x02) /* LCR */
+ {
+ DEBUG_PRINT(pProslic, "\nProSLIC : TestIn : Audio : Line in Use\n");
+
+ if(pTstin->audioTest.abortIfLineInUse == ABORT_LIU_ENABLED)
+ {
+ return RC_LINE_IN_USE;
+ }
+ }
+
+ /* Disable Powersave */
+ enhanceRegSave = ProSLIC_ReadReg(pProslic,47);
+ ProSLIC_WriteReg(pProslic,47,0x20);
+ Delay(pProTimer,10);
+
+
+ /* Setup Audio Filter, enable audio in OHT */
+ lf = ProSLIC_ReadReg(pProslic,30); /* LINEFEED */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ Delay(pProTimer,20); /* settle */
+ setup1kHzBandpass(pProslic);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_OHT);
+
+ /* Setup osc1 for 1kHz -10dBm tone, disable hybrid, enable filters */
+ ProSLIC_WriteRAM(pProslic,26,0x5A80000L); /* OSC1FREQ */
+ ProSLIC_WriteRAM(pProslic,27,0x5D8000L); /* OSC1AMP */
+ ProSLIC_WriteReg(pProslic,48,0x02); /* OMODE */
+ ProSLIC_WriteReg(pProslic,49,0x01); /* OCON */
+ ProSLIC_WriteReg(pProslic,44,0x10); /* DIGCON */
+ ProSLIC_WriteReg(pProslic,71,0x10); /* DIAG1 */
+
+ /* Settle */
+ Delay(pProTimer,800);
+
+ /* Read first gain measurement (Gtx + Grx + Gzadj) */
+ gainMeas1 = readAudioDiagLevel(pProslic,pTstin->audioTest.zerodBm_mVpk);
+
+ /* Bypass TXACHPF and set TXACEQ to unity */
+ gainCfg.acgain = ProSLIC_ReadRAM(pProslic,544); /* TXACGAIN */
+ gainCfg.aceq_c0 = ProSLIC_ReadRAM(pProslic,540); /* TXACEQ_C0 */
+ gainCfg.aceq_c1 = ProSLIC_ReadRAM(pProslic,541); /* TXACEQ_C1 */
+ gainCfg.aceq_c2 = ProSLIC_ReadRAM(pProslic,542); /* TXACEQ_C2 */
+ gainCfg.aceq_c3 = ProSLIC_ReadRAM(pProslic,543); /* TXACEQ_C3 */
+ ProSLIC_WriteRAM(pProslic,544,0x8000000L);
+ ProSLIC_WriteRAM(pProslic,543,0x0L);
+ ProSLIC_WriteRAM(pProslic,542,0x0L);
+ ProSLIC_WriteRAM(pProslic,541,0x0L);
+ ProSLIC_WriteRAM(pProslic,540,0x8000000L);
+ ProSLIC_WriteReg(pProslic,44,0x18);
+
+ /* Settle */
+ Delay(pProTimer,800);
+
+ /* Read second level measurement (RX level only) */
+ gainMeas2 = readAudioDiagLevel(pProslic,pTstin->audioTest.zerodBm_mVpk);
+
+ /* Adjust txgain if TXACGAIN wasn't unity during gainMeas1 */
+ if(gainCfg.acgain != 0x8000000L)
+ {
+ data = (gainCfg.acgain*10)/134217;
+ gainMeas3 = dBLookup(data);
+ }
+
+ /* Computations */
+ pTstin->audioTest.rxGain.value = gainMeas2 - Pin;
+ pTstin->audioTest.txGain.value = gainMeas1 - gainMeas2 + gainMeas3;
+
+#ifdef ENABLE_DEBUG
+ if( DEBUG_ENABLED(pProslic) )
+ {
+ LOGPRINT("ProSLIC : TestIn : Audio : gainMeas1 = %d\n", (int)gainMeas1);
+ LOGPRINT("ProSLIC : TestIn : Audio : gainMeas2 = %d\n", (int)gainMeas2);
+ LOGPRINT("ProSLIC : TestIn : Audio : gainMeas3 = %d\n", (int)gainMeas3);
+ }
+#endif
+ pTstin->audioTest.testResult = RC_TEST_PASSED;
+ pTstin->audioTest.testResult |= logTest(pProslic,&(pTstin->audioTest.rxGain),
+ "RX Path Gain");
+ pTstin->audioTest.testResult |= logTest(pProslic,&(pTstin->audioTest.txGain),
+ "TX Path Gain");
+
+
+
+ /*
+ ** Restore
+ */
+
+ /* Need to store/restore all modified reg/RAM */
+ ProSLIC_WriteRAM(pProslic,544,gainCfg.acgain);
+ ProSLIC_WriteRAM(pProslic,540,gainCfg.aceq_c0);
+ ProSLIC_WriteRAM(pProslic,541,gainCfg.aceq_c1);
+ ProSLIC_WriteRAM(pProslic,542,gainCfg.aceq_c2);
+ ProSLIC_WriteRAM(pProslic,543,gainCfg.aceq_c3);
+
+ ProSLIC_WriteReg(pProslic,71,0x0); /* DIAG1 */
+ ProSLIC_WriteReg(pProslic,44,0x0); /* DIGCON */
+ ProSLIC_WriteReg(pProslic,48,0x0); /* OMODE */
+ ProSLIC_WriteReg(pProslic,49,0x0); /* OCON */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ ProSLIC_WriteReg(pProslic,47,enhanceRegSave);
+ ProSLIC_SetLinefeedStatus(pProslic,lf);
+
+ /* Validate last test results */
+ pTstin->audioTest.testDataValid = TSTIN_RESULTS_VALID;
+
+ return pTstin->audioTest.testResult;
+}
+
+
+/* *********************************** */
+
+int ProSLIC_testInPcmLpbkSetup(proslicTestInObjType *pTstin,
+ proslicPcmLpbkTest *pcmLpbkTest)
+{
+ pTstin->pcmLpbkTest = *pcmLpbkTest;
+ pTstin->pcmLpbkTest.testEnable = 1;
+
+ return RC_NONE;
+}
+
+/* *********************************** */
+
+int ProSLIC_testInDcFeedSetup(proslicTestInObjType *pTstin,
+ proslicDcFeedTest *dcFeedTest)
+{
+ pTstin->dcFeedTest = *dcFeedTest;
+ pTstin->dcFeedTest.testEnable = 1;
+
+ return RC_NONE;
+}
+
+/* *********************************** */
+
+int ProSLIC_testInRingingSetup(proslicTestInObjType *pTstin,
+ proslicRingingTest *ringingTest)
+{
+ /* Copy limits per-channel */
+
+ pTstin->ringingTest = *ringingTest;
+ pTstin->ringingTest.testEnable = 1;
+
+ return RC_NONE;
+}
+/* *********************************** */
+
+int ProSLIC_testInBatterySetup(proslicTestInObjType *pTstin,
+ proslicBatteryTest *batteryTest)
+{
+ /* Copy limits per-channel */
+
+ pTstin->batteryTest = *batteryTest;
+ pTstin->batteryTest.testEnable = 1;
+
+ return RC_NONE;
+}
+
+/* *********************************** */
+
+int ProSLIC_testInAudioSetup(proslicTestInObjType *pTstin,
+ proslicAudioTest *audioTest)
+{
+ /* Copy limits per-channel */
+
+ pTstin->audioTest = *audioTest;
+ pTstin->audioTest.testEnable = 1;
+
+ return RC_NONE;
+}
+
+
+/* *********************************** */
+int ProSLIC_testInPrintLimits(proslicChanType *pProslic,
+ proslicTestInObjType *pTstin)
+{
+ /* Valid device check */
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+#ifdef ENABLE_DEBUG
+ if( DEBUG_ENABLED(pProslic ) )
+ {
+ LOGPRINT("\n");
+ LOGPRINT("************ Test-In Test Limits **************\n");
+ LOGPRINT("----------------------------------------------------------------\n");
+ LOGPRINT("ProSLIC : Test-In : Limits : vtip_on_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVtipOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vtip_on_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVtipOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vring_on_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVringOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vring_on_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVringOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vloop_on_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVloopOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vloop_on_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVloopOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vbat_on_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVbatOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vbat_on_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVbatOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : itip_on_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedItipOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : itip_on_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedItipOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iring_on_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIringOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iring_on_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIringOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iloop_on_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIloopOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iloop_on_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIloopOnhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ilong_on_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIlongOnhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ilong_on_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIlongOnhook.upperLimit));
+ LOGPRINT("----------------------------------------------------------------\n");
+ LOGPRINT("ProSLIC : Test-In : Limits : vtip_off_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVtipOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vtip_off_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVtipOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vring_off_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVringOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vring_off_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVringOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vloop_off_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVloopOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vloop_off_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVloopOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vbat_off_min (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVbatOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : vbat_off_max (mv) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedVbatOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : itip_off_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedItipOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : itip_off_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedItipOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iring_off_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIringOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iring_off_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIringOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iloop_off_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIloopOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : iloop_off_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIloopOffhook.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ilong_off_min (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIlongOffhook.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ilong_off_max (ua) = %d\n",
+ (int)(pTstin->dcFeedTest.dcfeedIlongOffhook.upperLimit));
+ LOGPRINT("----------------------------------------------------------------\n");
+ LOGPRINT("ProSLIC : Test-In : Limits : ringing_vac_min (mv) = %d\n",
+ (int)(pTstin->ringingTest.ringingVac.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ringing_vac_max (mv) = %d\n",
+ (int)(pTstin->ringingTest.ringingVac.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ringing_vdc_min (mv) = %d\n",
+ (int)(pTstin->ringingTest.ringingVdc.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : ringing_vdc_max (mv) = %d\n",
+ (int)(pTstin->ringingTest.ringingVdc.upperLimit));
+ LOGPRINT("----------------------------------------------------------------\n");
+ LOGPRINT("ProSLIC : Test-In : Limits : battery_vbat_min (mv) = %d\n",
+ (int)(pTstin->batteryTest.vbat.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : battery_vbat_max (mv) = %d\n",
+ (int)(pTstin->batteryTest.vbat.upperLimit));
+ LOGPRINT("----------------------------------------------------------------\n");
+ LOGPRINT("ProSLIC : Test-In : Limits : audio_txgain_min (mdB) = %d\n",
+ (int)(pTstin->audioTest.txGain.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : audio_txgain_max (mdB) = %d\n",
+ (int)(pTstin->audioTest.txGain.upperLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : audio_rxgain_min (mdB) = %d\n",
+ (int)(pTstin->audioTest.rxGain.lowerLimit));
+ LOGPRINT("ProSLIC : Test-In : Limits : audio_rxgain_max (mdB) = %d\n",
+ (int)(pTstin->audioTest.rxGain.upperLimit));
+ LOGPRINT("----------------------------------------------------------------\n");
+ LOGPRINT("\n");
+ }
+#else
+ SILABS_UNREFERENCED_PARAMETER(pTstin);
+#endif
+ return RC_NONE;
+}
+
+
+static ProSLIC_DCfeed_Cfg testLoad_DC_Cfg[] =
+{
+ {
+ 0x1DC6E1D3L, /* SLOPE_VLIM */
+ 0x1F909679L, /* SLOPE_RFEED */
+ 0x0040A0E0L, /* SLOPE_ILIM */
+ 0x1B8687BBL, /* SLOPE_DELTA1 */
+ 0x1CC4B75DL, /* SLOPE_DELTA2 */
+ 0x05A38633L, /* V_VLIM (48.000 v) */
+ 0x050D2839L, /* V_RFEED (43.000 v) */
+ 0x03FE7F0FL, /* V_ILIM (34.000 v) */
+ 0x009DAFD9L, /* CONST_RFEED (10.000 mA) */
+ 0x0045CBBCL, /* CONST_ILIM (15.000 mA) */
+ 0x002D8D96L, /* I_VLIM (0.000 mA) */
+ 0x005B0AFBL, /* LCRONHK (10.000 mA) */
+ 0x006D4060L, /* LCROFFHK (12.000 mA) */
+ 0x00008000L, /* LCRDBI (5.000 ms) */
+ 0x0048D595L, /* LONGHITH (8.000 mA) */
+ 0x003FBAE2L, /* LONGLOTH (7.000 mA) */
+ 0x00008000L, /* LONGDBI (5.000 ms) */
+ 0x000F0000L, /* LCRMASK (150.000 ms) */
+ 0x00080000L, /* LCRMASK_POLREV (80.000 ms) */
+ 0x00140000L, /* LCRMASK_STATE (200.000 ms) */
+ 0x00140000L, /* LCRMASK_LINECAP (200.000 ms) */
+ 0x01BA5E35L, /* VCM_OH (27.000 v) */
+ 0x0051EB85L, /* VOV_BAT (5.000 v) */
+ 0x00418937L, /* VOV_GND (4.000 v) */
+ }
+};
+
+/* *********************************** */
+int ProSLIC_testLoadTest(
+ SiVoiceChanType_ptr pProslic,
+ BOOLEAN is_testStart,
+ uint32_t timeDelayMsec)
+{
+ static ProSLIC_DCfeed_Cfg dcfeedCfg;
+ static uInt8 digcon_reg_cache;
+
+ TRACEPRINT(pProslic, " channel: %u is_testStart: %u delay = %u",
+ pProslic->channel,
+ is_testStart,
+ timeOffhookMsec);
+ /* Valid device check */
+
+ if(TSTIN_INVALID_PART_NUM)
+ {
+ return RC_UNSUPPORTED_FEATURE;
+ }
+
+ if( TRUE == is_testStart )
+ {
+ /* Verify line not in use */
+ if(ProSLIC_ReadReg(pProslic,PROSLIC_REG_LCRRTP) & 0x02) /* LCR */
+ {
+ DEBUG_PRINT(pProslic, "\nLine in Use: %u.\n", pProslic->channel);
+ return RC_LINE_IN_USE;
+ }
+
+ /* Setup lower ILIM linefeed */
+ ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
+ storeDCFeedPreset(pProslic, &dcfeedCfg, 0);
+
+ ProSLIC_DCFeedSetupCfg( pProslic, testLoad_DC_Cfg, 0 );
+
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ Delay(pProTimer,100);
+
+ /* Connect Test Load to cause LCR interrupt*/
+ setInternalTestLoad(pProslic,1);
+ Delay(pProTimer, timeDelayMsec);
+ DEBUG_PRINT(pProslic, "\n%s: test load on for channel %u\n",
+ __FUNCTION__, pProslic->channel);
+
+ /* Disable hybrid circuit for test load loopback */
+ digcon_reg_cache = ProSLIC_ReadReg(pProslic,PROSLIC_REG_DIGCON);
+
+ ProSLIC_WriteReg(pProslic, PROSLIC_REG_DIGCON,
+ digcon_reg_cache |0x10 );
+
+ /* At this point the test load should of caused a LCR interrupt and
+ there is an audio path available. NOTE: there may be some distortion
+ of the audio...
+ */
+
+ }
+ else
+ {
+ /* Restore hybrid circuit */
+ ProSLIC_WriteReg(pProslic,
+ PROSLIC_REG_DIGCON, digcon_reg_cache );
+
+ /* Disconnect Test Load */
+ setInternalTestLoad(pProslic,0);
+ Delay(pProTimer, timeDelayMsec);
+ DEBUG_PRINT(pProslic, "\n%s: test load off for channel %u.\n",
+ __FUNCTION__, pProslic->channel);
+
+ /* Restore DC Feed */
+ ProSLIC_DCFeedSetupCfg(pProslic, &dcfeedCfg, 0);
+ }
+
+ return RC_NONE;
+}
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si3218x_LCCB_constants.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si3218x_LCCB_constants.c
new file mode 100644
index 0000000..ad948e9
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si3218x_LCCB_constants.c
@@ -0,0 +1,686 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Si3218x ProSLIC API Configuration Tool Version 4.2.1
+ * Last Updated in API Release: 9.2.0
+ * source XML file: si3218x_LCCB_constants.xml
+ *
+ * Auto generated file from configuration tool.
+ */
+
+
+#include "../inc/proslic.h"
+#include "../inc/si3218x.h"
+
+Si3218x_General_Cfg Si3218x_General_Configuration = {
+0x72, /* DEVICE_KEY */
+BO_DCDC_LCCB, /* BOM_OPT */
+VDC_4P5_16P0, /* VDC_RANGE_OPT */
+AUTO_ZCAL_ENABLED, /* ZCAL_ENABLE */
+BO_STD_BOM, /* PM_BOM */
+0x00000000L, /* DCDC_OITHRESH_LO */
+0x01A00000L, /* DCDC_OITHRESH_HI */
+0x00A00000L, /* DCDC_OVTHRESH */
+5000L, /* DCDC_UVTHRESH */
+1000L, /* DCDC_UVHYST */
+0x00000000L, /* DCDC_FSW_VTHLO */
+0x00000000L, /* DCDC_FSW_VHYST */
+0x0048D15BL, /* P_TH_HVIC */
+0x07FEB800L, /* COEF_P_HVIC */
+0x00083120L, /* BAT_HYST */
+0x03D70A20L, /* VBATH_EXPECT (60.00V) */
+0x06666635L, /* VBATR_EXPECT (100.00V) */
+0x0FFF0000L, /* PWRSAVE_TIMER */
+0x01999A00L, /* OFFHOOK_THRESH */
+0x00F00000L, /* VBAT_TRACK_MIN */
+0x00F00000L, /* VBAT_TRACK_MIN_RNG */
+0x0ADD5500L, /* DCDC_ANA_SCALE */
+0x00800000L, /* THERM_DBI */
+0x00FFFFFFL, /* VOV_DCDC_SLOPE */
+0x00A18937L, /* VOV_DCDC_OS */
+0x00A18937L, /* VOV_RING_BAT_DCDC */
+0x00E49BA5L, /* VOV_RING_BAT_MAX */
+0x01018900L, /* DCDC_VERR */
+0x0080C480L, /* DCDC_VERR_HYST */
+0x00400000L, /* PD_UVLO */
+0x00400000L, /* PD_OVLO */
+0x00200000L, /* PD_OCLO */
+0x00400000L, /* PD_SWDRV */
+0x00000000L, /* DCDC_UVPOL */
+0x00200000L, /* DCDC_RNGTYPE */
+0x00180000L, /* DCDC_ANA_TOFF */
+0x00100000L, /* DCDC_ANA_TONMIN */
+0x012FC000L, /* DCDC_ANA_TONMAX */
+0x50, /* IRQEN1 */
+0x13, /* IRQEN2 */
+0x03, /* IRQEN3 */
+0x00, /* IRQEN4 */
+0x30, /* ENHANCE */
+0x3F, /* AUTO */
+};
+
+Si3218x_audioGain_Cfg Si3218x_audioGain_Presets [] = {
+{0x1377080L,0, 0x0L, 0x0L, 0x0L, 0x0L},
+{0x80C3180L,0, 0x0L, 0x0L, 0x0L, 0x0L}
+};
+
+Si3218x_Ring_Cfg Si3218x_Ring_Presets[] ={
+{
+/*
+ Loop = 500.0 ft @ 0.044 ohms/ft, REN = 3, Rcpe = 600 ohms
+ Rprot = 54 ohms, Type = LPR, Waveform = SINE
+*/
+0x00050000L, /* RTPER */
+0x07EFE000L, /* RINGFR (20.000 Hz) */
+0x00209380L, /* RINGAMP (55.000 vrms) */
+0x00000000L, /* RINGPHAS */
+0x00000000L, /* RINGOF (0.000 vdc) */
+0x15E5200EL, /* SLOPE_RING (100.000 ohms) */
+0x006C94D6L, /* IRING_LIM (70.000 mA) */
+0x00522220L, /* RTACTH (45.357 mA) */
+0x0FFFFFFFL, /* RTDCTH (450.000 mA) */
+0x00006000L, /* RTACDB (75.000 ms) */
+0x00006000L, /* RTDCDB (75.000 ms) */
+0x0051EB82L, /* VOV_RING_BAT (5.000 v) */
+0x00000000L, /* VOV_RING_GND (0.000 v) */
+0x05B835EFL, /* VBATR_EXPECT (89.368 v) */
+0x80, /* RINGTALO (2.000 s) */
+0x3E, /* RINGTAHI */
+0x00, /* RINGTILO (4.000 s) */
+0x7D, /* RINGTIHI */
+0x00000000L, /* ADAP_RING_MIN_I */
+0x00003000L, /* COUNTER_IRING_VAL */
+0x00051EB8L, /* COUNTER_VTR_VAL */
+0x00000000L, /* CONST_028 */
+0x00000000L, /* CONST_032 */
+0x00000000L, /* CONST_038 */
+0x00000000L, /* CONST_046 */
+0x00000000L, /* RRD_DELAY */
+0x00000000L, /* RRD_DELAY2 */
+0x01893740L, /* VBAT_TRACK_MIN_RNG */
+0x98, /* RINGCON */
+0x00, /* USERSTAT */
+0x02DC1AF7L, /* VCM_RING (43.434 v) */
+0x02DC1AF7L, /* VCM_RING_FIXED */
+0x003126E8L, /* DELTA_VCM */
+0x00200000L, /* DCDC_RNGTYPE */
+}, /* DEFAULT_RINGING */
+{
+/*
+ Loop = 500.0 ft @ 0.044 ohms/ft, REN = 5, Rcpe = 600 ohms
+ Rprot = 54 ohms, Type = LPR, Waveform = SINE
+*/
+0x00050000L, /* RTPER */
+0x07EFE000L, /* RINGFR (20.000 Hz) */
+0x001C0AFCL, /* RINGAMP (45.000 vrms) */
+0x00000000L, /* RINGPHAS */
+0x00000000L, /* RINGOF (0.000 vdc) */
+0x15E5200EL, /* SLOPE_RING (100.000 ohms) */
+0x006C94D6L, /* IRING_LIM (70.000 mA) */
+0x0068A9B9L, /* RTACTH (57.798 mA) */
+0x0FFFFFFFL, /* RTDCTH (450.000 mA) */
+0x00006000L, /* RTACDB (75.000 ms) */
+0x00006000L, /* RTDCDB (75.000 ms) */
+0x0051EB82L, /* VOV_RING_BAT (5.000 v) */
+0x00000000L, /* VOV_RING_GND (0.000 v) */
+0x04F7DA57L, /* VBATR_EXPECT (77.628 v) */
+0x80, /* RINGTALO (2.000 s) */
+0x3E, /* RINGTAHI */
+0x00, /* RINGTILO (4.000 s) */
+0x7D, /* RINGTIHI */
+0x00000000L, /* ADAP_RING_MIN_I */
+0x00003000L, /* COUNTER_IRING_VAL */
+0x00051EB8L, /* COUNTER_VTR_VAL */
+0x00000000L, /* CONST_028 */
+0x00000000L, /* CONST_032 */
+0x00000000L, /* CONST_038 */
+0x00000000L, /* CONST_046 */
+0x00000000L, /* RRD_DELAY */
+0x00000000L, /* RRD_DELAY2 */
+0x01893740L, /* VBAT_TRACK_MIN_RNG */
+0x98, /* RINGCON */
+0x00, /* USERSTAT */
+0x027BED2BL, /* VCM_RING (37.564 v) */
+0x027BED2BL, /* VCM_RING_FIXED */
+0x003126E8L, /* DELTA_VCM */
+0x00200000L, /* DCDC_RNGTYPE */
+} /* RING_F20_45VRMS_0VDC_LPR */
+};
+
+Si3218x_DCfeed_Cfg Si3218x_DCfeed_Presets[] = {
+{
+0x1C8A024CL, /* SLOPE_VLIM */
+0x1F909679L, /* SLOPE_RFEED */
+0x0040A0E0L, /* SLOPE_ILIM */
+0x1D5B21A9L, /* SLOPE_DELTA1 */
+0x1DD87A3EL, /* SLOPE_DELTA2 */
+0x05A38633L, /* V_VLIM (48.000 v) */
+0x050D2839L, /* V_RFEED (43.000 v) */
+0x03FE7F0FL, /* V_ILIM (34.000 v) */
+0x00B4F3C3L, /* CONST_RFEED (15.000 mA) */
+0x005D0FA6L, /* CONST_ILIM (20.000 mA) */
+0x002D8D96L, /* I_VLIM (0.000 mA) */
+0x005B0AFBL, /* LCRONHK (10.000 mA) */
+0x006D4060L, /* LCROFFHK (12.000 mA) */
+0x00008000L, /* LCRDBI (5.000 ms) */
+0x0048D595L, /* LONGHITH (8.000 mA) */
+0x003FBAE2L, /* LONGLOTH (7.000 mA) */
+0x00008000L, /* LONGDBI (5.000 ms) */
+0x000F0000L, /* LCRMASK (150.000 ms) */
+0x00080000L, /* LCRMASK_POLREV (80.000 ms) */
+0x00140000L, /* LCRMASK_STATE (200.000 ms) */
+0x00140000L, /* LCRMASK_LINECAP (200.000 ms) */
+0x01BA5E35L, /* VCM_OH (27.000 v) */
+0x0051EB85L, /* VOV_BAT (5.000 v) */
+0x00418937L, /* VOV_GND (4.000 v) */
+}, /* DCFEED_48V_20MA */
+{
+0x1C8A024CL, /* SLOPE_VLIM */
+0x1EE08C11L, /* SLOPE_RFEED */
+0x0040A0E0L, /* SLOPE_ILIM */
+0x1C940D71L, /* SLOPE_DELTA1 */
+0x1DD87A3EL, /* SLOPE_DELTA2 */
+0x05A38633L, /* V_VLIM (48.000 v) */
+0x050D2839L, /* V_RFEED (43.000 v) */
+0x03FE7F0FL, /* V_ILIM (34.000 v) */
+0x01241BC9L, /* CONST_RFEED (15.000 mA) */
+0x0074538FL, /* CONST_ILIM (25.000 mA) */
+0x002D8D96L, /* I_VLIM (0.000 mA) */
+0x005B0AFBL, /* LCRONHK (10.000 mA) */
+0x006D4060L, /* LCROFFHK (12.000 mA) */
+0x00008000L, /* LCRDBI (5.000 ms) */
+0x0048D595L, /* LONGHITH (8.000 mA) */
+0x003FBAE2L, /* LONGLOTH (7.000 mA) */
+0x00008000L, /* LONGDBI (5.000 ms) */
+0x000F0000L, /* LCRMASK (150.000 ms) */
+0x00080000L, /* LCRMASK_POLREV (80.000 ms) */
+0x00140000L, /* LCRMASK_STATE (200.000 ms) */
+0x00140000L, /* LCRMASK_LINECAP (200.000 ms) */
+0x01BA5E35L, /* VCM_OH (27.000 v) */
+0x0051EB85L, /* VOV_BAT (5.000 v) */
+0x00418937L, /* VOV_GND (4.000 v) */
+}, /* DCFEED_48V_25MA */
+{
+0x1E655196L, /* SLOPE_VLIM */
+0x001904EFL, /* SLOPE_RFEED */
+0x0040A0E0L, /* SLOPE_ILIM */
+0x1B4CAD9EL, /* SLOPE_DELTA1 */
+0x1BB0F47CL, /* SLOPE_DELTA2 */
+0x05A38633L, /* V_VLIM (48.000 v) */
+0x043AA4A6L, /* V_RFEED (36.000 v) */
+0x025977EAL, /* V_ILIM (20.000 v) */
+0x0068B19AL, /* CONST_RFEED (18.000 mA) */
+0x005D0FA6L, /* CONST_ILIM (20.000 mA) */
+0x002D8D96L, /* I_VLIM (0.000 mA) */
+0x005B0AFBL, /* LCRONHK (10.000 mA) */
+0x006D4060L, /* LCROFFHK (12.000 mA) */
+0x00008000L, /* LCRDBI (5.000 ms) */
+0x0048D595L, /* LONGHITH (8.000 mA) */
+0x003FBAE2L, /* LONGLOTH (7.000 mA) */
+0x00008000L, /* LONGDBI (5.000 ms) */
+0x000F0000L, /* LCRMASK (150.000 ms) */
+0x00080000L, /* LCRMASK_POLREV (80.000 ms) */
+0x00140000L, /* LCRMASK_STATE (200.000 ms) */
+0x00140000L, /* LCRMASK_LINECAP (200.000 ms) */
+0x01BA5E35L, /* VCM_OH (27.000 v) */
+0x0051EB85L, /* VOV_BAT (5.000 v) */
+0x00418937L, /* VOV_GND (4.000 v) */
+}, /* DCFEED_PSTN_DET_1 */
+{
+0x1A10433FL, /* SLOPE_VLIM */
+0x1C206275L, /* SLOPE_RFEED */
+0x0040A0E0L, /* SLOPE_ILIM */
+0x1C1F426FL, /* SLOPE_DELTA1 */
+0x1EB51625L, /* SLOPE_DELTA2 */
+0x041C91DBL, /* V_VLIM (35.000 v) */
+0x03E06C43L, /* V_RFEED (33.000 v) */
+0x038633E0L, /* V_ILIM (30.000 v) */
+0x022E5DE5L, /* CONST_RFEED (10.000 mA) */
+0x005D0FA6L, /* CONST_ILIM (20.000 mA) */
+0x0021373DL, /* I_VLIM (0.000 mA) */
+0x005B0AFBL, /* LCRONHK (10.000 mA) */
+0x006D4060L, /* LCROFFHK (12.000 mA) */
+0x00008000L, /* LCRDBI (5.000 ms) */
+0x0048D595L, /* LONGHITH (8.000 mA) */
+0x003FBAE2L, /* LONGLOTH (7.000 mA) */
+0x00008000L, /* LONGDBI (5.000 ms) */
+0x000F0000L, /* LCRMASK (150.000 ms) */
+0x00080000L, /* LCRMASK_POLREV (80.000 ms) */
+0x00140000L, /* LCRMASK_STATE (200.000 ms) */
+0x00140000L, /* LCRMASK_LINECAP (200.000 ms) */
+0x01BA5E35L, /* VCM_OH (27.000 v) */
+0x0051EB85L, /* VOV_BAT (5.000 v) */
+0x00418937L, /* VOV_GND (4.000 v) */
+} /* DCFEED_PSTN_DET_2 */
+};
+
+Si3218x_Impedance_Cfg Si3218x_Impedance_Presets[] ={
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=600_0_0 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x07F3A400L, 0x000FF180L, 0x00009380L, 0x1FFDA800L, /* TXACEQ */
+ 0x07EF1600L, 0x0014B500L, 0x1FFD6580L, 0x1FFCA400L}, /* RXACEQ */
+{0x0008EF00L, 0x00099780L, 0x017DF600L, 0x0096B900L, /* ECFIR/ECIIR */
+ 0x02549000L, 0x1E4B7D00L, 0x018EEE00L, 0x1EEE0600L,
+ 0x008A8080L, 0x1F713080L, 0x0489BA00L, 0x03592500L},
+{0x0086CE00L, 0x1EF46980L, 0x0084CB00L, 0x0FE34F00L, /* ZSYNTH */
+ 0x181CA780L, 0x5D},
+ 0x08EB8E00L, /* TXACGAIN */
+ 0x01532100L, /* RXACGAIN */
+ 0x07AA7180L, 0x18558F00L, 0x0754E300L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_600_0_0_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=270_750_150 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x0750E500L, 0x1FC70280L, 0x000BA980L, 0x1FFD2880L, /* TXACEQ */
+ 0x0A8E2380L, 0x1B905280L, 0x00847700L, 0x1FDAFA00L}, /* RXACEQ */
+{0x002C8880L, 0x1F630D80L, 0x027F7980L, 0x1F3AD200L, /* ECFIR/ECIIR */
+ 0x040B8680L, 0x1F414D00L, 0x01427B00L, 0x00208200L,
+ 0x0026AE00L, 0x1FD71680L, 0x0C8EDB00L, 0x1B688A00L},
+{0x1F657980L, 0x0096FE00L, 0x00035500L, 0x0D7FE800L, /* ZSYNTH */
+ 0x1A7F1A80L, 0xB4},
+ 0x08000000L, /* TXACGAIN */
+ 0x01106B80L, /* RXACGAIN */
+ 0x07BC8400L, 0x18437C80L, 0x07790880L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_270_750_150_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=370_620_310 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x08363C80L, 0x1FB03200L, 0x1FFBD200L, 0x1FFC7A00L, /* TXACEQ */
+ 0x0A0D0800L, 0x1BEB0880L, 0x1F9DF080L, 0x1FE07F00L}, /* RXACEQ */
+{0x00236380L, 0x1F947D00L, 0x020DE380L, 0x1FBEED00L, /* ECFIR/ECIIR */
+ 0x03050300L, 0x1F7D1D00L, 0x010A9F80L, 0x00329D80L,
+ 0x003E4100L, 0x1FC0DF00L, 0x0DAADE80L, 0x1A4F2600L},
+{0x00226100L, 0x1F8EEE80L, 0x004E9D00L, 0x0F0B9B00L, /* ZSYNTH */
+ 0x18F3E580L, 0x99},
+ 0x0808D100L, /* TXACGAIN */
+ 0x0131BE80L, /* RXACGAIN */
+ 0x07B5C100L, 0x184A3F80L, 0x076B8200L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_370_620_310_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=220_820_120 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x07194B80L, 0x1FC63800L, 0x0008D280L, 0x1FFC0600L, /* TXACEQ */
+ 0x0A849680L, 0x1BB04480L, 0x00A4AA00L, 0x1FD3E680L}, /* RXACEQ */
+{0x001B8C00L, 0x1FC65400L, 0x016A5F00L, 0x01323C80L, /* ECFIR/ECIIR */
+ 0x01DB4980L, 0x01484700L, 0x00258000L, 0x007E9C80L,
+ 0x0016FF00L, 0x1FE69100L, 0x0CE9A400L, 0x1B0EA980L},
+{0x00B3D800L, 0x1D2F8280L, 0x021C8B00L, 0x0A157F00L, /* ZSYNTH */
+ 0x1DE99E80L, 0xAD},
+ 0x08000000L, /* TXACGAIN */
+ 0x01084680L, /* RXACGAIN */
+ 0x07BBFA80L, 0x18440600L, 0x0777F580L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_220_820_120_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=600_0_0 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x07F3A400L, 0x000FF180L, 0x00009380L, 0x1FFDA800L, /* TXACEQ */
+ 0x07EF1600L, 0x0014B500L, 0x1FFD6580L, 0x1FFCA400L}, /* RXACEQ */
+{0x0008EF00L, 0x00099780L, 0x017DF600L, 0x0096B900L, /* ECFIR/ECIIR */
+ 0x02549000L, 0x1E4B7D00L, 0x018EEE00L, 0x1EEE0600L,
+ 0x008A8080L, 0x1F713080L, 0x0489BA00L, 0x03592500L},
+{0x0086CE00L, 0x1EF46980L, 0x0084CB00L, 0x0FE34F00L, /* ZSYNTH */
+ 0x181CA780L, 0x5D},
+ 0x08EB8E00L, /* TXACGAIN */
+ 0x01532100L, /* RXACGAIN */
+ 0x07AA7180L, 0x18558F00L, 0x0754E300L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_600_0_1000_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=200_680_100 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x0778B980L, 0x1FB97E00L, 0x00030780L, 0x1FFC2580L, /* TXACEQ */
+ 0x09CC0780L, 0x1D104400L, 0x0076CB80L, 0x1FDE3D80L}, /* RXACEQ */
+{0x1FF64C00L, 0x00456280L, 0x00BEC500L, 0x014D3E80L, /* ECFIR/ECIIR */
+ 0x02EB2B00L, 0x1E983B80L, 0x029EE280L, 0x1E7B7400L,
+ 0x00D19A80L, 0x1F293D80L, 0x06116D00L, 0x01D55C00L},
+{0x01241700L, 0x1CB53A80L, 0x02269400L, 0x0A14BA00L, /* ZSYNTH */
+ 0x1DE9D080L, 0x99},
+ 0x08000000L, /* TXACGAIN */
+ 0x01152480L, /* RXACGAIN */
+ 0x07B96C00L, 0x18469480L, 0x0772D800L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_200_680_100_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=220_820_115 rprot=30 rfuse=24 emi_cap=10*/
+{
+{0x070AC700L, 0x1FCC7280L, 0x00098700L, 0x1FFCE080L, /* TXACEQ */
+ 0x0A6A6400L, 0x1BE48B80L, 0x009F3B80L, 0x1FD56000L}, /* RXACEQ */
+{0x00314700L, 0x1F6C1D80L, 0x02347480L, 0x00158B80L, /* ECFIR/ECIIR */
+ 0x03173D00L, 0x0058E580L, 0x00A6DA80L, 0x004B0780L,
+ 0x001B1300L, 0x1FE2DE80L, 0x0C313180L, 0x1BB7FE00L},
+{0x1FD95980L, 0x1ECDE680L, 0x0156F600L, 0x0A0C9600L, /* ZSYNTH */
+ 0x1DEBF080L, 0xB4},
+ 0x08000000L, /* TXACGAIN */
+ 0x01069C80L, /* RXACGAIN */
+ 0x07BECB80L, 0x18413500L, 0x077D9700L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ }, /* ZSYN_220_820_115_30_0 */
+/* Source: Database file: cwdb.db */
+/* Database information: */
+/* parameters: zref=600_0_0 rprot=30 rfuse=24 emi_cap=0*/
+{
+{0x081A5300L, 0x1FE00A00L, 0x00071580L, 0x1FFE2600L, /* TXACEQ */
+ 0x07F9A800L, 0x1FFA7D80L, 0x1FF59E80L, 0x1FFF1400L}, /* RXACEQ */
+{0x0052DC80L, 0x1F455780L, 0x0297A080L, 0x0006D980L, /* ECFIR/ECIIR */
+ 0x0195DC00L, 0x000E1E80L, 0x1FC53680L, 0x00050800L,
+ 0x00233400L, 0x1FE6DC00L, 0x1FCD1E00L, 0x1FD2FE00L},
+{0x007B9C00L, 0x1F296C80L, 0x005BCD00L, 0x09F07F00L, /* ZSYNTH */
+ 0x1DF35080L, 0x6F},
+ 0x08C2DA80L, /* TXACGAIN */
+ 0x01495A80L, /* RXACGAIN */
+ 0x07BECC80L, 0x18413400L, 0x077D9900L, /* RXACHPF */
+#ifdef ENABLE_HIRES_GAIN
+ 0, 0 /* TXGAIN*10, RXGAIN*10 (hi_res) */
+#else
+ 0, 0 /* TXGAIN, RXGAIN */
+#endif
+ } /* WB_ZSYN_600_0_0_20_0 */
+};
+
+Si3218x_FSK_Cfg Si3218x_FSK_Presets[] ={
+{
+{
+0x02232000L, /* FSK01 */
+0x077C2000L /* FSK10 */
+},
+{
+0x0015C000L, /* FSKAMP0 (0.080 vrms )*/
+0x000BA000L /* FSKAMP1 (0.080 vrms) */
+},
+{
+0x06B60000L, /* FSKFREQ0 (2200.0 Hz space) */
+0x079C0000L /* FSKFREQ1 (1200.0 Hz mark) */
+},
+0x00, /* FSK8 */
+0x00, /* FSKDEPTH (1 deep fifo) */
+}, /* DEFAULT_FSK */
+{
+{
+0x026E4000L, /* FSK01 */
+0x0694C000L /* FSK10 */
+},
+{
+0x0014C000L, /* FSKAMP0 (0.080 vrms )*/
+0x000CA000L /* FSKAMP1 (0.080 vrms) */
+},
+{
+0x06D20000L, /* FSKFREQ0 (2100.0 Hz space) */
+0x078B0000L /* FSKFREQ1 (1300.0 Hz mark) */
+},
+0x00, /* FSK8 */
+0x00, /* FSKDEPTH (1 deep fifo) */
+} /* ETSI_FSK */
+};
+
+Si3218x_PulseMeter_Cfg Si3218x_PulseMeter_Presets[] ={
+{
+0x007A2B6AL, /* PM_AMP_THRESH (1.000) */
+0, /* Freq (12kHz) */
+0, /* PM_AUTO (off)*/
+0x07D00000L, /* PM_active (2000 ms) */
+0x07D00000L /* PM_inactive (2000 ms) */
+ } /* DEFAULT_PULSE_METERING */
+};
+
+Si3218x_Tone_Cfg Si3218x_Tone_Presets[] = {
+{
+ {
+ 0x07B30000L, /* OSC1FREQ (350.000 Hz) */
+ 0x000C6000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x00, /* O1TALO (0 ms) */
+ 0x00, /* O1TAHI */
+ 0x00, /* O1TILO (0 ms) */
+ 0x00 /* O1TIHI */
+ },
+ {
+ 0x07870000L, /* OSC2FREQ (440.000 Hz) */
+ 0x000FA000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x00, /* O2TALO (0 ms) */
+ 0x00, /* O2TAHI */
+ 0x00, /* O2TILO (0 ms) */
+ 0x00 /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_FCC_DIAL */
+{
+ {
+ 0x07700000L, /* OSC1FREQ (480.000 Hz) */
+ 0x00112000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0xA0, /* O1TALO (500 ms) */
+ 0x0F, /* O1TAHI */
+ 0xA0, /* O1TILO (500 ms) */
+ 0x0F /* O1TIHI */
+ },
+ {
+ 0x07120000L, /* OSC2FREQ (620.000 Hz) */
+ 0x00164000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0xA0, /* O2TALO (500 ms) */
+ 0x0F, /* O2TAHI */
+ 0xA0, /* O2TILO (500 ms) */
+ 0x0F /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_FCC_BUSY */
+{
+ {
+ 0x07700000L, /* OSC1FREQ (480.000 Hz) */
+ 0x00112000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x80, /* O1TALO (2000 ms) */
+ 0x3E, /* O1TAHI */
+ 0x00, /* O1TILO (4000 ms) */
+ 0x7D /* O1TIHI */
+ },
+ {
+ 0x07870000L, /* OSC2FREQ (440.000 Hz) */
+ 0x000FA000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x80, /* O2TALO (2000 ms) */
+ 0x3E, /* O2TAHI */
+ 0x00, /* O2TILO (4000 ms) */
+ 0x7D /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_FCC_RINGBACK */
+{
+ {
+ 0x07700000L, /* OSC1FREQ (480.000 Hz) */
+ 0x00112000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x60, /* O1TALO (300 ms) */
+ 0x09, /* O1TAHI */
+ 0x60, /* O1TILO (300 ms) */
+ 0x09 /* O1TIHI */
+ },
+ {
+ 0x07120000L, /* OSC2FREQ (620.000 Hz) */
+ 0x00164000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x60, /* O2TALO (300 ms) */
+ 0x09, /* O2TAHI */
+ 0x40, /* O2TILO (200 ms) */
+ 0x06 /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_FCC_REORDER */
+{
+ {
+ 0x07700000L, /* OSC1FREQ (480.000 Hz) */
+ 0x00112000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x40, /* O1TALO (200 ms) */
+ 0x06, /* O1TAHI */
+ 0x40, /* O1TILO (200 ms) */
+ 0x06 /* O1TIHI */
+ },
+ {
+ 0x07120000L, /* OSC2FREQ (620.000 Hz) */
+ 0x00164000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x40, /* O2TALO (200 ms) */
+ 0x06, /* O2TAHI */
+ 0x40, /* O2TILO (200 ms) */
+ 0x06 /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_FCC_CONGESTION */
+{
+ {
+ 0x1F2F0000L, /* OSC1FREQ (2130.000 Hz) */
+ 0x0063A000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x80, /* O1TALO (80 ms) */
+ 0x02, /* O1TAHI */
+ 0x80, /* O1TILO (80 ms) */
+ 0x02 /* O1TIHI */
+ },
+ {
+ 0x1B8E0000L, /* OSC2FREQ (2750.000 Hz) */
+ 0x00A84000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x80, /* O2TALO (80 ms) */
+ 0x02, /* O2TAHI */
+ 0x40, /* O2TILO (1000 ms) */
+ 0x1F /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_FCC_CAS */
+{
+ {
+ 0x07870000L, /* OSC1FREQ (440.000 Hz) */
+ 0x000FA000L, /* OSC1AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x60, /* O1TALO (300 ms) */
+ 0x09, /* O1TAHI */
+ 0x00, /* O1TILO (8000 ms) */
+ 0xFA /* O1TIHI */
+ },
+ {
+ 0x1B8E0000L, /* OSC2FREQ (2750.000 Hz) */
+ 0x00A84000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x80, /* O2TALO (2000 ms) */
+ 0x3E, /* O2TAHI */
+ 0x00, /* O2TILO (4000 ms) */
+ 0x7D /* O2TIHI */
+ },
+ 0x06 /* OMODE */
+}, /* TONEGEN_FCC_SAS */
+{
+ {
+ 0x1F2F0000L, /* OSC1FREQ (2130.000 Hz) */
+ 0x01BD0000L, /* OSC1AMP (-5.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x20, /* O1TALO (100 ms) */
+ 0x03, /* O1TAHI */
+ 0x20, /* O1TILO (100 ms) */
+ 0x03 /* O1TIHI */
+ },
+ {
+ 0x1B8E0000L, /* OSC2FREQ (2750.000 Hz) */
+ 0x02EFC000L, /* OSC2AMP (-5.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x20, /* O2TALO (100 ms) */
+ 0x03, /* O2TAHI */
+ 0x20, /* O2TILO (100 ms) */
+ 0x03 /* O2TIHI */
+ },
+ 0x66 /* OMODE */
+}, /* TONEGEN_ETSI_DTAS */
+{
+ {
+ 0x05A40000L, /* OSC1FREQ (1004.000 Hz) */
+ 0x005DE000L, /* OSC1AMP (-10.000 dBm) */
+ 0x00000000L, /* OSC1PHAS (0.000 rad) */
+ 0x00, /* O1TALO (8000 ms) */
+ 0xFA, /* O1TAHI */
+ 0x00, /* O1TILO (8000 ms) */
+ 0xFA /* O1TIHI */
+ },
+ {
+ 0x07870000L, /* OSC2FREQ (440.000 Hz) */
+ 0x000FA000L, /* OSC2AMP (-18.000 dBm) */
+ 0x00000000L, /* OSC2PHAS (0.000 rad) */
+ 0x80, /* O2TALO (2000 ms) */
+ 0x3E, /* O2TAHI */
+ 0x00, /* O2TILO (4000 ms) */
+ 0x7D /* O2TIHI */
+ },
+ 0x47 /* OMODE */
+} /* TONEGEN_1004 */
+};
+
+Si3218x_PCM_Cfg Si3218x_PCM_Presets[] ={
+ {
+ 0x01, /* PCM_FMT - u-Law */
+ 0x00, /* WIDEBAND - DISABLED (3.4kHz BW) */
+ 0x00, /* PCM_TRI - PCLK RISING EDGE */
+ 0x00, /* TX_EDGE - PCLK RISING EDGE */
+ 0x00 /* A-LAW - INVERT NONE */
+ }, /* PCM_8ULAW */
+ {
+ 0x00, /* PCM_FMT - A-Law */
+ 0x00, /* WIDEBAND - DISABLED (3.4kHz BW) */
+ 0x00, /* PCM_TRI - PCLK RISING EDGE */
+ 0x00, /* TX_EDGE - PCLK RISING EDGE */
+ 0x00 /* A-LAW - INVERT NONE */
+ }, /* PCM_8ALAW */
+ {
+ 0x03, /* PCM_FMT - 16-bit Linear */
+ 0x00, /* WIDEBAND - DISABLED (3.4kHz BW) */
+ 0x00, /* PCM_TRI - PCLK RISING EDGE */
+ 0x00, /* TX_EDGE - PCLK RISING EDGE */
+ 0x00 /* A-LAW - INVERT NONE */
+ }, /* PCM_16LIN */
+ {
+ 0x03, /* PCM_FMT - 16-bit Linear */
+ 0x01, /* WIDEBAND - ENABLED (7kHz BW) */
+ 0x00, /* PCM_TRI - PCLK RISING EDGE */
+ 0x00, /* TX_EDGE - PCLK RISING EDGE */
+ 0x00 /* A-LAW - INVERT NONE */
+ } /* PCM_16LIN_WB */
+};
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si3218x_intf.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si3218x_intf.c
new file mode 100644
index 0000000..7b778f5
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si3218x_intf.c
@@ -0,0 +1,3135 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SI3218X ProSLIC interface implementation file
+ *
+ * Author(s):
+ * cdp
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ */
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si_voice_ctrl.h"
+#include "../inc/si_voice_timer_intf.h"
+#include "../inc/proslic.h"
+#include "../inc/si3218x.h"
+#include "../inc/si3218x_intf.h"
+#include "../inc/si3218x_registers.h"
+#include "../config_inc/proslic_api_config.h"
+
+#define SI3218X_IRING_LIM_MAX 0xA00000L /* 103mA */
+#define SI3218X_REVA 2
+
+#define WriteReg pProslic->deviceId->ctrlInterface->WriteRegister_fptr
+#define ReadReg pProslic->deviceId->ctrlInterface->ReadRegister_fptr
+#define pProHW pProslic->deviceId->ctrlInterface->hCtrl
+#define Reset pProslic->deviceId->ctrlInterface->Reset_fptr
+#define Delay pProslic->deviceId->ctrlInterface->Delay_fptr
+#define pProTimer pProslic->deviceId->ctrlInterface->hTimer
+#define WriteRAM pProslic->deviceId->ctrlInterface->WriteRAM_fptr
+#define ReadRAM pProslic->deviceId->ctrlInterface->ReadRAM_fptr
+#define TimeElapsed pProslic->deviceId->ctrlInterface->timeElapsed_fptr
+#define getTime pProslic->deviceId->ctrlInterface->getTime_fptr
+
+#define WriteRegX deviceId->ctrlInterface->WriteRegister_fptr
+#define ReadRegX deviceId->ctrlInterface->ReadRegister_fptr
+#define pProHWX deviceId->ctrlInterface->hCtrl
+#define DelayX deviceId->ctrlInterface->Delay_fptr
+#define pProTimerX deviceId->ctrlInterface->hTimer
+#define ReadRAMX deviceId->ctrlInterface->ReadRAM_fptr
+#define WriteRAMX deviceId->ctrlInterface->WriteRAM_fptr
+
+#define DEVICE_KEY_MIN 0x6E
+#define DEVICE_KEY_MAX 0x77
+
+#ifdef ENABLE_DEBUG
+static const char LOGPRINT_PREFIX[] = "Si3218x: ";
+#endif
+
+/*
+** Externs
+*/
+
+/* General Configuration */
+extern Si3218x_General_Cfg Si3218x_General_Configuration;
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+extern const proslicPatch SI3218X_PATCH_A;
+extern Si3218x_General_Cfg Si3218x_General_Configuration_MultiBOM[];
+extern int si3218x_genconf_multi_max_preset;
+#else
+extern const proslicPatch SI3218X_PATCH_A_DEFAULT;
+#endif
+
+/* Ringing */
+#ifndef DISABLE_RING_SETUP
+extern Si3218x_Ring_Cfg Si3218x_Ring_Presets[];
+#endif
+
+/* Zsynth */
+#ifndef DISABLE_ZSYNTH_SETUP
+extern Si3218x_Impedance_Cfg Si3218x_Impedance_Presets [];
+#endif
+
+/* Audio Gain Scratch */
+extern Si3218x_audioGain_Cfg Si3218x_audioGain_Presets[];
+
+/* Pulse Metering */
+#ifndef DISABLE_PULSE_SETUP
+extern Si3218x_PulseMeter_Cfg Si3218x_PulseMeter_Presets [];
+#endif
+
+/* PCM */
+#ifndef DISABLE_PCM_SETUP
+extern Si3218x_PCM_Cfg Si3218x_PCM_Presets [];
+#endif
+
+#define SI3218X_RAM_DCDC_DCFF_ENABLE SI3218X_RAM_GENERIC_8
+#define GCONF Si3218x_General_Configuration
+
+/*
+** Constants
+*/
+#define BIT20LSB 1048576L
+#define OITHRESH_OFFS 900L
+#define OITHRESH_SCALE 100L
+#define OVTHRESH_OFFS 71000
+#define OVTHRESH_SCALE 3000L
+#define UVTHRESH_OFFS 4057L
+#define UVTHRESH_SCALE 187L
+#define UVHYST_OFFS 548L
+#define UVHYST_SCALE 47L
+
+/*
+** Local functions are defined first
+*/
+
+/*
+** Function: getChipType
+**
+** Description:
+** Decode ID register to identify chip type
+**
+** Input Parameters:
+** ID register value
+**
+** Return:
+** partNumberType
+*/
+static partNumberType getChipType(uInt8 data)
+{
+ /* For the parts that have a HV variant, we map to the lower voltage version,
+ the actual differences are handled in the constants file
+ */
+
+ const uInt8 partNums[8] =
+ {
+ UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM, UNSUPPORTED_PART_NUM,
+ SI32184, SI32182, SI32185, SI32183
+ };
+
+ uInt8 partNum = (data & 0x38) >> 3; /* PART_NUM[2:0] = ID[5:3] */
+
+ return partNums[ partNum ];
+}
+
+int Si3218x_GetChipInfo(proslicChanType_ptr pProslic)
+{
+ uInt8 id;
+ id = ReadReg(pProHW, pProslic->channel, PROSLIC_REG_ID);
+
+ pProslic->deviceId->chipRev = id & 0x7;
+ pProslic->deviceId->chipType = getChipType(id);
+
+ if(pProslic->deviceId->chipType == UNSUPPORTED_PART_NUM)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%sregister 0 read = 0x%02X\n", LOGPRINT_PREFIX, id);
+#endif
+ return RC_SPI_FAIL;
+ }
+ else
+ {
+ return RC_NONE;
+ }
+}
+
+/*
+** Function: Si3218x_ConverterSetup
+**
+** Description:
+** Program revision specific settings before powering converter
+**
+** Specifically, from general parameters and knowledge that this
+** is Si32188x, setup dcff drive, gate drive polarity, and charge pump.
+**
+** Returns:
+** int (error)
+**
+*/
+int Si3218x_ConverterSetup(proslicChanType_ptr pProslic)
+{
+ ramData inv_off;
+
+ /* Option to add a per-channel inversion for maximum flexibility */
+ if(pProslic->dcdc_polarity_invert)
+ {
+ inv_off = 0x100000L;
+ }
+ else
+ {
+ inv_off = 0x0L;
+ }
+
+ switch(Si3218x_General_Configuration.bom_option)
+ {
+ case BO_DCDC_LCQC_5W:
+ case BO_DCDC_LCCB:
+ case BO_DCDC_LCCB110:
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_LIFT_EN,
+ 0x0L); /* dcff disabled */
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_SWDRV_POL,
+ inv_off); /* non-inverted */
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_CPUMP,
+ 0x100000L); /* Charge pump on */
+ Delay(pProTimer,20); /* Cpump settle */
+ break;
+
+ case BO_DCDC_BUCK_BOOST:
+ /*
+ ** RevC buck-boost designs are identical to RevB - no gate drive,
+ ** dcff enabled, non-inverting (charge pump off)
+ */
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_CPUMP,0x0L);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_SWDRV_POL,inv_off);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_LIFT_EN,
+ 0x100000L); /* dcff enabled */
+ break;
+
+ default:
+ return RC_DCDC_SETUP_ERR;
+ }
+
+ return RC_NONE;
+}
+
+/*
+** Function: Si3218x_PowerUpConverter
+**
+** Description:
+** Powers all DC/DC converters sequentially with delay to minimize
+** peak power draw on VDC.
+**
+** Returns:
+** int (error)
+**
+*/
+
+int Si3218x_PowerUpConverter(proslicChanType_ptr pProslic)
+{
+ errorCodeType error = RC_DCDC_SETUP_ERR;
+ int32 vbath,vbat;
+ uInt8 reg = 0;
+ int timer = 0;
+
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ /*
+ ** - powerup digital dc/dc w/ OV clamping and shutdown
+ ** - delay
+ ** - verify no short circuits by looking for vbath/2
+ ** - clear dcdc status
+ ** - switch to analog converter with OV clamping only (no shutdown)
+ ** - select analog dcdc and disable pwrsave
+ ** - delay
+ */
+
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,
+ LF_FWD_OHT); /* Force out of pwrsave mode if called in error */
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,
+ LF_OPEN); /* Ensure open line before powering up converter */
+ reg = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,
+ reg&0x07); /* Disable powersave mode */
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
+ 0x700000L); /* In case OV or UV previously occurred */
+
+ /*
+ ** Setup converter drive polarity and charge pump enable
+ ** based on bom
+ */
+
+ error = Si3218x_ConverterSetup(pProslic);
+
+ if(error != RC_NONE)
+ {
+ DEBUG_PRINT (pProslic, "%sChannel %d : DCDC initialization failed\n",
+ LOGPRINT_PREFIX, pProslic->channel);
+ return error;
+ }
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,0x600000L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_BIAS,0x200000L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_HVIC,0x200000L);
+ Delay(pProTimer,50);
+
+ vbath = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATH_EXPECT);
+ vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
+ if(vbat & 0x10000000L)
+ {
+ vbat |= 0xF0000000L;
+ }
+ if(vbat < (vbath / 2))
+ {
+ pProslic->channelEnable = 0;
+ error = RC_VBAT_UP_TIMEOUT;
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
+ 0x300000L); /* shutdown converter */
+ DEBUG_PRINT (pProslic,
+ "%sChannel %d : DCDC Short Circuit Failure - disabling channel\n%sVBAT = %d.%d\n",
+ LOGPRINT_PREFIX, pProslic->channel, LOGPRINT_PREFIX,
+ (int)((vbat/SCALE_V_MADC)/1000),
+ SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
+ return error;
+ }
+ else /* Enable analog converter */
+ {
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_STATUS,0L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,0x400000L);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,
+ reg); /* Restore ENHANCE */
+ Delay(pProTimer,50);
+ }
+
+ /*
+ ** - monitor vbat vs expected level (VBATH_EXPECT)
+ */
+ vbath = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATH_EXPECT);
+ do
+ {
+ vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
+ if(vbat & 0x10000000L)
+ {
+ vbat |= 0xF0000000L;
+ }
+ Delay(pProTimer,10);
+ }
+ while((vbat < (vbath - COMP_5V))
+ &&(timer++ < SI3218X_TIMEOUT_DCDC_UP)); /* 2 sec timeout */
+
+ DEBUG_PRINT (pProslic, "%sChannel %d : VBAT Up = %d.%d v\n",
+ LOGPRINT_PREFIX,
+ pProslic->channel,(int)((vbat/SCALE_V_MADC)/1000),
+ SIVOICE_ABS(((vbat/SCALE_V_MADC) - (vbat/SCALE_V_MADC)/1000*1000)));
+ if(timer > SI3218X_TIMEOUT_DCDC_UP)
+ {
+ /* Error handling - shutdown converter, disable channel, set error tag */
+ pProslic->channelEnable = 0;
+ error = RC_VBAT_UP_TIMEOUT;
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_DCDC,
+ 0x900000L); /* shutdown converter */
+ DEBUG_PRINT (pProslic, "%sChannel %d : DCDC Power up timeout : Status=0x%08X\n",
+ LOGPRINT_PREFIX, pProslic->channel, ReadRAM(pProHW,pProslic->channel,
+ SI3218X_RAM_DCDC_STATUS));
+ }
+
+ return error;
+}
+
+/*
+**
+** PROSLIC INITIALIZATION FUNCTIONS
+**
+*/
+
+/*
+** Function: Si3218x_Init_MultiBOM
+**
+** Description:
+** - probe SPI to establish daisy chain length
+** - load patch
+** - initialize general parameters
+** - calibrate madc
+** - bring up DC/DC converters
+** - calibrate everything except madc & lb
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object array
+** fault: error code
+**
+** Return:
+** error code
+*/
+
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+int Si3218x_Init_MultiBOM (proslicChanType_ptr *pProslic, int size, int preset)
+{
+
+ if(preset < si3218x_genconf_multi_max_preset)
+ {
+ /* Copy selected General Configuration parameters to Std structure */
+ Si3218x_General_Configuration = Si3218x_General_Configuration_MultiBOM[preset];
+ }
+ else
+ {
+ return RC_INVALID_PRESET;
+ }
+ return Si3218x_Init_with_Options(pProslic,size, INIT_NO_OPT);
+}
+#endif
+
+
+/*
+** Function: Si3218x_SelectPatch
+**
+** Select patch based on general parameters
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object array
+** fault: error code
+** patch: Pointer to proslicPatch pointer
+**
+** Return:
+** error code
+*/
+int Si3218x_SelectPatch(proslicChanType_ptr pProslic,
+ const proslicPatch **patch)
+{
+
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+ if(Si3218x_General_Configuration.bom_option == BO_DCDC_LCQC_5W
+ || Si3218x_General_Configuration.bom_option == BO_DCDC_LCCB
+ || Si3218x_General_Configuration.bom_option == BO_DCDC_LCCB110
+ || Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST)
+ {
+ *patch = &(SI3218X_PATCH_A);
+ }
+ else
+ {
+ DEBUG_PRINT(pProslic, "%sChannel %d : Invalid Patch\n", LOGPRINT_PREFIX,
+ pProslic->channel);
+ pProslic->channelEnable = 0;
+ pProslic->error = RC_INVALID_PATCH;
+ return RC_INVALID_PATCH;
+ }
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ *patch = &(SI3218X_PATCH_A_DEFAULT);
+#endif
+
+ return RC_NONE;
+}
+
+/*
+** Function: Si3218x_GenParamUpdate
+**
+** Update general parameters
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object array
+** fault: error code
+**
+** Return:
+** error code
+*/
+
+int Si3218x_GenParamUpdate(proslicChanType_ptr pProslic,initSeqType seq)
+{
+ ramData ram_data;
+ uInt8 data;
+
+ switch(seq)
+ {
+ case INIT_SEQ_PRE_CAL:
+ /*
+ ** Force pwrsave off and disable AUTO-tracking - set to user configured state after cal
+ */
+ WriteReg(pProHW, pProslic->channel,SI3218X_REG_ENHANCE,0);
+ WriteReg(pProHW, pProslic->channel,SI3218X_REG_AUTO,0x2F);
+
+ /*
+ ** General Parameter Updates
+ */
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_P_TH_HVIC,
+ Si3218x_General_Configuration.p_th_hvic);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_COEF_P_HVIC,
+ Si3218x_General_Configuration.coef_p_hvic);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_BAT_HYST,
+ Si3218x_General_Configuration.bat_hyst);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBATH_EXPECT,
+ Si3218x_General_Configuration.vbath_expect);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
+ Si3218x_General_Configuration.vbatr_expect);
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_TIMER,
+ Si3218x_General_Configuration.pwrsave_timer);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_OFFHOOK_THRESH,
+ Si3218x_General_Configuration.pwrsave_ofhk_thresh);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN,
+ Si3218x_General_Configuration.vbat_track_min);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN_RNG,
+ Si3218x_General_Configuration.vbat_track_min_rng);
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_THERM_DBI,
+ Si3218x_General_Configuration.therm_dbi);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_DCDC_SLOPE,
+ Si3218x_General_Configuration.vov_dcdc_slope);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_DCDC_OS,
+ Si3218x_General_Configuration.vov_dcdc_os);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VOV_RING_BAT_MAX,
+ Si3218x_General_Configuration.vov_ring_bat_max);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VERR,
+ Si3218x_General_Configuration.dcdc_verr);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VERR_HYST,
+ Si3218x_General_Configuration.dcdc_verr_hyst);
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_UVLO,
+ Si3218x_General_Configuration.pd_uvlo);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_OVLO,
+ Si3218x_General_Configuration.pd_ovlo);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_OCLO,
+ Si3218x_General_Configuration.pd_oclo);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PD_SWDRV,
+ Si3218x_General_Configuration.pd_swdrv);
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVPOL,
+ Si3218x_General_Configuration.dcdc_uvpol);
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,
+ Si3218x_General_Configuration.dcdc_rngtype);
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TOFF,
+ Si3218x_General_Configuration.dcdc_ana_toff);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TONMIN,
+ Si3218x_General_Configuration.dcdc_ana_tonmin);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_ANA_TONMAX,
+ Si3218x_General_Configuration.dcdc_ana_tonmax);
+
+
+ /*
+ ** Hardcoded RAM
+ */
+
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OITHRESH_LO,
+ GCONF.i_oithresh_lo);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OITHRESH_HI,
+ GCONF.i_oithresh_hi);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_OVTHRESH,GCONF.v_ovthresh);
+
+ ram_data = (GCONF.v_uvthresh > UVTHRESH_OFFS)?(GCONF.v_uvthresh -
+ UVTHRESH_OFFS)/UVTHRESH_SCALE:0L;
+ ram_data *= BIT20LSB;
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVTHRESH,ram_data);
+
+ ram_data = (GCONF.v_uvhyst > UVHYST_OFFS)?(GCONF.v_uvhyst -
+ UVHYST_OFFS)/UVHYST_SCALE:0L;
+ ram_data *= BIT20LSB;
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_UVHYST,ram_data);
+
+ /* Set default audio gain based on PM bom */
+ if(Si3218x_General_Configuration.pm_bom == BO_PM_BOM)
+ {
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_SCALE_KAUDIO,BOM_KAUDIO_PM);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_AC_ADC_GAIN,BOM_AC_ADC_GAIN_PM);
+ }
+ else
+ {
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_SCALE_KAUDIO,BOM_KAUDIO_NO_PM);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_AC_ADC_GAIN,
+ BOM_AC_ADC_GAIN_NO_PM);
+ }
+
+ /*
+ ** Hardcoded changes to default settings
+ */
+ data = ReadReg(pProHW, pProslic->channel,SI3218X_REG_GPIO_CFG1);
+ data &= 0xF9; /* Clear DIR for GPIO 1&2 */
+ data |= 0x60; /* Set ANA mode for GPIO 1&2 */
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_GPIO_CFG1,
+ data); /* coarse sensors analog mode */
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_PDN,
+ 0x80); /* madc powered in open state */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_1,
+ 0x71EB851L); /* Fix HPF corner */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PD_REF_OSC,
+ 0x200000L); /* PLL freerun workaround */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ILOOPLPF,
+ 0x4EDDB9L); /* 20pps pulse dialing enhancement */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ILONGLPF,
+ 0x806D6L); /* 20pps pulse dialing enhancement */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VDIFFLPF,
+ 0x10038DL); /* 20pps pulse dialing enhancement */
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_DCDC_VREF_CTRL,0x0L);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCM_TH,0x106240L);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCMLPF,0x10059FL);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_CM_SPEEDUP_TIMER,0x0F0000);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_VCM_HYST,0x206280L);
+
+ /* Prevent Ref Osc from powering down in PLL Freerun mode (pd_ref_osc) */
+ ram_data = ReadRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_CTRL_LO);
+ WriteRAM(pProHW, pProslic->channel,SI3218X_RAM_PWRSAVE_CTRL_LO,
+ ram_data&0x07FFFFFFL); /* clear b27 */
+ break;
+
+
+ case INIT_SEQ_POST_CAL:
+ WriteReg(pProHW, pProslic->channel,SI3218X_REG_ENHANCE,
+ Si3218x_General_Configuration.enhance&0x1F);
+ WriteReg(pProHW, pProslic->channel,SI3218X_REG_AUTO,
+ Si3218x_General_Configuration.auto_reg);
+ if(Si3218x_General_Configuration.zcal_en)
+ {
+ WriteReg(pProHW,pProslic->channel, SI3218X_REG_ZCAL_EN, 0x04);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return RC_NONE;
+}
+
+/*
+** Function: Si3218x_Init_with_Options
+**
+** Description:
+** - probe SPI to establish daisy chain length
+** - load patch
+** - initialize general parameters
+** - calibrate madc
+** - bring up DC/DC converters
+** - calibrate everything except madc & lb
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC object array
+** fault: error code
+**
+** Return:
+** error code
+*/
+
+int Si3218x_Init_with_Options (proslicChanType_ptr *pProslic, int size,
+ initOptionsType init_opt)
+{
+ /*
+ ** This function will initialize the chipRev and chipType members in pProslic
+ ** as well as load the initialization structures.
+ */
+
+ uInt8 data;
+ uInt8 calSetup[] = {0x00, 0x00, 0x01, 0x80}; /* CALR0-CALR3 */
+ int k, device_count;
+ const proslicPatch *patch;
+ uInt8 status;
+
+ LOGPRINT("%s(%d) size = %d init_opt = %d\n", __FUNCTION__, __LINE__, size,
+ init_opt);
+ /*
+ **
+ ** First qualify general parameters by identifying valid device key. This
+ ** will prevent inadvertent use of other device's preset files, which could
+ ** lead to improper initialization and high current states.
+ */
+
+ data = Si3218x_General_Configuration.device_key;
+
+ if((data < DEVICE_KEY_MIN)||(data > DEVICE_KEY_MAX))
+ {
+ pProslic[0]->error = RC_INVALID_GEN_PARAM;
+ return pProslic[0]->error;
+ }
+
+ /* reset error code */
+ for(k = 0; k < size; k++)
+ {
+ pProslic[k]->error = RC_NONE;
+ }
+
+ if( (init_opt == INIT_REINIT) || (init_opt == INIT_SOFTRESET) )
+ {
+ ProSLIC_ReInit_helper(pProslic, size, init_opt, SI3218X_CHAN_PER_DEVICE);
+
+ /* for single channel devices, we need do a full restore.. */
+ if(init_opt == INIT_REINIT)
+ {
+ init_opt = 0;
+ }
+}
+
+ if( init_opt != INIT_REINIT )
+ {
+ if( (SiVoice_IdentifyChannels(pProslic, size, &device_count, NULL) != RC_NONE)
+ ||(device_count == 0) )
+ {
+ DEBUG_PRINT(*pProslic, "%s: failed to detect any ProSLICs\n", LOGPRINT_PREFIX);
+ return RC_SPI_FAIL;
+ }
+
+ /*
+ ** Probe each channel and enable all channels that respond
+ */
+ for (k=0; k<size; k++)
+ {
+ if ((pProslic[k]->channelEnable)
+ &&(pProslic[k]->channelType == PROSLIC))
+ {
+ if ( (ProSLIC_VerifyMasterStat(pProslic[k]) != RC_NONE)
+ || (ProSLIC_VerifyControlInterface(pProslic[k]) != RC_NONE) )
+ {
+ pProslic[k]->channelEnable = 0;
+ pProslic[k]->error = RC_SPI_FAIL;
+ DEBUG_PRINT(*pProslic, "%s: SPI communications or PCLK/FS failure\n", LOGPRINT_PREFIX);
+ return pProslic[k]->error; /* Halt init if SPI fail */
+ }
+ }
+ }
+ } /* init_opt !REINIT */
+
+
+ if( (init_opt != INIT_NO_PATCH_LOAD ) && (init_opt != INIT_REINIT) )
+ {
+ /*
+ ** Load patch (load on every channel since single channel device)
+ */
+ for (k=0; k<size; k++)
+ {
+ if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
+ {
+
+ /* Select Patch*/
+ if (pProslic[k]->deviceId->chipRev == SI3218X_REVA )
+ {
+ status = (uInt8) Si3218x_SelectPatch(pProslic[k],&patch);
+ }
+ else
+ {
+ DEBUG_PRINT(pProslic[k], "%sChannel %d : Unsupported Device Revision (%d)\n",
+ LOGPRINT_PREFIX, pProslic[k]->channel,pProslic[k]->deviceId->chipRev );
+ pProslic[k]->channelEnable = 0;
+ pProslic[k]->error = RC_UNSUPPORTED_DEVICE_REV;
+ return RC_UNSUPPORTED_DEVICE_REV;
+ }
+
+ data = 1; /* Use this as a flag to see if we need to load the patch */
+ /* If the patch doesn't match, we need to do a full init, change settings */
+ if(init_opt == INIT_SOFTRESET)
+ {
+ ramData patchData;
+ patchData = pProslic[k]->ReadRAMX(pProslic[k]->pProHWX, pProslic[k]->channel,
+ PROSLIC_RAM_PATCHID);
+
+ if( patchData == patch->patchSerial)
+ {
+ data = 0;
+ }
+ else
+ {
+ init_opt = INIT_NO_OPT;
+ }
+ } /* SOFTRESET */
+
+ /* Load Patch */
+ if(status == RC_NONE)
+ {
+ if(data == 1)
+ {
+ Si3218x_LoadPatch(pProslic[k],patch);
+#ifndef DISABLE_VERIFY_PATCH
+ /* Optional Patch Verification */
+ data = (uInt8)Si3218x_VerifyPatch(pProslic[k],patch);
+ if (data != RC_NONE)
+ {
+ DEBUG_PRINT(pProslic[k], "%sChannel %d : Patch verification failed (%d)\n",
+ LOGPRINT_PREFIX, k, data);
+ pProslic[k]->channelEnable=0;
+ pProslic[k]->error = RC_PATCH_ERR;
+ return data;
+ }
+#endif
+ }
+ }
+ else
+ {
+ return status;
+ }
+ } /* channel == PROSLIC */
+ } /* for all channles */
+ }/* init_opt - need to reload patch */
+
+ /*
+ ** Load general parameters - includes all BOM dependencies
+ */
+ if(init_opt != INIT_SOFTRESET)
+ {
+ for (k=0; k<size; k++)
+ {
+ if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
+ {
+ Si3218x_GenParamUpdate(pProslic[k],INIT_SEQ_PRE_CAL);
+ }
+
+ pProslic[k]->WriteRAMX(pProslic[k]->pProHWX,pProslic[k]->channel,
+ SI3218X_RAM_IRING_LIM,SI3218X_IRING_LIM_MAX);
+ }
+ }
+
+ if((init_opt != INIT_NO_CAL)
+ && (init_opt != INIT_SOFTRESET)) /* Must recal on single channel devices */
+ {
+ /*
+ ** Calibrate (madc offset)
+ */
+ ProSLIC_Calibrate(pProslic,size,calSetup,TIMEOUT_MADC_CAL);
+ }/* init_opt */
+
+ /*
+ ** Bring up DC/DC converters sequentially to minimize
+ ** peak power demand on VDC
+ */
+ for (k=0; k<size; k++)
+ {
+ if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
+ {
+ pProslic[k]->error = Si3218x_PowerUpConverter(pProslic[k]);
+ }
+ }
+
+ if((init_opt != INIT_NO_CAL) && (init_opt != INIT_SOFTRESET))
+ {
+ /*
+ ** Calibrate remaining cals (except madc, lb)
+ */
+ calSetup[1] = SI3218X_CAL_STD_CALR1;
+ calSetup[2] = SI3218X_CAL_STD_CALR2;
+
+ ProSLIC_Calibrate(pProslic,size,calSetup,TIMEOUT_GEN_CAL);
+ }
+
+ /*
+ ** Apply post calibration general parameters
+ */
+ if(init_opt != INIT_SOFTRESET)
+ {
+ for (k=0; k<size; k++)
+ {
+
+ if ((pProslic[k]->channelEnable)&&(pProslic[k]->channelType == PROSLIC))
+ {
+ Si3218x_GenParamUpdate(pProslic[k],INIT_SEQ_POST_CAL);
+ }
+ }
+ }
+
+ /* Restore linefeed state after initialization for REINIT/SOFTRESET */
+ if( (init_opt == INIT_REINIT) || (init_opt == INIT_SOFTRESET) )
+ {
+ for(k = 0; k < size; k++)
+ {
+ pProslic[k]->WriteRegX(pProslic[k]->pProHWX,pProslic[k]->channel,
+ SI3218X_REG_LINEFEED,pProslic[k]->scratch);
+ }
+ }
+
+ /*
+ ** If any channel incurred a non-fatal error, return
+ ** RC_NON_FATAL_INIT_ERR to trigger user to read each channel's
+ ** error status
+ */
+ for (k=0; k<size; k++)
+ {
+ if(pProslic[k]->error != RC_NONE)
+ {
+ return RC_NON_FATAL_INIT_ERR;
+ }
+ }
+
+ return RC_NONE;
+}
+
+/*
+** Function: Si3218x_EnableInterrupts
+**
+** Description:
+** Enables interrupts
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC channel obj
+**
+** Returns:
+** 0
+*/
+
+int Si3218x_EnableInterrupts (proslicChanType_ptr pProslic)
+{
+ uInt8 i;
+#ifdef GCI_MODE
+ uInt8 data;
+#endif
+ /* Clear pending interrupts first */
+ for(i = SI3218X_REG_IRQ1; i < SI3218X_REG_IRQ4; i++)
+ {
+#ifdef GCI_MODE
+ data = ReadReg(pProHW,pProslic->channel, i);
+ WriteReg(pProHW,pProslic->channel,i,data); /*clear interrupts (gci only)*/
+#else
+ (void)ReadReg(pProHW,pProslic->channel, i);
+#endif
+
+ }
+
+ WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN1,
+ Si3218x_General_Configuration.irqen1);
+ WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN2,
+ Si3218x_General_Configuration.irqen2);
+ WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN3,
+ Si3218x_General_Configuration.irqen3);
+ WriteReg (pProHW,pProslic->channel,SI3218X_REG_IRQEN4,
+ Si3218x_General_Configuration.irqen4);
+
+ return RC_NONE;
+}
+
+/*
+**
+** PROSLIC CONFIGURATION FUNCTIONS
+**
+*/
+
+/*
+** Function: Si3218x_RingSetup
+**
+** Description:
+** configure ringing
+**
+** Input Parameters:
+** pProslic: pointer to PROSLIC channel obj
+** preset: ring preset
+**
+** Returns:
+** 0
+*/
+
+#ifndef DISABLE_RING_SETUP
+int Si3218x_RingSetup (proslicChanType *pProslic, int preset)
+{
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTPER,
+ Si3218x_Ring_Presets[preset].rtper);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGFR,
+ Si3218x_Ring_Presets[preset].freq);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGAMP,
+ Si3218x_Ring_Presets[preset].amp);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGPHAS,
+ Si3218x_Ring_Presets[preset].phas);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RINGOF,
+ Si3218x_Ring_Presets[preset].offset);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_RING,
+ Si3218x_Ring_Presets[preset].slope_ring);
+
+ if(Si3218x_Ring_Presets[preset].iring_lim > SI3218X_IRING_LIM_MAX)
+ {
+ Si3218x_Ring_Presets[preset].iring_lim = SI3218X_IRING_LIM_MAX;
+ }
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_IRING_LIM,
+ Si3218x_Ring_Presets[preset].iring_lim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTACTH,
+ Si3218x_Ring_Presets[preset].rtacth);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTDCTH,
+ Si3218x_Ring_Presets[preset].rtdcth);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTACDB,
+ Si3218x_Ring_Presets[preset].rtacdb);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RTDCDB,
+ Si3218x_Ring_Presets[preset].rtdcdb);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_RING_BAT,
+ Si3218x_Ring_Presets[preset].vov_ring_bat);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_RING_GND,
+ Si3218x_Ring_Presets[preset].vov_ring_gnd);
+
+#ifndef NOCLAMP_VBATR
+ /* Always limit VBATR_EXPECT to the general configuration maximum */
+ if(Si3218x_Ring_Presets[preset].vbatr_expect >
+ Si3218x_General_Configuration.vbatr_expect)
+ {
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
+ Si3218x_General_Configuration.vbatr_expect);
+ DEBUG_PRINT(pProslic,
+ "%sRingSetup : VBATR_EXPECT : Clamped to Gen Conf Limit\n",LOGPRINT_PREFIX);
+ }
+ else
+ {
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
+ Si3218x_Ring_Presets[preset].vbatr_expect);
+ }
+
+#else
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBATR_EXPECT,
+ Si3218x_Ring_Presets[preset].vbatr_expect);
+#endif
+
+
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTALO,
+ Si3218x_Ring_Presets[preset].talo);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTAHI,
+ Si3218x_Ring_Presets[preset].tahi);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTILO,
+ Si3218x_Ring_Presets[preset].tilo);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGTIHI,
+ Si3218x_Ring_Presets[preset].tihi);
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VBAT_TRACK_MIN_RNG,
+ Si3218x_Ring_Presets[preset].dcdc_vref_min_rng);
+
+ /*
+ ** LPR Handler
+ **
+ ** If USERSTAT == 0x01, adjust RINGCON and clear USERSTAT
+ */
+ if (Si3218x_Ring_Presets[preset].userstat == 0x01)
+ {
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGCON,
+ (0x80|Si3218x_Ring_Presets[preset].ringcon) & ~(0x40));
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_USERSTAT,0x00);
+ }
+ else
+ {
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RINGCON,
+ Si3218x_Ring_Presets[preset].ringcon);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_USERSTAT,
+ Si3218x_Ring_Presets[preset].userstat);
+ }
+
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_RING,
+ Si3218x_Ring_Presets[preset].vcm_ring);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_RING_FIXED,
+ Si3218x_Ring_Presets[preset].vcm_ring_fixed);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DELTA_VCM,
+ Si3218x_Ring_Presets[preset].delta_vcm);
+
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,
+ Si3218x_Ring_Presets[preset].dcdc_rngtype);
+
+
+ /*
+ ** If multi bom supported **AND** a buck boost converter
+ ** is being used, force dcdc_rngtype to be fixed.
+ */
+#ifdef SIVOICE_MULTI_BOM_SUPPORT
+#define DCDC_RNGTYPE_BKBT 0L
+ /* Automatically adjust DCDC_RNGTYPE */
+ if(Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST)
+ {
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_DCDC_RNGTYPE,DCDC_RNGTYPE_BKBT);
+ }
+#endif
+
+
+ return RC_NONE;
+}
+#endif
+
+/*
+** Function: PROSLIC_ZsynthSetup
+**
+** Description:
+** configure impedance synthesis
+*/
+
+#ifndef DISABLE_ZSYNTH_SETUP
+int Si3218x_ZsynthSetup (proslicChanType *pProslic, int preset)
+{
+ uInt8 lf;
+ uInt8 cal_en = 0;
+ uInt16 timer = 500;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ lf = ReadReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C2,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C3,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c3);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C4,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c4);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C5,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c5);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C6,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c6);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C7,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c7);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C8,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c8);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECFIR_C9,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_c9);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_B0,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_b0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_B1,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_b1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_A1,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_a1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ECIIR_A2,
+ Si3218x_Impedance_Presets[preset].hybrid.ecfir_a2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_A1,
+ Si3218x_Impedance_Presets[preset].zsynth.zsynth_a1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_A2,
+ Si3218x_Impedance_Presets[preset].zsynth.zsynth_a2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B1,
+ Si3218x_Impedance_Presets[preset].zsynth.zsynth_b1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B0,
+ Si3218x_Impedance_Presets[preset].zsynth.zsynth_b0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_ZSYNTH_B2,
+ Si3218x_Impedance_Presets[preset].zsynth.zsynth_b2);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_RA,
+ Si3218x_Impedance_Presets[preset].zsynth.ra);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
+ Si3218x_Impedance_Presets[preset].txgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
+ Si3218x_Impedance_Presets[preset].rxgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
+ Si3218x_Impedance_Presets[preset].rxgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_1,
+ Si3218x_Impedance_Presets[preset].rxachpf_b0_1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_1,
+ Si3218x_Impedance_Presets[preset].rxachpf_b1_1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_1,
+ Si3218x_Impedance_Presets[preset].rxachpf_a1_1);
+
+ /*
+ ** Scale based on desired gain plan
+ */
+ Si3218x_dbgSetTXGain(pProslic,Si3218x_Impedance_Presets[preset].txgain_db,
+ preset,TXACGAIN_SEL);
+ Si3218x_dbgSetRXGain(pProslic,Si3218x_Impedance_Presets[preset].rxgain_db,
+ preset,RXACGAIN_SEL);
+ Si3218x_TXAudioGainSetup(pProslic,TXACGAIN_SEL);
+ Si3218x_RXAudioGainSetup(pProslic,RXACGAIN_SEL);
+
+ /*
+ ** Perform Zcal in case OHT used (eg. no offhook event to trigger auto Zcal)
+ */
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR0,0x00);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR1,0x40);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR2,0x00);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_CALR3,0x80); /* start cal */
+
+ /* Wait for zcal to finish */
+ do
+ {
+ cal_en = ReadReg(pProHW,pProslic->channel,SI3218X_REG_CALR3);
+ Delay(pProTimer,1);
+ timer--;
+ }
+ while((cal_en&0x80)&&(timer>0));
+
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,lf);
+
+ if(timer > 0)
+ {
+ return RC_NONE;
+ }
+ else
+ {
+ return RC_CAL_TIMEOUT;
+ }
+}
+#endif
+
+/*
+** Function: PROSLIC_AudioGainSetup
+**
+** Description:
+** configure audio gains
+*/
+int Si3218x_TXAudioGainSetup (proslicChanType *pProslic, int preset)
+{
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
+ Si3218x_audioGain_Presets[preset].acgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
+ Si3218x_audioGain_Presets[preset].aceq_c0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
+ Si3218x_audioGain_Presets[preset].aceq_c1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
+ Si3218x_audioGain_Presets[preset].aceq_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
+ Si3218x_audioGain_Presets[preset].aceq_c3);
+
+ return RC_NONE;
+}
+
+/*
+** Function: PROSLIC_AudioGainSetup
+**
+** Description:
+** configure audio gains
+*/
+
+int Si3218x_RXAudioGainSetup (proslicChanType *pProslic, int preset)
+{
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
+ Si3218x_audioGain_Presets[preset].acgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
+ Si3218x_audioGain_Presets[preset].acgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
+ Si3218x_audioGain_Presets[preset].aceq_c0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
+ Si3218x_audioGain_Presets[preset].aceq_c1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
+ Si3218x_audioGain_Presets[preset].aceq_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
+ Si3218x_audioGain_Presets[preset].aceq_c3);
+
+ return RC_NONE;
+}
+
+
+/*
+** Function: PROSLIC_AudioGainScale
+**
+** Description:
+** Multiply path gain by passed value for PGA and EQ scale (no reference to dB,
+** multiply by a scale factor)
+*/
+int Si3218x_AudioGainScale (proslicChanType *pProslic, int preset,
+ uInt32 pga_scale, uInt32 eq_scale,int rx_tx_sel)
+{
+
+ if(rx_tx_sel == TXACGAIN_SEL)
+ {
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].acgain =
+ (Si3218x_Impedance_Presets[preset].txgain/1000)*pga_scale;
+ if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3 |= 0xf0000000L;
+ }
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c0 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c0/1000)*eq_scale;
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c1 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c1/1000)*eq_scale;
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c2 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c2/1000)*eq_scale;
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c3 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.txaceq_c3/1000)*eq_scale;
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACGAIN,
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].acgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C0,
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C1,
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C2,
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACEQ_C3,
+ Si3218x_audioGain_Presets[TXACGAIN_SEL].aceq_c3);
+ }
+ else
+ {
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain =
+ (Si3218x_Impedance_Presets[preset].rxgain/1000)*pga_scale;
+ if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
+ }
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c0 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c0/1000)*eq_scale;
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c1 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c1/1000)*eq_scale;
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c2 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c2/1000)*eq_scale;
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c3 = ((int32)
+ Si3218x_Impedance_Presets[preset].audioEQ.rxaceq_c3/1000)*eq_scale;
+
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN_SAVE,
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACGAIN,
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].acgain);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C0,
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C1,
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C2,
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACEQ_C3,
+ Si3218x_audioGain_Presets[RXACGAIN_SEL].aceq_c3);
+ }
+ return 0;
+}
+int Si3218x_TXAudioGainScale (proslicChanType *pProslic, int preset,
+ uInt32 pga_scale, uInt32 eq_scale)
+{
+ return Si3218x_AudioGainScale(pProslic,preset,pga_scale,eq_scale,TXACGAIN_SEL);
+}
+int Si3218x_RXAudioGainScale (proslicChanType *pProslic, int preset,
+ uInt32 pga_scale, uInt32 eq_scale)
+{
+ return Si3218x_AudioGainScale(pProslic,preset,pga_scale,eq_scale,RXACGAIN_SEL);
+}
+
+
+/*
+** Function: PROSLIC_DCFeedSetup
+**
+** Description:
+** configure dc feed
+*/
+
+#ifndef DISABLE_DCFEED_SETUP
+int Si3218x_DCFeedSetupCfg (proslicChanType *pProslic, Si3218x_DCfeed_Cfg *cfg,
+ int preset)
+{
+ uInt8 lf;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+ lf = ReadReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,0);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_VLIM,
+ cfg[preset].slope_vlim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_RFEED,
+ cfg[preset].slope_rfeed);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_ILIM,
+ cfg[preset].slope_ilim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_DELTA1,cfg[preset].delta1);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_SLOPE_DELTA2,cfg[preset].delta2);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_VLIM,cfg[preset].v_vlim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_RFEED,cfg[preset].v_rfeed);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_V_ILIM,cfg[preset].v_ilim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_CONST_RFEED,
+ cfg[preset].const_rfeed);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_CONST_ILIM,
+ cfg[preset].const_ilim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_I_VLIM,cfg[preset].i_vlim);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRONHK,cfg[preset].lcronhk);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCROFFHK,cfg[preset].lcroffhk);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRDBI,cfg[preset].lcrdbi);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGHITH,cfg[preset].longhith);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGLOTH,cfg[preset].longloth);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LONGDBI,cfg[preset].longdbi);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK,cfg[preset].lcrmask);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_POLREV,
+ cfg[preset].lcrmask_polrev);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_STATE,
+ cfg[preset].lcrmask_state);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_LCRMASK_LINECAP,
+ cfg[preset].lcrmask_linecap);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VCM_OH,cfg[preset].vcm_oh);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_BAT,cfg[preset].vov_bat);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_VOV_GND,cfg[preset].vov_gnd);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_LINEFEED,lf);
+
+ return RC_NONE;
+}
+
+#endif
+
+/*
+** Function: PROSLIC_PulseMeterSetup
+**
+** Description:
+** configure pulse metering
+*/
+
+#ifndef DISABLE_PULSE_SETUP
+int Si3218x_PulseMeterSetup (proslicChanType *pProslic, int preset)
+{
+ uInt8 reg;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ else
+ {
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_AMP_THRESH,
+ Si3218x_PulseMeter_Presets[preset].pm_amp_thresh);
+ reg = (Si3218x_PulseMeter_Presets[preset].pmFreq<<1)|
+ (Si3218x_PulseMeter_Presets[preset].pmAuto<<3);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_ACTIVE,
+ Si3218x_PulseMeter_Presets[preset].pmActive);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_PM_INACTIVE,
+ Si3218x_PulseMeter_Presets[preset].pmInactive);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_PMCON,reg);
+ return RC_NONE;
+ }
+
+}
+#endif
+
+/*
+** Function: PROSLIC_PCMSetup
+**
+** Description:
+** configure pcm
+*/
+
+#ifndef DISABLE_PCM_SETUP
+int Si3218x_PCMSetup(proslicChanType *pProslic, int preset)
+{
+ uInt8 regTemp;
+ uInt8 pmEn;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ pmEn = ReadReg(pProHW,pProslic->channel,
+ SI3218X_REG_PMCON) & 0x01; /* PM/wideband lockout */
+ if (Si3218x_PCM_Presets[preset].widebandEn && pmEn)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT ("%s Wideband Mode is not supported while Pulse Metering is enabled.\n",
+ LOGPRINT_PREFIX);
+#endif
+ }
+ else if (Si3218x_PCM_Presets[preset].widebandEn && !pmEn)
+ {
+ /* TXIIR settings */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_1,0x3538E80L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_1,0x3538E80L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_1,0x1AA9100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_2,0x2505400L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_2,0x2CB8100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_2,0x1D7FA500L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_3,0x1276D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_3,0x2335300L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_3,0x19D5F700L);
+ /* RXIIR settings */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_1,0x6A71D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_1,0x6A71D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_1,0x1AA9100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_2,0x2505400L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_2,0x2CB8100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_2,0x1D7FA500L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_3,0x1276D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_3,0x2335300L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_3,0x19D5F700L);
+ /*
+ ** RXHPF
+ ** Note: Calling ProSLIC_ZsynthSetup() will overwrite some
+ ** of these values. ProSLIC_PCMSetup() should always
+ ** be called after loading coefficients when using
+ ** wideband mode
+ */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_1,0x7CFF900L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_1,0x18300700L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_1,0x79FF201L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B0_2,0x7CEDA1DL);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B1_2,0x106320D4L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_B2_2,0x7CEDA1DL);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A1_2,0xF9A910FL);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_A2_2,0x185FFDA8L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACHPF_GAIN,0x08000000L);
+ /* TXHPF */
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B0_1,0x0C7FF4CEL);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B1_1,0x13800B32L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_1,0x079FF201L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B0_2,0x030FDD10L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B1_2,0x19E0996CL);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_B2_2,0x030FDD10L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A1_2,0x0F9A910FL);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_A2_2,0x185FFDA8L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACHPF_GAIN,0x0CD30000L);
+
+ regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON);
+#ifndef DISABLE_HPF_WIDEBAND
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,
+ regTemp&~(0xC)); /* Enable HPF */
+#else
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,
+ regTemp|(0xC)); /* Disable HPF */
+#endif
+ regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,regTemp|1);
+ }
+ else
+ {
+ regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_DIGCON,regTemp&~(0xC));
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_1,0x3538E80L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_1,0x3538E80L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_1,0x1AA9100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_2,0x2505400L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_2,0x2CB8100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_2,0x1D7FA500L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B0_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B1_3,0x1276D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_B2_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A1_3,0x2335300L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_TXACIIR_A2_3,0x19D5F700L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_1,0x6A71D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_1,0x6A71D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_1,0x1AA9100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_2,0x2505400L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_2,0x216D100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_2,0x2CB8100L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_2,0x1D7FA500L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B0_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B1_3,0x1276D00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_B2_3,0x2CD9B00L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A1_3,0x2335300L);
+ WriteRAM(pProHW,pProslic->channel,SI3218X_RAM_RXACIIR_A2_3,0x19D5F700L);
+ regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE);
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_ENHANCE,regTemp&~(1));
+ }
+ regTemp = Si3218x_PCM_Presets[preset].pcmFormat;
+ regTemp |= Si3218x_PCM_Presets[preset].pcm_tri << 5;
+ regTemp |= Si3218x_PCM_Presets[preset].alaw_inv << 2;
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_PCMMODE,regTemp);
+ regTemp = ReadReg(pProHW,pProslic->channel,SI3218X_REG_PCMTXHI);
+ regTemp &= 3;
+ regTemp |= Si3218x_PCM_Presets[preset].tx_edge<<4;
+ WriteReg(pProHW,pProslic->channel,SI3218X_REG_PCMTXHI,regTemp);
+
+ return RC_NONE;
+}
+#endif
+
+/*
+**
+** PROSLIC CONTROL FUNCTIONS
+**
+*/
+
+/*
+
+** Function: PROSLIC_dbgSetDCFeed
+**
+** Description:
+** provisionally function for setting up
+** dcfeed given desired open circuit voltage
+** and loop current.
+*/
+
+int Si3218x_dbgSetDCFeed (proslicChanType *pProslic, uInt32 v_vlim_val,
+ uInt32 i_ilim_val, int32 preset)
+{
+#ifndef DISABLE_DCFEED_SETUP
+ /* Note: * needs more descriptive return codes in the event of an out of range argument */
+ uInt16 vslope = 160;
+ uInt16 rslope = 720;
+ uInt32 vscale1 = 1386;
+ uInt32 vscale2 =
+ 1422; /* 1386x1422 = 1970892 broken down to minimize trunc err */
+ uInt32 iscale1 = 913;
+ uInt32 iscale2 = 334; /* 913x334 = 304942 */
+ uInt32 i_rfeed_val, v_rfeed_val, const_rfeed_val, i_vlim_val, const_ilim_val,
+ v_ilim_val;
+ int32 signedVal;
+ /* Set Linefeed to open state before modifying DC Feed */
+
+ /* Assumptions must be made to minimize computations. This limits the
+ ** range of available settings, but should be more than adequate for
+ ** short loop applications.
+ **
+ ** Assumtions:
+ **
+ ** SLOPE_VLIM => 160ohms
+ ** SLOPE_RFEED => 720ohms
+ ** I_RFEED => 3*I_ILIM/4
+ **
+ ** With these assumptions, the DC Feed parameters now become
+ **
+ ** Inputs: V_VLIM, I_ILIM
+ ** Constants: SLOPE_VLIM, SLOPE_ILIM, SLOPE_RFEED, SLOPE_DELTA1, SLOPE_DELTA2
+ ** Outputs: V_RFEED, V_ILIM, I_VLIM, CONST_RFEED, CONST_ILIM
+ **
+ */
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ /* Validate arguments */
+ if((i_ilim_val < 15)||(i_ilim_val > 45))
+ {
+ return 1; /* need error code */
+ }
+ if((v_vlim_val < 30)||(v_vlim_val > 52))
+ {
+ return 1; /* need error code */
+ }
+
+ /* Calculate voltages in mV and currents in uA */
+ v_vlim_val *= 1000;
+ i_ilim_val *= 1000;
+
+ /* I_RFEED */
+ i_rfeed_val = (3*i_ilim_val)/4;
+
+ /* V_RFEED */
+ v_rfeed_val = v_vlim_val - (i_rfeed_val*vslope)/1000;
+
+ /* V_ILIM */
+ v_ilim_val = v_rfeed_val - (rslope*(i_ilim_val - i_rfeed_val))/1000;
+
+ /* I_VLIM */
+ i_vlim_val = (v_vlim_val*1000)/4903;
+
+ /* CONST_RFEED */
+ signedVal = v_rfeed_val * (i_ilim_val - i_rfeed_val);
+ signedVal /= (v_rfeed_val - v_ilim_val);
+ signedVal = i_rfeed_val + signedVal;
+
+ /* signedVal in uA here */
+ signedVal *= iscale1;
+ signedVal /= 100;
+ signedVal *= iscale2;
+ signedVal /= 10;
+
+ if(signedVal < 0)
+ {
+ const_rfeed_val = (signedVal)+ (1L<<29);
+ }
+ else
+ {
+ const_rfeed_val = signedVal & 0x1FFFFFFF;
+ }
+
+ /* CONST_ILIM */
+ const_ilim_val = i_ilim_val;
+
+ /* compute RAM values */
+ v_vlim_val *= vscale1;
+ v_vlim_val /= 100;
+ v_vlim_val *= vscale2;
+ v_vlim_val /= 10;
+
+ v_rfeed_val *= vscale1;
+ v_rfeed_val /= 100;
+ v_rfeed_val *= vscale2;
+ v_rfeed_val /= 10;
+
+ v_ilim_val *= vscale1;
+ v_ilim_val /= 100;
+ v_ilim_val *= vscale2;
+ v_ilim_val /= 10;
+
+ const_ilim_val *= iscale1;
+ const_ilim_val /= 100;
+ const_ilim_val *= iscale2;
+ const_ilim_val /= 10;
+
+ i_vlim_val *= iscale1;
+ i_vlim_val /= 100;
+ i_vlim_val *= iscale2;
+ i_vlim_val /= 10;
+
+ Si3218x_DCfeed_Presets[preset].slope_vlim = 0x18842BD7L;
+ Si3218x_DCfeed_Presets[preset].slope_rfeed = 0x1E8886DEL;
+ Si3218x_DCfeed_Presets[preset].slope_ilim = 0x40A0E0L;
+ Si3218x_DCfeed_Presets[preset].delta1 = 0x1EABA1BFL;
+ Si3218x_DCfeed_Presets[preset].delta2 = 0x1EF744EAL;
+ Si3218x_DCfeed_Presets[preset].v_vlim = v_vlim_val;
+ Si3218x_DCfeed_Presets[preset].v_rfeed = v_rfeed_val;
+ Si3218x_DCfeed_Presets[preset].v_ilim = v_ilim_val;
+ Si3218x_DCfeed_Presets[preset].const_rfeed = const_rfeed_val;
+ Si3218x_DCfeed_Presets[preset].const_ilim = const_ilim_val;
+ Si3218x_DCfeed_Presets[preset].i_vlim = i_vlim_val;
+
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+ SILABS_UNREFERENCED_PARAMETER(v_vlim_val);
+ SILABS_UNREFERENCED_PARAMETER(i_ilim_val);
+ return RC_IGNORE;
+#endif
+}
+
+/*
+** Function: PROSLIC_dbgSetDCFeedVopen
+**
+** Description:
+** provisionally function for setting up
+** dcfeed given desired open circuit voltage.
+** Entry I_ILIM value will be used.
+*/
+int Si3218x_dbgSetDCFeedVopen (proslicChanType *pProslic, uInt32 v_vlim_val,
+ int32 preset)
+{
+#ifndef DISABLE_DCFEED_SETUP
+ uInt32 i_ilim_val;
+ uInt32 iscale1 = 913;
+ uInt32 iscale2 = 334; /* 913x334 = 304942 */
+
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ /* Read present CONST_ILIM value */
+ i_ilim_val = Si3218x_DCfeed_Presets[preset].const_ilim;
+
+
+ i_ilim_val /= iscale2;
+ i_ilim_val /= iscale1;
+
+ return Si3218x_dbgSetDCFeed(pProslic,v_vlim_val,i_ilim_val,preset);
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+ SILABS_UNREFERENCED_PARAMETER(v_vlim_val);
+ return RC_IGNORE;
+#endif
+}
+
+/*
+** Function: PROSLIC_dbgSetDCFeedIloop
+**
+** Description:
+** provisionally function for setting up
+** dcfeed given desired loop current.
+** Entry V_VLIM value will be used.
+*/
+int Si3218x_dbgSetDCFeedIloop (proslicChanType *pProslic, uInt32 i_ilim_val,
+ int32 preset)
+{
+#ifndef DISABLE_DCFEED_SETUP
+
+ uInt32 v_vlim_val;
+ uInt32 vscale1 = 1386;
+ uInt32 vscale2 =
+ 1422; /* 1386x1422 = 1970892 broken down to minimize trunc err */
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ /* Read present V_VLIM value */
+ v_vlim_val = Si3218x_DCfeed_Presets[preset].v_vlim;
+
+ v_vlim_val /= vscale2;
+ v_vlim_val /= vscale1;
+
+ return Si3218x_dbgSetDCFeed(pProslic,v_vlim_val,i_ilim_val, preset);
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+ SILABS_UNREFERENCED_PARAMETER(i_ilim_val);
+ return RC_IGNORE;
+#endif
+}
+
+typedef struct
+{
+ uInt8 freq;
+ ramData ringfr; /* trise scale for trap */
+ uInt32 ampScale;
+} ProSLIC_SineRingFreqLookup;
+
+typedef struct
+{
+ uInt8 freq;
+ ramData rtacth;
+ ramData rtper;
+ ramData rtdb;
+} ProSLIC_SineRingtripLookup;
+
+typedef struct
+{
+ uInt8 freq;
+ uInt16 cfVal[6];
+} ProSLIC_TrapRingFreqLookup;
+
+typedef struct
+{
+ uInt8 freq;
+ ramData rtper;
+ ramData rtdb;
+ uInt32 rtacth[6];
+} ProSLIC_TrapRingtripLookup;
+
+static const ProSLIC_SineRingFreqLookup sineRingFreqTable[] =
+ /* Freq RINGFR, vScale */
+ {
+ {15, 0x7F6E930L, 18968L},
+ {16, 0x7F5A8E0L, 20234L},
+ {20, 0x7EFD9D5L, 25301L},
+ {22, 0x7EC770AL, 27843L},
+ {23, 0x7EAA6E2L, 29113L},
+ {25, 0x7E6C925L, 31649L},
+ {30, 0x7DBB96BL, 38014L},
+ {34, 0x7D34155L, 42270L}, /* Actually 33.33Hz */
+ {35, 0x7CEAD72L, 44397L},
+ {40, 0x7BFA887L, 50802L},
+ {45, 0x7AEAE74L, 57233L},
+ {50, 0x79BC384L, 63693L},
+ {0,0,0}
+ }; /* terminator */
+
+static const ProSLIC_SineRingtripLookup sineRingtripTable[] =
+ /* Freq rtacth */
+ {
+ {15, 11440000L, 0x6A000L, 0x4000L },
+ {16, 10810000L, 0x64000L, 0x4000L },
+ {20, 8690000L, 0x50000L, 0x8000L },
+ {22, 7835000L, 0x48000L, 0x8000L },
+ {23, 7622000L, 0x46000L, 0x8000L },
+ {25, 6980000L, 0x40000L, 0xA000L },
+ {30, 5900000L, 0x36000L, 0xA000L },
+ {34, 10490000L, 0x60000L, 0x6000L }, /* Actually 33.33 */
+ {35, 10060000L, 0x5C000L, 0x6000L },
+ {40, 8750000L, 0x50000L, 0x8000L },
+ {45, 7880000L, 0x48000L, 0x8000L },
+ {50, 7010000L, 0x40000L, 0xA000L },
+ {0,0L, 0L, 0L}
+ }; /* terminator */
+
+static const ProSLIC_TrapRingFreqLookup trapRingFreqTable[] =
+ /* Freq multCF11 multCF12 multCF13 multCF14 multCF15 multCF16*/
+ {
+ {15, {69,122, 163, 196, 222,244}},
+ {16, {65,115, 153, 184, 208,229}},
+ {20, {52,92, 122, 147, 167,183}},
+ {22, {47,83, 111, 134, 152,166}},
+ {23, {45,80, 107, 128, 145,159}},
+ {25, {42,73, 98, 118, 133,146}},
+ {30, {35,61, 82, 98, 111,122}},
+ {34, {31,55, 73, 88, 100,110}},
+ {35, {30,52, 70, 84, 95,104}},
+ {40, {26,46, 61, 73, 83,91}},
+ {45, {23,41, 54, 65, 74,81}},
+ {50, {21,37, 49, 59, 67,73}},
+ {0,{0L,0L,0L,0L}} /* terminator */
+ };
+
+
+static const ProSLIC_TrapRingtripLookup trapRingtripTable[] =
+ /* Freq rtper rtdb rtacthCR11 rtacthCR12 rtacthCR13 rtacthCR14 rtacthCR15 rtacthCR16*/
+ {
+ {15, 0x6A000L, 0x4000L, {16214894L, 14369375L, 12933127L, 11793508L, 10874121L, 10121671L}},
+ {16, 0x64000L, 0x4000L, {15201463L, 13471289L, 12124806L, 11056414L, 10194489L, 9489067L}},
+ {20, 0x50000L, 0x6000L, {12161171L, 10777031L, 9699845L, 8845131L, 8155591L, 7591253L}},
+ {22, 0x48000L, 0x6000L, {11055610L, 9797301L, 8818041L, 8041028L, 7414174L, 6901139L}},
+ {23, 0x46000L, 0x6000L, {10574931L, 9371331L, 8434648L, 7691418L, 7091818L, 6601090L}},
+ {25, 0x40000L, 0x8000L, {9728937L, 8621625L, 7759876L, 7076105L, 6524473L, 6073003L}},
+ {30, 0x36000L, 0x8000L, {8107447L, 7184687L, 6466563L, 5896754L, 5437061L, 5060836L}},
+ {34, 0x60000L, 0x6000L, {7297432L, 6466865L, 5820489L, 5307609L, 4893844L, 4555208L}},
+ {35, 0x5C000L, 0x6000L, {6949240L, 6158303L, 5542769L, 5054361L, 4660338L, 4337859L}},
+ {40, 0x50000L, 0x6000L, {6080585L, 5388516L, 4849923L, 4422565L, 4077796L, 3795627L}},
+ {45, 0x48000L, 0x6000L, {5404965L, 4789792L, 4311042L, 3931169L, 3624707L, 3373890L}},
+ {50, 0x40000L, 0x8000L, {4864468L, 4310812L, 3879938L, 3538052L, 3262236L, 3036501L}},
+ {0,0x0L, 0x0L, {0L,0L,0L,0L}} /* terminator */
+ };
+
+/*
+** Function: PROSLIC_dbgRingingSetup
+**
+** Description:
+** Provision function for setting up
+** Ring type, frequency, amplitude and dc offset.
+** Main use will be by peek/poke applications.
+*/
+int Si3218x_dbgSetRinging (proslicChanType *pProslic,
+ ProSLIC_dbgRingCfg *ringCfg, int preset)
+{
+#ifndef DISABLE_RING_SETUP
+ int errVal,i=0;
+ uInt32 vScale = 1608872L; /* (2^28/170.25)*((100+4903)/4903) */
+ ramData dcdcVminTmp;
+
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ errVal = RC_NONE;
+
+ switch(ringCfg->ringtype)
+ {
+ case ProSLIC_RING_SINE:
+ i=0;
+ do
+ {
+ if(sineRingFreqTable[i].freq >= ringCfg->freq)
+ {
+ break;
+ }
+ i++;
+ }
+ while (sineRingFreqTable[i].freq);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(sineRingFreqTable[i].freq == 0)
+ {
+ i--;
+ errVal = RC_RING_V_LIMITED;
+ }
+
+ /* Update RINGFR RINGAMP, RINGOFFSET, and RINGCON */
+ Si3218x_Ring_Presets[preset].freq = sineRingFreqTable[i].ringfr;
+ Si3218x_Ring_Presets[preset].amp = ringCfg->amp * sineRingFreqTable[i].ampScale;
+ Si3218x_Ring_Presets[preset].offset = ringCfg->offset * vScale;
+ Si3218x_Ring_Presets[preset].phas = 0L;
+
+ /* Don't alter anything in RINGCON other than clearing the TRAP bit */
+ Si3218x_Ring_Presets[preset].ringcon &= 0xFE;
+
+ Si3218x_Ring_Presets[preset].rtper = sineRingtripTable[i].rtper;
+ Si3218x_Ring_Presets[preset].rtacdb = sineRingtripTable[i].rtdb;
+ Si3218x_Ring_Presets[preset].rtdcdb = sineRingtripTable[i].rtdb;
+ Si3218x_Ring_Presets[preset].rtdcth = 0xFFFFFFFL;
+ Si3218x_Ring_Presets[preset].rtacth = sineRingtripTable[i].rtacth;
+ break;
+
+ case ProSLIC_RING_TRAP_CF11:
+ case ProSLIC_RING_TRAP_CF12:
+ case ProSLIC_RING_TRAP_CF13:
+ case ProSLIC_RING_TRAP_CF14:
+ case ProSLIC_RING_TRAP_CF15:
+ case ProSLIC_RING_TRAP_CF16:
+ i=0;
+ do
+ {
+ if(trapRingFreqTable[i].freq >= ringCfg->freq)
+ {
+ break;
+ }
+ i++;
+ }
+ while (trapRingFreqTable[i].freq);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(trapRingFreqTable[i].freq == 0)
+ {
+ i--;
+ errVal = RC_RING_V_LIMITED;
+ }
+
+ /* Update RINGFR RINGAMP, RINGOFFSET, and RINGCON */
+ Si3218x_Ring_Presets[preset].amp = ringCfg->amp * vScale;
+ Si3218x_Ring_Presets[preset].freq =
+ Si3218x_Ring_Presets[preset].amp/trapRingFreqTable[i].cfVal[ringCfg->ringtype];
+ Si3218x_Ring_Presets[preset].offset = ringCfg->offset * vScale;
+ Si3218x_Ring_Presets[preset].phas = 262144000L/trapRingFreqTable[i].freq;
+
+ /* Don't alter anything in RINGCON other than setting the TRAP bit */
+ Si3218x_Ring_Presets[preset].ringcon |= 0x01;
+
+ /* RTPER and debouce timers */
+ Si3218x_Ring_Presets[preset].rtper = trapRingtripTable[i].rtper;
+ Si3218x_Ring_Presets[preset].rtacdb = trapRingtripTable[i].rtdb;
+ Si3218x_Ring_Presets[preset].rtdcdb = trapRingtripTable[i].rtdb;
+
+
+ Si3218x_Ring_Presets[preset].rtdcth = 0xFFFFFFFL;
+ Si3218x_Ring_Presets[preset].rtacth =
+ trapRingtripTable[i].rtacth[ringCfg->ringtype];
+
+
+ break;
+ }
+
+ /*
+ ** DCDC tracking sluggish under light load at higher ring freq.
+ ** Reduce tracking depth above 40Hz. This should have no effect
+ ** if using the Buck-Boost architecture.
+ */
+ if((sineRingFreqTable[i].freq >= 40)
+ ||(Si3218x_General_Configuration.bom_option == BO_DCDC_BUCK_BOOST))
+ {
+ dcdcVminTmp = ringCfg->amp + ringCfg->offset;
+ dcdcVminTmp *= 1000;
+ dcdcVminTmp *= SCALE_V_MADC;
+ Si3218x_Ring_Presets[preset].dcdc_vref_min_rng = dcdcVminTmp;
+ }
+ else
+ {
+ Si3218x_Ring_Presets[preset].dcdc_vref_min_rng = 0x1800000L;
+ }
+
+ return errVal;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+ SILABS_UNREFERENCED_PARAMETER(preset);
+ SILABS_UNREFERENCED_PARAMETER(ringCfg);
+ return RC_IGNORE;
+#endif
+}
+
+
+typedef struct
+{
+ int32 gain;
+ uInt32 scale;
+} ProSLIC_GainScaleLookup;
+
+#ifndef ENABLE_HIRES_GAIN
+static int Si3218x_dbgSetGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int tx_rx_sel)
+{
+ int errVal = 0;
+ int32 i;
+ int32 gain_pga, gain_eq;
+ const ProSLIC_GainScaleLookup gainScaleTable[]
+ = /* gain, scale=10^(gain/20) */
+ {
+ {-30, 32},
+ {-29, 35},
+ {-28, 40},
+ {-27, 45},
+ {-26, 50},
+ {-25, 56},
+ {-24, 63},
+ {-23, 71},
+ {-22, 79},
+ {-21, 89},
+ {-20, 100},
+ {-19, 112},
+ {-18, 126},
+ {-17, 141},
+ {-16, 158},
+ {-15, 178},
+ {-14, 200},
+ {-13, 224},
+ {-12, 251},
+ {-11, 282},
+ {-10, 316},
+ {-9, 355},
+ {-8, 398},
+ {-7, 447},
+ {-6, 501},
+ {-5, 562},
+ {-4, 631},
+ {-3, 708},
+ {-2, 794},
+ {-1, 891},
+ {0, 1000},
+ {1, 1122},
+ {2, 1259},
+ {3, 1413},
+ {4, 1585},
+ {5, 1778},
+ {6, 1995},
+ {0xff,0} /* terminator */
+ };
+
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+
+ /* Test against max gain */
+ if (gain > PROSLIC_EXTENDED_GAIN_MAX)
+ {
+ errVal = RC_GAIN_OUT_OF_RANGE;
+ DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d out of range\n", LOGPRINT_PREFIX,
+ (int)gain);
+ gain = PROSLIC_EXTENDED_GAIN_MAX; /* Clamp to maximum */
+ }
+
+ /* Test against min gain */
+ if (gain < PROSLIC_GAIN_MIN)
+ {
+ errVal = RC_GAIN_OUT_OF_RANGE;
+ DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d out of range\n", LOGPRINT_PREFIX,
+ (int)gain);
+ gain = PROSLIC_GAIN_MIN; /* Clamp to minimum */
+ }
+
+ /* Distribute gain */
+ if(gain == 0)
+ {
+ gain_pga = 0;
+ gain_eq = 0;
+ }
+ else if(gain > PROSLIC_GAIN_MAX)
+ {
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ gain_pga = PROSLIC_GAIN_MAX;
+ gain_eq = gain - PROSLIC_GAIN_MAX;
+ }
+ else
+ {
+ gain_pga = gain - PROSLIC_GAIN_MAX;
+ gain_eq = PROSLIC_GAIN_MAX;
+ }
+ }
+ else if(gain > 0)
+ {
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ gain_pga = gain;
+ gain_eq = 0;
+ }
+ else
+ {
+ gain_pga = 0;
+ gain_eq = gain;
+ }
+ }
+ else
+ {
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ gain_pga = 0;
+ gain_eq = gain;
+ }
+ else
+ {
+ gain_pga = gain;
+ gain_eq = 0;
+ }
+
+ }
+
+
+ /*
+ ** Lookup PGA Appropriate PGA Gain
+ */
+ i=0;
+ do
+ {
+ if(gainScaleTable[i].gain >= gain_pga) /* was gain_1 */
+ {
+ break;
+ }
+ i++;
+ }
+ while (gainScaleTable[i].gain!=0xff);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(gainScaleTable[i].gain == 0xff)
+ {
+ i--;
+ errVal = RC_GAIN_DELTA_TOO_LARGE;
+ }
+
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ Si3218x_audioGain_Presets[0].acgain =
+ (Si3218x_Impedance_Presets[impedance_preset].txgain/1000)
+ *gainScaleTable[i].scale;
+ }
+ else
+ {
+ Si3218x_audioGain_Presets[1].acgain =
+ (Si3218x_Impedance_Presets[impedance_preset].rxgain/1000)
+ *gainScaleTable[i].scale;
+ }
+
+
+ /*
+ ** Lookup EQ Gain
+ */
+ i=0;
+ do
+ {
+ if(gainScaleTable[i].gain >= gain_eq) /* was gain_2 */
+ {
+ break;
+ }
+ i++;
+ }
+ while (gainScaleTable[i].gain!=0xff);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(gainScaleTable[i].gain == 0xff)
+ {
+ i--;
+ errVal = RC_GAIN_DELTA_TOO_LARGE;
+ }
+
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ /*sign extend negative numbers*/
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 |= 0xf0000000L;
+ }
+
+ Si3218x_audioGain_Presets[0].aceq_c0 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0/1000)
+ *gainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[0].aceq_c1 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1/1000)
+ *gainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[0].aceq_c2 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2/1000)
+ *gainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[0].aceq_c3 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3/1000)
+ *gainScaleTable[i].scale;
+ }
+ else
+ {
+ /*sign extend negative numbers*/
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
+ }
+
+ Si3218x_audioGain_Presets[1].aceq_c0 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0/1000)
+ *gainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[1].aceq_c1 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1/1000)
+ *gainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[1].aceq_c2 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2/1000)
+ *gainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[1].aceq_c3 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3/1000)
+ *gainScaleTable[i].scale;
+ }
+
+
+ return errVal;
+}
+#else /* ENABLE_HIRES_GAIN */
+/*
+** Function: Si3218x_dbgSetGainHiRes()
+**
+** Description:
+** Provision function for setting up
+** TX and RX gain with 0.1dB resolution instead
+** of 1.0dB resolution
+*/
+static int Si3218x_dbgSetGainHiRes (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int tx_rx_sel)
+{
+ int errVal = 0;
+ int32 i;
+ int32 coarseGainIndex, fineGainIndex;
+ int32 gain_pga, gain_eq;
+ int32 coarseGain, fineGain;
+ int32 tmp;
+ const ProSLIC_GainScaleLookup coarseGainScaleTable[]
+ = /* gain, scale=10^(gain/20) */
+ {
+ {-30, 32},
+ {-29, 35},
+ {-28, 40},
+ {-27, 45},
+ {-26, 50},
+ {-25, 56},
+ {-24, 63},
+ {-23, 71},
+ {-22, 79},
+ {-21, 89},
+ {-20, 100},
+ {-19, 112},
+ {-18, 126},
+ {-17, 141},
+ {-16, 158},
+ {-15, 178},
+ {-14, 200},
+ {-13, 224},
+ {-12, 251},
+ {-11, 282},
+ {-10, 316},
+ {-9, 355},
+ {-8, 398},
+ {-7, 447},
+ {-6, 501},
+ {-5, 562},
+ {-4, 631},
+ {-3, 708},
+ {-2, 794},
+ {-1, 891},
+ {0, 1000},
+ {1, 1122},
+ {2, 1259},
+ {3, 1413},
+ {4, 1585},
+ {5, 1778},
+ {6, 1995},
+ {0xff,0} /* terminator */
+ };
+
+ const ProSLIC_GainScaleLookup fineGainScaleTable[]
+ = /* gain, scale=10^(gain/20) */
+ {
+ {-9, 902},
+ {-8, 912},
+ {-7, 923},
+ {-6, 933},
+ {-5, 944},
+ {-4, 955},
+ {-3, 966},
+ {-2, 977},
+ {-1, 989},
+ {0, 1000},
+ {1, 1012},
+ {2, 1023},
+ {3, 1035},
+ {4, 1047},
+ {5, 1059},
+ {6, 1072},
+ {7, 1084},
+ {8, 1096},
+ {9, 1109},
+ {0xff,0} /* terminator */
+ };
+
+ SILABS_UNREFERENCED_PARAMETER(pProslic);
+
+ /* Test against max gain */
+ if (gain > (PROSLIC_GAIN_MAX*10L))
+ {
+ errVal = RC_GAIN_OUT_OF_RANGE;
+ DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d dB*10 out of range\n",
+ LOGPRINT_PREFIX, gain);
+ gain = (PROSLIC_GAIN_MAX*10L); /* Clamp to maximum */
+ }
+
+ /* Test against min gain */
+ if (gain < (PROSLIC_GAIN_MIN*10L))
+ {
+ errVal = RC_GAIN_OUT_OF_RANGE;
+ DEBUG_PRINT(pProslic, "%sdbgSetGain: Gain %d dB*10 out of range\n",
+ LOGPRINT_PREFIX, gain);
+ gain = (PROSLIC_GAIN_MIN*10); /* Clamp to minimum */
+ }
+
+ /* Distribute gain */
+ coarseGain = gain/10L;
+ fineGain = gain - (coarseGain*10L);
+
+ /* Distribute coarseGain */
+ if(coarseGain == 0)
+ {
+ gain_pga = 0;
+ gain_eq = 0;
+ }
+ else if(coarseGain > 0)
+ {
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ gain_pga = coarseGain;
+ gain_eq = 0;
+ }
+ else
+ {
+ gain_pga = 0;
+ gain_eq = coarseGain;
+ }
+ }
+ else
+ {
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ gain_pga = 0;
+ gain_eq = coarseGain;
+ }
+ else
+ {
+ gain_pga = coarseGain;
+ gain_eq = 0;
+ }
+ }
+
+ /*
+ ** Lookup PGA Appopriate PGA Gain
+ */
+ i=0;
+ do
+ {
+ if(coarseGainScaleTable[i].gain >= gain_pga)
+ {
+ break;
+ }
+ i++;
+ }
+ while (coarseGainScaleTable[i].gain!=0xff);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(coarseGainScaleTable[i].gain == 0xff)
+ {
+ i--;
+ errVal = RC_GAIN_DELTA_TOO_LARGE;
+ }
+
+ coarseGainIndex = i; /* Store coarse index */
+
+ /* Find fineGain */
+ i = 0;
+ do
+ {
+ if(fineGainScaleTable[i].gain >= fineGain)
+ {
+ break;
+ }
+ i++;
+ }
+ while (fineGainScaleTable[i].gain!=0xff);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(fineGainScaleTable[i].gain == 0xff)
+ {
+ i--;
+ errVal = RC_GAIN_DELTA_TOO_LARGE;
+ }
+
+ fineGainIndex = i;
+
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ Si3218x_audioGain_Presets[0].acgain = ((
+ Si3218x_Impedance_Presets[impedance_preset].txgain/1000L)
+ *coarseGainScaleTable[coarseGainIndex].scale);
+ }
+ else
+ {
+ Si3218x_audioGain_Presets[1].acgain = ((
+ Si3218x_Impedance_Presets[impedance_preset].rxgain/1000L)
+ * coarseGainScaleTable[coarseGainIndex].scale)/1000L
+ * fineGainScaleTable[fineGainIndex].scale;
+ }
+
+ /*
+ ** Lookup EQ Gain
+ */
+ i=0;
+ do
+ {
+ if(coarseGainScaleTable[i].gain >= gain_eq)
+ {
+ break;
+ }
+ i++;
+ }
+ while (coarseGainScaleTable[i].gain!=0xff);
+
+ /* Set to maximum value if exceeding maximum value from table */
+ if(coarseGainScaleTable[i].gain == 0xff)
+ {
+ i--;
+ errVal = RC_GAIN_DELTA_TOO_LARGE;
+ }
+
+ coarseGainIndex = i; /* Store coarse index */
+
+ if(tx_rx_sel == TXACGAIN_SEL)
+ {
+ /*sign extend negative numbers*/
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3 |= 0xf0000000L;
+ }
+
+ tmp = (((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c0/1000L)
+ *coarseGainScaleTable[coarseGainIndex].scale);
+ tmp = tmp / (int32)1000L;
+ tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
+ Si3218x_audioGain_Presets[0].aceq_c0 = tmp;
+
+ tmp = (((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c1/1000L)
+ *coarseGainScaleTable[coarseGainIndex].scale);
+ tmp = tmp / (int32)1000L;
+ tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
+ Si3218x_audioGain_Presets[0].aceq_c1 = tmp;
+
+ tmp = (((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c2/1000L)
+ *coarseGainScaleTable[coarseGainIndex].scale);
+ tmp = tmp / (int32)1000L;
+ tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
+ Si3218x_audioGain_Presets[0].aceq_c2 = tmp;
+
+ tmp = (((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.txaceq_c3/1000L)
+ *coarseGainScaleTable[coarseGainIndex].scale);
+ tmp = tmp / (int32)1000L;
+ tmp = tmp * (int32)fineGainScaleTable[fineGainIndex].scale;
+ Si3218x_audioGain_Presets[0].aceq_c3 = tmp;
+ }
+ else
+ {
+ /*sign extend negative numbers*/
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2 |= 0xf0000000L;
+ }
+ if (Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 & 0x10000000L)
+ {
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3 |= 0xf0000000L;
+ }
+
+ Si3218x_audioGain_Presets[1].aceq_c0 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c0/1000)
+ *coarseGainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[1].aceq_c1 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c1/1000)
+ * coarseGainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[1].aceq_c2 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c2/1000)
+ * coarseGainScaleTable[i].scale;
+ Si3218x_audioGain_Presets[1].aceq_c3 = ((int32)
+ Si3218x_Impedance_Presets[impedance_preset].audioEQ.rxaceq_c3/1000)
+ * coarseGainScaleTable[i].scale;
+ }
+
+ return errVal;
+}
+#endif /* ENABLE_HIRES_GAIN */
+
+/*
+** Function: PROSLIC_dbgSetTXGain
+**
+** Description:
+** Provision function for setting up
+** TX gain
+*/
+
+int Si3218x_dbgSetTXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset)
+{
+ SILABS_UNREFERENCED_PARAMETER(audio_gain_preset);
+#ifdef ENABLE_HIRES_GAIN
+ return Si3218x_dbgSetGainHiRes(pProslic,gain,impedance_preset,TXACGAIN_SEL);
+#else
+ return Si3218x_dbgSetGain(pProslic,gain,impedance_preset,TXACGAIN_SEL);
+#endif
+}
+
+/*
+** Function: PROSLIC_dbgSetRXGain
+**
+** Description:
+** Provision function for setting up
+** RX gain
+*/
+int Si3218x_dbgSetRXGain (proslicChanType *pProslic, int32 gain,
+ int impedance_preset, int audio_gain_preset)
+{
+ SILABS_UNREFERENCED_PARAMETER(audio_gain_preset);
+#ifdef ENABLE_HIRES_GAIN
+ return Si3218x_dbgSetGainHiRes(pProslic,gain,impedance_preset,RXACGAIN_SEL);
+#else
+ return Si3218x_dbgSetGain(pProslic,gain,impedance_preset,RXACGAIN_SEL);
+#endif
+}
+
+/*
+** Function: Si3218x_GetRAMScale
+**
+** Description:
+** Read scale factor for passed RAM location
+**
+** Return Value:
+** int32 scale
+*/
+static int32 Si3218x_GetRAMScale(uInt16 addr)
+{
+ int32 scale;
+
+ switch(addr)
+ {
+ case SI3218X_RAM_MADC_ILOOP:
+ case SI3218X_RAM_MADC_ITIP:
+ case SI3218X_RAM_MADC_IRING:
+ case SI3218X_RAM_MADC_ILONG:
+ scale = SCALE_I_MADC;
+ break;
+
+ case SI3218X_RAM_MADC_VTIPC:
+ case SI3218X_RAM_MADC_VRINGC:
+ case SI3218X_RAM_MADC_VBAT:
+ case SI3218X_RAM_MADC_VDC:
+ case SI3218X_RAM_MADC_VDC_OS:
+ case SI3218X_RAM_MADC_VLONG:
+ case SI3218X_RAM_VDIFF_SENSE:
+ case SI3218X_RAM_VDIFF_FILT:
+ case SI3218X_RAM_VDIFF_COARSE:
+ case SI3218X_RAM_VTIP:
+ case SI3218X_RAM_VRING:
+ scale = SCALE_V_MADC;
+ break;
+
+ default:
+ scale = 1;
+ break;
+ }
+
+ return scale;
+}
+
+/*
+** Function: Si3218x_ReadMADCScaled
+**
+** Description:
+** Read MADC (or other sensed voltages/currents) and
+** return scaled value in int32 format.
+**
+** Return Value:
+** int32 voltage in mV or
+** int32 current in uA
+*/
+int32 Si3218x_ReadMADCScaled(proslicChanType_ptr pProslic,uInt16 addr,
+ int32 scale)
+{
+ int32 data;
+
+ /*
+ ** Read 29-bit RAM and sign extend to 32-bits
+ */
+ data = ReadRAM(pProHW,pProslic->channel,addr);
+ if(data & 0x10000000L)
+ {
+ data |= 0xF0000000L;
+ }
+
+ /*
+ ** Scale to provided value, or use defaults if scale = 0
+ */
+ if(scale == 0)
+ {
+ scale = Si3218x_GetRAMScale(addr);
+ }
+
+ data /= scale;
+
+ return data;
+}
+
+/*
+** Function: Si3218x_LineMonitor
+**
+** Description:
+** Monitor line voltages and currents
+*/
+int Si3218x_LineMonitor(proslicChanType *pProslic, proslicMonitorType *monitor)
+{
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ if(pProslic->channelEnable)
+ {
+ monitor->vtr = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VDIFF_FILT);
+ if(monitor->vtr & 0x10000000L)
+ {
+ monitor->vtr |= 0xf0000000L;
+ }
+ monitor->vtr /= SCALE_V_MADC;
+
+ monitor->vtip = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VTIP);
+ if(monitor->vtip & 0x10000000L)
+ {
+ monitor->vtip |= 0xf0000000L;
+ }
+ monitor->vtip /= SCALE_V_MADC;
+
+ monitor->vring = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_VRING);
+ if(monitor->vring & 0x10000000L)
+ {
+ monitor->vring |= 0xf0000000L;
+ }
+ monitor->vring /= SCALE_V_MADC;
+
+ monitor->vlong = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VLONG);
+ if(monitor->vlong & 0x10000000L)
+ {
+ monitor->vlong |= 0xf0000000L;
+ }
+ monitor->vlong /= SCALE_V_MADC;
+
+ monitor->vbat = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_VBAT);
+ if(monitor->vbat & 0x10000000L)
+ {
+ monitor->vbat |= 0xf0000000L;
+ }
+ monitor->vbat /= SCALE_V_MADC;
+
+ monitor->vdc = 0; /* Si3218x has no SVDC */
+
+ monitor->itr = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ILOOP);
+ if(monitor->itr & 0x10000000L)
+ {
+ monitor->itr |= 0xf0000000L;
+ }
+ monitor->itr /= SCALE_I_MADC;
+
+ monitor->itip = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ITIP);
+ if(monitor->itip & 0x10000000L)
+ {
+ monitor->itip |= 0xf0000000L;
+ }
+ monitor->itip /= SCALE_I_MADC;
+
+ monitor->iring = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_IRING);
+ if(monitor->iring & 0x10000000L)
+ {
+ monitor->iring |= 0xf0000000L;
+ }
+ monitor->iring /= SCALE_I_MADC;
+
+ monitor->ilong = ReadRAM(pProHW,pProslic->channel,SI3218X_RAM_MADC_ILONG);
+ if(monitor->ilong & 0x10000000L)
+ {
+ monitor->ilong |= 0xf0000000L;
+ }
+ monitor->ilong /= SCALE_I_MADC;
+
+ monitor->p_hvic = ReadRAM(pProHW,pProslic->channel,
+ SI3218X_RAM_P_Q1_D); /* P_HVIC_LPF */
+ if(monitor->p_hvic & 0x10000000L)
+ {
+ monitor->p_hvic |= 0xf0000000L;
+ }
+ monitor->p_hvic /= SCALE_P_MADC;
+ }
+
+ return RC_NONE;
+}
+
+/*
+** Function: Si3218x_PSTNCheck
+**
+** Description:
+** Continuous monitoring of longitudinal current.
+** If an average of N samples exceed avgThresh or a
+** single sample exceeds singleThresh, the linefeed
+** is forced into the open state.
+**
+** This protects the port from connecting to a live
+** pstn line (faster than power alarm).
+**
+*/
+int Si3218x_PSTNCheck (proslicChanType *pProslic,
+ proslicPSTNCheckObjType *pPSTNCheck)
+{
+ uInt8 i;
+
+ if( (pProslic->channelType != PROSLIC)
+ || (pPSTNCheck->samples == 0) )
+ {
+ return RC_NONE; /* Ignore DAA channels */
+ }
+
+ /* Adjust buffer index */
+ if(pPSTNCheck->count >= pPSTNCheck->samples)
+ {
+ pPSTNCheck->buffFull = TRUE;
+ pPSTNCheck->count = 0; /* reset buffer ptr */
+ }
+
+ /* Read next sample */
+ pPSTNCheck->ilong[pPSTNCheck->count] = ReadRAM(pProHW,pProslic->channel,
+ SI3218X_RAM_MADC_ILONG);
+ if(pPSTNCheck->ilong[pPSTNCheck->count] & 0x10000000L)
+ {
+ pPSTNCheck->ilong[pPSTNCheck->count] |= 0xf0000000L;
+ }
+ pPSTNCheck->ilong[pPSTNCheck->count] /= SCALE_I_MADC;
+
+ /* Monitor magnitude only */
+ if(pPSTNCheck->ilong[pPSTNCheck->count] < 0)
+ {
+ pPSTNCheck->ilong[pPSTNCheck->count] = -pPSTNCheck->ilong[pPSTNCheck->count];
+ }
+
+ /* Quickly test for single measurement violation */
+ if(pPSTNCheck->ilong[pPSTNCheck->count] > pPSTNCheck->singleThresh)
+ {
+ return RC_PSTN_CHECK_SINGLE_FAIL; /* fail */
+ }
+
+ /* Average once buffer is full */
+ if(pPSTNCheck->buffFull == TRUE)
+ {
+ pPSTNCheck->avgIlong = 0;
+ for(i=0; i<pPSTNCheck->samples; i++)
+ {
+ pPSTNCheck->avgIlong += pPSTNCheck->ilong[i];
+ }
+ pPSTNCheck->avgIlong /= pPSTNCheck->samples;
+
+ if(pPSTNCheck->avgIlong > pPSTNCheck->avgThresh)
+ {
+ /* reinit obj and return fail */
+ pPSTNCheck->count = 0;
+ pPSTNCheck->buffFull = FALSE;
+ return RC_PSTN_CHECK_AVG_FAIL;
+ }
+ else
+ {
+ pPSTNCheck->count++;
+ return RC_NONE;
+ }
+ }
+ else
+ {
+ pPSTNCheck->count++;
+ return RC_NONE;
+ }
+}
+
+#ifdef PSTN_DET_ENABLE
+/*
+** Function: abs_int32
+**
+** Description:
+** abs implementation for int32 type
+*/
+static int32 abs_int32(int32 a)
+{
+ if(a < 0)
+ {
+ return -1*a;
+ }
+ return a;
+}
+
+/*
+** Function: Si3218x_DiffPSTNCheck
+**
+** Description:
+** Monitor for excessive longitudinal current, which
+** would be present if a live pstn line was connected
+** to the port.
+**
+** Returns:
+** RC_NONE - test in progress
+** RC_COMPLETE_NO_ERR - test complete, no alarms or errors
+** RC_POWER_ALARM_HVIC - test interrupted by HVIC power alarm
+** RC_
+**
+*/
+
+int Si3218x_DiffPSTNCheck (proslicChanType *pProslic,
+ proslicDiffPSTNCheckObjType *pPSTNCheck)
+{
+ uInt8 loop_status;
+ int i;
+
+ if(pProslic->channelType != PROSLIC)
+ {
+ return RC_CHANNEL_TYPE_ERR; /* Ignore DAA channels */
+ }
+
+
+ switch(pPSTNCheck->pState.stage)
+ {
+ case 0:
+ /* Optional OPEN foreign voltage measurement - only execute if LCS = 0 */
+ /* Disable low power mode */
+ pPSTNCheck->enhanceRegSave = ReadReg(pProHW,pProslic->channel, PROSLIC_REG_ENHANCE);
+ WriteReg(pProHW,pProslic->channel, PROSLIC_REG_ENHANCE,
+ pPSTNCheck->enhanceRegSave&0x07); /* Disable powersave */
+ pPSTNCheck->vdiff1_avg = 0;
+ pPSTNCheck->vdiff2_avg = 0;
+ pPSTNCheck->iloop1_avg = 0;
+ pPSTNCheck->iloop2_avg = 0;
+ pPSTNCheck->return_status = RC_COMPLETE_NO_ERR;
+ /* Do OPEN state hazardous voltage measurement if enabled and ONHOOK */
+ Si3218x_ReadHookStatus(pProslic,&loop_status);
+ if((loop_status == PROSLIC_ONHOOK)&&(pPSTNCheck->femf_enable == 1))
+ {
+ pPSTNCheck->pState.stage++;
+ }
+ else
+ {
+ pPSTNCheck->pState.stage = 10;
+ }
+
+ return RC_NONE;
+
+ case 1:
+ /* Change linefeed to OPEN state for HAZV measurement, setup coarse sensors */
+ pPSTNCheck->lfstate_entry = ReadReg(pProHW,pProslic->channel, PROSLIC_REG_LINEFEED);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_OPEN);
+ pPSTNCheck->pState.stage++;
+ return RC_NONE;
+
+ case 2:
+ /* Settle */
+ ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_OPEN_FEMF_SETTLE);
+ return RC_NONE;
+
+ case 3:
+ /* Measure HAZV */
+ pPSTNCheck->vdiff_open = Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_COARSE,0);
+ DEBUG_PRINT(pProslic, "%sDiff PSTN : Vopen = %d mV\n", LOGPRINT_PREFIX,
+ pPSTNCheck->vdiff_open);
+
+ /* Stop PSTN check if differential voltage > max_femf_vopen present */
+ if(abs_int32(pPSTNCheck->vdiff_open) > pPSTNCheck->max_femf_vopen)
+ {
+ pPSTNCheck->pState.stage = 70;
+ pPSTNCheck->return_status = RC_PSTN_OPEN_FEMF;
+ }
+ else
+ {
+ pPSTNCheck->pState.stage = 10;
+ }
+ return 0;
+
+ case 10:
+ /* Load first DC feed preset */
+ ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->dcfPreset1);
+ ProSLIC_SetLinefeedStatus(pProslic,LF_FWD_ACTIVE);
+ pPSTNCheck->pState.stage++;
+ return RC_NONE;
+
+ case 11:
+ /* Settle */
+ ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_DIFF_IV1_SETTLE);
+ return RC_NONE;
+
+ case 12:
+ /* Measure VDIFF and ILOOP, switch to 2nd DCFEED setup */
+ pPSTNCheck->vdiff1[pPSTNCheck->pState.sampleIterations] =
+ Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_FILT,0);
+ pPSTNCheck->iloop1[pPSTNCheck->pState.sampleIterations] =
+ Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_MADC_ILOOP,0);
+#ifdef ENABLE_DEBUG
+ if ( DEBUG_ENABLED(pProslic) )
+ {
+ LOGPRINT("%sDiff PSTN: Vdiff1[%d] = %d mV\n", LOGPRINT_PREFIX,
+ pPSTNCheck->pState.sampleIterations,
+ pPSTNCheck->vdiff1[pPSTNCheck->pState.sampleIterations]);
+ LOGPRINT("%sDiff PSTN: Iloop1[%d] = %d uA\n", LOGPRINT_PREFIX,
+ pPSTNCheck->pState.sampleIterations,
+ pPSTNCheck->iloop1[pPSTNCheck->pState.sampleIterations]);
+ }
+#endif
+ pPSTNCheck->pState.sampleIterations++;
+ if(pPSTNCheck->pState.sampleIterations >= pPSTNCheck->samples)
+ {
+ ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->dcfPreset2);
+ pPSTNCheck->pState.stage++;
+ pPSTNCheck->pState.sampleIterations = 0;
+ }
+ return RC_NONE;
+
+ case 13:
+ /* Settle feed 500ms */
+ ProSLIC_PSTN_delay_poll(&(pPSTNCheck->pState), PSTN_DET_DIFF_IV2_SETTLE);
+ return RC_NONE;
+
+ case 14:
+ /* Measure VDIFF and ILOOP*/
+ pPSTNCheck->vdiff2[pPSTNCheck->pState.sampleIterations] =
+ Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_VDIFF_FILT,0);
+ pPSTNCheck->iloop2[pPSTNCheck->pState.sampleIterations] =
+ Si3218x_ReadMADCScaled(pProslic,SI3218X_RAM_MADC_ILOOP,0);
+#ifdef ENABLE_DEBUG
+ if ( DEBUG_ENABLED(pProslic) )
+ {
+ LOGPRINT("%sDiff PSTN: Vdiff2[%d] = %d mV\n", LOGPRINT_PREFIX,
+ pPSTNCheck->pState.sampleIterations,
+ pPSTNCheck->vdiff2[pPSTNCheck->pState.sampleIterations]);
+ LOGPRINT("%sDiff PSTN: Iloop2[%d] = %d uA\n", LOGPRINT_PREFIX,
+ pPSTNCheck->pState.sampleIterations,
+ pPSTNCheck->iloop2[pPSTNCheck->pState.sampleIterations]);
+ }
+#endif
+ pPSTNCheck->pState.sampleIterations++;
+ if(pPSTNCheck->pState.sampleIterations >= pPSTNCheck->samples)
+ {
+ /* Compute averages */
+ for (i=0; i<pPSTNCheck->samples; i++)
+ {
+ pPSTNCheck->vdiff1_avg += pPSTNCheck->vdiff1[i];
+ pPSTNCheck->iloop1_avg += pPSTNCheck->iloop1[i];
+ pPSTNCheck->vdiff2_avg += pPSTNCheck->vdiff2[i];
+ pPSTNCheck->iloop2_avg += pPSTNCheck->iloop2[i];
+ }
+
+ pPSTNCheck->vdiff1_avg /= pPSTNCheck->samples;
+ pPSTNCheck->iloop1_avg /= pPSTNCheck->samples;
+ pPSTNCheck->vdiff2_avg /= pPSTNCheck->samples;
+ pPSTNCheck->iloop2_avg /= pPSTNCheck->samples;
+
+ /* Force small (probably offset) currents to minimum value */
+ if(abs_int32(pPSTNCheck->iloop1_avg) < PSTN_DET_MIN_ILOOP)
+ {
+ pPSTNCheck->iloop1_avg = PSTN_DET_MIN_ILOOP;
+ }
+ if(abs_int32(pPSTNCheck->iloop2_avg) < PSTN_DET_MIN_ILOOP)
+ {
+ pPSTNCheck->iloop2_avg = PSTN_DET_MIN_ILOOP;
+ }
+
+ /* Calculate measured loop impedance */
+ pPSTNCheck->rl1 = abs_int32((
+ pPSTNCheck->vdiff1_avg*1000L)/pPSTNCheck->iloop1_avg);
+ pPSTNCheck->rl2 = abs_int32((
+ pPSTNCheck->vdiff2_avg*1000L)/pPSTNCheck->iloop2_avg);
+
+ /* Force non-zero loop resistance */
+ if(pPSTNCheck->rl1 == 0)
+ {
+ pPSTNCheck->rl1 = 1;
+ }
+ if(pPSTNCheck->rl2 == 0)
+ {
+ pPSTNCheck->rl2 = 1;
+ }
+
+ /* Qualify loop impedances */
+ pPSTNCheck->rl_ratio = (pPSTNCheck->rl1*1000L)/pPSTNCheck->rl2;
+#ifdef ENABLE_DEBUG
+ if ( DEBUG_ENABLED(pProslic) )
+ {
+ const char fmt_string[] = "%sDiffPSTN: %s = %d %s\n";
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "VDIFF1", pPSTNCheck->vdiff1_avg, "mV");
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "ILOOP1",pPSTNCheck->iloop1_avg, "uA");
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "VDIFF2",pPSTNCheck->vdiff2_avg, "mV");
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "ILOOP2",pPSTNCheck->iloop2_avg, "uA");
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL1",pPSTNCheck->rl1, "ohm");
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL2",pPSTNCheck->rl2, "ohm");
+ LOGPRINT(fmt_string, LOGPRINT_PREFIX, "RL_Ratio",pPSTNCheck->rl_ratio, " ");
+ }
+#endif
+
+ /* Restore */
+ pPSTNCheck->pState.sampleIterations = 0;
+ pPSTNCheck->pState.stage = 70;
+ }
+ return RC_NONE;
+
+ case 70: /* Reset test state, restore entry conditions */
+ ProSLIC_DCFeedSetup(pProslic,pPSTNCheck->entryDCFeedPreset);
+ ProSLIC_SetLinefeedStatus(pProslic,pPSTNCheck->lfstate_entry);
+ WriteReg(pProHW,pProslic->channel,PROSLIC_REG_ENHANCE, pPSTNCheck->enhanceRegSave);
+ pPSTNCheck->pState.stage = 0;
+ pPSTNCheck->pState.waitIterations = 0;
+ pPSTNCheck->pState.sampleIterations = 0;
+ return pPSTNCheck->return_status;
+
+ }
+ return RC_NONE;
+}
+
+#endif
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si_voice.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si_voice.c
new file mode 100644
index 0000000..c30ee2c
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si_voice.c
@@ -0,0 +1,563 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author(s):
+ * laj
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This file contains common (ProSIC + DAA) functions.
+ *
+ */
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si_voice.h"
+#include "../config_inc/proslic_api_config.h"
+
+#ifdef ENABLE_DEBUG
+#define LOGPRINT_PREFIX "SiVoice: "
+#endif
+
+#ifdef SI3217X
+#include "si3217x.h"
+#include "si3217x_intf.h"
+#endif
+
+#ifdef SI3218X
+#include "../inc/si3218x.h"
+#include "../inc/si3218x_intf.h"
+#endif
+
+#ifdef SI3219X
+#include "si3219x.h"
+#include "si3219x_intf.h"
+#endif
+
+#ifdef SI3226X
+#include "si3226x.h"
+#include "si3226x_intf.h"
+#endif
+
+#ifdef SI3228X
+#include "si3228x.h"
+#include "si3228x_intf.h"
+#endif
+
+#define pCtrl(X) (X)->deviceId->ctrlInterface
+#define pProHW(X) pCtrl((X))->hCtrl
+#define ReadReg(PCHAN, CHANNEL, REGADDR) (PCHAN)->deviceId->ctrlInterface->ReadRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR))
+#define WriteReg(PCHAN, CHANNEL, REGADDR, REGDATA) (PCHAN)->deviceId->ctrlInterface->WriteRegister_fptr(pProHW(PCHAN), (CHANNEL), (REGADDR), (REGDATA))
+
+/*
+** Control object constructor/destructor
+*/
+int SiVoice_createControlInterfaces (SiVoiceControlInterfaceType **pCtrlIntf,
+ uInt32 interface_count)
+{
+ TRACEPRINT_NOCHAN("count = %lu\n", (unsigned long)interface_count);
+#ifndef DISABLE_MALLOC
+ *pCtrlIntf = SIVOICE_CALLOC(sizeof(SiVoiceControlInterfaceType),
+ interface_count);
+ if(*pCtrlIntf == NULL)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s%s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
+#endif
+ return RC_NO_MEM;
+ }
+
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pCtrlIntf);
+ SILABS_UNREFERENCED_PARAMETER(interface_count);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+int SiVoice_destroyControlInterfaces ( SiVoiceControlInterfaceType **pCtrlIntf )
+{
+
+ TRACEPRINT_NOCHAN("\n",NULL);
+#ifndef DISABLE_MALLOC
+ if( pCtrlIntf && *pCtrlIntf)
+ {
+ SIVOICE_FREE ((SiVoiceControlInterfaceType *)*pCtrlIntf);
+ *pCtrlIntf = NULL;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pCtrlIntf);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/*
+** Device object constructor/destructor
+*/
+int SiVoice_createDevices (SiVoiceDeviceType **pDevice, uInt32 device_count)
+{
+
+ TRACEPRINT_NOCHAN("\n",NULL);
+#ifndef DISABLE_MALLOC
+ *pDevice = SIVOICE_CALLOC (sizeof(SiVoiceDeviceType), device_count);
+
+ if(*pDevice == NULL)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s%s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
+#endif
+ return RC_NO_MEM;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pDevice);
+ SILABS_UNREFERENCED_PARAMETER(device_count);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+int SiVoice_destroyDevices (SiVoiceDeviceType **pDevice)
+{
+
+ TRACEPRINT_NOCHAN("\n", NULL);
+#ifndef DISABLE_MALLOC
+ if(pDevice && *pDevice)
+ {
+ SIVOICE_FREE ((SiVoiceDeviceType *)*pDevice);
+ *pDevice = NULL;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pDevice);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/*
+** Channel object constructor/destructor
+*/
+int SiVoice_createChannels (SiVoiceChanType_ptr *pChan, uInt32 channel_count)
+{
+
+ TRACEPRINT_NOCHAN("count = %lu\n", (unsigned long) channel_count);
+#ifndef DISABLE_MALLOC
+ *pChan = SIVOICE_CALLOC(sizeof(SiVoiceChanType),channel_count);
+ if(*pChan == NULL)
+ {
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%s%s: failed to allocate memory", LOGPRINT_PREFIX, __FUNCTION__);
+#endif
+ return RC_NO_MEM;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(pChan);
+ SILABS_UNREFERENCED_PARAMETER(channel_count);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+int SiVoice_destroyChannels (SiVoiceChanType_ptr *hProslic)
+{
+
+ TRACEPRINT_NOCHAN("\n",NULL);
+#ifndef DISABLE_MALLOC
+ if(hProslic && *hProslic)
+ {
+ SIVOICE_FREE ((SiVoiceChanType_ptr)*hProslic);
+ *hProslic = NULL;
+ }
+ return RC_NONE;
+#else
+ SILABS_UNREFERENCED_PARAMETER(hProslic);
+ return RC_UNSUPPORTED_FEATURE;
+#endif
+}
+
+/*
+** Host control linkage
+*/
+int SiVoice_setControlInterfaceCtrlObj (SiVoiceControlInterfaceType *pCtrlIntf,
+ void *hCtrl)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->hCtrl = hCtrl;
+ return RC_NONE;
+}
+
+/*
+** Host reset linkage
+*/
+int SiVoice_setControlInterfaceReset (SiVoiceControlInterfaceType *pCtrlIntf,
+ ctrl_Reset_fptr Reset_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->Reset_fptr = Reset_fptr;
+ return RC_NONE;
+}
+
+/*
+** Host register/RAM read/write linkage
+*/
+int SiVoice_setControlInterfaceWriteRegister (SiVoiceControlInterfaceType
+ *pCtrlIntf, ctrl_WriteRegister_fptr WriteRegister_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->WriteRegister_fptr = WriteRegister_fptr;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceReadRegister (SiVoiceControlInterfaceType
+ *pCtrlIntf, ctrl_ReadRegister_fptr ReadRegister_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->ReadRegister_fptr = ReadRegister_fptr;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceWriteRAM (SiVoiceControlInterfaceType *pCtrlIntf,
+ ctrl_WriteRAM_fptr WriteRAM_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->WriteRAM_fptr = WriteRAM_fptr;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceReadRAM (SiVoiceControlInterfaceType *pCtrlIntf,
+ ctrl_ReadRAM_fptr ReadRAM_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->ReadRAM_fptr = ReadRAM_fptr;
+ return RC_NONE;
+}
+
+/*
+** Host timer linkage
+*/
+int SiVoice_setControlInterfaceTimerObj (SiVoiceControlInterfaceType *pCtrlIntf,
+ void *hTimer)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->hTimer = hTimer;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceDelay (SiVoiceControlInterfaceType *pCtrlIntf,
+ system_delay_fptr Delay_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->Delay_fptr = Delay_fptr;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceSemaphore (SiVoiceControlInterfaceType
+ *pCtrlIntf, ctrl_Semaphore_fptr semaphore_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->Semaphore_fptr = semaphore_fptr;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceTimeElapsed (SiVoiceControlInterfaceType
+ *pCtrlIntf, system_timeElapsed_fptr timeElapsed_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->timeElapsed_fptr = timeElapsed_fptr;
+ return RC_NONE;
+}
+
+int SiVoice_setControlInterfaceGetTime (SiVoiceControlInterfaceType *pCtrlIntf,
+ system_getTime_fptr getTime_fptr)
+{
+ TRACEPRINT_NOCHAN("\n",NULL);
+ pCtrlIntf->getTime_fptr = getTime_fptr;
+ return RC_NONE;
+}
+
+/*
+** Channel object initialization
+*/
+int SiVoice_SWInitChan (SiVoiceChanType_ptr pChan,int channel,int chipType,
+ SiVoiceDeviceType *pDeviceObj, SiVoiceControlInterfaceType *pCtrlIntf)
+{
+ TRACEPRINT_NOCHAN( "channel = %d chipType = %d\n", channel, chipType);
+ pChan->channel = (uInt8)channel;
+ pChan->deviceId = pDeviceObj;
+ pChan->deviceId->ctrlInterface = pCtrlIntf;
+ pChan->channelEnable=1;
+ pChan->error = RC_NONE;
+ pChan->debugMode = 0;
+ pChan->dcdc_polarity_invert = 0;
+#ifdef PROSLIC_BOM_DEFAULT
+ pChan->bomOption = PROSLIC_BOM_DEFAULT;
+#else
+ pChan->bomOption = 0;
+#endif
+
+ switch (chipType)
+ {
+ case SI3217X_TYPE:
+ pChan->deviceId->chipType = SI32171;
+ break;
+
+ case SI3218X_TYPE:
+ pChan->deviceId->chipType = SI32180;
+ break;
+
+ case SI3219X_TYPE:
+ pChan->deviceId->chipType = SI32190;
+ break;
+
+ case SI3226X_TYPE:
+ pChan->deviceId->chipType = SI32260;
+ break;
+
+ case SI3228X_TYPE:
+ pChan->deviceId->chipType = SI32280;
+ break;
+
+ case SI3050_TYPE:
+ pChan->deviceId->chipType = SI3050;
+ break;
+
+ default:
+ return RC_UNSUPPORTED_FEATURE;
+ }
+ return RC_NONE;
+}
+
+/*
+** Reset control
+*/
+int SiVoice_Reset (SiVoiceChanType_ptr pChan)
+{
+ TRACEPRINT_NOCHAN( "\n", NULL);
+ /*
+ ** assert reset, wait 250ms, release reset, wait 250ms
+ */
+ pChan->deviceId->ctrlInterface->Reset_fptr(
+ pChan->deviceId->ctrlInterface->hCtrl,1);
+
+ pChan->deviceId->ctrlInterface->Delay_fptr(
+ pChan->deviceId->ctrlInterface->hTimer,250);
+
+ pChan->deviceId->ctrlInterface->Reset_fptr(
+ pChan->deviceId->ctrlInterface->hCtrl,0);
+
+ pChan->deviceId->ctrlInterface->Delay_fptr(
+ pChan->deviceId->ctrlInterface->hTimer,250);
+
+ return RC_NONE;
+}
+
+/*
+** Debug Mode Control
+*/
+int SiVoice_setSWDebugMode (SiVoiceChanType_ptr pChan, int debugEn)
+{
+#ifdef ENABLE_DEBUG
+ TRACEPRINT_NOCHAN( "debugEn %d\n", debugEn);
+ pChan->debugMode = (0xFE & pChan->debugMode) | (debugEn != 0);
+#else
+ SILABS_UNREFERENCED_PARAMETER(pChan);
+ SILABS_UNREFERENCED_PARAMETER(debugEn);
+#endif
+ return RC_NONE;
+}
+
+/*
+** Trace Mode Control
+*/
+int SiVoice_setTraceMode (SiVoiceChanType_ptr pChan, int traceEn)
+{
+#ifdef ENABLE_TRACES
+ TRACEPRINT_NOCHAN( "debugEn %d\n", traceEn);
+ pChan->debugMode = (0xFD & pChan->debugMode) | ((traceEn != 0)<<1);
+#else
+ SILABS_UNREFERENCED_PARAMETER(pChan);
+ SILABS_UNREFERENCED_PARAMETER(traceEn);
+#endif
+ return RC_NONE;
+}
+
+/*
+** Error status
+*/
+int SiVoice_getErrorFlag (SiVoiceChanType_ptr pChan, int *error)
+{
+ TRACEPRINT( pChan, "\n", NULL);
+ *error = pChan->error;
+ return RC_NONE;
+}
+
+int SiVoice_clearErrorFlag (SiVoiceChanType_ptr pChan)
+{
+ TRACEPRINT( pChan, "\n", NULL);
+ pChan->error = RC_NONE;
+ return RC_NONE;
+}
+
+/*
+** Channel status
+*/
+int SiVoice_setChannelEnable (SiVoiceChanType_ptr pChan, int chanEn)
+{
+ TRACEPRINT( pChan, "enable = %d\n", chanEn);
+ pChan->channelEnable = chanEn;
+ return RC_NONE;
+}
+
+int SiVoice_getChannelEnable (SiVoiceChanType_ptr pChan, int *chanEn)
+{
+ TRACEPRINT( pChan, "\n", NULL);
+ *chanEn = pChan->channelEnable;
+ return RC_NONE;
+}
+
+uInt8 SiVoice_ReadReg(SiVoiceChanType_ptr hProslic,uInt8 addr)
+{
+ TRACEPRINT( hProslic, "addr = %u\n", (unsigned int)addr);
+ return ReadReg(hProslic, hProslic->channel, addr);
+}
+
+int SiVoice_WriteReg(SiVoiceChanType_ptr hProslic,uInt8 addr,uInt8 data)
+{
+ TRACEPRINT( hProslic, "addr = %u data = 0x%02X\n", (unsigned int)addr,
+ (unsigned int) data);
+ return WriteReg(hProslic, hProslic->channel, addr, data);
+}
+
+/*****************************************************************************************************/
+#if defined(SI3217X) || defined(SI3218X) || defined(SI3219X) || defined(SI3226X) || defined(SI3228X)
+#include "../inc/proslic.h"
+
+/* Iterate through the number of channels to determine if it's a SLIC, DAA, or unknown. Rev ID and chiptype is
+ * also filled in.
+ */
+int SiVoice_IdentifyChannels(SiVoiceChanType_ptr *pProslic, int size,
+ int *slicCount, int *daaCount)
+{
+ int i;
+ int rc = RC_NONE;
+ SiVoiceChanType_ptr currentChannel;
+
+ TRACEPRINT( *pProslic, "size = %d\n", size);
+
+ if(slicCount)
+ {
+ *slicCount = 0;
+ }
+ if(daaCount)
+ {
+ *daaCount = 0;
+ }
+
+ for(i = 0; i < size; i++)
+ {
+ currentChannel = pProslic[i];
+ /* SiVoice_SWInitChan() fills in the chipType initially with something the user provided, fill it
+ * in with the correct info.. The GetChipInfo may probe registers to compare them with their
+ * initial values, so this function MUST only be called after a chipset reset.
+ */
+#ifdef SI3217X
+ if (currentChannel->deviceId->chipType >= SI32171
+ && currentChannel->deviceId->chipType <= SI32179)
+ {
+ rc = Si3217x_GetChipInfo(currentChannel);
+ }
+#endif
+
+#ifdef SI3218X
+ if (currentChannel->deviceId->chipType >= SI32180
+ && currentChannel->deviceId->chipType <= SI32189)
+ {
+ rc = Si3218x_GetChipInfo(currentChannel);
+ }
+#endif
+
+#ifdef SI3219X
+ if ( IS_SI3219X(currentChannel->deviceId) )
+ {
+ rc = Si3219x_GetChipInfo(currentChannel);
+ }
+#endif
+
+#ifdef SI3226X
+ if (currentChannel->deviceId->chipType >= SI32260
+ && currentChannel->deviceId->chipType <= SI32269)
+ {
+ rc = Si3226x_GetChipInfo(currentChannel);
+ }
+#endif
+
+#ifdef SI3228X
+ if (currentChannel->deviceId->chipType >= SI32280
+ && currentChannel->deviceId->chipType <= SI32289)
+ {
+ rc = Si3228x_GetChipInfo(currentChannel);
+ }
+#endif
+
+ if(rc != RC_NONE)
+ {
+ return rc;
+ }
+
+ currentChannel->channelType = ProSLIC_identifyChannelType(currentChannel);
+ if(currentChannel->channelType == PROSLIC)
+ {
+ if(slicCount)
+ {
+ (*slicCount)++;
+ }
+ }
+ else if(currentChannel->channelType == DAA)
+ {
+ if(daaCount)
+ {
+ (*daaCount)++;
+ }
+ }
+#ifdef ENABLE_DEBUG
+ {
+ const char *dev_type = "UNKNOWN";
+ if(currentChannel->channelType == PROSLIC)
+ {
+ dev_type = "PROSLIC";
+ }
+ else if(currentChannel->channelType == DAA)
+ {
+ dev_type = "DAA";
+ }
+ LOGPRINT("%sChannel %d: Type = %s Rev = %d\n",
+ LOGPRINT_PREFIX, currentChannel->channel, dev_type,
+ currentChannel->deviceId->chipRev);
+
+ }
+#endif /* ENABLE_DEBUG */
+ }
+ return RC_NONE;
+}
+#endif
+
+/*
+** Function: ProSLIC_Version
+**
+** Description:
+** Return API version
+**
+** Returns:
+** string of the API release.
+*/
+
+extern const char *SiVoiceAPIVersion;
+char *SiVoice_Version()
+{
+ return (char *)SiVoiceAPIVersion;
+}
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si_voice_version.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si_voice_version.c
new file mode 100644
index 0000000..5d4aaaa
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/si_voice_version.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * file: si_voice_version.c
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * THIS FILE IS AUTOGENERATED - DO NOT MODIFY
+ *
+ */
+
+
+
+char *SiVoiceAPIVersion = "9.2.0";
+
+
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/vdaa.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/vdaa.c
new file mode 100644
index 0000000..9a73c44
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/vdaa.c
@@ -0,0 +1,1350 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Vdaa VoiceDAA interface implementation file
+ *
+ * Distributed by:
+ * Silicon Laboratories, Inc
+ *
+ * This file contains proprietary information.
+ * No dissemination allowed without prior written permission from
+ * Silicon Laboratories, Inc.
+ *
+ * File Description:
+ * This is the implementation file for the main VoiceDAA API.
+ *
+ */
+
+#include "../config_inc/si_voice_datatypes.h"
+#include "../inc/si_voice_ctrl.h"
+#include "../inc/si_voice_timer_intf.h"
+#include "../inc/vdaa.h"
+#include "../inc/vdaa_registers.h"
+#include "../config_inc/vdaa_api_config.h"
+
+#define WriteReg pVdaa->deviceId->ctrlInterface->WriteRegister_fptr
+#define ReadReg pVdaa->deviceId->ctrlInterface->ReadRegister_fptr
+#define pVdaaHW pVdaa->deviceId->ctrlInterface->hCtrl
+
+#define WriteRegX deviceId->ctrlInterface->WriteRegister_fptr
+#define ReadRegX deviceId->ctrlInterface->ReadRegister_fptr
+#define pVdaaHWX deviceId->ctrlInterface->hCtrl
+#define LOGPRINT_PREFIX "VDAA: "
+
+/*
+** Static VDAA driver functions
+*/
+
+/*
+** Function: isVerifiedDAA
+**
+** Description:
+** Verifies addressed channel is DAA
+**
+** Input Parameters:
+** pVdaa: pointer to SiVoiceChanType or vdaaChanType
+**
+** Return:
+** Verified DAA
+** Not DAA RC_CHANNEL_TYPE_ERR
+**
+*/
+
+static int isVerifiedDAA(vdaaChanType *pVdaa)
+{
+ uInt8 data = ReadReg(pVdaaHW,pVdaa->channel,LSIDE_REV);
+ if ( (data & 0x40) == 0 ) /*This bit is always 1 for DAA*/
+ {
+ LOGPRINT("%sDAA device not detected\n",LOGPRINT_PREFIX);
+ return RC_CHANNEL_TYPE_ERR;
+ }
+ else
+ {
+ /* For Si3050, the value will be zero initially (calloc), for Si32178/9, this will
+ * be non-zero (Rev B).
+ */
+ if(pVdaa->deviceId->chipRev == 0)
+ {
+ /* Read Device ID and store it */
+ /* NOTE: in earlier releases we also read the line side info here. This is now done
+ Vdaa_duringPowerUpLineside since the information we read was always 0.
+ */
+ data = pVdaa->ReadRegX(pVdaa->pVdaaHWX,pVdaa->channel,SYS_LINE_DEV_REV);
+ pVdaa->deviceId->chipRev= data&0xF;
+#ifdef ENABLE_DEBUG
+ LOGPRINT("%sChipRev = 0x%x\n", LOGPRINT_PREFIX, pVdaa->deviceId->chipRev);
+#endif
+ }
+ }
+
+ return RC_NONE;
+}
+
+#if 0 /* Removed for now since it isn't used, keeping code as reference */
+/*
+** Function: probeDaisyChain
+**
+** Description:
+** Identify how many VDAA devices are in daisychain
+** Only called if channel 0 has be previously qualified
+** as a VDAA.
+**
+** Input Parameters:
+** pVdaa: pointer to SiVoiceChanType or vdaaChanType
+**
+** Return:
+** number of channels in daisy chain
+**
+*/
+
+static int probeDaisyChain (vdaaChanType *pVdaa)
+{
+ int i=0;
+ WriteReg(pVdaaHW,BROADCAST,PCMRX_CNT_LO,0x23); /* Broadcast */
+ while ((ReadReg(pVdaaHW,(uInt8)i++,PCMRX_CNT_LO) == 0x23)
+ &&(i<=16)); /* Count number of channels */
+ return i-1; /* Return number of channels */
+}
+#endif
+
+/*
+**
+** ------ VDAA CONFIGURATION FUNCTIONS -----
+**
+*/
+
+/*
+** Function: Vdaa_RingDetectSetup
+**
+** Description:
+** configure ring detect setup
+**
+** Returns:
+**
+*/
+
+#ifndef DISABLE_VDAA_RING_DETECT_SETUP
+extern vdaa_Ring_Detect_Cfg Vdaa_Ring_Detect_Presets[];
+int Vdaa_RingDetectSetup (vdaaChanType *pVdaa,int32 preset)
+{
+
+ uInt8 regTemp = 0;
+ TRACEPRINT( pVdaa, "preset = %d\n", (unsigned int) preset);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,CTRL2) & 0xfB;
+ regTemp |= Vdaa_Ring_Detect_Presets[preset].rdi<<2;
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,INTL_CTRL1) & 0xfe;
+ regTemp |= Vdaa_Ring_Detect_Presets[preset].rt&1;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL1,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,INTL_CTRL2) & 0xef;
+ regTemp |= ((Vdaa_Ring_Detect_Presets[preset].rt>>1)<<4);
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL2,regTemp);
+
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL3,
+ Vdaa_Ring_Detect_Presets[preset].rfwe<<1);
+
+ regTemp = (Vdaa_Ring_Detect_Presets[preset].rdly&0x3) << 6;
+ regTemp |= Vdaa_Ring_Detect_Presets[preset].rmx ;
+ WriteReg(pVdaaHW,pVdaa->channel,RNG_VLD_CTRL1,regTemp);
+
+ regTemp = (Vdaa_Ring_Detect_Presets[preset].rdly>>2) << 7;
+ regTemp |= Vdaa_Ring_Detect_Presets[preset].rto << 3 ;
+ regTemp |= Vdaa_Ring_Detect_Presets[preset].rcc ;
+ WriteReg(pVdaaHW,pVdaa->channel,RNG_VLD_CTRL2,regTemp);
+
+ regTemp = Vdaa_Ring_Detect_Presets[preset].rngv << 7;
+ regTemp |= Vdaa_Ring_Detect_Presets[preset].ras ;
+ WriteReg(pVdaaHW,pVdaa->channel,RNG_VLD_CTRL3,regTemp);
+
+ regTemp = Vdaa_Ring_Detect_Presets[preset].rpol<<1;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL4,regTemp);
+
+ return RC_NONE;
+}
+#endif
+
+/*
+** Function: Vdaa_TXAudioGainSetup
+**
+** Description:
+** configure tx audio gain
+**
+** Returns:
+**
+**
+*/
+#ifndef DISABLE_VDAA_AUDIO_GAIN_SETUP
+extern vdaa_audioGain_Cfg Vdaa_audioGain_Presets[];
+
+int Vdaa_TXAudioGainSetup (vdaaChanType *pVdaa,int32 preset)
+{
+ uInt8 regTemp = 0;
+ TRACEPRINT( pVdaa, "preset = %d\n", (unsigned int) preset);
+
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ if(Vdaa_audioGain_Presets[preset].xga2 == XGA_ATTEN)
+ {
+ regTemp = 0x10;
+ }
+
+ regTemp |= Vdaa_audioGain_Presets[preset].acgain2 ;
+ WriteReg(pVdaaHW,pVdaa->channel,TX_GN_CTRL2,regTemp);
+
+ regTemp = 0;
+ if(Vdaa_audioGain_Presets[preset].xga3 == XGA_ATTEN)
+ {
+ regTemp = 0x10 ;
+ }
+
+ regTemp |= Vdaa_audioGain_Presets[preset].acgain3 ;
+ WriteReg(pVdaaHW,pVdaa->channel,TX_GN_CTRL3,regTemp);
+
+ if(Vdaa_audioGain_Presets[preset].cpEn)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,TXCALL_PROG_ATTEN,
+ Vdaa_audioGain_Presets[preset].callProgress);
+ }
+
+ return RC_NONE;
+}
+# endif
+
+
+/*
+** Function: Vdaa_RXAudioGainSetup
+**
+** Description:
+** configure rx audio gain
+**
+** Returns:
+**
+**
+*/
+#ifndef DISABLE_VDAA_AUDIO_GAIN_SETUP
+extern vdaa_audioGain_Cfg Vdaa_audioGain_Presets[];
+
+int Vdaa_RXAudioGainSetup (vdaaChanType *pVdaa,int32 preset)
+{
+ uInt8 regTemp = 0;
+
+ TRACEPRINT( pVdaa, "preset = %d\n", (unsigned int) preset);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ if(Vdaa_audioGain_Presets[preset].xga2 == XGA_ATTEN)
+ {
+ regTemp = 0x10;
+ }
+ regTemp |= Vdaa_audioGain_Presets[preset].acgain2 ;
+ WriteReg(pVdaaHW,pVdaa->channel,RX_GN_CTRL2,regTemp);
+
+ regTemp = 0;
+ if(Vdaa_audioGain_Presets[preset].xga3 == XGA_ATTEN)
+ {
+ regTemp = 0x10;
+ }
+ regTemp |= Vdaa_audioGain_Presets[preset].acgain3 ;
+ WriteReg(pVdaaHW,pVdaa->channel,RX_GN_CTRL3,regTemp);
+
+ if(Vdaa_audioGain_Presets[preset].cpEn)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,RXCALL_PROG_ATTEN,
+ Vdaa_audioGain_Presets[preset].callProgress);
+ }
+
+ return RC_NONE;
+}
+#endif
+
+
+/*
+** Function: Vdaa_PCMSetup
+**
+** Description:
+** configure pcm format, clocking and edge placement
+**
+** Returns:
+**
+**
+*/
+#ifndef DISABLE_VDAA_PCM_SETUP
+extern vdaa_PCM_Cfg Vdaa_PCM_Presets [];
+
+int Vdaa_PCMSetup (vdaaChanType *pVdaa,int32 preset)
+{
+ uInt8 regTemp = 0;
+
+ TRACEPRINT( pVdaa, "preset = %d\n", (unsigned int) preset);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL)&0xe0;
+ regTemp |= Vdaa_PCM_Presets[preset].pcm_tri;
+ regTemp |= Vdaa_PCM_Presets[preset].pcmHwy << 1;
+ regTemp |= Vdaa_PCM_Presets[preset].pcmFormat << 3;
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL,regTemp);
+
+ return RC_NONE;
+}
+#endif
+
+/*
+** Function: Vdaa_PCMTimeSlotSetup
+**
+** Description:
+** configure pcm timeslot
+**
+** Returns:
+**
+*/
+int Vdaa_PCMTimeSlotSetup (vdaaChanType *pVdaa, uInt16 rxcount, uInt16 txcount)
+{
+ uInt8 data = 0;
+ uInt8 pcmStatus;
+
+ TRACEPRINT( pVdaa, "rxcount = %u txcount = %u\n", (unsigned int)rxcount,
+ (unsigned int)txcount);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ /* Disable PCM if enabled - restore after updating timeslots */
+ pcmStatus = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL);
+ if (pcmStatus&0x20)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL,pcmStatus&~(0x20));
+ }
+
+ /*Storing 10 bit value of Transmit PCM sample in REG 34 and REG 35[0:1]*/
+ data = (uInt8)(txcount & 0xff);
+ WriteReg(pVdaaHW,pVdaa->channel,PCMTX_CNT_LO,data);
+ data = (uInt8)(txcount >> 8) ;
+ WriteReg(pVdaaHW,pVdaa->channel,PCMTX_CNT_HI,data);
+
+ /*Storing 10 bit value of Receive PCM sample in REG 34 and REG 35[0:1]*/
+ data = (uInt8)(rxcount & 0xff);
+ WriteReg(pVdaaHW,pVdaa->channel,PCMRX_CNT_LO,data);
+ data = (uInt8)(rxcount >> 8);
+ WriteReg(pVdaaHW,pVdaa->channel,PCMRX_CNT_HI,data);
+
+ /* Enable back the PCM after storing the values*/
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL,pcmStatus);
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_CountrySetup
+**
+** Description:
+** configure country specific settings
+**
+** Returns:
+**
+**
+*/
+
+#ifndef DISABLE_VDAA_COUNTRY_SETUP
+extern vdaa_Country_Cfg Vdaa_Country_Presets [];
+
+int Vdaa_CountrySetup (vdaaChanType *pVdaa,int32 preset)
+{
+ uInt8 regTemp = 0;
+
+ TRACEPRINT( pVdaa, "preset = %d\n", (unsigned int) preset);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,CTRL2) & 0xFD;
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regTemp); /* disable hybrid */
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,INTL_CTRL1) & 0xFD;
+ regTemp |= Vdaa_Country_Presets[preset].rz << 1 ;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL1,regTemp);
+
+ regTemp = Vdaa_Country_Presets[preset].dcr;
+ regTemp |= Vdaa_Country_Presets[preset].ilim<<1;
+ regTemp |= Vdaa_Country_Presets[preset].mini<<4;
+ regTemp |= Vdaa_Country_Presets[preset].dcv<<6;
+ WriteReg(pVdaaHW,pVdaa->channel,DC_TERM_CTRL,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,AC_TERM_CTRL) & 0xF0;
+ regTemp |= Vdaa_Country_Presets[preset].acim;
+ WriteReg(pVdaaHW,pVdaa->channel,AC_TERM_CTRL,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,SPRK_QNCH_CTRL) & 0xAF;
+ regTemp |= ((Vdaa_Country_Presets[preset].ohs_sq >> 2)&1)<<4 ;
+ regTemp |= ((Vdaa_Country_Presets[preset].ohs_sq >> 3)&1)<<6 ;
+ WriteReg(pVdaaHW,pVdaa->channel,SPRK_QNCH_CTRL,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,INTL_CTRL1) & 0xBF;
+ regTemp |= ((Vdaa_Country_Presets[preset].ohs_sq >> 1)&1)<<6 ;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL1,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL5) & 0xE7;
+ regTemp |= (Vdaa_Country_Presets[preset].ohs_sq&1)<<3 ;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL5,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,CTRL2) & 0xFD;
+ regTemp |= (Vdaa_Country_Presets[preset].hbe)<<1 ;
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regTemp);
+
+ return RC_NONE;
+}
+#endif
+
+/*
+** Function: Vdaa_HybridSetup
+**
+** Description:
+** configure hybrid
+**
+*/
+
+#ifndef DISABLE_VDAA_HYBRID_SETUP
+extern vdaa_Hybrid_Cfg Vdaa_Hybrid_Presets [];
+
+int Vdaa_HybridSetup (vdaaChanType *pVdaa,int32 preset)
+{
+ uInt8 regSave = 0;
+
+ TRACEPRINT( pVdaa, "preset = %d\n", (unsigned int) preset);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regSave = ReadReg(pVdaaHW,pVdaa->channel,CTRL2);
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regSave&0xFD); /* disable hybrid */
+
+ WriteReg(pVdaaHW,pVdaa->channel,HYB1,Vdaa_Hybrid_Presets[preset].hyb1);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB2,Vdaa_Hybrid_Presets[preset].hyb2);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB3,Vdaa_Hybrid_Presets[preset].hyb3);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB4,Vdaa_Hybrid_Presets[preset].hyb4);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB5,Vdaa_Hybrid_Presets[preset].hyb5);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB6,Vdaa_Hybrid_Presets[preset].hyb6);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB7,Vdaa_Hybrid_Presets[preset].hyb7);
+ WriteReg(pVdaaHW,pVdaa->channel,HYB8,Vdaa_Hybrid_Presets[preset].hyb8);
+
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,
+ regSave); /* Restore hybrid enable state at entry */
+
+ return RC_NONE;
+}
+#endif
+
+/*
+** Function: Vdaa_SetAudioMute
+**
+** Description:
+** Control RX and TX mute
+**
+*/
+
+int Vdaa_SetAudioMute(vdaaChanType *pVdaa, tMUTE mute)
+{
+ uInt8 regData;
+
+ TRACEPRINT( pVdaa, "mode = %u\n", (unsigned int) mute);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regData = ReadReg(pVdaaHW,pVdaa->channel,TXRX_GN_CTRL);
+
+ switch(mute)
+ {
+ case MUTE_DISABLE_ALL:
+ regData = 0;
+ break;
+
+ case MUTE_DISABLE_RX:
+ regData &= 0x80;
+ break;
+
+ case MUTE_DISABLE_TX:
+ regData &= 0x08;
+ break;
+
+ case MUTE_ENABLE_RX:
+ regData |= 0x08;
+ break;
+
+ case MUTE_ENABLE_TX:
+ regData |= 0x80;
+ break;
+
+ case MUTE_ENABLE_ALL:
+ regData = 0x88;
+ break;
+ }
+
+ WriteReg(pVdaaHW,pVdaa->channel,TXRX_GN_CTRL,regData);
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_PCMStart
+**
+** Description:
+** Enables PCM bus
+**
+*/
+
+int Vdaa_PCMStart (vdaaChanType *pVdaa)
+{
+ uInt8 data = 0;
+
+ TRACEPRINT( pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ /*Enable PCM transfers by setting REG 33[5]=1 */
+ data = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL);
+ data |= 0x20;
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL,data);
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_PCMStop
+**
+** Description:
+** Disables PCM bus
+**
+*/
+
+int Vdaa_PCMStop (vdaaChanType *pVdaa)
+{
+ uInt8 data = 0;
+
+ TRACEPRINT( pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ /*disable PCM transfers by setting REG 33[5]=0 */
+ data = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL);
+ data &= ~(0x20);
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL,data);
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_SetInterruptMask
+**
+** Description:
+** Enables interrupts based on passed 9-bit bitmask. Bit
+** values defined by vdaaIntMask enum.
+**
+*/
+
+int Vdaa_SetInterruptMask(vdaaChanType *pVdaa, vdaaIntMask bitmask)
+{
+ uInt8 intMaskReg = 0;
+ uInt8 cviReg = 0;
+
+ TRACEPRINT( pVdaa, "mask = 0x%03x\n", (unsigned int)bitmask);
+ /* Channel validation */
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_CHANNEL_TYPE_ERR;
+ }
+
+ intMaskReg = (uInt8)(bitmask & 0x00ff);
+ cviReg = ReadReg(pVdaaHW,pVdaa->channel,LN_VI_THRESH_INTE_CTRL);
+ cviReg |= (uInt8) ((bitmask >> 7) & 0x0002);
+
+ WriteReg (pVdaaHW,pVdaa->channel,INTE_MSK,intMaskReg);
+ WriteReg(pVdaaHW,pVdaa->channel,LN_VI_THRESH_INTE_CTRL,cviReg);
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_ReadRingDetectStatus
+**
+** Description:
+** Reads ring detect/hook status
+**
+** Returns:
+**
+**
+*/
+
+int Vdaa_ReadRingDetectStatus (vdaaChanType *pVdaa,
+ vdaaRingDetectStatusType *pStatus)
+{
+ uInt8 reg;
+
+ TRACEPRINT( pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ reg = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL1);
+ pStatus->offhook = reg & 0x01;
+ pStatus->ringDetected = (reg & 0x4)>>2;
+ pStatus->onhookLineMonitor = (reg & 0x8)>>3;
+ pStatus->ringDetectedPos = (reg & 0x20)>>5;
+ pStatus->ringDetectedNeg = (reg & 0x40)>>6;
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_Init
+**
+** Description:
+** Initialize VDAA, load general config parameters
+**
+*/
+
+extern vdaa_General_Cfg Vdaa_General_Configuration;
+
+int Vdaa_Init (vdaaChanType_ptr *pVdaa,int size)
+{
+ uInt8 data;
+ int k;
+ int num_devices = 0;
+
+ TRACEPRINT( *pVdaa, "size = %d\n", size);
+
+ for (k=0; k<size; k++)
+ {
+
+ if(pVdaa[k]->channelType == PROSLIC)
+ {
+ continue; /* Skip if we know this is a ProSLIC, else check the device out */
+ }
+
+ if (isVerifiedDAA(pVdaa[k]) == RC_CHANNEL_TYPE_ERR)
+ {
+ pVdaa[k]->channelEnable = FALSE;
+ pVdaa[k]->error = RC_CHANNEL_TYPE_ERR;
+ pVdaa[k]->channelType = UNKNOWN;
+ DEBUG_PRINT(pVdaa[k], "%sVDAA not supported on this device\n",LOGPRINT_PREFIX);
+ continue;
+ }
+ else
+ {
+ pVdaa[k]->channelType = DAA;
+ }
+
+ if (pVdaa[k]->channelEnable)
+ {
+ /*Try to write innocuous register to test SPI is working*/
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,PCMRX_CNT_LO,0x5A);
+ data = pVdaa[k]->ReadRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,PCMRX_CNT_LO);
+ if (data != 0x5A)
+ {
+ pVdaa[k]->error = RC_SPI_FAIL;
+ pVdaa[k]->channelEnable = FALSE;
+ DEBUG_PRINT(pVdaa[k], "%sVDAA %d not communicating\n",LOGPRINT_PREFIX,
+ pVdaa[k]->channel);
+ }
+ else
+ {
+ num_devices++;
+ }
+ }
+ }
+
+ if(num_devices == 0)
+ {
+ DEBUG_PRINT(*pVdaa, "%sNo DAA devices detected\n", LOGPRINT_PREFIX);
+ return RC_SPI_FAIL;
+ }
+
+ for (k=0; k<size; k++)
+ {
+ if(pVdaa[k]->channelType != DAA)
+ {
+ continue; /* Skip PROSLIC or UNDEFINED ports */
+ }
+ if (pVdaa[k]->channelEnable)
+ {
+
+ /* Apply General Configuration parameters */
+
+ /* No need to read-modify-write here since registers are in their reset state */
+ data = (Vdaa_General_Configuration.pwmm << 4) |
+ (Vdaa_General_Configuration.pwmEnable << 3);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,CTRL1, data);
+
+ data = (Vdaa_General_Configuration.inte << 7) | (Vdaa_General_Configuration.intp
+ << 6) | 0x03;
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,CTRL2, data);
+
+ data = (Vdaa_General_Configuration.hssm << 3);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,SMPL_CTRL, data);
+
+ data = (Vdaa_General_Configuration.iire << 4);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,INTL_CTRL1, data);
+
+ data = (Vdaa_General_Configuration.rcald << 4);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,RES_CALIB, data);
+
+ data = (Vdaa_General_Configuration.full2 << 4);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,AC_TERM_CTRL, data);
+
+ data = (Vdaa_General_Configuration.lvfd) | (Vdaa_General_Configuration.filt <<
+ 1) |
+ (Vdaa_General_Configuration.foh << 5) | (Vdaa_General_Configuration.full << 7);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,DAA_CTRL5, data);
+
+ data = (Vdaa_General_Configuration.spim << 6);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,PCM_SPI_CTRL, data);
+
+ data = (Vdaa_General_Configuration.cvp) | (Vdaa_General_Configuration.cvs << 2);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,LN_VI_THRESH_INTE_CTRL,
+ data);
+
+ data = (Vdaa_General_Configuration.gce << 1) | (Vdaa_General_Configuration.rg1
+ << 2);
+ pVdaa[k]->WriteRegX(pVdaa[k]->pVdaaHWX,pVdaa[k]->channel,SPRK_QNCH_CTRL, data);
+
+ /* Enable Lineside Device */
+ Vdaa_PowerupLineside(pVdaa[k]);
+ }
+ }
+ DEBUG_PRINT(*pVdaa,"%sDAA initialization completed\n",LOGPRINT_PREFIX);
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_ReadLinefeedStatus
+**
+** Description:
+** Read Status of Line Feed
+**
+** Returns:
+** RC_VDAA_ILOOP_OVLD if LCS >= 0x1F
+** - no overload
+**
+*/
+
+int Vdaa_ReadLinefeedStatus (vdaaChanType *pVdaa,int8 *vloop, int16 *iloop)
+{
+ int16 regTemp = 0x1F;
+ uInt8 iloop_reg; /* REG 12[4:0] = Loop current*/
+
+ TRACEPRINT( pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+ regTemp &= ReadReg(pVdaaHW,pVdaa->channel,LSIDE_STAT);
+ iloop_reg = (uInt8)regTemp;
+ *iloop = (regTemp*LCS_SCALE_NUM) /
+ LCS_SCALE_DEN; /* Multiply the read result by 3.3mA/bit*/
+
+ *vloop = (int8) ReadReg(pVdaaHW,pVdaa->channel,LINE_VOLT_STAT);
+ if(*vloop & 0x80)
+ {
+ *vloop = ~(*vloop - 1)*(-1);
+ }
+
+ if (iloop_reg == 0x1F)
+ {
+ return RC_VDAA_ILOOP_OVLD;
+ }
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_GetInterrupts
+**
+** Description:
+** Get Interrupts
+**
+** Returns:
+** number of interrupts
+**
+*/
+
+int Vdaa_GetInterrupts (vdaaChanType *pVdaa,vdaaIntType *pIntData)
+{
+ uInt8 data = 0;
+ int j;
+ TRACEPRINT( pVdaa, "\n", NULL);
+ pIntData->number = 0;
+
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ data = ReadReg(pVdaaHW,pVdaa->channel,INTE_SRC); /*Snapshot Interrupts*/
+ WriteReg(pVdaaHW,pVdaa->channel,INTE_SRC,~(data)); /*Clear interrupts*/
+
+ for (j=0; j<8; j++)
+ {
+ if (data &(1<<j))
+ {
+
+ pIntData->irqs[pIntData->number] = j;
+ pIntData->number++;
+
+ }
+ }
+ data = ReadReg(pVdaaHW,pVdaa->channel,LN_VI_THRESH_INTE_CTRL);
+
+ if (data &(0x08)) /*to determine if CVI Interrupt is set*/
+ {
+ pIntData->irqs[pIntData->number] = CVI;
+ pIntData->number++;
+ data &= ~(0x08);
+ WriteReg(pVdaaHW,pVdaa->channel,LN_VI_THRESH_INTE_CTRL,data);
+
+ }
+
+ return pIntData->number;
+}
+
+/*
+** Function: Vdaa_ClearInterrupts
+**
+** Description:
+** Clear Interrupts
+**
+** Returns:
+**
+**
+*/
+
+int Vdaa_ClearInterrupts (vdaaChanType *pVdaa)
+{
+ uInt8 data = 0;
+
+ TRACEPRINT( pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteReg(pVdaaHW,pVdaa->channel,INTE_SRC,
+ 0x00); /* Clear interrupts in REG 4 by writing 0's*/
+
+ /*Clear CVI interrupt by writing 0 at REG 44[3]*/
+ data = ReadReg(pVdaaHW,pVdaa->channel,LN_VI_THRESH_INTE_CTRL);
+ WriteReg(pVdaaHW,pVdaa->channel,LN_VI_THRESH_INTE_CTRL,data&0xF7);
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_GetHookStatus
+**
+** Description:
+** Read VDAA Hook Status
+**
+** Return Values -
+** VDAA_ONHOOK
+** VDAA_OFFHOOK
+** VDAA_ONHOOK_MONITOR
+** RC_INVALID_HOOK_STATUS
+*/
+
+uInt8 Vdaa_GetHookStatus (vdaaChanType *pVdaa)
+{
+ uInt8 data;
+
+ TRACEPRINT( pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL1);
+ data &= 0x09; /* Look at only ONHM and OH */
+
+ if((data & 0x80)&&(data & 0x01))
+ {
+ return VDAA_ONHOOK_MONITOR;
+ }
+ else if (data & 0x01)
+ {
+ return VDAA_OFFHOOK;
+ }
+ else
+ {
+ return VDAA_ONHOOK;
+ }
+}
+
+/*
+** Function: Vdaa_SetHookStatus
+**
+** Description:
+** Set VDAA Hook switch to ONHOOK, OFFHOOK,
+** or ONHOOK_MONITOR
+**
+*/
+
+int Vdaa_SetHookStatus (vdaaChanType *pVdaa,uInt8 newHookStatus)
+{
+ uInt8 data= 0 ;
+
+ TRACEPRINT( pVdaa, "hookstate = %u\n", (unsigned int) newHookStatus);
+
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ switch (newHookStatus)
+ {
+ case VDAA_DIG_LOOPBACK:
+ /*Setting REG6[4]=1,REG5[0]=0,REG5[3]=0*/
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL2);
+ data |= 0x10;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL2,data);
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL1);
+ data &= ~(0x09);
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL1,data);
+ break;
+
+ case VDAA_ONHOOK:
+ /*Setting REG6[4]=0,REG5[0]=0,REG5[3]=0*/
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL1);
+ data &= 0xF6;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL1,data);
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL2);
+ data &= 0xEF;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL2,data);
+ break;
+
+ case VDAA_OFFHOOK:
+ /*Setting REG6[4]=0,REG5[0]=1,REG5[3]=0*/
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL1);
+ data &= 0xF7;
+ data |= 0x01;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL1,data);
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL2);
+ data &= 0xEF;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL2,data);
+ break;
+
+ case VDAA_ONHOOK_MONITOR:
+ /*Setting REG6[4]=0,REG5[0]=0,REG5[3]=1*/
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL1);
+ data &= 0xFE;
+ data |= 0x08;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL1,data);
+ data = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL2);
+ data &= 0xEF;
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL2,data);
+ break;
+
+ default:
+ return RC_UNSUPPORTED_OPTION;
+ }
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_SetLoopbackMode
+**
+** Description:
+** Loopback mode control
+**
+*/
+
+int Vdaa_SetLoopbackMode(vdaaChanType_ptr pVdaa, tLpbkMode lpbk_mode,
+ tLpbkStatus lpbk_status)
+{
+ uInt8 regData;
+
+ TRACEPRINT(pVdaa, "lpbk_mode = %u lpbk_status = %d\n", (unsigned int) lpbk_mode,
+ (unsigned int) lpbk_status);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ switch(lpbk_mode)
+ {
+ case LPBK_NONE:
+ /* Disable all loopback types, regardless of lpbk_status */
+ regData = ReadReg(pVdaaHW,pVdaa->channel,CTRL1);
+ if(regData & 0x02)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL1, regData & ~(0x02));
+ }
+
+ regData = ReadReg(pVdaaHW,pVdaa->channel,DAA_CTRL3);
+ if(regData & 0x01)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL3,0);
+ }
+
+ regData = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL);
+ if(regData & 0x80)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL, regData & ~(0x80));
+ }
+ break;
+
+ case LPBK_IDL:
+ if(lpbk_status)
+ {
+ regData = ReadReg(pVdaaHW,pVdaa->channel,CTRL1);
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL1, regData | 0x02);
+ }
+ else
+ {
+ regData = ReadReg(pVdaaHW,pVdaa->channel,CTRL1);
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL1, regData & ~(0x02));
+ }
+ break;
+
+ case LPBK_DDL:
+ if(lpbk_status)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL3, 0x01);
+ }
+ else
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL3, 0);
+ }
+ break;
+
+ case LPBK_PCML:
+ if(lpbk_status)
+ {
+ regData = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL);
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL, regData | 0x80);
+ }
+ else
+ {
+ regData = ReadReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL);
+ WriteReg(pVdaaHW,pVdaa->channel,PCM_SPI_CTRL, regData & ~(0x80));
+ }
+ break;
+
+ default:
+ return RC_UNSUPPORTED_OPTION;
+ }
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_ADCCal
+**
+** Description:
+** This function calibrates the VDAA ADC manually
+**
+*/
+
+int Vdaa_ADCCal (vdaaChanType_ptr pVdaa, int32 size)
+{
+ uInt8 regTemp = 0;
+ int32 i;
+
+ TRACEPRINT(pVdaa, "size = %d\n", (int) size);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ for(i = 0; i < size; i++)
+ {
+ /* Clear the previous ADC Calibration data by toggling CALZ*/
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,INTL_CTRL2);
+ regTemp |= 0x80;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL2,regTemp);
+ regTemp &= ~0x80;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL2,regTemp);
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,INTL_CTRL2); /*disable auto cal*/
+ regTemp |= 0x20;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL2,regTemp);
+
+ regTemp |= 0x40; /*initiate manual cal*/
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL2,regTemp);
+ regTemp &= ~0x40;
+ WriteReg(pVdaaHW,pVdaa->channel,INTL_CTRL2,regTemp);
+ pVdaa++;
+ }
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_EnableWatchdog
+**
+** Description:
+** Enables watchdog timer
+**
+*/
+
+int Vdaa_EnableWatchdog(vdaaChanType_ptr pVdaa)
+{
+ uInt8 regTemp;
+
+ TRACEPRINT(pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,CTRL2);
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regTemp | 0x10);
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_SetHybridEnable
+**
+** Description:
+** Enables watchdog timer
+**
+*/
+
+int Vdaa_SetHybridEnable(vdaaChanType_ptr pVdaa, int enable)
+{
+ uInt8 regTemp;
+ TRACEPRINT(pVdaa, "enable = %d\n", enable);
+
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ regTemp = ReadReg(pVdaaHW,pVdaa->channel,CTRL2);
+ if(enable)
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regTemp | 0x02);
+ }
+ else
+ {
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL2,regTemp & ~(0x02));
+ }
+
+ return RC_NONE;
+}
+
+
+/*
+** Function: Vdaa_SoftReset
+**
+** Description:
+** Execute soft reset
+**
+*/
+
+int Vdaa_SoftReset(vdaaChanType_ptr pVdaa)
+{
+ TRACEPRINT(pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteReg(pVdaaHW,pVdaa->channel,CTRL1,0x80);
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_ReadFDTStatus
+**
+** Description:
+** Read FDT bit
+**
+** Returns:
+** 0 - Frame Not Detected
+** 1 - Frame Detected
+**
+*/
+
+int Vdaa_ReadFDTStatus(vdaaChanType_ptr pVdaa)
+{
+ TRACEPRINT(pVdaa, "\n", NULL);
+ return (ReadReg(pVdaaHW,pVdaa->channel,LSIDE_REV) & 0x40);
+}
+
+/*
+** Function: Vdaa_PowerupLineside
+**
+** Description:
+** Power up lineside device
+**
+*/
+
+int Vdaa_PowerupLineside(vdaaChanType_ptr pVdaa)
+{
+ uInt8 data;
+
+ TRACEPRINT(pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL2,0); /* Powerup lineside device */
+ /* We do a double read to give the front end time to power up and sync up with the system side.. */
+ data = ReadReg(pVdaaHW,pVdaa->channel,LSIDE_REV);
+ data = 0;
+ data = ReadReg(pVdaaHW,pVdaa->channel,LSIDE_REV);
+ pVdaa->deviceId->lsRev= ((data&0x3C)>>2);
+ data = pVdaa->ReadRegX(pVdaa->pVdaaHWX,pVdaa->channel,SYS_LINE_DEV_REV);
+ pVdaa->deviceId->lsType= ((data&~(0xF))>>4);
+
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_PowerdownLineside
+**
+** Description:
+** Power down lineside device
+**
+*/
+
+int Vdaa_PowerdownLineside(vdaaChanType_ptr pVdaa)
+{
+ TRACEPRINT(pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ WriteReg(pVdaaHW,pVdaa->channel,DAA_CTRL2,0x10);
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_PrintDebugData
+**
+** Description:
+** Dump of VDAA register space
+**
+** Input Parameters:
+** pVdaa: pointer to SiVoiceChanType or vdaaChanType
+**
+*/
+
+int Vdaa_PrintDebugData (vdaaChanType *pVdaa)
+{
+#ifdef ENABLE_DEBUG
+ int i;
+ for (i=0; i<60; i++)
+ {
+ LOGPRINT ("%sRegister %d = %X\n",LOGPRINT_PREFIX,i,ReadReg(pVdaaHW,
+ pVdaa->channel,i));
+ }
+#endif
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_InitLineInUseCheck
+**
+** Description:
+** Set line in use test limits
+**
+** Input Parameters:
+** liuCfg: pointer to vdaa_LIU_Config
+** minOnV: minimum acceptable onhook voltage (below indicates parallel handset)
+** minOffV: minimum acceptable offhook voltage (below indicates parallel handset)
+** minOffI: minimum acceptable offhook loop current (below indicates parallel handset)
+**
+*/
+
+int Vdaa_InitLineInUseCheck(vdaa_LIU_Config *liuCfg, int8 minOnV, int8 minOffV,
+ int16 minOffI)
+{
+ TRACEPRINT_NOCHAN("min0nV = %d minoffV = %d minOffI = %d\n", minOnV, minOffV,
+ minOffI);
+ liuCfg->status = PAR_HANDSET_NOT_DETECTED;
+ liuCfg->min_onhook_vloop = minOnV;
+ liuCfg->min_offhook_vloop = minOffV;
+ liuCfg->min_offhook_iloop = minOffI;
+ return RC_NONE;
+}
+
+/*
+** Function: Vdaa_CheckForLineInUse
+**
+** Description:
+** Monitor LVCS to detect intrusion or parallel handset
+**
+** Input Parameters:
+** pVdaa: pointer to SiVoiceChanType or vdaaChanType
+** liuCfg: pointer to vdaa_LIU_Config
+**
+** Output Parameters:
+**
+** Return:
+** VDAA_ONHOOK - line is onhook
+** VDAA_OFFHOOK - line is offhook (in use)
+**
+*/
+
+uInt8 Vdaa_CheckForLineInUse(vdaaChanType *pVdaa, vdaa_LIU_Config *liuCfg)
+{
+ int8 vloop;
+ int16 iloop;
+
+ TRACEPRINT(pVdaa, "\n", NULL);
+ if(pVdaa->channelType != DAA)
+ {
+ return RC_IGNORE;
+ }
+
+ /* Check voltage and current */
+ Vdaa_ReadLinefeedStatus(pVdaa, &vloop,&iloop);
+ if(vloop < 0)
+ {
+ vloop *= -1;
+ }
+ liuCfg->measured_iloop = iloop;
+ liuCfg->measured_vloop = vloop;
+ liuCfg->status = PAR_HANDSET_NOT_DETECTED;
+
+ /* Read hookswitch status */
+ if(Vdaa_GetHookStatus(pVdaa) == VDAA_OFFHOOK)
+ {
+ if((vloop < liuCfg->min_offhook_vloop)||(iloop < liuCfg->min_offhook_iloop))
+ {
+ liuCfg->status = PAR_HANDSET_DETECTED;
+ }
+
+ return VDAA_OFFHOOK;
+ }
+ else
+ {
+ if(vloop < liuCfg->min_onhook_vloop)
+ {
+ liuCfg->status = PAR_HANDSET_DETECTED;
+ }
+
+ return VDAA_ONHOOK;
+ }
+}
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/vdaa_constants.c b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/vdaa_constants.c
new file mode 100644
index 0000000..9c4606b
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/src/vdaa_constants.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Si3217x ProSLIC API Configuration Tool Version 4.2.1
+ * Last Updated in API Release: 9.2.0
+ * source XML file: si3217x_FLBK_GDRV_constants.xml
+ *
+ * Auto generated file from configuration tool.
+ */
+
+#include "../inc/vdaa.h"
+
+vdaa_General_Cfg Vdaa_General_Configuration = {
+ INTE_DISABLED,
+ INTE_ACTIVE_LOW,
+ RES_CAL_ENABLED,
+ FS_8KHZ,
+ FOH_128,
+ LVS_FORCE_ENABLED,
+ CVS_CURRENT,
+ CVP_ABOVE,
+ GCE_DISABLED,
+ IIR_DISABLED,
+ FULL2_ENABLED,
+ FULL_DISABLED,
+ FILT_HPF_200HZ,
+ RG1_DISABLED,
+ PWM_DELTA_SIGMA,
+ PWM_DISABLED,
+ SPIM_TRI_CS
+};
+
+vdaa_Country_Cfg Vdaa_Country_Presets[] ={
+ {
+ RZ_MAX,
+ DC_50,
+ AC_600,
+ DCV3_5,
+ MINI_10MA,
+ ILIM_DISABLED,
+ OHS_LESS_THAN_0_5MS,
+ HYBRID_ENABLED
+ }, /* COU_USA */
+ {
+ RZ_MAX,
+ DC_50,
+ AC_270__750_150,
+ DCV3_5,
+ MINI_10MA,
+ ILIM_ENABLED,
+ OHS_3MS,
+ HYBRID_ENABLED
+ }, /* COU_GERMANY */
+ {
+ RZ_MAX,
+ DC_50,
+ AC_200__680_100,
+ DCV3_5,
+ MINI_10MA,
+ ILIM_DISABLED,
+ OHS_LESS_THAN_0_5MS,
+ HYBRID_ENABLED
+ }, /* COU_CHINA */
+ {
+ RZ_MAX,
+ DC_50,
+ AC_220__820_120,
+ DCV3_2,
+ MINI_12MA,
+ ILIM_DISABLED,
+ OHS_26MS,
+ HYBRID_ENABLED
+ } /* COU_AUSTRALIA */
+};
+
+vdaa_audioGain_Cfg Vdaa_audioGain_Presets[] ={
+ {
+ 0, /* mute */
+ XGA_GAIN, /* xXGA2 */
+ 0, /* xXG2 */
+ XGA_GAIN, /* xXGA3 */
+ 0, /* xXG3 */
+ 64, /* AxM */
+ 0 /* cpEn */
+ }, /* AUDIO_GAIN_0DB */
+ {
+ 0, /* mute */
+ XGA_ATTEN, /* xXGA2 */
+ 4, /* xXG2 */
+ XGA_GAIN, /* xXGA3 */
+ 0, /* xXG3 */
+ 64, /* AxM */
+ 0 /* cpEn */
+ }, /* AUDIO_ATTEN_4DB */
+ {
+ 0, /* mute */
+ XGA_ATTEN, /* xXGA2 */
+ 6, /* xXG2 */
+ XGA_GAIN, /* xXGA3 */
+ 0, /* xXG3 */
+ 64, /* AxM */
+ 0 /* cpEn */
+ }, /* AUDIO_ATTEN_6DB */
+ {
+ 0, /* mute */
+ XGA_ATTEN, /* xXGA2 */
+ 11, /* xXG2 */
+ XGA_GAIN, /* xXGA3 */
+ 0, /* xXG3 */
+ 64, /* AxM */
+ 0 /* cpEn */
+ } /* AUDIO_ATTEN_11DB */
+};
+
+vdaa_Ring_Detect_Cfg Vdaa_Ring_Detect_Presets[] ={
+ {
+ RDLY_512MS,
+ RT__13_5VRMS_16_5VRMS,
+ 12, /* RMX */
+ RTO_1408MS,
+ RCC_640MS,
+ RNGV_DISABLED,
+ 17, /* RAS */
+ RFWE_HALF_WAVE,
+ RDI_BEG_END_BURST,
+ RGDT_ACTIVE_LOW
+ }, /* RING_DET_NOVAL_LOWV */
+ {
+ RDLY_512MS,
+ RT__40_5VRMS_49_5VRMS,
+ 12, /* RMX */
+ RTO_1408MS,
+ RCC_640MS,
+ RNGV_ENABLED,
+ 17, /* RAS */
+ RFWE_RNGV_RING_ENV,
+ RDI_BEG_END_BURST,
+ RGDT_ACTIVE_LOW
+ } /* RING_DET_VAL_HIGHV */
+};
+
+vdaa_PCM_Cfg Vdaa_PCM_Presets[] ={
+ {
+ U_LAW,
+ PCLK_1_PER_BIT,
+ TRI_POS_EDGE
+ }, /* DAA_PCM_8ULAW */
+ {
+ A_LAW,
+ PCLK_1_PER_BIT,
+ TRI_POS_EDGE
+ }, /* DAA_PCM_8ALAW */
+ {
+ LINEAR_16_BIT,
+ PCLK_1_PER_BIT,
+ TRI_POS_EDGE
+ } /* DAA_PCM_16LIN */
+};
+
+vdaa_Hybrid_Cfg Vdaa_Hybrid_Presets[] ={
+ {
+ 0, /* HYB1 */
+ 254, /* HYB2 */
+ 0, /* HYB3 */
+ 1, /* HYB4 */
+ 255, /* HYB5 */
+ 1, /* HYB6 */
+ 0, /* HYB7 */
+ 0 /* HYB8 */
+ }, /* HYB_600_0_0_500FT_24AWG */
+ {
+ 4, /* HYB1 */
+ 246, /* HYB2 */
+ 242, /* HYB3 */
+ 4, /* HYB4 */
+ 254, /* HYB5 */
+ 255, /* HYB6 */
+ 1, /* HYB7 */
+ 255 /* HYB8 */
+ }, /* HYB_270_750_150_500FT_24AWG */
+ {
+ 4, /* HYB1 */
+ 245, /* HYB2 */
+ 243, /* HYB3 */
+ 7, /* HYB4 */
+ 253, /* HYB5 */
+ 0, /* HYB6 */
+ 1, /* HYB7 */
+ 255 /* HYB8 */
+ }, /* HYB_200_680_100_500FT_24AWG */
+ {
+ 4, /* HYB1 */
+ 244, /* HYB2 */
+ 241, /* HYB3 */
+ 6, /* HYB4 */
+ 253, /* HYB5 */
+ 255, /* HYB6 */
+ 2, /* HYB7 */
+ 255 /* HYB8 */
+ } /* HYB_220_820_120_500FT_24AWG */
+};
+
diff --git a/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/timer.h b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/timer.h
new file mode 100644
index 0000000..02b8a01
--- /dev/null
+++ b/target/linux/mediatek/files-5.4/sound/soc/codecs/si3218x/timer.h
@@ -0,0 +1,89 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * $Id: Timer.h 109 2008-10-22 19:45:09Z lajordan@SILABS.COM $
+ *
+ * This file is system specific and should be edited for your hardware platform
+ *
+ * This file is used by proslic_timer_intf.h and proslic_spiGci.h
+ */
+#ifndef TIME_TYPE_H
+#define TIME_TYPE_H
+
+typedef long long _int64;
+
+/*
+** System timer interface structure
+*/
+typedef struct{
+ _int64 ticksPerSecond;
+} systemTimer_S;
+
+/*
+** System time stamp
+*/
+typedef struct{
+ _int64 time;
+} timeStamp;
+
+/*
+** Function: SYSTEM_TimerInit
+**
+** Description:
+** Initializes the timer used in the delay and time measurement functions
+** by doing a long inaccurate sleep and counting the ticks
+**
+** Input Parameters:
+**
+** Return:
+** none
+*/
+void TimerInit (systemTimer_S *pTimerObj);
+/*
+** Function: DelayWrapper
+**
+** Description:
+** Waits the specified number of ms
+**
+** Input Parameters:
+** hTimer: timer pointer
+** timeInMs: time in ms to wait
+**
+** Return:
+** none
+*/
+int time_DelayWrapper (void *hTimer, int timeInMs);
+
+
+/*
+** Function: TimeElapsedWrapper
+**
+** Description:
+** Calculates number of ms that have elapsed
+**
+** Input Parameters:
+** hTImer: pointer to timer object
+** startTime: timer value when function last called
+** timeInMs: pointer to time elapsed
+**
+** Return:
+** timeInMs: time elapsed since start time
+*/
+int time_TimeElapsedWrapper (void *hTimer, void *startTime, int *timeInMs);
+
+int time_GetTimeWrapper (void *hTimer, void *time);
+#endif
+/*
+** $Log: Timer.h,v $
+** Revision 1.2 2007/02/21 16:55:18 lajordan
+** moved function prototypes here
+**
+** Revision 1.1 2007/02/16 23:55:07 lajordan
+** no message
+**
+** Revision 1.2 2007/02/15 23:33:25 lajordan
+** no message
+**
+** Revision 1.1.1.1 2006/07/13 20:26:08 lajordan
+** no message
+**
+*/