for thermal protection bypass configurations, bypass calibration Re update
authorPeter Li <a0220410@ti.com>
Thu, 18 May 2017 16:21:02 +0000 (00:21 +0800)
committerPeter Li <a0220410@ti.com>
Thu, 18 May 2017 16:21:02 +0000 (00:21 +0800)
dts.readme
tas2557-codec.c
tas2557-core.c
tas2557-core.h
tas2557.h

index 641ebdb1bfa9e6365afe54ecc78114d3c9ec6052..de1c4bed5c6391e2cfb2eba2b4b03ff476d9865d 100755 (executable)
@@ -7,5 +7,6 @@ example for dts:
                        ti,cdc-reset-gpio = <&msmgpio 73 0>;
                        ti,irq-gpio = <&msmgpio 59 0>;
                        ti,i2s-bits = <16>;   /* support 16, 24, 32 */
+                       ti,bypass-tmax = <0>;   /* 0, not bypass; 1, bypass */
                        status = "ok";
                };
\ No newline at end of file
index 0fa00f04f0643ea9842885fa8a391bab1d58f776..a5a545d24359531d0a099c7cfa5ce2247e192799 100755 (executable)
@@ -331,18 +331,20 @@ static int tas2557_Cali_get(struct snd_kcontrol *pKcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol);
 #endif
        struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec);
-       int ret = 0;
+       bool ret = 0;
        int prm_r0 = 0;
 
        mutex_lock(&pTAS2557->codec_lock);
 
        ret = tas2557_get_Cali_prm_r0(pTAS2557, &prm_r0);
-       pValue->value.integer.value[0] = prm_r0;
-       dev_dbg(pTAS2557->dev, "%s = 0x%x\n", __func__, prm_r0);
+       if (ret)
+               pValue->value.integer.value[0] = prm_r0;
+
 
        mutex_unlock(&pTAS2557->codec_lock);
-       return ret;
+       return 0;
 }
+
 static int tas2557_program_get(struct snd_kcontrol *pKcontrol,
        struct snd_ctl_elem_value *pValue)
 {
index 5589351a8e2e4a9f9ecf3d8fbf820aa0e34549f5..9fe58c9f74e8ed95a203db22d7f3c4ff56ca3840 100755 (executable)
@@ -462,11 +462,11 @@ int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable)
                if (!pTAS2557->mbPowerUp) {
                        if (pTAS2557->mbLoadConfigurationPrePowerUp) {
                                dev_dbg(pTAS2557->dev, "load coefficient before power\n");
+                               pTAS2557->mbLoadConfigurationPrePowerUp = false;
                                nResult = tas2557_load_coefficient(pTAS2557,
                                        pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false);
                                if (nResult < 0)
                                        goto end;
-                               pTAS2557->mbLoadConfigurationPrePowerUp = false;
                        }
 
                        pTAS2557->clearIRQ(pTAS2557);
@@ -1403,8 +1403,8 @@ static int tas2557_load_configuration(struct tas2557_priv *pTAS2557,
        }
 
        if (pTAS2557->mbPowerUp) {
-               nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
                pTAS2557->mbLoadConfigurationPrePowerUp = false;
+               nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true);
        } else {
                dev_dbg(pTAS2557->dev,
                        "TAS2557 was powered down, will load coefficient when power up\n");
@@ -1562,6 +1562,104 @@ static int tas2557_load_calibration(struct tas2557_priv *pTAS2557,      char *pFileNa
        return nResult;
 }
 
+static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557,
+       struct TBlock *pBlock, int nReg, int *pnValue)
+{
+       int nCoefficient = 0;
+       bool bFound = false;
+       unsigned char *pCommands;
+       int nBook, nPage, nOffset, len;
+       int i, n;
+
+       pCommands = pBlock->mpData;
+       for (i = 0 ; i < pBlock->mnCommands;) {
+               nBook = pCommands[4 * i + 0];
+               nPage = pCommands[4 * i + 1];
+               nOffset = pCommands[4 * i + 2];
+               if ((nOffset < 0x7f) || (nOffset == 0x81))
+                       i++;
+               else if (nOffset == 0x85) {
+                       len = ((int)nBook << 8) | nPage;
+                       nBook = pCommands[4 * i + 4];
+                       nPage = pCommands[4 * i + 5];
+                       nOffset = pCommands[4 * i + 6];
+                       n = 4 * i + 7;
+                       i += 2;
+                       i += ((len - 1) / 4);
+                       if ((len - 1) % 4)
+                               i++;
+                       if ((nBook != TAS2557_BOOK_ID(nReg))
+                               || (nPage != TAS2557_PAGE_ID(nReg)))
+                               continue;
+                       if (nOffset > TAS2557_PAGE_REG(nReg))
+                               continue;
+                       if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) {
+                               n += (TAS2557_PAGE_REG(nReg) - nOffset);
+                               nCoefficient = ((int)pCommands[n] << 24)
+                                               | ((int)pCommands[n + 1] << 16)
+                                               | ((int)pCommands[n + 2] << 8)
+                                               | (int)pCommands[n + 3];
+                               bFound = true;
+                               break;
+                       }
+               } else {
+                       dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset);
+                       break;
+               }
+       }
+
+       if (bFound) {
+               *pnValue = nCoefficient;
+               dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__,
+                       TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), TAS2557_PAGE_REG(nReg),
+                       nCoefficient);
+       }
+
+       return bFound;
+}
+
+static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557,
+       struct TData *pData, int blockType, int nReg, int *pnValue)
+{
+       bool bFound = false;
+       struct TBlock *pBlock;
+       int i;
+
+       for (i = 0; i < pData->mnBlocks; i++) {
+               pBlock = &(pData->mpBlocks[i]);
+               if (pBlock->mnType == blockType) {
+                       bFound = tas2557_get_coefficient_in_block(pTAS2557,
+                                               pBlock, nReg, pnValue);
+                       if (bFound)
+                               break;
+               }
+       }
+
+       return bFound;
+}
+
+static bool tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557,
+       struct TConfiguration *pConfiguration, int *pnTMax)
+{
+       struct TData *pData;
+       bool bFound = false;
+       int nBlockType, nReg, nCoefficient;
+
+       if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1)
+               nReg = TAS2557_PG2P1_CALI_T_REG;
+       else
+               nReg = TAS2557_PG1P0_CALI_T_REG;
+
+       nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A;
+
+       pData = &(pConfiguration->mData);
+       bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCoefficient);
+       if (bFound)
+               *pnTMax = nCoefficient;
+
+       return bFound;
+}
+
 void tas2557_fw_ready(const struct firmware *pFW, void *pContext)
 {
        struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext;
@@ -1771,7 +1869,10 @@ end:
 int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
 {
        struct TCalibration *pCalibration = NULL;
+       struct TConfiguration *pConfiguration;
        struct TProgram *pProgram;
+       int nTmax = 0;
+       bool bFound = false;
        int nResult = 0;
 
        if ((!pTAS2557->mpFirmware->mpPrograms)
@@ -1804,7 +1905,17 @@ int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration)
 
        pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]);
        pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]);
+       pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]);
        if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) {
+               if (pTAS2557->mbBypassTMax) {
+                       bFound = tas2557_find_Tmax_in_configuration(pTAS2557, pConfiguration, &nTmax);
+                       if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) {
+                               dev_dbg(pTAS2557->dev, "%s, config[%s] bypass load calibration\n",
+                                       __func__, pConfiguration->mpName);
+                               goto end;
+                       }
+               }
+
                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)
@@ -1820,20 +1931,14 @@ end:
        return nResult;
 }
 
-int tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
+bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
 {
-       int nResult = 0;
-       int n, nn;
        struct TCalibration *pCalibration;
        struct TData *pData;
-       struct TBlock *pBlock;
        int nReg;
-       int nBook, nPage, nOffset;
-       unsigned char *pCommands;
        int nCali_Re;
        bool bFound = false;
        int nBlockType;
-       int len;
 
        if (!pTAS2557->mpCalFirmware->mnCalibrations) {
                dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__);
@@ -1850,50 +1955,14 @@ int tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0)
        pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]);
        pData = &(pCalibration->mData);
 
-       for (n = 0; n < pData->mnBlocks; n++) {
-               pBlock = &(pData->mpBlocks[n]);
-               if (pBlock->mnType == nBlockType) {
-                       pCommands = pBlock->mpData;
-                       for (nn = 0 ; nn < pBlock->mnCommands;) {
-                               nBook = pCommands[4 * nn + 0];
-                               nPage = pCommands[4 * nn + 1];
-                               nOffset = pCommands[4 * nn + 2];
-                               if ((nOffset < 0x7f) || (nOffset == 0x81))
-                                       nn++;
-                               else if (nOffset == 0x85) {
-                                       len = ((int)nBook << 8) | nPage;
-
-                                       nBook = pCommands[4 * nn + 4];
-                                       nPage = pCommands[4 * nn + 5];
-                                       nOffset = pCommands[4 * nn + 6];
-                                       if ((nBook == TAS2557_BOOK_ID(nReg))
-                                               && (nPage == TAS2557_PAGE_ID(nReg))
-                                               && (nOffset == TAS2557_PAGE_REG(nReg))) {
-                                               nCali_Re = ((int)pCommands[4 * nn + 7] << 24)
-                                                       | ((int)pCommands[4 * nn + 8] << 16)
-                                                       | ((int)pCommands[4 * nn + 9] << 8)
-                                                       | (int)pCommands[4 * nn + 10];
-                                               bFound = true;
-                                               goto end;
-                                       }
-                                       nn += 2;
-                                       nn += ((len - 1) / 4);
-                                       if ((len - 1) % 4)
-                                               nn++;
-                               } else {
-                                       dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset);
-                                       break;
-                               }
-                       }
-               }
-       }
+       bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCali_Re);
 
 end:
 
        if (bFound)
                *prm_r0 = nCali_Re;
 
-       return nResult;
+       return bFound;
 }
 
 int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
@@ -1926,6 +1995,13 @@ int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557)
        else
                pTAS2557->mnI2SBits = value;
 
+       rc = of_property_read_u32(np, "ti,bypass-tmax", &value);
+       if (rc)
+               dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n",
+                       "ti,bypass-tmax", np->full_name, rc);
+       else
+               pTAS2557->mbBypassTMax = (value > 0);
+
 end:
 
        return ret;
index e031a19c92a94cb28c9acd49a84a3374256a504c..77f84f81d645e4b8fc3f32f171a4d794654f771c 100755 (executable)
@@ -50,6 +50,7 @@
 #define TAS2557_YRAM5_START_REG                        8
 #define TAS2557_YRAM5_END_REG                  27
 
+#define TAS2557_COEFFICIENT_TMAX       0x7fffffff
 #define TAS2557_SAFE_GUARD_PATTERN             0x5a
 #define LOW_TEMPERATURE_CHECK_PERIOD 5000      /* 5 second */
 
@@ -66,7 +67,7 @@ int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate);
 int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate);
 int tas2557_set_config(struct tas2557_priv *pTAS2557, int config);
 void tas2557_fw_ready(const struct firmware *pFW, void *pContext);
-int tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0);
+bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0);
 int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, int nConfig);
 int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration);
 int tas2557_load_default(struct tas2557_priv *pTAS2557);
index cd781024f4d8a4c5deff32e67b686963eb9a7f35..14837f98bdd6832e37f0c143a8c960140e7aa95b 100755 (executable)
--- a/tas2557.h
+++ b/tas2557.h
 #define TAS2557_CRYPTIC_REG                    TAS2557_REG(0, 253, 71)
 #define TAS2557_PG2P1_CALI_R0_REG              TAS2557_REG(0x8c, 0x2f, 0x40)
 #define TAS2557_PG1P0_CALI_R0_REG              TAS2557_REG(0x8c, 0x2f, 0x28)
+#define TAS2557_PG2P1_CALI_T_REG               TAS2557_REG(0x8c, 0x30, 0x20)
+#define TAS2557_PG1P0_CALI_T_REG               TAS2557_REG(0x8c, 0x30, 0x08)
 
 #define TAS2557_DAC_INTERPOL_REG               TAS2557_REG(100, 0, 1)
 #define TAS2557_SOFT_MUTE_REG                  TAS2557_REG(100, 0, 7)
@@ -460,6 +462,12 @@ struct tas2557_priv {
        bool mbRuntimeSuspend;
 
        unsigned int mnErrCode;
+
+       /* for configurations with maximum TLimit 0x7fffffff,
+        * bypass calibration update, usually used in factory test
+       */
+       bool mbBypassTMax;
+
 #ifdef CONFIG_TAS2557_CODEC
        struct mutex codec_lock;
 #endif