[][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/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;
+}
+