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>
This commit is contained in:
Родитель
de8cab7b38
Коммит
caf7c1f1de
|
@ -801,6 +801,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
|
||||
*/
|
||||
|
@ -859,6 +877,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);
|
||||
|
|
|
@ -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>");
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче