Fix IRQ related bugs
authorTracy Yi <tracy-yi@ti.com>
Mon, 22 Apr 2019 07:37:25 +0000 (15:37 +0800)
committerTracy Yi <tracy-yi@ti.com>
Mon, 22 Apr 2019 07:37:25 +0000 (15:37 +0800)
Signed-off-by: Tracy Yi <tracy-yi@ti.com>
tas2563-codec.c
tas2563-regmap.c
tas2563.h
tiload.c

index 002fcc006b7e89d790861d7fdb07d4777328c654..3b97b1d47e743420486bcb1d69df6caaf42fdfb6 100644 (file)
@@ -54,7 +54,7 @@
 #define        PPC_DRIVER_MTPLLSRC                     0x00000400
 #define        PPC_DRIVER_CFGDEV_NONCRC        0x00000101
 
-#define TAS2563_CAL_NAME    "/data/vendor/pa_cal/tas2563_cal.bin"
+#define TAS2563_CAL_NAME    "/mnt/vendor/persist/audio/tas2563_cal.bin"
 #define RESTART_MAX 3
 
 #define TAS2563_UDELAY 0xFFFFFFFE
@@ -72,8 +72,6 @@
 #define TAS2563_BLOCK_CFG_POST                 0x05
 #define TAS2563_BLOCK_CFG_POST_POWER   0x06
 
-static char pICN[] = {0x00, 0x01, 0x09, 0x45};
-static char pICNDelay[] = {0x00, 0x01, 0x00, 0x00};
 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt);
 static void tas2563_clear_firmware(struct TFirmware *pFirmware);
 
@@ -1108,7 +1106,7 @@ static int tas2563_codec_resume(struct snd_soc_codec *codec)
 
 static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
 {
-       int nResult = 0;
+       int nResult = 0, irqreg;
        /*unsigned int nValue;*/
        const char *pFWName;
        struct TProgram *pProgram;
@@ -1123,7 +1121,8 @@ static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
                        pTAS2563->dev, GFP_KERNEL, pTAS2563, tas2563_fw_ready);
 
                if(nResult < 0) {
-                       dev_err(pTAS2563->dev, "%s, firmware is loaded, %d\n", __func__, nResult);
+                       dev_err(pTAS2563->dev, "%s, firmware is not loaded, return %d\n",
+                                       __func__, nResult);
                        goto end;
                }
        }
@@ -1162,6 +1161,7 @@ static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
 
        switch (state) {
        case TAS2563_POWER_ACTIVE:
+/*
                nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
                        TAS2563_PowerControl_OperationalMode10_Mask |
                        TAS2563_PowerControl_ISNSPower_Mask |
@@ -1171,14 +1171,20 @@ static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
                        TAS2563_PowerControl_ISNSPower_Active);
                if (nResult < 0)
                        return nResult;
+*/
+
+//Clear latched IRQ before power on
+               pTAS2563->update_bits(pTAS2563, TAS2563_InterruptConfiguration,
+                                       TAS2563_InterruptConfiguration_CLEARLATINT_Mask,
+                                       TAS2563_InterruptConfiguration_CLEARLATINT_CLEAR);
                pTAS2563->mbPowerUp = true;
-               dev_info(pTAS2563->dev, "set ICN to -90dB\n");
-               nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_REG, pICN, 4);
-               if(nResult < 0)
-                       return nResult;
 
-               dev_info(pTAS2563->dev, "set ICN delay\n");
-               nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_DELAY, pICNDelay, 4);
+               pTAS2563->read(pTAS2563, TAS2563_LatchedInterruptReg0, &irqreg);
+               dev_info(pTAS2563->dev, "IRQ reg is: %d, %d\n", irqreg, __LINE__);
+
+//             pTAS2563->enableIRQ(pTAS2563, true);
+               schedule_delayed_work(&pTAS2563->irq_work, msecs_to_jiffies(100));
+
                break;
 
        case TAS2563_POWER_MUTE:
@@ -1197,6 +1203,7 @@ static int tas2563_set_power_state(struct tas2563_priv *pTAS2563, int state)
                        TAS2563_PowerControl_OperationalMode10_Mask,
                        TAS2563_PowerControl_OperationalMode10_Shutdown);
                        pTAS2563->mbPowerUp = false;
+                       pTAS2563->enableIRQ(pTAS2563, false);
                break;
 
        default:
@@ -1267,10 +1274,12 @@ static int tas2563_mute(struct snd_soc_dai *dai, int mute)
 static int tas2563_slot_config(struct snd_soc_codec *codec, struct tas2563_priv *pTAS2563, int blr_clk_ratio)
 {
        int ret = 0;
-       pTAS2563->update_bits(pTAS2563,
+       ret = pTAS2563->update_bits(pTAS2563,
                        TAS2563_TDMConfigurationReg5, 0xff, 0x42);
+       if(ret < 0)
+               return ret;
 
-       pTAS2563->update_bits(pTAS2563,
+       ret = pTAS2563->update_bits(pTAS2563,
                        TAS2563_TDMConfigurationReg6, 0xff, 0x40);
 
        return ret;
@@ -1474,8 +1483,21 @@ int tas2563_load_default(struct tas2563_priv *pTAS2563)
        if (ret < 0)
                goto end;
 
+/*Enable TDM IRQ */
+       ret = pTAS2563->update_bits(pTAS2563, TAS2563_InterruptMaskReg0,
+                       TAS2563_InterruptMaskReg0_TDMClockErrorINTMASK_Mask,
+                       TAS2563_InterruptMaskReg0_TDMClockErrorINTMASK_Unmask);
+/* disable the DMA5 deglitch filter and halt timer */
+       ret = pTAS2563->update_bits(pTAS2563, TAS2563_CLKERR_Config,
+                       TAS2563_CLKERR_Config_DMA5FILTER_Mask,
+                       TAS2563_CLKERR_Config_DMA5FILTER_Disable);
+/* disable clk halt timer */
+       ret = pTAS2563->update_bits(pTAS2563, TAS2563_InterruptConfiguration,
+                       TAS2563_InterruptConfiguration_CLKHALT_Mask,
+                       TAS2563_InterruptConfiguration_CLKHALT_Disable);
+
 end:
-/* power up failed, restart later */
+/* Load default failed, restart later */
        dev_info(pTAS2563->dev, "%s, %d, ret = %d", __func__, __LINE__, ret);
        if (ret < 0)
                schedule_delayed_work(&pTAS2563->irq_work,
@@ -1838,9 +1860,6 @@ int tas2563_set_program(struct tas2563_priv *pTAS2563,
        if (nResult < 0)
                goto end;
        msleep(1);
-       nResult = tas2563_load_default(pTAS2563);
-       if (nResult < 0)
-               goto end;
 
        dev_info(pTAS2563->dev, "load program %d (%s)\n", nProgram, pProgram->mpName);
        nResult = tas2563_load_data(pTAS2563, &(pProgram->mData), TAS2563_BLOCK_PGM_DEV_A);
@@ -1852,6 +1871,10 @@ int tas2563_set_program(struct tas2563_priv *pTAS2563,
        if (nResult < 0)
                goto end;
 
+       nResult = tas2563_load_default(pTAS2563);
+       if (nResult < 0)
+               goto end;
+
        // Enable IV data
        nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
                                TAS2563_PowerControl_ISNSPower_Mask |
@@ -1863,7 +1886,7 @@ int tas2563_set_program(struct tas2563_priv *pTAS2563,
 
        if (pTAS2563->mbPowerUp) {
 //             pTAS2563->clearIRQ(pTAS2563);
-//             dev_info(pTAS2563->dev, "device powered up, load startup\n");
+               dev_info(pTAS2563->dev, "device powered up, load startup\n");
                nResult = tas2563_set_power_state(pTAS2563, TAS2563_POWER_MUTE);
 
                if (nResult < 0)
@@ -2083,7 +2106,7 @@ static int tas2563_hw_params(struct snd_pcm_substream *substream,
 {
        struct snd_soc_codec *codec = dai->codec;
        struct tas2563_priv *pTAS2563 = snd_soc_codec_get_drvdata(codec);
-       int ret = 0;
+       int nResult = 0;
        int blr_clk_ratio;
 
        dev_info(pTAS2563->dev, "%s, format: %d\n", __func__,
@@ -2091,10 +2114,10 @@ static int tas2563_hw_params(struct snd_pcm_substream *substream,
 
        mutex_lock(&pTAS2563->codec_lock);
 
-       ret = tas2563_set_bitwidth(pTAS2563, params_format(params));
-       if(ret < 0)
+       nResult = tas2563_set_bitwidth(pTAS2563, params_format(params));
+       if(nResult < 0)
        {
-               dev_info(pTAS2563->dev, "set bitwidth failed, %d\n", ret);
+               dev_info(pTAS2563->dev, "set bitwidth failed, %d\n", nResult);
                goto ret;
        }
 
@@ -2106,11 +2129,11 @@ static int tas2563_hw_params(struct snd_pcm_substream *substream,
        dev_info(pTAS2563->dev, "%s, sample rate: %d\n", __func__,
                params_rate(params));
 
-       ret = tas2563_set_samplerate(pTAS2563, params_rate(params));
+       nResult = tas2563_set_samplerate(pTAS2563, params_rate(params));
 
 ret:
        mutex_unlock(&pTAS2563->codec_lock);
-       return ret;
+       return nResult;
 }
 
 static int tas2563_set_fmt(struct tas2563_priv *pTAS2563, unsigned int fmt)
index a9c580f4bcb35fa2ddb65dea4e5d92bed83257b7..3a98cdb751588e57b7c290759c3c4e7bfc5771bd 100755 (executable)
@@ -56,6 +56,8 @@
 
 #define LOW_TEMPERATURE_GAIN 6
 #define LOW_TEMPERATURE_COUNTER 12
+static char pICN[] = {0x00, 0x00, 0x2f, 0x2c};
+static char pICNDelay[] = {0x00, 0x00, 0x70, 0x80};
 
 static int tas2563_change_book_page(struct tas2563_priv *pTAS2563,
        int book, int page)
@@ -115,9 +117,9 @@ static int tas2563_dev_read(struct tas2563_priv *pTAS2563,
                dev_err(pTAS2563->dev, "%s, ERROR, L=%d, E=%d\n",
                        __func__, __LINE__, nResult);
        else
-               dev_dbg(pTAS2563->dev, "%s: BOOK:PAGE:REG %u:%u:%u\n", __func__,
+               dev_dbg(pTAS2563->dev, "%s: BOOK:PAGE:REG %u:%u:%u,%x\n", __func__,
                        TAS2563_BOOK_ID(reg), TAS2563_PAGE_ID(reg),
-                       TAS2563_PAGE_REG(reg));
+                       TAS2563_PAGE_REG(reg), *pValue);
 
 end:
        mutex_unlock(&pTAS2563->dev_lock);
@@ -262,7 +264,7 @@ static const struct reg_default tas2563_reg_defaults[] = {
        { TAS2563_TDMConfigurationReg3, 0x10 },
        { TAS2563_InterruptMaskReg0, 0xfc },
        { TAS2563_InterruptMaskReg1, 0xb1 },
-       { TAS2563_InterruptConfiguration, 0x05 },
+       { TAS2563_InterruptConfiguration, 0x1d },
        { TAS2563_MiscIRQ, 0x81 },
        { TAS2563_ClockConfiguration, 0x0c },
 
@@ -328,6 +330,7 @@ static void irq_work_routine(struct work_struct *work)
        unsigned int nDevInt1Status = 0, nDevInt2Status = 0;
        int nCounter = 2;
        int nResult = 0;
+       int irqreg;
 
        dev_info(pTAS2563->dev, "%s\n", __func__);
 #ifdef CONFIG_TAS2563_CODEC
@@ -344,24 +347,24 @@ static void irq_work_routine(struct work_struct *work)
                goto end;
        }
 
-       nResult = regmap_write(pTAS2563->regmap, TAS2563_InterruptMaskReg0,
+       nResult = tas2563_dev_write(pTAS2563, TAS2563_InterruptMaskReg0,
                                TAS2563_InterruptMaskReg0_Disable);
-       nResult = regmap_write(pTAS2563->regmap, TAS2563_InterruptMaskReg1,
+       nResult = tas2563_dev_write(pTAS2563, TAS2563_InterruptMaskReg1,
                                TAS2563_InterruptMaskReg1_Disable);
 
        if (nResult < 0)
                goto reload;
 
-       nResult = regmap_read(pTAS2563->regmap, TAS2563_LatchedInterruptReg0, &nDevInt1Status);
+       nResult = tas2563_dev_read(pTAS2563, TAS2563_LatchedInterruptReg0, &nDevInt1Status);
        if (nResult >= 0)
-               nResult = regmap_read(pTAS2563->regmap, TAS2563_LatchedInterruptReg1, &nDevInt2Status);
+               nResult = tas2563_dev_read(pTAS2563, TAS2563_LatchedInterruptReg1, &nDevInt2Status);
        else
                goto reload;
 
-       dev_dbg(pTAS2563->dev, "IRQ status : 0x%x, 0x%x\n",
+       dev_info(pTAS2563->dev, "IRQ status : 0x%x, 0x%x\n",
                        nDevInt1Status, nDevInt2Status);
 
-       if (((nDevInt1Status & 0x3) != 0) || ((nDevInt2Status & 0x0f) != 0)) {
+       if (((nDevInt1Status & 0x7) != 0) || ((nDevInt2Status & 0x0f) != 0)) {
                /* in case of INT_OC, INT_OT, INT_OVLT, INT_UVLT, INT_BO */
 
                if (nDevInt1Status & TAS2563_LatchedInterruptReg0_OCEFlagSticky_Interrupt) {
@@ -399,7 +402,7 @@ static void irq_work_routine(struct work_struct *work)
                nCounter = 2;
 
                while (nCounter > 0) {
-                       nResult = regmap_read(pTAS2563->regmap, TAS2563_PowerControl, &nDevInt1Status);
+                       nResult = tas2563_dev_read(pTAS2563, TAS2563_PowerControl, &nDevInt1Status);
                        if (nResult < 0)
                                goto reload;
 
@@ -407,12 +410,42 @@ static void irq_work_routine(struct work_struct *work)
                                != TAS2563_PowerControl_OperationalMode10_Shutdown)
                                break;
 
+                       pTAS2563->read(pTAS2563, TAS2563_LatchedInterruptReg0, &irqreg);
+                       dev_info(pTAS2563->dev, "IRQ reg is: %s %d, %d\n", __func__, irqreg, __LINE__);
+
+                       nResult = pTAS2563->update_bits(pTAS2563, TAS2563_PowerControl,
+                               TAS2563_PowerControl_OperationalMode10_Mask |
+                               TAS2563_PowerControl_ISNSPower_Mask |
+                               TAS2563_PowerControl_VSNSPower_Mask,
+                               TAS2563_PowerControl_OperationalMode10_Active |
+                               TAS2563_PowerControl_VSNSPower_Active |
+                               TAS2563_PowerControl_ISNSPower_Active);
+                       if (nResult < 0)
+                               goto reload;
+
+                       pTAS2563->read(pTAS2563, TAS2563_LatchedInterruptReg0, &irqreg);
+                       dev_info(pTAS2563->dev, "IRQ reg is: %s, %d, %d\n", __func__, irqreg, __LINE__);
+
+                       dev_info(pTAS2563->dev, "set ICN to -90dB\n");
+                       nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_REG, pICN, 4);
+                       if(nResult < 0)
+                               goto reload;
+
+                       pTAS2563->read(pTAS2563, TAS2563_LatchedInterruptReg0, &irqreg);
+                       dev_info(pTAS2563->dev, "IRQ reg is: %d, %d\n", irqreg, __LINE__);
+
+                       dev_info(pTAS2563->dev, "set ICN delay\n");
+                       nResult = pTAS2563->bulk_write(pTAS2563, TAS2563_ICN_DELAY, pICNDelay, 4);
+
+                       pTAS2563->read(pTAS2563, TAS2563_LatchedInterruptReg0, &irqreg);
+                       dev_info(pTAS2563->dev, "IRQ reg is: %d, %d\n", irqreg, __LINE__);
+
                        nCounter--;
                        if (nCounter > 0) {
-                               /* in case check pow status just after power on TAS2563 */
+                               /* in case check power status just after power on TAS2563 */
                                dev_dbg(pTAS2563->dev, "PowSts B: 0x%x, check again after 10ms\n",
                                        nDevInt1Status);
-                               msleep(10);
+                               msleep(20);
                        }
                }
 
@@ -428,11 +461,11 @@ static void irq_work_routine(struct work_struct *work)
                pTAS2563->mnErrCode &= ~ERROR_CLASSD_PWR;
        }
 
-       nResult = regmap_write(pTAS2563->regmap, TAS2563_InterruptMaskReg0, 0xfc);
+       nResult = tas2563_dev_write(pTAS2563, TAS2563_InterruptMaskReg0, 0xf8);
        if (nResult < 0)
                goto reload;
 
-       nResult = regmap_write(pTAS2563->regmap, TAS2563_InterruptMaskReg1, 0xb1);
+       nResult = tas2563_dev_write(pTAS2563, TAS2563_InterruptMaskReg1, 0xb1);
        if (nResult < 0)
                goto reload;
 
@@ -444,11 +477,11 @@ reload:
        //tas2563_LoadConfig(pTAS2563);
        tas2563_set_program(pTAS2563, pTAS2563->mnCurrentProgram, pTAS2563->mnCurrentConfiguration);
 
+end:
        if (nResult >= 0) {
                tas2563_enableIRQ(pTAS2563, true);
        }
-       
-end:
+
 #ifdef CONFIG_TAS2563_CODEC
        mutex_unlock(&pTAS2563->codec_lock);
 #endif
@@ -677,7 +710,7 @@ static int tas2563_i2c_probe(struct i2c_client *pClient,
                dev_dbg(pTAS2563->dev, "irq = %d\n", pTAS2563->mnIRQ);
                INIT_DELAYED_WORK(&pTAS2563->irq_work, irq_work_routine);
                nResult = request_threaded_irq(pTAS2563->mnIRQ, tas2563_irq_handler,
-                                       NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+                                       NULL, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                                        pClient->name, pTAS2563);
                if (nResult < 0) {
                        dev_err(pTAS2563->dev,
index bae9a2b1f7da24c0f7c658f3a95dac8342dc1027..f07ea83a0d5aba7e4cef04fe1e42cea6956138ec 100644 (file)
--- a/tas2563.h
+++ b/tas2563.h
@@ -524,9 +524,12 @@ struct TYCRC {
 
     /* Interrupt Configuration */
 #define TAS2563_InterruptConfiguration  TAS2563_REG(0x0, 0x0, 0x30)
-#define TAS2563_InterruptConfiguration_INTTHRUSW_Mask  (0x1 << 2),
-#define TAS2563_InterruptConfiguration_INTTHRUSW_IntOnIRQZ  (0x0 << 2)
-#define TAS2563_InterruptConfiguration_INTTHRUSW_IntFor2ms  (0x1 << 2)
+#define TAS2563_InterruptConfiguration_CLKHALT_Mask (0x1 << 6)
+#define TAS2563_InterruptConfiguration_CLKHALT_Enable (0x0 << 6)
+#define TAS2563_InterruptConfiguration_CLKHALT_Disable (0x1 << 6)
+#define TAS2563_InterruptConfiguration_CLEARLATINT_Mask  (0x1 << 2)
+#define TAS2563_InterruptConfiguration_CLEARLATINT_NOCLEAR  (0x0 << 2)
+#define TAS2563_InterruptConfiguration_CLEARLATINT_CLEAR  (0x1 << 2)
 #define TAS2563_InterruptConfiguration_PININTConfig10_Mask  (0x3 << 0)
 #define TAS2563_InterruptConfiguration_PININTConfig10_AssertOnLiveInterrupts \
        (0x0 << 0)
@@ -647,6 +650,11 @@ TAS2563_InterruptConfiguration_PININTConfig10_Assert2msOnLatchedInterrupts \
 #define TAS2563_I2CChecksum  TAS2563_REG(0x0, 0x0, 0x7E)
 #define TAS2563_I2CChecksum_I2CChecksum70_Mask  (0xff << 0)
 
+#define TAS2563_CLKERR_Config TAS2563_REG(0x0, 0x1, 0x31)
+#define TAS2563_CLKERR_Config_DMA5FILTER_Mask (0x1 << 1)
+#define TAS2563_CLKERR_Config_DMA5FILTER_Enable (0x0 << 0)
+#define TAS2563_CLKERR_Config_DMA5FILTER_Disable (0x1 << 1)
+
 #define TAS2563_SA_COEFF_SWAP_REG      TAS2563_REG(0, 0x35, 0x2c)
 #define TAS2563_CALI_T_REG     TAS2563_REG(0x8c, 0x30, 0x20)
 #define TAS2563_CALI_R0_REG            TAS2563_REG(0x8c, 0x2f, 0x40)
@@ -658,7 +666,7 @@ TAS2563_InterruptConfiguration_PININTConfig10_Assert2msOnLatchedInterrupts \
 
     /* Book */
 #define TAS2563_Book  TAS2563_REG(0x0, 0x0, 0x7F)
-#define TAS2563_Book_Book70_Mask  (0xff << 0)
+#define TAS2563_Book_Mask  (0xff << 0)
 
 #define TAS2563_FW_NAME     "tas2563_uCDSP.bin"
 
@@ -687,7 +695,7 @@ TAS2563_InterruptConfiguration_PININTConfig10_Assert2msOnLatchedInterrupts \
 #define ERROR_UNDER_VOLTAGE    0x0000010
 #define ERROR_BROWNOUT         0x0000020
 #define ERROR_CLASSD_PWR       0x0000040
-#define ERROR_FAILSAFE         0x4000000
+#define ERROR_FAILSAFE         0x4000000
 
 #define TAS2563_COEFFICIENT_TMAX       0x7fffffff
 #define TAS2563_SAFE_GUARD_PATTERN     0x5a
index 203e481d49120dbc698696480e38208b3687140a..017e9bf3f052c2025b325a396baa9bfe95fbdab8 100755 (executable)
--- a/tiload.c
+++ b/tiload.c
@@ -38,7 +38,7 @@
 #include "tiload.h"
 
 /* enable debug prints in the driver */
-//#define DEBUG
+#define DEBUG
 
 static struct cdev *tiload_cdev;
 static int tiload_major; /* Dynamic allocation of Mjr No. */
@@ -144,8 +144,8 @@ static ssize_t tiload_read(struct file *filp, char __user *buf,
        dev_info(pTAS2563->dev, "read size = %d, reg_addr= %x , count = %d\n",
                (int) size, reg_addr, (int) count);
 /*     for (i = 0; i < (int) size; i++) {
-*              dev_dbg(pTAS2563->dev, "rd_data[%d]=%x\n", i, rd_data[i]);
-*      }
+               dev_dbg(pTAS2563->dev, "rd_data[%d]=%x\n", i, rd_data[i]);
+       }
 */
 #endif
        if (size != count)