mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-05 16:37:50 +00:00
ASoC: cs35l56: Bugfixes and efficiency improvement
Merge series from Richard Fitzgerald <rf@opensource.cirrus.com>: First two patches are bugfixes. Third patch skips the overhead of rebooting the amp after applying firmware files when we know that it isn't necessary.
This commit is contained in:
commit
83b3432fc5
2 changed files with 47 additions and 19 deletions
|
@ -223,6 +223,7 @@
|
||||||
|
|
||||||
#define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001
|
#define CS35L56_MBOX_CMD_AUDIO_PLAY 0x0B000001
|
||||||
#define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002
|
#define CS35L56_MBOX_CMD_AUDIO_PAUSE 0x0B000002
|
||||||
|
#define CS35L56_MBOX_CMD_AUDIO_REINIT 0x0B000003
|
||||||
#define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001
|
#define CS35L56_MBOX_CMD_HIBERNATE_NOW 0x02000001
|
||||||
#define CS35L56_MBOX_CMD_WAKEUP 0x02000002
|
#define CS35L56_MBOX_CMD_WAKEUP 0x02000002
|
||||||
#define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003
|
#define CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE 0x02000003
|
||||||
|
|
|
@ -825,25 +825,23 @@ static void cs35l56_system_reset(struct cs35l56_private *cs35l56)
|
||||||
regcache_cache_only(cs35l56->regmap, false);
|
regcache_cache_only(cs35l56->regmap, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cs35l56_dsp_work(struct work_struct *work)
|
static void cs35l56_secure_patch(struct cs35l56_private *cs35l56)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Use wm_adsp to load and apply the firmware patch and coefficient files */
|
||||||
|
ret = wm_adsp_power_up(&cs35l56->dsp);
|
||||||
|
if (ret)
|
||||||
|
dev_dbg(cs35l56->dev, "%s: wm_adsp_power_up ret %d\n", __func__, ret);
|
||||||
|
else
|
||||||
|
cs35l56_mbox_send(cs35l56, CS35L56_MBOX_CMD_AUDIO_REINIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cs35l56_patch(struct cs35l56_private *cs35l56)
|
||||||
{
|
{
|
||||||
struct cs35l56_private *cs35l56 = container_of(work,
|
|
||||||
struct cs35l56_private,
|
|
||||||
dsp_work);
|
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
int ret = 0;
|
int ret;
|
||||||
|
|
||||||
if (!cs35l56->init_done)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cs35l56->dsp.part = devm_kasprintf(cs35l56->dev, GFP_KERNEL, "cs35l56%s-%02x",
|
|
||||||
cs35l56->secured ? "s" : "", cs35l56->rev);
|
|
||||||
|
|
||||||
if (!cs35l56->dsp.part)
|
|
||||||
return;
|
|
||||||
|
|
||||||
pm_runtime_get_sync(cs35l56->dev);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Disable SoundWire interrupts to prevent race with IRQ work.
|
* Disable SoundWire interrupts to prevent race with IRQ work.
|
||||||
|
@ -909,9 +907,6 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
||||||
err_unlock:
|
err_unlock:
|
||||||
mutex_unlock(&cs35l56->irq_lock);
|
mutex_unlock(&cs35l56->irq_lock);
|
||||||
err:
|
err:
|
||||||
pm_runtime_mark_last_busy(cs35l56->dev);
|
|
||||||
pm_runtime_put_autosuspend(cs35l56->dev);
|
|
||||||
|
|
||||||
/* Re-enable SoundWire interrupts */
|
/* Re-enable SoundWire interrupts */
|
||||||
if (cs35l56->sdw_peripheral) {
|
if (cs35l56->sdw_peripheral) {
|
||||||
cs35l56->sdw_irq_no_unmask = false;
|
cs35l56->sdw_irq_no_unmask = false;
|
||||||
|
@ -920,6 +915,32 @@ static void cs35l56_dsp_work(struct work_struct *work)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cs35l56_dsp_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct cs35l56_private *cs35l56 = container_of(work,
|
||||||
|
struct cs35l56_private,
|
||||||
|
dsp_work);
|
||||||
|
|
||||||
|
if (!cs35l56->init_done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pm_runtime_get_sync(cs35l56->dev);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the device is running in secure mode the firmware files can
|
||||||
|
* only contain insecure tunings and therefore we do not need to
|
||||||
|
* shutdown the firmware to apply them and can use the lower cost
|
||||||
|
* reinit sequence instead.
|
||||||
|
*/
|
||||||
|
if (cs35l56->secured)
|
||||||
|
cs35l56_secure_patch(cs35l56);
|
||||||
|
else
|
||||||
|
cs35l56_patch(cs35l56);
|
||||||
|
|
||||||
|
pm_runtime_mark_last_busy(cs35l56->dev);
|
||||||
|
pm_runtime_put_autosuspend(cs35l56->dev);
|
||||||
|
}
|
||||||
|
|
||||||
static int cs35l56_component_probe(struct snd_soc_component *component)
|
static int cs35l56_component_probe(struct snd_soc_component *component)
|
||||||
{
|
{
|
||||||
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
|
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
|
||||||
|
@ -1507,6 +1528,12 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
|
||||||
dev_info(cs35l56->dev, "Cirrus Logic CS35L56%s Rev %02X OTP%d\n",
|
dev_info(cs35l56->dev, "Cirrus Logic CS35L56%s Rev %02X OTP%d\n",
|
||||||
cs35l56->secured ? "s" : "", cs35l56->rev, otpid);
|
cs35l56->secured ? "s" : "", cs35l56->rev, otpid);
|
||||||
|
|
||||||
|
/* Populate the DSP information with the revision and security state */
|
||||||
|
cs35l56->dsp.part = devm_kasprintf(cs35l56->dev, GFP_KERNEL, "cs35l56%s-%02x",
|
||||||
|
cs35l56->secured ? "s" : "", cs35l56->rev);
|
||||||
|
if (!cs35l56->dsp.part)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
/* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
|
/* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
|
||||||
regmap_write(cs35l56->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
|
regmap_write(cs35l56->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
|
||||||
regmap_update_bits(cs35l56->regmap, CS35L56_IRQ1_MASK_1,
|
regmap_update_bits(cs35l56->regmap, CS35L56_IRQ1_MASK_1,
|
||||||
|
|
Loading…
Reference in a new issue