diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 5af4fb46b431..3add6367804b 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -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, diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 51d9d7aefb2f..8e806617bd35 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -254,8 +254,9 @@ 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; + int ret = 0; + unsigned int sts, i; + bool ack = false; /* Reset DSP sticky bit */ regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2, @@ -268,26 +269,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) { + + /* Poll for DSP ACK */ + 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, @@ -641,12 +649,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, CS35L41_PUP_DONE_MASK); @@ -1925,8 +1927,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, "cs35l41", cs35l41); diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h index 5b7bd79e0074..d285f802d168 100644 --- a/sound/soc/codecs/cs35l41.h +++ b/sound/soc/codecs/cs35l41.h @@ -736,7 +736,6 @@ extern const struct cs35l41_otp_map_element_t cs35l41_otp_map_map[CS35L41_NUM_OTP_MAPS]; #define CS35L41_REGSTRIDE 4 -#define CS35L41_MBOXWAIT 5 #define CS35L41_DSP_VIRT1_MBOX_SHIFT 20 #define CS35L41_DSP_VIRT2_MBOX_SHIFT 21