mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-09 21:59:12 -04:00
ASoC: cs35l41: Implement support for dynamic DMA
Implement support for dynamically allocating DMA buffer in CSPL firmware for firmware. SQA-1029 Mot-CRs-fixed: (CR): River: AoU bringup on Marley+Prince Change-Id: I0ff90e85e96ff5029e276f00e82f0503913fb9f1 Signed-off-by: Li Xu <li.xu@cirrus.com> Reviewed-on: https://gerrit.mot.com/1238847 Tested-by: Jira Key SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Reviewed-by: Konstantin Makariev <kmakariev@motorola.com> Submit-Approved: Jira Key
This commit is contained in:
parent
0c614b6196
commit
5ec000c5dc
3 changed files with 166 additions and 82 deletions
|
|
@ -61,6 +61,7 @@ struct cs35l41_private {
|
|||
int extclk_freq;
|
||||
int extclk_cfg;
|
||||
int sclk;
|
||||
unsigned int cspl_cmd;
|
||||
bool tdm_mode;
|
||||
bool i2s_mode;
|
||||
bool swire_mode;
|
||||
|
|
|
|||
|
|
@ -216,6 +216,143 @@ static SOC_ENUM_SINGLE_DECL(pcm_sft_ramp,
|
|||
CS35L41_AMP_DIG_VOL_CTRL, 0,
|
||||
cs35l41_pcm_sftramp_text);
|
||||
|
||||
static const char * const cs35l41_cspl_cmd_text[] = {
|
||||
"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_RESUME,
|
||||
(unsigned int)CSPL_MBOX_CMD_REINIT,
|
||||
(unsigned int)CSPL_MBOX_CMD_STOP_PRE_REINIT,
|
||||
};
|
||||
|
||||
static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_cspl_cmd, SND_SOC_NOPM, 0, 0,
|
||||
cs35l41_cspl_cmd_text, cs35l41_cspl_cmd_val);
|
||||
|
||||
static bool cs35l41_is_csplmboxsts_correct(enum cs35l41_cspl_mboxcmd cmd,
|
||||
enum cs35l41_cspl_mboxstate sts)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CSPL_MBOX_CMD_NONE:
|
||||
case CSPL_MBOX_CMD_UNKNOWN_CMD:
|
||||
return true;
|
||||
case CSPL_MBOX_CMD_PAUSE:
|
||||
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_csplmboxcmd(struct cs35l41_private *cs35l41,
|
||||
enum cs35l41_cspl_mboxcmd cmd)
|
||||
{
|
||||
int ret;
|
||||
unsigned int sts;
|
||||
|
||||
/* Reset DSP sticky bit */
|
||||
regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2,
|
||||
1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT);
|
||||
|
||||
/* Reset AP sticky bit */
|
||||
regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2,
|
||||
1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
usecs_to_jiffies(CS35L41_MBOXWAIT));
|
||||
if (ret == 0) {
|
||||
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,
|
||||
1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT);
|
||||
|
||||
if (regmap_read(cs35l41->regmap,
|
||||
CS35L41_CSPL_MBOX_STS, &sts) < 0) {
|
||||
dev_err(cs35l41->dev, "Failed to read %u\n",
|
||||
CS35L41_CSPL_MBOX_STS);
|
||||
ret = -EACCES;
|
||||
}
|
||||
|
||||
if (!cs35l41_is_csplmboxsts_correct(cmd,
|
||||
(enum cs35l41_cspl_mboxstate)sts)) {
|
||||
dev_err(cs35l41->dev,
|
||||
"Failed to set mailbox(cmd: %u, sts: %u)\n", cmd, sts);
|
||||
ret = -ENOMSG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs35l41_cspl_cmd_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(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;
|
||||
cs35l41->cspl_cmd = soc_enum->values[i];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs35l41_cspl_cmd_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
|
||||
struct cs35l41_private *cs35l41 = snd_soc_codec_get_drvdata(codec);
|
||||
struct soc_enum *soc_enum;
|
||||
unsigned int i;
|
||||
int ret = 0;
|
||||
|
||||
soc_enum = (struct soc_enum *)kcontrol->private_value;
|
||||
|
||||
for (i = 0; i < soc_enum->items; i++) {
|
||||
if (cs35l41->cspl_cmd == soc_enum->values[i])
|
||||
break;
|
||||
}
|
||||
|
||||
if (i >= soc_enum->items) {
|
||||
/* Cannot find value */
|
||||
dev_err(cs35l41->dev, "Cannot find cspl cmd\n");
|
||||
i = 0;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
ucontrol->value.enumerated.item[0] = i;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char * const cs35l41_pcm_source_texts[] = {"ASP", "DSP"};
|
||||
static const unsigned int cs35l41_pcm_source_values[] = {0x08, 0x32};
|
||||
static SOC_VALUE_ENUM_SINGLE_DECL(cs35l41_pcm_source_enum,
|
||||
|
|
@ -326,6 +463,8 @@ static const struct snd_kcontrol_new cs35l41_aud_controls[] = {
|
|||
SOC_SINGLE_RANGE("ASPTX4 Slot Position", CS35L41_SP_FRAME_TX_SLOT, 24,
|
||||
0, 7, 0),
|
||||
SOC_ENUM("PCM Soft Ramp", pcm_sft_ramp),
|
||||
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),
|
||||
WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
|
||||
|
|
@ -618,80 +757,6 @@ static const struct reg_sequence cs35l41_pdn_patch[] = {
|
|||
{0x00000040, 0x00000033},
|
||||
};
|
||||
|
||||
static bool cs35l41_is_csplmboxsts_correct(enum cspl_mboxcmd cmd,
|
||||
enum cspl_mboxstate sts)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CSPL_MBOX_CMD_NONE:
|
||||
case CSPL_MBOX_CMD_UNKNOWN_CMD:
|
||||
return true;
|
||||
case CSPL_MBOX_CMD_PAUSE:
|
||||
return (sts == CSPL_MBOX_STS_PAUSED);
|
||||
case CSPL_MBOX_CMD_RESUME:
|
||||
return (sts == CSPL_MBOX_STS_RUNNING);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int cs35l41_set_csplmboxcmd(struct cs35l41_private *cs35l41,
|
||||
enum cspl_mboxcmd cmd)
|
||||
{
|
||||
int ret;
|
||||
unsigned int sts;
|
||||
|
||||
/* Reset DSP sticky bit */
|
||||
regmap_write(cs35l41->regmap, CS35L41_IRQ2_STATUS2,
|
||||
1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT);
|
||||
|
||||
/* Reset AP sticky bit */
|
||||
regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS2,
|
||||
1 << CS35L41_CSPL_MBOX_CMD_FW_SHIFT);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
usecs_to_jiffies(CS35L41_MBOXWAIT));
|
||||
if (ret == 0) {
|
||||
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,
|
||||
1 << CS35L41_CSPL_MBOX_CMD_DRV_SHIFT);
|
||||
|
||||
if (regmap_read(cs35l41->regmap,
|
||||
CS35L41_CSPL_MBOX_STS, &sts) < 0) {
|
||||
dev_err(cs35l41->dev, "Failed to read %u\n",
|
||||
CS35L41_CSPL_MBOX_STS);
|
||||
ret = -EACCES;
|
||||
}
|
||||
|
||||
if (!cs35l41_is_csplmboxsts_correct(cmd, (enum cspl_mboxstate)sts)) {
|
||||
dev_err(cs35l41->dev,
|
||||
"Failed to set mailbox(cmd: %u, sts: %u)\n", cmd, sts);
|
||||
ret = -ENOMSG;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
|
|
@ -711,14 +776,25 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
|
|||
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
if (cs35l41->halo_booted)
|
||||
ret = cs35l41_set_csplmboxcmd(cs35l41,
|
||||
CSPL_MBOX_CMD_RESUME);
|
||||
if (cs35l41->halo_booted) {
|
||||
if (cs35l41->cspl_cmd == CSPL_MBOX_CMD_STOP_PRE_REINIT)
|
||||
/* Send this command on power down event */
|
||||
ret = cs35l41_set_csplmboxcmd(cs35l41,
|
||||
CSPL_MBOX_CMD_RESUME);
|
||||
else
|
||||
ret = cs35l41_set_csplmboxcmd(cs35l41,
|
||||
cs35l41->cspl_cmd);
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
if (cs35l41->halo_booted)
|
||||
ret = cs35l41_set_csplmboxcmd(cs35l41,
|
||||
CSPL_MBOX_CMD_PAUSE);
|
||||
if (cs35l41->halo_booted) {
|
||||
if (cs35l41->cspl_cmd == CSPL_MBOX_CMD_STOP_PRE_REINIT)
|
||||
ret = cs35l41_set_csplmboxcmd(cs35l41,
|
||||
cs35l41->cspl_cmd);
|
||||
else
|
||||
ret = cs35l41_set_csplmboxcmd(cs35l41,
|
||||
CSPL_MBOX_CMD_PAUSE);
|
||||
}
|
||||
|
||||
regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
|
||||
CS35L41_GLOBAL_EN_MASK, 0);
|
||||
|
|
@ -1669,6 +1745,9 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
|
|||
int timeout = 100;
|
||||
int irq_pol = 0;
|
||||
|
||||
/* Default to RESUME cmd */
|
||||
cs35l41->cspl_cmd = (unsigned int)CSPL_MBOX_CMD_RESUME;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cs35l41_supplies); i++)
|
||||
cs35l41->supplies[i].supply = cs35l41_supplies[i];
|
||||
|
||||
|
|
|
|||
|
|
@ -741,16 +741,20 @@ extern const struct cs35l41_otp_map_element_t
|
|||
#define CS35L41_CSPL_MBOX_CMD_DRV CS35L41_DSP_VIRT1_MBOX_1
|
||||
#define CS35L41_CSPL_MBOX_CMD_DRV_SHIFT CS35L41_DSP_VIRT1_MBOX_SHIFT
|
||||
|
||||
enum cspl_mboxstate {
|
||||
enum cs35l41_cspl_mboxstate {
|
||||
CSPL_MBOX_STS_RUNNING = 0,
|
||||
CSPL_MBOX_STS_PAUSED = 1,
|
||||
CSPL_MBOX_STS_RDY_FOR_REINIT = 2,
|
||||
};
|
||||
|
||||
enum cspl_mboxcmd {
|
||||
enum cs35l41_cspl_mboxcmd {
|
||||
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_UNKNOWN_CMD = -1,
|
||||
CSPL_MBOX_CMD_INVALID_SEQUENCE = -2,
|
||||
};
|
||||
|
||||
#endif /*__CS35L41_H__*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue