diff options
author | Stefan Binding <sbinding@opensource.cirrus.com> | 2022-05-09 22:46:43 +0100 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-05-16 09:54:14 +0200 |
commit | caf7c1f1de9f011ea0e6494fcb1b2ba203bd3422 (patch) | |
tree | 7ef689937881dba5217f85575d121bb58bfddbda /sound/soc/codecs | |
parent | de8cab7b38d74e7f2bec7f3abe129c31354a5dcf (diff) | |
download | linux-caf7c1f1de9f011ea0e6494fcb1b2ba203bd3422.tar.bz2 |
ASoC: cs35l41: Move cs35l41_set_cspl_mbox_cmd to shared code
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.
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220509214703.4482-7-vitalyr@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/cs35l41-lib.c | 57 | ||||
-rw-r--r-- | sound/soc/codecs/cs35l41.c | 69 | ||||
-rw-r--r-- | sound/soc/codecs/cs35l41.h | 18 |
3 files changed, 62 insertions, 82 deletions
diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c index 491616c7c5c7..451d3be37157 100644 --- a/sound/soc/codecs/cs35l41-lib.c +++ b/sound/soc/codecs/cs35l41-lib.c @@ -1206,6 +1206,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@cirrus.com>"); MODULE_AUTHOR("Lucas Tanure, Cirrus Logic Inc, <tanureal@opensource.cirrus.com>"); 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; |