From 53f96bc4f8328fd3b146418a50adfa12cebe744b Mon Sep 17 00:00:00 2001 From: Peter Li Date: Sun, 26 Mar 2017 16:24:36 +0800 Subject: [PATCH] 1. IRQ use Level trigger 2. add clock error detection 3. prepare for PPC3 TAS2557 app driver version 0x300 update --- tas2557-codec.c | 51 +++++++++ tas2557-core.c | 269 +++++++++++++++++++++++++++++++++-------------- tas2557-core.h | 1 + tas2557-misc.c | 158 +++++++++++++++++----------- tas2557-regmap.c | 96 +++++++++++++++-- tas2557.h | 58 +++++++--- 6 files changed, 463 insertions(+), 170 deletions(-) diff --git a/tas2557-codec.c b/tas2557-codec.c index 0650da9..2bd6fb4 100755 --- a/tas2557-codec.c +++ b/tas2557-codec.c @@ -426,6 +426,55 @@ static DECLARE_TLV_DB_SCALE(dac_tlv, 0, 100, 0); +static const char * const chl_setup_text[] = { + "default", + "DevA-Mute", + "DevA-Left", + "DevA-Right", + "DevA-MonoMix" +}; +static const struct soc_enum chl_setup_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(chl_setup_text), chl_setup_text), +}; + +static int tas2557_dsp_chl_setup_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnChannelState; + + mutex_unlock(&pTAS2557->codec_lock); + + return 0; +} + +static int tas2557_dsp_chl_setup_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + int channel_state = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + tas2557_SA_DevChnSetup(pTAS2557, channel_state); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + static const struct snd_kcontrol_new tas2557_snd_controls[] = { SOC_SINGLE_TLV("DAC Playback Volume", TAS2557_SPK_CTRL_REG, 3, 0x0f, 0, dac_tlv), @@ -439,6 +488,8 @@ static const struct snd_kcontrol_new tas2557_snd_controls[] = { tas2557_fs_get, tas2557_fs_put), SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0, tas2557_calibration_get, tas2557_calibration_put), + SOC_ENUM_EXT("DSPChl Setup", chl_setup_enum[0], + tas2557_dsp_chl_setup_get, tas2557_dsp_chl_setup_put), }; static struct snd_soc_codec_driver soc_codec_driver_tas2557 = { diff --git a/tas2557-core.c b/tas2557-core.c index d7d5bbb..4bc1cfa 100755 --- a/tas2557-core.c +++ b/tas2557-core.c @@ -41,7 +41,9 @@ #include "tas2557.h" #include "tas2557-core.h" -#define PPC_DRIVER_VERSION 0x00000200 +#define PPC_DRIVER_CRCCHK 0x00000200 +#define PPC_DRIVER_CONFDEV 0x00000300 + #define TAS2557_CAL_NAME "/data/tas2557_cal.bin" @@ -70,20 +72,20 @@ static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, static unsigned int p_tas2557_default_data[] = { TAS2557_SAR_ADC2_REG, 0x05, /* enable SAR ADC */ -/*TODO TAS2555_CLK_ERR_CTRL2, 0x39, enable clock error detection on PLL */ -/*TODO TAS2555_CLK_ERR_CTRL3, 0x11, enable clock error detection on PLL */ + TAS2557_CLK_ERR_CTRL2, 0x21, /*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/ + TAS2557_CLK_ERR_CTRL3, 0x21, /*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */ TAS2557_SAFE_GUARD_REG, TAS2557_SAFE_GUARD_PATTERN, /* safe guard */ 0xFFFFFFFF, 0xFFFFFFFF }; static unsigned int p_tas2557_irq_config[] = { -/* TAS2555_CLK_HALT_REG, 0x71, TODO */ + TAS2557_CLK_HALT_REG, 0x71, /* enable clk halt detect2 interrupt */ TAS2557_INT_GEN1_REG, 0x11, /* enable spk OC and OV */ TAS2557_INT_GEN2_REG, 0x11, /* enable clk err1 and die OT */ TAS2557_INT_GEN3_REG, 0x11, /* enable clk err2 and brownout */ TAS2557_INT_GEN4_REG, 0x01, /* disable SAR, enable clk halt */ - TAS2557_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */ TAS2557_GPIO4_PIN_REG, 0x07, /* set GPIO4 as int1, default */ + TAS2557_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */ 0xFFFFFFFF, 0xFFFFFFFF }; @@ -91,12 +93,11 @@ static unsigned int p_tas2557_startup_data[] = { TAS2557_GPI_PIN_REG, 0x15, /* enable DIN, MCLK, CCI */ TAS2557_GPIO1_PIN_REG, 0x01, /* enable BCLK */ TAS2557_GPIO2_PIN_REG, 0x01, /* enable WCLK */ - TAS2557_CLK_ERR_CTRL, 0x00, /* enable clock error detection */ TAS2557_POWER_CTRL2_REG, 0xA0, /* Class-D, Boost power up */ TAS2557_POWER_CTRL2_REG, 0xA3, /* Class-D, Boost, IV sense power up */ TAS2557_POWER_CTRL1_REG, 0xF8, /* PLL, DSP, clock dividers power up */ - TAS2557_UDELAY, 2000, /* delay */ -/* TAS2557_CLK_ERR_CTRL, 0x03, TODO enable clock error detection */ + TAS2557_UDELAY, 2000, /* delay */ + TAS2557_CLK_ERR_CTRL, 0x03, /* enable clock error detection */ 0xFFFFFFFF, 0xFFFFFFFF }; @@ -121,13 +122,6 @@ static unsigned int p_tas2557_shutdown_data[] = { 0xFFFFFFFF, 0xFFFFFFFF }; -static unsigned int p_tas2557_mute_DSP_down_data[] = { - TAS2557_MUTE_REG, 0x03, /* mute */ - TAS2557_POWER_CTRL1_REG, 0x60, /* DSP power down */ - TAS2557_UDELAY, 0xFF, /* delay */ - 0xFFFFFFFF, 0xFFFFFFFF -}; - static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557, unsigned int *pData) { @@ -156,6 +150,79 @@ int tas2557_configIRQ(struct tas2557_priv *pTAS2557) return tas2557_dev_load_data(pTAS2557, p_tas2557_irq_config); } +/* +* for PG2.1 Dual Mono +*/ +int tas2557_SA_DevChnSetup(struct tas2557_priv *pTAS2557, unsigned int mode) +{ + int nResult = 0; + struct TProgram *pProgram; + unsigned char buf_mute[16] = {0}; + unsigned char buf_DevA_Left[16] = {0x40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + unsigned char buf_DevA_Right[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0x40, 0, 0, 0, 0, 0, 0, 0}; + unsigned char buf_DevA_MonoMix[16] = {0x20, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0, 0, 0, 0, 0}; + unsigned char *pDevABuf; + + dev_dbg(pTAS2557->dev, "%s, mode %d\n", __func__, mode); + if ((pTAS2557->mpFirmware->mnPrograms == 0) + || (pTAS2557->mpFirmware->mnConfigurations == 0)) { + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (pProgram->mnAppMode != TAS2557_APP_TUNINGMODE) { + dev_err(pTAS2557->dev, "%s, not tuning mode\n", __func__); + goto end; + } + + if (pTAS2557->mnPGID != TAS2557_PG_VERSION_2P1) { + dev_err(pTAS2557->dev, "%s, currently we only support PG2.1\n", __func__); + goto end; + } + + if (pTAS2557->mbLoadConfigurationPrePowerUp) { + dev_dbg(pTAS2557->dev, "%s, setup channel after coeff update\n", __func__); + pTAS2557->mnChannelState = mode; + goto end; + } + + switch (mode) { + case TAS2557_DEVA_CHL_DEFAULT: + pDevABuf = pTAS2557->mnDevAChlData; + break; + + case TAS2557_DEVA_CHL_MUTE: + pDevABuf = buf_mute; + break; + + case TAS2557_DEVA_CHL_LEFT: + pDevABuf = buf_DevA_Left; + break; + + case TAS2557_DEVA_CHL_RIGHT: + pDevABuf = buf_DevA_Right; + break; + + case TAS2557_DEVA_CHL_MONOMIX: + pDevABuf = buf_DevA_MonoMix; + break; + default: + break; + } + + if (pDevABuf) { + nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_SA_PG2P1_CHL_CTRL_REG, pDevABuf, 16); + if (nResult < 0) + goto end; + pTAS2557->mnChannelState = mode; + } + +end: + + return nResult; +} + int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate) { int ret = 0, n = -1; @@ -287,6 +354,10 @@ end: static void failsafe(struct tas2557_priv *pTAS2557) { dev_err(pTAS2557->dev, "%s\n", __func__); + pTAS2557->mnErrCode |= ERROR_FAILSAFE; + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + pTAS2557->enableIRQ(pTAS2557, false); tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); pTAS2557->mbPowerUp = false; pTAS2557->hw_reset(pTAS2557); @@ -297,6 +368,15 @@ static void failsafe(struct tas2557_priv *pTAS2557) tas2557_clear_firmware(pTAS2557->mpFirmware); } +int tas2557_checkPLL(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; +/* +* TO DO +*/ + + return nResult; +} /* * tas2557_load_coefficient @@ -329,7 +409,7 @@ static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557, pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]); pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]); - + pTAS2557->mnCurrentConfiguration = nNewConfig; if (pPrevConfiguration) { if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) { dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__); @@ -346,7 +426,7 @@ static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557, if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) pTAS2557->enableIRQ(pTAS2557, false); - nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_mute_DSP_down_data); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); if (nResult < 0) goto end; bRestorePower = true; @@ -360,6 +440,7 @@ static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557, if (nResult < 0) goto end; pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate; + dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n", pNewConfiguration->mpName); nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A); @@ -373,7 +454,17 @@ prog_coefficient: TAS2557_BLOCK_CFG_COEFF_DEV_A); if (nResult < 0) goto end; - pTAS2557->mnCurrentConfiguration = nNewConfig; + if (pTAS2557->mnChannelState == TAS2557_DEVA_CHL_DEFAULT) { + nResult = pTAS2557->bulk_read(pTAS2557, + TAS2557_SA_PG2P1_CHL_CTRL_REG, pTAS2557->mnDevAChlData, 16); + if (nResult < 0) + goto end; + } else { + nResult = tas2557_SA_DevChnSetup(pTAS2557, pTAS2557->mnChannelState); + if (nResult < 0) + goto end; + } + if (pTAS2557->mpCalFirmware->mnCalibrations) { pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]); dev_dbg(pTAS2557->dev, "load calibration\n"); @@ -389,6 +480,12 @@ prog_coefficient: nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); if (nResult < 0) goto end; + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } dev_dbg(pTAS2557->dev, "device powered up, load unmute\n"); nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); @@ -410,8 +507,7 @@ end: int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable) { - int nResult = 0, nRetry = 10; - unsigned char nBuf[4]; + int nResult = 0; unsigned int nValue; struct TProgram *pProgram; @@ -444,45 +540,19 @@ int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable) pTAS2557->mbLoadConfigurationPrePowerUp = false; } - if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { - dev_dbg(pTAS2557->dev, "Tuning mode, check PLL\n"); - /* check PLL */ -pllcheck: - nResult = pTAS2557->write(pTAS2557, TAS2557_POWER_CTRL1_REG, 0xf8); - if (nResult < 0) - goto end; - msleep(2); - /* check TAS2557 */ - memset(nBuf, 0, 4); - nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_XMEM_44_REG, nBuf, 4); - if (nResult < 0) - goto end; - nValue = ((unsigned int)nBuf[0] << 24) | ((unsigned int)nBuf[1] << 16) | ((unsigned int)nBuf[2] << 8) | nBuf[3]; - if (nValue == 0) { - nResult = pTAS2557->write(pTAS2557, TAS2557_POWER_CTRL1_REG, 0x60); - if (nResult < 0) - goto end; - msleep(2); - nResult = pTAS2557->write(pTAS2557, TAS2557_POWER_CTRL1_REG, 0x00); - if (nResult < 0) - goto end; - msleep(2); - nRetry--; - nResult = -EAGAIN; - if (nRetry == 0) - goto end; - - dev_info(pTAS2557->dev, "PLL is absent, check again %d\n", nRetry); - goto pllcheck; - } - } - pTAS2557->clearIRQ(pTAS2557); /* power on device */ dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n"); nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); if (nResult < 0) goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + goto end; + } + } dev_dbg(pTAS2557->dev, "Enable: load unmute sequence\n"); nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); if (nResult < 0) @@ -521,11 +591,8 @@ pllcheck: end: if (nResult < 0) { - if (nRetry == 0) - dev_err(pTAS2557->dev, "PLL is absent and enable timeout\n"); - else - dev_err(pTAS2557->dev, "enable failure %d\n", nResult); - failsafe(pTAS2557); + if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); } return nResult; @@ -533,9 +600,9 @@ end: int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate) { + int nResult = 0; struct TConfiguration *pConfiguration; unsigned int nConfiguration; - int nResult = 0; dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n", nSamplingRate); @@ -645,7 +712,8 @@ static int fw_parse_header(struct tas2557_priv *pTAS2557, pFirmware->mnDeviceFamily = fw_convert_number(pData); pData += 4; if (pFirmware->mnDeviceFamily != 0) { - dev_err(pTAS2557->dev, "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily); + dev_err(pTAS2557->dev, + "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily); return -EINVAL; } @@ -653,7 +721,8 @@ static int fw_parse_header(struct tas2557_priv *pTAS2557, pData += 4; if (pFirmware->mnDevice != 2) { - dev_err(pTAS2557->dev, "device %d, not TAS2557", pFirmware->mnDevice); + dev_err(pTAS2557->dev, + "device %d, not TAS2557 Dual Mono", pFirmware->mnDevice); return -EINVAL; } @@ -670,7 +739,7 @@ static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware * pBlock->mnType = fw_convert_number(pData); pData += 4; - if (pFirmware->mnDriverVersion >= PPC_DRIVER_VERSION) { + if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) { pBlock->mbPChkSumPresent = pData[0]; pData++; @@ -693,7 +762,6 @@ static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware * n = pBlock->mnCommands * 4; pBlock->mpData = kmemdup(pData, n, GFP_KERNEL); pData += n; - return pData - pDataStart; } @@ -716,12 +784,12 @@ static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmw pImageData->mpBlocks = kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL); + for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) { n = fw_parse_block_data(pTAS2557, pFirmware, &(pImageData->mpBlocks[nBlock]), pData); pData += n; } - return pData - pDataStart; } @@ -815,7 +883,8 @@ static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557, pFirmware->mpConfigurations = kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations, GFP_KERNEL); - for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations; nConfiguration++) { + for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations; + nConfiguration++) { pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]); memcpy(pConfiguration->mpName, pData, 64); pData += 64; @@ -824,6 +893,11 @@ static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557, pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); pData += n + 1; + if (pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV) { + pConfiguration->mnDevices = (pData[0] << 8) + pData[1]; + pData += 2; + } + pConfiguration->mnProgram = pData[0]; pData++; @@ -858,7 +932,9 @@ int fw_parse_calibration_data(struct tas2557_priv *pTAS2557, pFirmware->mpCalibrations = kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL); - for (nCalibration = 0; nCalibration < pFirmware->mnCalibrations; nCalibration++) { + for (nCalibration = 0; + nCalibration < pFirmware->mnCalibrations; + nCalibration++) { pCalibration = &(pFirmware->mpCalibrations[nCalibration]); memcpy(pCalibration->mpName, pData, 64); pData += 64; @@ -1286,10 +1362,12 @@ start: dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n", pBlock->mnPChkSum, (nValue1&0xff)); nResult = -EAGAIN; + pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK; goto check; } nResult = 0; + pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK; dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType); } @@ -1298,8 +1376,10 @@ start: dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n", pBlock->mnYChkSum, nCRCChkSum); nResult = -EAGAIN; + pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK; goto check; } + pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK; nResult = 0; dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType); } @@ -1347,7 +1427,7 @@ static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, struct TConfiguration *pCurrentConfiguration = NULL; struct TConfiguration *pNewConfiguration = NULL; - dev_dbg(pTAS2557->dev, "tas2557_load_configuration: %d\n", nConfiguration); + dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration); if ((!pTAS2557->mpFirmware->mpPrograms) || (!pTAS2557->mpFirmware->mpConfigurations)) { @@ -1400,8 +1480,10 @@ static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, end: - if (nResult < 0) - failsafe(pTAS2557); + if (nResult < 0) { + if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); + } return nResult; } @@ -1553,6 +1635,14 @@ void tas2557_fw_ready(const struct firmware *pFW, void *pContext) unsigned int nProgram = 0; unsigned int nSampleRate = 0; +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + dev_info(pTAS2557->dev, "%s:\n", __func__); if (unlikely(!pFW) || unlikely(!pFW->data)) { @@ -1594,14 +1684,21 @@ void tas2557_fw_ready(const struct firmware *pFW, void *pContext) } pTAS2557->mnCurrentSampleRate = nSampleRate; - nResult = tas2557_set_program(pTAS2557, nProgram, -1); end: - return; + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif } -int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, int nConfig) +int tas2557_set_program(struct tas2557_priv *pTAS2557, + unsigned int nProgram, int nConfig) { struct TProgram *pProgram; unsigned int nConfiguration = 0; @@ -1669,7 +1766,7 @@ int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, in if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) pTAS2557->enableIRQ(pTAS2557, false); - nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_mute_DSP_down_data); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); if (nResult < 0) goto end; } @@ -1705,8 +1802,15 @@ int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, in nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); if (nResult < 0) goto end; - dev_dbg(pTAS2557->dev, - "device powered up, load unmute\n"); + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + } + dev_dbg(pTAS2557->dev, "device powered up, load unmute\n"); nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); if (nResult < 0) goto end; @@ -1723,9 +1827,10 @@ int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, in end: - if (nResult < 0) - failsafe(pTAS2557); - + if (nResult < 0) { + if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); + } return nResult; } @@ -1743,10 +1848,12 @@ int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration) } if (nCalibration == 0x00FF) { - dev_info(pTAS2557->dev, "load new calibration file %s\n", TAS2557_CAL_NAME); nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME); - if (nResult < 0) + if (nResult < 0) { + dev_info(pTAS2557->dev, "load new calibration file %s fail %d\n", + TAS2557_CAL_NAME, nResult); goto end; + } nCalibration = 0; } @@ -1762,7 +1869,7 @@ int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration) pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { - dev_dbg(pTAS2557->dev, "Enable: load calibration\n"); + dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__); nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A); if (nResult < 0) goto end; diff --git a/tas2557-core.h b/tas2557-core.h index 53914f1..7170428 100755 --- a/tas2557-core.h +++ b/tas2557-core.h @@ -59,6 +59,7 @@ struct TYCRC { }; int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable); +int tas2557_SA_DevChnSetup(struct tas2557_priv *pTAS2557, unsigned int mode); int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, int *pTemperature); int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate); int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate); diff --git a/tas2557-misc.c b/tas2557-misc.c index db4bb3d..f53425b 100755 --- a/tas2557-misc.c +++ b/tas2557-misc.c @@ -120,63 +120,70 @@ static ssize_t tas2557_file_read(struct file *file, char *buf, size_t count, lof break; case TIAUDIO_CMD_PROGRAM: { - if (g_logEnable) - dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM: count = %d\n", (int)count); - - if (count == PROGRAM_BUF_SIZE) { - p_kBuf = kzalloc(count, GFP_KERNEL); - if (p_kBuf != NULL) { - struct TProgram *pProgram = - &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); - p_kBuf[0] = pTAS2557->mpFirmware->mnPrograms; - p_kBuf[1] = pTAS2557->mnCurrentProgram; - p_kBuf[2] = pProgram->mnAppMode; - p_kBuf[3] = (pProgram->mnBoost&0xff00)>>8; - p_kBuf[4] = (pProgram->mnBoost&0x00ff); - memcpy(&p_kBuf[5], pProgram->mpName, FW_NAME_SIZE); - strlcpy(&p_kBuf[5+FW_NAME_SIZE], pProgram->mpDescription, strlen(pProgram->mpDescription) + 1); - ret = copy_to_user(buf, p_kBuf, count); - if (ret != 0) { - /* Failed to copy all the data, exit */ - dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); - } - kfree(p_kBuf); + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM: count = %d\n", (int)count); + + if (count == PROGRAM_BUF_SIZE) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TProgram *pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + p_kBuf[0] = pTAS2557->mpFirmware->mnPrograms; + p_kBuf[1] = pTAS2557->mnCurrentProgram; + p_kBuf[2] = pProgram->mnAppMode; + p_kBuf[3] = (pProgram->mnBoost&0xff00)>>8; + p_kBuf[4] = (pProgram->mnBoost&0x00ff); + memcpy(&p_kBuf[5], pProgram->mpName, FW_NAME_SIZE); + strlcpy(&p_kBuf[5+FW_NAME_SIZE], pProgram->mpDescription, strlen(pProgram->mpDescription) + 1); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); } else - dev_err(pTAS2557->dev, "read no mem\n"); + dev_err(pTAS2557->dev, "read buffer not sufficient\n"); } else - dev_err(pTAS2557->dev, "read buffer not sufficient\n"); + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); } break; case TIAUDIO_CMD_CONFIGURATION: { - if (g_logEnable) - dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION: count = %d\n", (int)count); - if (count == CONFIGURATION_BUF_SIZE) { - p_kBuf = kzalloc(count, GFP_KERNEL); - if (p_kBuf != NULL) { - struct TConfiguration *pConfiguration = - &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); - - p_kBuf[0] = pTAS2557->mpFirmware->mnConfigurations; - p_kBuf[1] = pTAS2557->mnCurrentConfiguration; - memcpy(&p_kBuf[2], pConfiguration->mpName, FW_NAME_SIZE); - p_kBuf[2+FW_NAME_SIZE] = pConfiguration->mnProgram; - p_kBuf[3+FW_NAME_SIZE] = pConfiguration->mnPLL; - p_kBuf[4+FW_NAME_SIZE] = (pConfiguration->mnSamplingRate&0x000000ff); - p_kBuf[5+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x0000ff00)>>8); - p_kBuf[6+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x00ff0000)>>16); - p_kBuf[7+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0xff000000)>>24); - strlcpy(&p_kBuf[8+FW_NAME_SIZE], pConfiguration->mpDescription, strlen(pConfiguration->mpDescription)+1); - ret = copy_to_user(buf, p_kBuf, count); - if (ret != 0) { - /* Failed to copy all the data, exit */ - dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); - } - kfree(p_kBuf); + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION: count = %d\n", (int)count); + if (count == CONFIGURATION_BUF_SIZE) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TConfiguration *pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + + p_kBuf[0] = pTAS2557->mpFirmware->mnConfigurations; + p_kBuf[1] = pTAS2557->mnCurrentConfiguration; + memcpy(&p_kBuf[2], pConfiguration->mpName, FW_NAME_SIZE); + p_kBuf[2+FW_NAME_SIZE] = pConfiguration->mnProgram; + p_kBuf[3+FW_NAME_SIZE] = pConfiguration->mnPLL; + p_kBuf[4+FW_NAME_SIZE] = (pConfiguration->mnSamplingRate&0x000000ff); + p_kBuf[5+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x0000ff00)>>8); + p_kBuf[6+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x00ff0000)>>16); + p_kBuf[7+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0xff000000)>>24); + strlcpy(&p_kBuf[8+FW_NAME_SIZE], pConfiguration->mpDescription, strlen(pConfiguration->mpDescription)+1); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); } else - dev_err(pTAS2557->dev, "read no mem\n"); + dev_err(pTAS2557->dev, "read buffer not sufficient\n"); } else - dev_err(pTAS2557->dev, "read buffer not sufficient\n"); + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); } break; @@ -352,21 +359,33 @@ static ssize_t tas2557_file_write(struct file *file, const char *buf, size_t cou break; case TIAUDIO_CMD_PROGRAM: + { if (count == 2) { - if (g_logEnable) - dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM, set to %d\n", p_kBuf[1]); - tas2557_set_program(pTAS2557, p_kBuf[1], -1); - pTAS2557->mnDBGCmd = 0; + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM, set to %d\n", p_kBuf[1]); + tas2557_set_program(pTAS2557, p_kBuf[1], -1); + pTAS2557->mnDBGCmd = 0; + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); } + } break; case TIAUDIO_CMD_CONFIGURATION: + { if (count == 2) { - if (g_logEnable) - dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION, set to %d\n", p_kBuf[1]); - tas2557_set_config(pTAS2557, p_kBuf[1]); - pTAS2557->mnDBGCmd = 0; + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION, set to %d\n", p_kBuf[1]); + tas2557_set_config(pTAS2557, p_kBuf[1]); + pTAS2557->mnDBGCmd = 0; + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); } + } break; case TIAUDIO_CMD_FW_TIMESTAMP: @@ -374,12 +393,17 @@ static ssize_t tas2557_file_write(struct file *file, const char *buf, size_t cou break; case TIAUDIO_CMD_CALIBRATION: + { if (count == 2) { - if (g_logEnable) - dev_info(pTAS2557->dev, "TIAUDIO_CMD_CALIBRATION, set to %d\n", p_kBuf[1]); - tas2557_set_calibration(pTAS2557, p_kBuf[1]); - pTAS2557->mnDBGCmd = 0; + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CALIBRATION, set to %d\n", p_kBuf[1]); + tas2557_set_calibration(pTAS2557, p_kBuf[1]); + pTAS2557->mnDBGCmd = 0; + } } + } break; case TIAUDIO_CMD_SAMPLERATE: @@ -483,19 +507,25 @@ static long tas2557_file_unlocked_ioctl(struct file *file, unsigned int cmd, uns case SMARTPA_SPK_SWITCH_PROGRAM: { - tas2557_set_program(pTAS2557, arg, -1); + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_program(pTAS2557, arg, -1); } break; case SMARTPA_SPK_SWITCH_CONFIGURATION: { - tas2557_set_config(pTAS2557, arg); + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_config(pTAS2557, arg); } break; case SMARTPA_SPK_SWITCH_CALIBRATION: { - tas2557_set_calibration(pTAS2557, arg); + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_calibration(pTAS2557, arg); } break; diff --git a/tas2557-regmap.c b/tas2557-regmap.c index 5453d02..9f20c16 100755 --- a/tas2557-regmap.c +++ b/tas2557-regmap.c @@ -103,6 +103,10 @@ static int tas2557_change_book_page( } end: + if (nResult < 0) + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; return nResult; } @@ -136,8 +140,10 @@ static int tas2557_dev_read( if (nResult < 0) { dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; goto end; - } + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; *pValue = Value; } @@ -182,9 +188,12 @@ static int tas2557_dev_write( TAS2557_PAGE_ID(nRegister)); if (nResult >= 0) { nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nValue); - if (nResult < 0) + if (nResult < 0) { dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; } end: @@ -220,9 +229,12 @@ static int tas2557_dev_bulk_read( TAS2557_PAGE_ID(nRegister)); if (nResult >= 0) { nResult = regmap_bulk_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength); - if (nResult < 0) + if (nResult < 0) { dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; } end: @@ -258,9 +270,12 @@ static int tas2557_dev_bulk_write( TAS2557_PAGE_ID(nRegister)); if (nResult >= 0) { nResult = regmap_bulk_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength); - if (nResult < 0) + if (nResult < 0) { dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; } end: @@ -296,9 +311,12 @@ static int tas2557_dev_update_bits( TAS2557_PAGE_ID(nRegister)); if (nResult >= 0) { nResult = regmap_update_bits(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nMask, nValue); - if (nResult < 0) + if (nResult < 0) { dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; } end: @@ -346,6 +364,9 @@ static void tas2557_hw_reset(struct tas2557_priv *pTAS2557) pTAS2557->mnCurrentBook = -1; pTAS2557->mnCurrentPage = -1; + if (pTAS2557->mnErrCode) + dev_info(pTAS2557->dev, "before reset, ErrCode=0x%x\n", pTAS2557->mnErrCode); + pTAS2557->mnErrCode = 0; } static void irq_work_routine(struct work_struct *work) @@ -367,6 +388,12 @@ static void irq_work_routine(struct work_struct *work) if (!pTAS2557->mbPowerUp) goto end; + if ((!pTAS2557->mpFirmware->mnConfigurations) + || (!pTAS2557->mpFirmware->mnPrograms)) { + dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_1, &nDevInt1Status); if (nResult >= 0) nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_2, &nDevInt2Status); @@ -374,9 +401,57 @@ static void irq_work_routine(struct work_struct *work) if (nResult < 0) goto program; - if (((nDevInt1Status & 0xdc) != 0) || ((nDevInt2Status & 0x0c) != 0)) { + if (((nDevInt1Status & 0xfc) != 0) || ((nDevInt2Status & 0x0c) != 0)) { /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */ dev_err(pTAS2557->dev, "critical error: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status); + if (nDevInt1Status & 0x80) { + pTAS2557->mnErrCode |= ERROR_OVER_CURRENT; + dev_err(pTAS2557->dev, "DEVA SPK over current!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_OVER_CURRENT; + + if (nDevInt1Status & 0x40) { + pTAS2557->mnErrCode |= ERROR_UNDER_VOLTAGE; + dev_err(pTAS2557->dev, "DEVA SPK under voltage!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_UNDER_VOLTAGE; + + if (nDevInt1Status & 0x20) { + pTAS2557->mnErrCode |= ERROR_CLK_HALT; + dev_err(pTAS2557->dev, "DEVA clk halted!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_HALT; + + if (nDevInt1Status & 0x10) { + pTAS2557->mnErrCode |= ERROR_DIE_OVERTEMP; + dev_err(pTAS2557->dev, "DEVA die over temperature!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_DIE_OVERTEMP; + + if (nDevInt1Status & 0x08) { + pTAS2557->mnErrCode |= ERROR_BROWNOUT; + dev_err(pTAS2557->dev, "DEVA brownout!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_BROWNOUT; + + if (nDevInt1Status & 0x04) { + pTAS2557->mnErrCode |= ERROR_CLK_LOST; + dev_err(pTAS2557->dev, "DEVA clock lost!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_LOST; + + if (nDevInt2Status & 0x08) { + pTAS2557->mnErrCode |= ERROR_CLK_DET1; + dev_err(pTAS2557->dev, "DEVA clk detection 1!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_DET1; + + if (nDevInt2Status & 0x04) { + pTAS2557->mnErrCode |= ERROR_CLK_DET2; + dev_err(pTAS2557->dev, "DEVA clk detection 2!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_DET2; + goto program; } else { nResult = tas2557_dev_read(pTAS2557, TAS2557_POWER_UP_FLAG_REG, &nDevPowerUpFlag); @@ -388,9 +463,12 @@ static void irq_work_routine(struct work_struct *work) if (nResult < 0) goto program; if (nDevPowerStatus & 0x80) + pTAS2557->mnErrCode |= ERROR_CLASSD_PWR; goto program; /* failed to power on the Class-D */ } + pTAS2557->mnErrCode &= ~ERROR_CLASSD_PWR; + dev_dbg(pTAS2557->dev, "%s: INT1=0x%x, INT2=0x%x; PowerUpFlag=0x%x, PwrStatus=0x%x\n", __func__, nDevInt1Status, nDevInt2Status, nDevPowerUpFlag, nDevPowerStatus); goto end; @@ -416,8 +494,8 @@ static irqreturn_t tas2557_irq_handler(int irq, void *dev_id) struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)dev_id; tas2557_enableIRQ(pTAS2557, false); - /* get IRQ status after 100 ms */ - schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100)); + /* get IRQ status after 50 ms */ + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(50)); return IRQ_HANDLED; } @@ -666,7 +744,7 @@ static int tas2557_i2c_probe(struct i2c_client *pClient, dev_dbg(pTAS2557->dev, "irq = %d\n", pTAS2557->mnIRQ); INIT_DELAYED_WORK(&pTAS2557->irq_work, irq_work_routine); nResult = request_threaded_irq(pTAS2557->mnIRQ, tas2557_irq_handler, - NULL, IRQF_TRIGGER_RISING | IRQF_ONESHOT, + NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, pClient->name, pTAS2557); if (nResult < 0) { dev_err(pTAS2557->dev, diff --git a/tas2557.h b/tas2557.h index 228b881..f230a21 100755 --- a/tas2557.h +++ b/tas2557.h @@ -80,6 +80,8 @@ #define TAS2557_SAFE_GUARD_REG TAS2557_REG(0, 0, 37) #define TAS2557_ASI_CTL1_REG TAS2557_REG(0, 0, 42) #define TAS2557_CLK_ERR_CTRL TAS2557_REG(0, 0, 44) +#define TAS2557_CLK_ERR_CTRL2 TAS2557_REG(0, 0, 45) /* B0_P0_R0x2d*/ +#define TAS2557_CLK_ERR_CTRL3 TAS2557_REG(0, 0, 46) /* B0_P0_R0x2e*/ #define TAS2557_DBOOST_CFG_REG TAS2557_REG(0, 0, 52) #define TAS2557_POWER_UP_FLAG_REG TAS2557_REG(0, 0, 100) #define TAS2557_FLAGS_1 TAS2557_REG(0, 0, 104) /* B0_P0_R0x68*/ @@ -100,7 +102,6 @@ #define TAS2557_ASI1_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 15) #define TAS2557_ASI1_DAC_CLKOUT_REG TAS2557_REG(0, 1, 16) #define TAS2557_ASI1_ADC_CLKOUT_REG TAS2557_REG(0, 1, 17) - #define TAS2557_ASI2_DAC_FORMAT_REG TAS2557_REG(0, 1, 21) #define TAS2557_ASI2_ADC_FORMAT_REG TAS2557_REG(0, 1, 22) #define TAS2557_ASI2_OFFSET1_REG TAS2557_REG(0, 1, 23) @@ -115,7 +116,6 @@ #define TAS2557_ASI2_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 35) #define TAS2557_ASI2_DAC_CLKOUT_REG TAS2557_REG(0, 1, 36) #define TAS2557_ASI2_ADC_CLKOUT_REG TAS2557_REG(0, 1, 37) - #define TAS2557_GPIO1_PIN_REG TAS2557_REG(0, 1, 61) /*B0_P1_R0x3d */ #define TAS2557_GPIO2_PIN_REG TAS2557_REG(0, 1, 62) /*B0_P1_R0x3e */ #define TAS2557_GPIO3_PIN_REG TAS2557_REG(0, 1, 63) /*B0_P1_R0x3f */ @@ -126,24 +126,20 @@ #define TAS2557_GPIO8_PIN_REG TAS2557_REG(0, 1, 68) #define TAS2557_GPIO9_PIN_REG TAS2557_REG(0, 1, 69) #define TAS2557_GPIO10_PIN_REG TAS2557_REG(0, 1, 70) - #define TAS2557_GPI_PIN_REG TAS2557_REG(0, 1, 77) /*B0_P1_R0x4d */ #define TAS2557_GPIO_HIZ_CTRL1_REG TAS2557_REG(0, 1, 79) #define TAS2557_GPIO_HIZ_CTRL2_REG TAS2557_REG(0, 1, 80) #define TAS2557_GPIO_HIZ_CTRL3_REG TAS2557_REG(0, 1, 81) #define TAS2557_GPIO_HIZ_CTRL4_REG TAS2557_REG(0, 1, 82) #define TAS2557_GPIO_HIZ_CTRL5_REG TAS2557_REG(0, 1, 83) - #define TAS2557_BIT_BANG_CTRL_REG TAS2557_REG(0, 1, 87) #define TAS2557_BIT_BANG_OUT1_REG TAS2557_REG(0, 1, 88) #define TAS2557_BIT_BANG_OUT2_REG TAS2557_REG(0, 1, 89) #define TAS2557_BIT_BANG_IN1_REG TAS2557_REG(0, 1, 90) #define TAS2557_BIT_BANG_IN2_REG TAS2557_REG(0, 1, 91) #define TAS2557_BIT_BANG_IN3_REG TAS2557_REG(0, 1, 92) - #define TAS2557_PDM_IN_CLK_REG TAS2557_REG(0, 1, 94) #define TAS2557_PDM_IN_PIN_REG TAS2557_REG(0, 1, 95) - #define TAS2557_ASIM_IFACE1_REG TAS2557_REG(0, 1, 98) #define TAS2557_ASIM_FORMAT_REG TAS2557_REG(0, 1, 99) #define TAS2557_ASIM_IFACE3_REG TAS2557_REG(0, 1, 100) @@ -152,19 +148,16 @@ #define TAS2557_ASIM_IFACE6_REG TAS2557_REG(0, 1, 103) #define TAS2557_ASIM_IFACE7_REG TAS2557_REG(0, 1, 104) #define TAS2557_ASIM_IFACE8_REG TAS2557_REG(0, 1, 105) -#define TAS2557_ASIM_IFACE9_REG TAS2557_REG(0, 1, 106) - +#define TAS2557_CLK_HALT_REG TAS2557_REG(0, 1, 106) /* B0_P1_R0x6a */ #define TAS2557_INT_GEN1_REG TAS2557_REG(0, 1, 108) /* B0_P1_R0x6c */ -#define TAS2557_INT_GEN2_REG TAS2557_REG(0, 1, 109) +#define TAS2557_INT_GEN2_REG TAS2557_REG(0, 1, 109) /* B0_P1_R0x6d */ #define TAS2557_INT_GEN3_REG TAS2557_REG(0, 1, 110) /* B0_P1_R0x6e */ #define TAS2557_INT_GEN4_REG TAS2557_REG(0, 1, 111) /* B0_P1_R0x6f */ #define TAS2557_INT_MODE_REG TAS2557_REG(0, 1, 114) /* B0_P1_R0x72 */ - #define TAS2557_MAIN_CLKIN_REG TAS2557_REG(0, 1, 115) #define TAS2557_PLL_CLKIN_REG TAS2557_REG(0, 1, 116) #define TAS2557_CLKOUT_MUX_REG TAS2557_REG(0, 1, 117) #define TAS2557_CLKOUT_CDIV_REG TAS2557_REG(0, 1, 118) - #define TAS2557_HACK_GP01_REG TAS2557_REG(0, 1, 122) #define TAS2557_HACK01_REG TAS2557_REG(0, 2, 10) @@ -180,7 +173,6 @@ #define TAS2557_SA_PG1P0_CHL_CTRL_REG TAS2557_REG(0, 58, 120) /* B0_P0x3a_R0x78 */ - #define TAS2557_TEST_MODE_REG TAS2557_REG(0, 253, 13) #define TAS2557_BROADCAST_REG TAS2557_REG(0, 253, 54) #define TAS2557_CRYPTIC_REG TAS2557_REG(0, 253, 71) @@ -198,7 +190,6 @@ #define TAS2557_RAMP_CLK_DIV_MSB_REG TAS2557_REG(100, 0, 43) #define TAS2557_RAMP_CLK_DIV_LSB_REG TAS2557_REG(100, 0, 44) -#define TAS2557_XMEM_44_REG TAS2557_REG(130, 2, 64) /* B0x82_P0x02_R0x40 */ #define TAS2557_DIE_TEMP_REG TAS2557_REG(130, 2, 124) /* B0x82_P0x02_R0x7C */ /* Bits */ @@ -296,9 +287,39 @@ #define TAS2557_FW_NAME "tas2557_uCDSP.bin" #define TAS2557_PG1P0_FW_NAME "tas2557_pg1p0_uCDSP.bin" -#define TAS2557_APP_ROM1MODE 0 -#define TAS2557_APP_ROM2MODE 1 -#define TAS2557_APP_TUNINGMODE 2 +#define TAS2557_APP_ROM1MODE 0 +#define TAS2557_APP_ROM2MODE 1 +#define TAS2557_APP_TUNINGMODE 2 +#define TAS2557_APP_ROM1_96KHZ 3 +#define TAS2557_APP_ROM2_96KHZ 4 +#define TAS2557_APP_RAMMODE 5 + +#define TAS2557_BOOST_OFF 0 +#define TAS2557_BOOST_DEVA 1 +#define TAS2557_BOOST_DEVB 2 +#define TAS2557_BOOST_BOTH 3 + +#define TAS2557_DEVA_CHL_DEFAULT 0 /* DevA default */ +#define TAS2557_DEVA_CHL_MUTE 1 /* DevA mute */ +#define TAS2557_DEVA_CHL_LEFT 2 /* DevA left channel */ +#define TAS2557_DEVA_CHL_RIGHT 3 /* DevA right channel */ +#define TAS2557_DEVA_CHL_MONOMIX 4 /* DevA (L+R)/2 */ + +#define ERROR_NONE 0x00000000 +#define ERROR_PLL_ABSENT 0x00000001 +#define ERROR_DEVA_I2C_COMM 0x00000002 +#define ERROR_PRAM_CRCCHK 0x00000008 +#define ERROR_YRAM_CRCCHK 0x00000010 +#define ERROR_CLK_DET2 0x00000020 +#define ERROR_CLK_DET1 0x00000040 +#define ERROR_CLK_LOST 0x00000080 +#define ERROR_BROWNOUT 0x00000100 +#define ERROR_DIE_OVERTEMP 0x00000200 +#define ERROR_CLK_HALT 0x00000400 +#define ERROR_UNDER_VOLTAGE 0x00000800 +#define ERROR_OVER_CURRENT 0x00001000 +#define ERROR_CLASSD_PWR 0x00002000 +#define ERROR_FAILSAFE 0x40000000 struct TBlock { unsigned int mnType; @@ -334,6 +355,7 @@ struct TPLL { struct TConfiguration { char mpName[64]; char *mpDescription; + unsigned int mnDevices; unsigned int mnProgram; unsigned int mnPLL; unsigned int mnSamplingRate; @@ -430,6 +452,9 @@ struct tas2557_priv { bool mbIRQEnable; unsigned char mnI2SBits; + unsigned int mnChannelState; + unsigned char mnDevAChlData[16]; + /* for low temperature check */ unsigned int mnDevGain; unsigned int mnDevCurrentGain; @@ -437,6 +462,7 @@ struct tas2557_priv { struct hrtimer mtimer; struct work_struct mtimerwork; + unsigned int mnErrCode; #ifdef CONFIG_TAS2557_CODEC struct mutex codec_lock; #endif -- 2.39.2