(CR):[Kane][audio]kernel:udpdate SPK PAcs35l41 driver
authorzhangjiaquan <zhangjiaquan@huaqin.com>
Thu, 3 Jan 2019 07:11:01 +0000 (02:11 -0500)
committerxiest1 <xiest1@lenovo.com>
Tue, 5 Nov 2019 09:30:11 +0000 (17:30 +0800)
1,udpdate SPK PAcs35l41 driver
2,solve the VA current issue,now va current is 0.2ma when pa is off

Change-Id: Ic2c2b1da04831f6147b47354776e0017ad84f38a
Signed-off-by: zhangjiaquan <zhangjiaquan@huaqin.com>
drivers/extcon/extcon-madera.c
include/sound/cs35l41.h
sound/soc/codecs/cs35l41-i2c.c
sound/soc/codecs/cs35l41-spi.c
sound/soc/codecs/cs35l41-tables.c
sound/soc/codecs/cs35l41.c
sound/soc/codecs/cs35l41.h

index 29eabaf3dada16e0a33e0d7cfaa9895ad3b5eb83..1a00044d2d48660c510360b15d0aa2b11b4b8698 100755 (executable)
@@ -2333,7 +2333,7 @@ static irqreturn_t madera_micdet(int irq, void *data)
         * and prevent race conditions if an IRQ occurs while
         * running the delayed work
         */
-       dev_warn(info->dev, "micdet IRQ debounce is %d ",msecs_to_jiffies(debounce));
+       dev_warn(info->dev, "micdet IRQ debounce  msecs_to_jiffies is %d ",msecs_to_jiffies(debounce));
        schedule_delayed_work(&info->micd_detect_work,
                              msecs_to_jiffies(debounce));
 
index b138d4ce778e1621885e8b985fe3b39b6f889e0b..3add6367804b4703d59446804e210c75438729bb 100755 (executable)
@@ -62,7 +62,7 @@ struct cs35l41_private {
        int extclk_cfg;
        int sclk;
        unsigned int cspl_cmd;
-       bool tdm_mode;
+       bool dspa_mode;
        bool i2s_mode;
        bool swire_mode;
        bool halo_booted;
@@ -72,7 +72,6 @@ struct cs35l41_private {
        struct gpio_desc *reset_gpio;
        struct completion global_pup_done;
        struct completion global_pdn_done;
-       struct completion mbox_cmd;
 };
 
 int cs35l41_probe(struct cs35l41_private *cs35l41,
index 2d6e5905d76013729f5243bcc80cb541f27b823f..2f4422a58af61d1076a4845d04ac60f8ff2e2862 100755 (executable)
@@ -43,6 +43,7 @@ static struct regmap_config cs35l41_regmap_i2c = {
        .num_reg_defaults = ARRAY_SIZE(cs35l41_reg),
        .volatile_reg = cs35l41_volatile_reg,
        .readable_reg = cs35l41_readable_reg,
+       .precious_reg = cs35l41_precious_reg,
        .cache_type = REGCACHE_RBTREE,
 };
 
index f4bf632649736f313e1b42889a31bdb8214c11b2..550e80a982cb2ceeeb36a7d8290ee29459a20775 100755 (executable)
@@ -39,6 +39,7 @@ static struct regmap_config cs35l41_regmap_spi = {
        .num_reg_defaults = ARRAY_SIZE(cs35l41_reg),
        .volatile_reg = cs35l41_volatile_reg,
        .readable_reg = cs35l41_readable_reg,
+       .precious_reg = cs35l41_precious_reg,
        .cache_type = REGCACHE_RBTREE,
 };
 
index 0ef66615dc5ff0b9d10142df12c5591bf2f41d15..5ba396e36293d39bc484c8cea2c8f27e614b78bf 100755 (executable)
@@ -600,6 +600,15 @@ bool cs35l41_readable_reg(struct device *dev, unsigned int reg)
        }
 }
 
+bool cs35l41_precious_reg(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case CS35L41_OTP_MEM0 ... CS35L41_OTP_MEM31:
+               return true;
+       default:
+               return false;
+       }
+}
 bool cs35l41_volatile_reg(struct device *dev, unsigned int reg)
 {
        switch (reg) {
@@ -607,6 +616,7 @@ bool cs35l41_volatile_reg(struct device *dev, unsigned int reg)
        case CS35L41_SFT_RESET:
        case CS35L41_FABID:
        case CS35L41_REVID:
+       case CS35L41_DTEMP_EN:
        case CS35L41_IRQ1_STATUS:
        case CS35L41_IRQ1_STATUS1:
        case CS35L41_IRQ1_STATUS2:
@@ -924,13 +934,6 @@ const struct cs35l41_otp_map_element_t
                .bit_offset = 16,
                .word_offset = 2,
        },
-       {
-               .id = 0x03,
-               .map = otp_map_2,
-               .num_elements = CS35L41_NUM_OTP_ELEM,
-               .bit_offset = 16,
-               .word_offset = 2,
-       },
        {
                .id = 0x06,
                .map = otp_map_2,
index 5649fcfd5f17623ff2457849566c1755bba2fe2c..757af395571ac5422e2d76d3071ff2032166c4bf 100755 (executable)
@@ -220,12 +220,14 @@ static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
                            cs35l41_pcm_sftramp_text);
 
 static const char * const cs35l41_cspl_cmd_text[] = {
+       "CSPL_MBOX_CMD_PAUSE",
        "CSPL_MBOX_CMD_RESUME",
        "CSPL_MBOX_CMD_REINIT",
        "CSPL_MBOX_CMD_STOP_PRE_REINIT",
 };
 
 static const unsigned int cs35l41_cspl_cmd_val[] = {
+       (unsigned int)CSPL_MBOX_CMD_PAUSE,
        (unsigned int)CSPL_MBOX_CMD_RESUME,
        (unsigned int)CSPL_MBOX_CMD_REINIT,
        (unsigned int)CSPL_MBOX_CMD_STOP_PRE_REINIT,
@@ -257,12 +259,18 @@ static bool cs35l41_is_csplmboxsts_correct(enum cs35l41_cspl_mboxcmd cmd,
 static int cs35l41_set_csplmboxcmd(struct cs35l41_private *cs35l41,
                                   enum cs35l41_cspl_mboxcmd cmd)
 {
-       int             ret;
-       unsigned int    sts;
-    #ifdef CS35L41_NO_MBOX_SUPPORT
-               dev_warn(cs35l41->dev, "MBOX support is disabled\n");
-               return 0;
-    #endif
+       int             ret = 0;
+       unsigned int    sts, i;
+       bool            ack = false;
+#ifdef CS35L41_NO_MBOX_SUPPORT
+       if(CSPL_MBOX_CMD_PAUSE==cmd)
+       {
+               regmap_write(cs35l41->regmap, CS35L41_CSPL_MBOX_CMD_DRV, cmd);
+               msleep(1);
+       }
+       dev_warn(cs35l41->dev, "MBOX support is disabled\n");
+       return 0;
+#endif
        /* Reset DSP sticky bit */
        regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2,
                     1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT);
@@ -274,26 +282,33 @@ static int cs35l41_set_csplmboxcmd(struct cs35l41_private *cs35l41,
        /*
         * Set mailbox cmd
         */
-       reinit_completion(&cs35l41->mbox_cmd);
+
        /* Unmask DSP INT */
        regmap_update_bits(cs35l41->regmap, CS35L41_IRQ2_MASK2,
                           1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT, 0);
        /* Unmask AP INT */
-       regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK2,
-                          1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT, 0);
        regmap_write(cs35l41->regmap, CS35L41_CSPL_MBOX_CMD_DRV, cmd);
-       ret = wait_for_completion_timeout(&cs35l41->mbox_cmd,
-                                         msecs_to_jiffies(CS35L41_MBOXWAIT));
-       if (ret == 0) {
+
+       for (i = 0; i < 5; i++) {
+               usleep_range(1000, 1010);
+               regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS2, &sts);
+               if (sts & (1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT)) {
+                       dev_dbg(cs35l41->dev,
+                               "%u: Received ACK in EINT for mbox cmd (%d)\n",
+                               i, cmd);
+                       regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2,
+                            1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT);
+                       ack = true;
+                       break;
+               }
+       }
+       if (!ack) {
                dev_err(cs35l41->dev,
                        "Timout waiting for DSP to set mbox cmd\n");
                ret = -ETIMEDOUT;
        }
 
        /* Mask AP INT */
-       regmap_update_bits(cs35l41->regmap, CS35L41_IRQ1_MASK2,
-                          1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT,
-                          1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT);
        /* Mask DSP INT */
        regmap_update_bits(cs35l41->regmap, CS35L41_IRQ2_MASK2,
                           1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT,
@@ -323,12 +338,15 @@ static int cs35l41_cspl_cmd_put(struct snd_kcontrol *kcontrol,
        struct cs35l41_private  *cs35l41 = snd_soc_codec_get_drvdata(codec);
        struct soc_enum         *soc_enum;
        unsigned int            i = ucontrol->value.enumerated.item[0];
-       int                     ret = 0;
 
        soc_enum = (struct soc_enum *)kcontrol->private_value;
+       if (i >= soc_enum->items) {
+               dev_err(codec->dev, "Invalid mixer input (%u)\n", i);
+               return -EINVAL;
+       }
        cs35l41->cspl_cmd = soc_enum->values[i];
 
-       return ret;
+       return 0;
 }
 
 static int cs35l41_cspl_cmd_get(struct snd_kcontrol *kcontrol,
@@ -479,12 +497,17 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
                         0, 7, 0),
        SOC_SINGLE_RANGE("ASPTX4 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 24,
                         0, 7, 0),
+       SOC_SINGLE_RANGE("ASPRX1 Slot Position", CS35L41_SP_FRAME_RX_SLOT, 0,
+                        0, 7, 0),
+       SOC_SINGLE_RANGE("ASPRX2 Slot Position", CS35L41_SP_FRAME_RX_SLOT, 8,
+                        0, 7, 0),
        SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
        SOC_ENUM("Boost Enable", bst_en_ctl),
        SOC_VALUE_ENUM_EXT("CSPL Command", cs35l41_cspl_cmd,
                           cs35l41_cspl_cmd_get, cs35l41_cspl_cmd_put),
        SOC_SINGLE_EXT("DSP Booted", SND_SOC_NOPM, 0, 1, 0,
                        cs35l41_halo_booted_get, cs35l41_halo_booted_put),
+       SOC_SINGLE("GLOBAL_EN from GPIO", CS35L41_PWR_CTRL1, 8, 1, 0),
        WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
 };
 
@@ -638,11 +661,6 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
                !(status[2] & ~masks[2]) && !(status[3] & ~masks[3]))
                return IRQ_NONE;
 
-       if (status[1] & (1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT)) {
-               regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2,
-                            1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT);
-               complete(&cs35l41->mbox_cmd);
-       }
 
        if (status[0] & CS35L41_PUP_DONE_MASK) {
                regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
@@ -803,6 +821,12 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
                                ret = cs35l41_set_csplmboxcmd(cs35l41,
                                                        cs35l41->cspl_cmd);
                }
+               regmap_update_bits(cs35l41->regmap, CS35L41_AMP_OUT_MUTE,
+                               CS35L41_AMP_MUTE_MASK, 0);
+               break;
+       case SND_SOC_DAPM_PRE_PMD:
+               regmap_update_bits(cs35l41->regmap, CS35L41_AMP_OUT_MUTE,
+                               CS35L41_AMP_MUTE_MASK, CS35L41_AMP_MUTE_MASK);
                break;
        case SND_SOC_DAPM_POST_PMD:
                if (cs35l41->halo_booted) {
@@ -867,7 +891,8 @@ static const struct snd_soc_dapm_widget cs35l41_dapm_widgets[] = {
 
        SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L41_PWR_CTRL2, 0, 0, NULL, 0,
                                cs35l41_main_amp_event,
-                               SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
+                               SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU
+                               | SND_SOC_DAPM_PRE_PMD),
 
        SND_SOC_DAPM_INPUT("VP"),
        SND_SOC_DAPM_INPUT("VBST"),
@@ -996,12 +1021,12 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
        case SND_SOC_DAIFMT_DSP_A:
                asp_fmt = 0;
                cs35l41->i2s_mode = false;
-               cs35l41->tdm_mode = true;
+               cs35l41->dspa_mode = true;
                break;
        case SND_SOC_DAIFMT_I2S:
                asp_fmt = 2;
                cs35l41->i2s_mode = true;
-               cs35l41->tdm_mode = false;
+               cs35l41->dspa_mode = false;
                break;
        default:
                dev_warn(cs35l41->dev, "cs35l41_set_dai_fmt: Invalid or unsupported DAI format\n");
@@ -1203,7 +1228,7 @@ static int cs35l41_pcm_hw_params(struct snd_pcm_substream *substream,
                regmap_update_bits(cs35l41->regmap, CS35L41_SP_RX_WL,
                                CS35L41_ASP_RX_WL_MASK,
                                asp_wl << CS35L41_ASP_RX_WL_SHIFT);
-               if (cs35l41->i2s_mode || cs35l41->tdm_mode) {
+               if (cs35l41->i2s_mode) {
                        regmap_update_bits(cs35l41->regmap,
                                        CS35L41_SP_FRAME_RX_SLOT,
                                        CS35L41_ASP_RX1_SLOT_MASK,
@@ -1723,12 +1748,27 @@ static const struct reg_sequence cs35l41_reva0_errata_patch[] = {
        {0x00000040,                    0x00005555},
        {0x00000040,                    0x0000AAAA},
        {0x00003854,                    0x05180240},
+       {CS35L41_VIMON_SPKMON_RESYNC,   0x00000000},
        {CS35L41_OTP_TRIM_30,           0x9091A1C8},
        {0x00003014,                    0x0200EE0E},
        {CS35L41_BSTCVRT_DCM_CTRL,      0x00000051},
        {0x00000054,                    0x00000004},
        {CS35L41_IRQ1_DB3,              0x00000000},
        {CS35L41_IRQ2_DB3,              0x00000000},
+       {CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000},
+       {CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000},
+       {CS35L41_ASP_CONTROL4,          0x00000000},
+       {0x00000040,                    0x0000CCCC},
+       {0x00000040,                    0x00003333},
+};
+static const struct reg_sequence cs35l41_revb0_errata_patch[] = {
+       {0x00000040,                    0x00005555},
+       {0x00000040,                    0x0000AAAA},
+       {CS35L41_VIMON_SPKMON_RESYNC,   0x00000000},
+       {CS35L41_BSTCVRT_DCM_CTRL,      0x00000051},
+       {CS35L41_DSP1_YM_ACCEL_PL0_PRI, 0x00000000},
+       {CS35L41_DSP1_XM_ACCEL_PL0_PRI, 0x00000000},
+       {CS35L41_ASP_CONTROL4,          0x00000000},
        {0x00000040,                    0x0000CCCC},
        {0x00000040,                    0x00003333},
 };
@@ -1885,7 +1925,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
        init_completion(&cs35l41->global_pdn_done);
        init_completion(&cs35l41->global_pup_done);
 
-       init_completion(&cs35l41->mbox_cmd);
 
        ret = devm_request_threaded_irq(cs35l41->dev, cs35l41->irq, NULL,
                                cs35l41_irq, IRQF_ONESHOT | irq_pol,
@@ -1913,7 +1952,14 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
                }
                break;
        case CS35L41_REVID_B0:
-               regmap_write(cs35l41->regmap, CS35L41_BSTCVRT_DCM_CTRL, 0x51);
+               ret = regmap_multi_reg_write(cs35l41->regmap,
+                               cs35l41_revb0_errata_patch,
+                               ARRAY_SIZE(cs35l41_revb0_errata_patch));
+               if (ret < 0) {
+                       dev_err(cs35l41->dev,
+                               "Failed to apply B0 errata patch %d\n", ret);
+                       goto err;
+               }
                break;
        }
 
index 81d2b0ddc94e73dcb11ff6731960b270a13e1e8b..56c90ba24eb37e18e136265c5f729b10fdeb47bc 100755 (executable)
@@ -71,6 +71,7 @@
 #define CS35L41_BSTCVRT_DCM_MODE_FORCE 0x00003820
 #define CS35L41_BSTCVRT_OVERVOLT_CTRL  0x00003830
 #define CS35L41_VI_VOL_POL             0x00004000
+#define CS35L41_VIMON_SPKMON_RESYNC    0x00004100
 #define CS35L41_DTEMP_WARN_THLD                0x00004220
 #define CS35L41_DTEMP_CFG              0x00004224
 #define CS35L41_DTEMP_EN               0x00004308
@@ -83,6 +84,7 @@
 #define CS35L41_SP_FRAME_RX_SLOT       0x00004820
 #define CS35L41_SP_TX_WL               0x00004830
 #define CS35L41_SP_RX_WL               0x00004840
+#define CS35L41_ASP_CONTROL4           0x00004854
 #define CS35L41_DAC_PCM1_SRC           0x00004C00
 #define CS35L41_ASP_TX1_SRC            0x00004C20
 #define CS35L41_ASP_TX2_SRC            0x00004C24
 #define CS35L41_MAX_CACHE_REG          0x0000006B
 #define CS35L41_OTP_SIZE_WORDS         32
 #define CS35L41_NUM_OTP_ELEM           100
-#define CS35L41_NUM_OTP_MAPS           4
+#define CS35L41_NUM_OTP_MAPS           3
 
 #define CS35L41_VALID_PDATA            0x80000000
 
 #define CS35L41_BST_EN_DEFAULT         0x2
 #define CS35L41_BST_EN_BYPASS          1
 
+#define CS35L41_AMP_MUTE_MASK          0x10
 #define CS35L41_PDN_DONE_MASK          0x00800000
 #define CS35L41_PDN_DONE_SHIFT         23
 #define CS35L41_PUP_DONE_MASK          0x01000000
                                | SNDRV_PCM_FMTBIT_S32_LE)
 
 bool cs35l41_readable_reg(struct device *dev, unsigned int reg);
+bool cs35l41_precious_reg(struct device *dev, unsigned int reg);
 bool cs35l41_volatile_reg(struct device *dev, unsigned int reg);
 
 struct cs35l41_otp_packed_element_t {
@@ -731,7 +735,6 @@ extern const struct cs35l41_otp_map_element_t
                                cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS];
 
 #define CS35L41_REGSTRIDE                      4
-#define CS35L41_MBOXWAIT                       50
 
 #define CS35L41_DSP_VIRT1_MBOX_SHIFT           20
 #define CS35L41_DSP_VIRT2_MBOX_SHIFT           21