Commit 83b3432f authored by Mark Brown's avatar Mark Brown

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.
parents af53b00f 1a8edfcf
...@@ -223,6 +223,7 @@ ...@@ -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) ...@@ -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)
{ {
struct cs35l56_private *cs35l56 = container_of(work, int ret;
struct cs35l56_private,
dsp_work);
unsigned int reg;
unsigned int val;
int ret = 0;
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) /* Use wm_adsp to load and apply the firmware patch and coefficient files */
return; 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);
}
pm_runtime_get_sync(cs35l56->dev); static void cs35l56_patch(struct cs35l56_private *cs35l56)
{
unsigned int reg;
unsigned int val;
int ret;
/* /*
* 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) ...@@ -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) ...@@ -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) ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment