update for broadcasting mode and PRAM checksum master
authorPeter Li <a0220410@ti.com>
Thu, 13 Jul 2017 10:22:13 +0000 (18:22 +0800)
committerPeter Li <a0220410@ti.com>
Thu, 13 Jul 2017 10:22:13 +0000 (18:22 +0800)
tas2555-core.c
tas2555.h

index 99e74ecc64ed5dcba1739a1d1b6df2bb90e4554a..9460325b98dd80ce3d7b2295e6078737b2269b87 100755 (executable)
@@ -45,6 +45,9 @@
 #include "tas2555-core.h"
 
 #define PPC_WITH_DRIVER_VERSION                0x010bc000
+#define PPC_WITH_CHECKSUM                      0x010c8400
+#define PPC_DRIVER_VERSION                     0x00000200
+
 #define TAS2555_CAL_NAME    "/data/tas2555_cal.bin"
 
 //set default PLL CLKIN to GPI2 (MCLK) = 0x00
@@ -54,7 +57,7 @@ static void tas2555_load_calibration(struct tas2555_priv *pTAS2555,
        char *pFileName);
 static void tas2555_load_data(struct tas2555_priv *pTAS2555, TData * pData,
        unsigned int nType);
-static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock);
+static int tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock);
 static void tas2555_load_configuration(struct tas2555_priv *pTAS2555,
        unsigned int nConfiguration, bool bLoadSame);
        
@@ -120,17 +123,55 @@ static unsigned int p_tas2555_unmute_data[] = {
        0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
 };
 
-static unsigned int p_tas2555_enter_broadcast_data[] = {
-       channel_both, TAS2555_TEST_MODE_REG, 0x0d,              //enter test mode
-       channel_both, TAS2555_BROADCAST_REG, 0x81,      //enable broadcast
-       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-};
+static int tas2555_enter_broadcast_mode(struct tas2555_priv *pTAS2555)
+{
+       int nResult = 0;
 
-static unsigned int p_tas2555_exit_broadcast_data[] = {
-       channel_broadcast, TAS2555_TEST_MODE_REG, 0x0d,         //enter test mode
-       channel_broadcast, TAS2555_BROADCAST_REG, 0x01, //disable broadcast
-       0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
-};
+       nResult = pTAS2555->write(pTAS2555, channel_both, TAS2555_TEST_MODE_REG, 0x0d);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->write(pTAS2555, channel_left, TAS2555_BROADCAST_REG, (pTAS2555->mnLBroadcastSet & 0x1f) | 0x80);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->write(pTAS2555, channel_right, TAS2555_BROADCAST_REG, (pTAS2555->mnRBroadcastSet & 0x1f) | 0x80);
+       if (nResult < 0)
+               goto end;
+
+end:
+
+       return nResult;
+}
+
+static int tas2555_exit_broadcast_mode(struct tas2555_priv *pTAS2555)
+{
+       int nResult = 0;
+
+       nResult = pTAS2555->write(pTAS2555, channel_broadcast, TAS2555_TEST_MODE_REG, 0x0d);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->write(pTAS2555, channel_broadcast, TAS2555_BROADCAST_REG, 0x01);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->write(pTAS2555, channel_both, TAS2555_TEST_MODE_REG, 0x0d);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->write(pTAS2555, channel_left, TAS2555_BROADCAST_REG, pTAS2555->mnLBroadcastSet & 0x1f);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->write(pTAS2555, channel_right, TAS2555_BROADCAST_REG, pTAS2555->mnRBroadcastSet & 0x1f);
+       if (nResult < 0)
+               goto end;
+
+end:
+
+       return nResult;
+}
 
 static unsigned int p_tas2555_shutdown_data[] = {
        channel_both, TAS2555_SOFT_MUTE_REG, 0x01,      //soft mute
@@ -183,7 +224,38 @@ static int tas2555_dev_load_data(struct tas2555_priv *pTAS2555,
 
 int tas2555_load_default(struct tas2555_priv *pTAS2555)
 {
-       return tas2555_dev_load_data(pTAS2555, p_tas2555_default_data);
+       int nResult = 0;
+
+       nResult = pTAS2555->write(pTAS2555, channel_both, TAS2555_TEST_MODE_REG, 0x0d);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->read(pTAS2555, channel_left, TAS2555_BROADCAST_REG, &pTAS2555->mnLBroadcastSet);
+       if (nResult < 0)
+               goto end;
+
+       nResult = pTAS2555->read(pTAS2555, channel_right, TAS2555_BROADCAST_REG, &pTAS2555->mnRBroadcastSet);
+       if (nResult < 0)
+               goto end;
+
+       dev_dbg(pTAS2555->dev, "%s, DevA Trim=0x%x, DevB Trim=0x%x\n",
+               __func__, pTAS2555->mnLBroadcastSet, pTAS2555->mnRBroadcastSet);
+
+       nResult = tas2555_dev_load_data(pTAS2555, p_tas2555_default_data);
+       if (nResult < 0)
+               goto end;
+
+       /* enable DOUT tri-state for extra BCLKs */
+       nResult = pTAS2555->update_bits(pTAS2555, channel_both, TAS2555_ASI1_DAC_FORMAT_REG, 0x01, 0x01);
+       if (nResult < 0)
+               goto end;
+
+       /* Interrupt pin, low-highZ, high active driven */
+       nResult = pTAS2555->update_bits(pTAS2555, channel_both, TAS2555_GPIO_HIZ_CTRL2_REG, 0x30, 0x30);
+
+end:
+
+       return nResult;
 }
 
 void tas2555_enable(struct tas2555_priv *pTAS2555, bool bEnable)
@@ -452,9 +524,25 @@ static int fw_parse_block_data(struct tas2555_priv *pTAS2555,
 
        pBlock->mnType = fw_convert_number(pData);
        pData += 4;
-
-       dev_dbg(pTAS2555->dev, "TBlock type[%d]\n", pBlock->mnType);
+       
+       if(pTAS2555->mpFirmware->mnDriverVersion  
+               >= PPC_DRIVER_VERSION ){
+               pBlock->mbPChkSumPresent = pData[0];
+               pData++;
+               
+               pBlock->mnPChkSum = pData[0];
+               pData++;
                
+               pBlock->mbYChkSumPresent = pData[0];
+               pData++;
+               
+               pBlock->mnYChkSum = pData[0];
+               pData++;
+       }else{
+               pBlock->mbPChkSumPresent = 0;
+               pBlock->mbYChkSumPresent = 0;
+       }
+
        pBlock->mnCommands = fw_convert_number(pData);
        pData += 4;
 
@@ -687,8 +775,10 @@ static int fw_parse(struct tas2555_priv *pTAS2555,
        return 0;
 }
 
-static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
+static int tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
 {
+       int nResult = 0;
+       int nRetry = 6;
        unsigned int nCommand = 0;
        unsigned char nBook;
        unsigned char nPage;
@@ -696,11 +786,13 @@ static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
        unsigned char nData;
        unsigned int nLength;
        enum channel chl;
+       unsigned int nValue = 0;
+       unsigned char nCRCChkSum = 0;
        unsigned char *pData = pBlock->mpData;
 
        dev_dbg(pTAS2555->dev, "TAS2555 load block: Type = %d, commands = %d\n",
                pBlock->mnType, pBlock->mnCommands);
-       
+
        if((pBlock->mnType == TAS2555_BLOCK_PLL)
                ||(pBlock->mnType == TAS2555_BLOCK_POST)
                ||(pBlock->mnType == TAS2555_BLOCK_POST_POWER_UP)){
@@ -717,13 +809,27 @@ static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
                chl = channel_broadcast;                
        }else{
                dev_err(pTAS2555->dev, "block type error %d\n", pBlock->mnType);
-               return;
+               return 0;
        }
-       
+
+start:
        if(chl == channel_broadcast){
-               tas2555_dev_load_data(pTAS2555, p_tas2555_enter_broadcast_data);
+               nResult = tas2555_enter_broadcast_mode(pTAS2555);
        }
-                       
+
+       if(pBlock->mbPChkSumPresent){
+               nResult = pTAS2555->write(pTAS2555, chl, TAS2555_CRC_RESET_REG, 1);
+               if(nResult < 0) {
+                       dev_err(pTAS2555->dev, "I2C err\n");
+                       goto err;
+               }
+       }
+
+       if (pBlock->mbYChkSumPresent)
+               nCRCChkSum = 0;
+
+       nCommand = 0;
+
        while (nCommand < pBlock->mnCommands) {
                pData = pBlock->mpData + nCommand * 4;
 
@@ -734,41 +840,80 @@ static void tas2555_load_block(struct tas2555_priv *pTAS2555, TBlock * pBlock)
 
                nCommand++;
 
-               if (nOffset <= 0x7F){
-                       pTAS2555->write(pTAS2555, 
-                                                       chl, 
-                                                       TAS2555_REG(nBook, nPage, nOffset),
-                                                       nData);
-               }else if (nOffset == 0x81) {
+               if (nOffset <= 0x7F) {
+                       pTAS2555->write(pTAS2555, chl, TAS2555_REG(nBook, nPage, nOffset), nData);
+               } else if (nOffset == 0x81) {
                        unsigned int nSleep = (nBook << 8) + nPage;
+
                        msleep(nSleep);
-               }else if (nOffset == 0x85) {
+               } else if (nOffset == 0x85) {
                        pData += 4;
                        nLength = (nBook << 8) + nPage;
                        nBook = pData[0];
                        nPage = pData[1];
                        nOffset = pData[2];
                        if (nLength > 1)
-                               pTAS2555->bulk_write(pTAS2555, 
-                                                                       chl, 
-                                                                       TAS2555_REG(nBook, nPage, nOffset), 
-                                                                       pData + 3, 
-                                                                       nLength);
+                               pTAS2555->bulk_write(pTAS2555, chl, TAS2555_REG(nBook, nPage, nOffset),
+                                                                       pData + 3, nLength);
                        else
-                               pTAS2555->write(pTAS2555, 
-                                                               chl, 
-                                                               TAS2555_REG(nBook, nPage, nOffset),
-                                                               pData[3]);
+                               pTAS2555->write(pTAS2555, chl,
+                                                               TAS2555_REG(nBook, nPage, nOffset), pData[3]);
 
                        nCommand++;
                        if (nLength >= 2)
                                nCommand += ((nLength - 2) / 4) + 1;
                }
        }
-       
-       if(chl == channel_broadcast){
-               tas2555_dev_load_data(pTAS2555, p_tas2555_exit_broadcast_data);
+
+       if (chl == channel_broadcast) {
+               nResult = tas2555_exit_broadcast_mode(pTAS2555);
+       }
+
+       if (pBlock->mbPChkSumPresent) {
+               if ((chl == channel_broadcast) || (chl&channel_left)) {
+                       pTAS2555->read(pTAS2555, channel_left, TAS2555_CRC_CHECKSUM_REG, &nValue);
+                       if ((nValue&0xff) != pBlock->mnPChkSum) {
+                               dev_err(pTAS2555->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
+                                       pBlock->mnPChkSum, (nValue&0xff));
+                               nRetry--;
+                               if (nRetry != 0) {
+                                       dev_info(pTAS2555->dev, "try to reload block type(%d)\n", pBlock->mnType);
+                                       goto start;
+                               }
+                               nResult = -1;
+                               goto err;
+                       } else {
+                               dev_dbg(pTAS2555->dev, "Block PChkSum match\n");
+                       }
+               }
+
+               if ((chl == channel_broadcast) || (chl&channel_right)) {
+                       pTAS2555->read(pTAS2555, channel_right, TAS2555_CRC_CHECKSUM_REG, &nValue);
+                       if ((nValue&0xff) != pBlock->mnPChkSum) {
+                               dev_err(pTAS2555->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n",
+                                       pBlock->mnPChkSum, (nValue&0xff));
+                               nRetry--;
+                               if(nRetry != 0) {
+                                       dev_info(pTAS2555->dev, "try to reload block type(%d)\n", pBlock->mnType);
+                                       goto start;
+                               }
+                               nResult = -1;
+                               goto err;
+                       } else {
+                               dev_dbg(pTAS2555->dev, "Block PChkSum match\n");
+                       }
+               }
+       }
+
+       if(pBlock->mbYChkSumPresent){
+       }
+
+err:
+       if(nResult < 0){
+               dev_err(pTAS2555->dev, "Block (%d) load error\n",
+                               pBlock->mnType);
        }
+       return nResult;
 }
 
 static void tas2555_load_data(struct tas2555_priv *pTAS2555, TData * pData,
index 0890a5ad377cc0783ef8690cd79f55ead7910c6a..c6d0177e7a62e6875be50122cbb2c323b5381c07 100755 (executable)
--- a/tas2555.h
+++ b/tas2555.h
 
 typedef struct {
        unsigned int mnType;
+       unsigned char mbPChkSumPresent;
+       unsigned char mnPChkSum;
+       unsigned char mbYChkSumPresent;
+       unsigned char mnYChkSum;                
        unsigned int mnCommands;
        unsigned char *mpData;
 } TBlock;
@@ -364,7 +368,9 @@ struct tas2555_priv {
        unsigned char mnLCurrentBook;
        unsigned char mnLCurrentPage;
        unsigned char mnRCurrentBook;
-       unsigned char mnRCurrentPage;   
+       unsigned char mnRCurrentPage;
+       unsigned int mnLBroadcastSet;
+       unsigned int mnRBroadcastSet;
        bool mbTILoadActive;
        int reset_gpio;
        bool mbPowerUp;