From: Stefan Binding <sbinding@xxxxxxxxxxxxxxxxxxxxx> This function is used to control the DSP Firmware for cs35l41, and will be needed by the cs35l41 hda driver, when firmware support is added. Acked-by: Charles Keepax <ckeepax@xxxxxxxxxxxxxxxxxxxxx> Signed-off-by: Stefan Binding <sbinding@xxxxxxxxxxxxxxxxxxxxx> Signed-off-by: Vitaly Rodionov <vitalyr@xxxxxxxxxxxxxxxxxxxxx> --- include/sound/cs35l41.h | 20 ++++++++++ sound/soc/codecs/cs35l41-lib.c | 57 ++++++++++++++++++++++++++++ sound/soc/codecs/cs35l41.c | 69 +++------------------------------- sound/soc/codecs/cs35l41.h | 18 --------- 4 files changed, 82 insertions(+), 82 deletions(-) diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h index 5bd2a5d370ce..77cfd92cf33b 100644 --- a/include/sound/cs35l41.h +++ b/include/sound/cs35l41.h @@ -800,6 +800,24 @@ struct cs35l41_otp_map_element_t { u32 word_offset; }; +enum cs35l41_cspl_mbox_status { + CSPL_MBOX_STS_RUNNING = 0, + CSPL_MBOX_STS_PAUSED = 1, + CSPL_MBOX_STS_RDY_FOR_REINIT = 2, +}; + +enum cs35l41_cspl_mbox_cmd { + CSPL_MBOX_CMD_NONE = 0, + CSPL_MBOX_CMD_PAUSE = 1, + CSPL_MBOX_CMD_RESUME = 2, + CSPL_MBOX_CMD_REINIT = 3, + CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, + CSPL_MBOX_CMD_HIBERNATE = 5, + CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, + CSPL_MBOX_CMD_UNKNOWN_CMD = -1, + CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, +}; + /* * IRQs */ @@ -858,6 +876,8 @@ int cs35l41_set_channels(struct device *dev, struct regmap *reg, unsigned int tx_num, unsigned int *tx_slot, unsigned int rx_num, unsigned int *rx_slot); int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); +int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + enum cs35l41_cspl_mbox_cmd cmd); int cs35l41_init_boost(struct device *dev, struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg); bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type); diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index d6017461766c..56464e5844d6 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1208,6 +1208,63 @@ int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg) } EXPORT_SYMBOL_GPL(cs35l41_gpio_config); +static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, + enum cs35l41_cspl_mbox_status sts) +{ + switch (cmd) { + case CSPL_MBOX_CMD_NONE: + case CSPL_MBOX_CMD_UNKNOWN_CMD: + return true; + case CSPL_MBOX_CMD_PAUSE: + case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: + return (sts == CSPL_MBOX_STS_PAUSED); + case CSPL_MBOX_CMD_RESUME: + return (sts == CSPL_MBOX_STS_RUNNING); + case CSPL_MBOX_CMD_REINIT: + return (sts == CSPL_MBOX_STS_RUNNING); + case CSPL_MBOX_CMD_STOP_PRE_REINIT: + return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); + default: + return false; + } +} + +int cs35l41_set_cspl_mbox_cmd(struct device *dev, struct regmap *regmap, + enum cs35l41_cspl_mbox_cmd cmd) +{ + unsigned int sts = 0, i; + int ret; + + // Set mailbox cmd + ret = regmap_write(regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); + if (ret < 0) { + if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) + dev_err(dev, "Failed to write MBOX: %d\n", ret); + return ret; + } + + // Read mailbox status and verify it is appropriate for the given cmd + for (i = 0; i < 5; i++) { + usleep_range(1000, 1100); + + ret = regmap_read(regmap, CS35L41_DSP_MBOX_2, &sts); + if (ret < 0) { + dev_err(dev, "Failed to read MBOX STS: %d\n", ret); + continue; + } + + if (!cs35l41_check_cspl_mbox_sts(cmd, sts)) + dev_dbg(dev, "[%u] cmd %u returned invalid sts %u", i, cmd, sts); + else + return 0; + } + + dev_err(dev, "Failed to set mailbox cmd %u (status %u)\n", cmd, sts); + + return -ENOMSG; +} +EXPORT_SYMBOL_GPL(cs35l41_set_cspl_mbox_cmd); + MODULE_DESCRIPTION("CS35L41 library"); MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@xxxxxxxxxx>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@xxxxxxxxxxxxxxxxxxxxx>"); diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c index 912196f45648..0285946688f7 100644 --- a/sound/soc/codecs/cs35l41.c +++ b/sound/soc/codecs/cs35l41.c @@ -208,67 +208,6 @@ static int cs35l41_dsp_preload_ev(struct snd_soc_dapm_widget *w, } } -static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd, - enum cs35l41_cspl_mbox_status sts) -{ - switch (cmd) { - case CSPL_MBOX_CMD_NONE: - case CSPL_MBOX_CMD_UNKNOWN_CMD: - return true; - case CSPL_MBOX_CMD_PAUSE: - case CSPL_MBOX_CMD_OUT_OF_HIBERNATE: - return (sts == CSPL_MBOX_STS_PAUSED); - case CSPL_MBOX_CMD_RESUME: - return (sts == CSPL_MBOX_STS_RUNNING); - case CSPL_MBOX_CMD_REINIT: - return (sts == CSPL_MBOX_STS_RUNNING); - case CSPL_MBOX_CMD_STOP_PRE_REINIT: - return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT); - default: - return false; - } -} - -static int cs35l41_set_cspl_mbox_cmd(struct cs35l41_private *cs35l41, - enum cs35l41_cspl_mbox_cmd cmd) -{ - unsigned int sts = 0, i; - int ret; - - // Set mailbox cmd - ret = regmap_write(cs35l41->regmap, CS35L41_DSP_VIRT1_MBOX_1, cmd); - if (ret < 0) { - if (cmd != CSPL_MBOX_CMD_OUT_OF_HIBERNATE) - dev_err(cs35l41->dev, "Failed to write MBOX: %d\n", ret); - return ret; - } - - // Read mailbox status and verify it is appropriate for the given cmd - for (i = 0; i < 5; i++) { - usleep_range(1000, 1100); - - ret = regmap_read(cs35l41->regmap, CS35L41_DSP_MBOX_2, &sts); - if (ret < 0) { - dev_err(cs35l41->dev, "Failed to read MBOX STS: %d\n", ret); - continue; - } - - if (!cs35l41_check_cspl_mbox_sts(cmd, sts)) { - dev_dbg(cs35l41->dev, - "[%u] cmd %u returned invalid sts %u", - i, cmd, sts); - } else { - return 0; - } - } - - dev_err(cs35l41->dev, - "Failed to set mailbox cmd %u (status %u)\n", - cmd, sts); - - return -ENOMSG; -} - static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -299,9 +238,11 @@ static int cs35l41_dsp_audio_ev(struct snd_soc_dapm_widget *w, return -EINVAL; } - return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_RESUME); + return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_RESUME); case SND_SOC_DAPM_PRE_PMD: - return cs35l41_set_cspl_mbox_cmd(cs35l41, CSPL_MBOX_CMD_PAUSE); + return cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, + CSPL_MBOX_CMD_PAUSE); default: return 0; } @@ -1475,7 +1416,7 @@ static int cs35l41_exit_hibernate(struct cs35l41_private *cs35l41) dev_dbg(cs35l41->dev, "Exit hibernate\n"); for (j = 0; j < wake_retries; j++) { - ret = cs35l41_set_cspl_mbox_cmd(cs35l41, + ret = cs35l41_set_cspl_mbox_cmd(cs35l41->dev, cs35l41->regmap, CSPL_MBOX_CMD_OUT_OF_HIBERNATE); if (!ret) break; diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h index e3369e0aa89f..c85cbc1dd333 100644 --- a/sound/soc/codecs/cs35l41.h +++ b/sound/soc/codecs/cs35l41.h @@ -23,24 +23,6 @@ extern const struct dev_pm_ops cs35l41_pm_ops; -enum cs35l41_cspl_mbox_status { - CSPL_MBOX_STS_RUNNING = 0, - CSPL_MBOX_STS_PAUSED = 1, - CSPL_MBOX_STS_RDY_FOR_REINIT = 2, -}; - -enum cs35l41_cspl_mbox_cmd { - CSPL_MBOX_CMD_NONE = 0, - CSPL_MBOX_CMD_PAUSE = 1, - CSPL_MBOX_CMD_RESUME = 2, - CSPL_MBOX_CMD_REINIT = 3, - CSPL_MBOX_CMD_STOP_PRE_REINIT = 4, - CSPL_MBOX_CMD_HIBERNATE = 5, - CSPL_MBOX_CMD_OUT_OF_HIBERNATE = 6, - CSPL_MBOX_CMD_UNKNOWN_CMD = -1, - CSPL_MBOX_CMD_INVALID_SEQUENCE = -2, -}; - struct cs35l41_private { struct wm_adsp dsp; /* needs to be first member */ struct snd_soc_codec *codec; -- 2.34.1