Commit 461c6232 authored by Ben Zhang's avatar Ben Zhang Committed by Mark Brown

ASoC: rt5677: Load firmware via SPI using delayed work

The firmware rt5677_elf_vad is an ELF binary obtained from
request_firmware(). Sections of the ELF are loaded to
the DSP via SPI. A model (e.g. en_us.mmap) can optionally be
loaded to the DSP at RT5677_MODEL_ADDR to overwrite the
baked-in model in rt5677_elf_vad.

Then we switch to DSP mode, load firmware, and let DSP run.
When a hotword is detected, an interrupt is fired and
rt5677_irq() is called. When 'DSP VAD Switch' is turned off,
the codec is set back to normal mode.

The kcontrol 'DSP VAD Switch' is automatically enabled/disabled
when the hotwording PCM stream is opened/closed.
Signed-off-by: default avatarBen Zhang <benzh@chromium.org>
Signed-off-by: default avatarCurtis Malainey <cujomalainey@chromium.org>
Link: https://lore.kernel.org/r/20191106011335.223061-2-cujomalainey@chromium.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent fe965096
......@@ -26,6 +26,7 @@
#include <sound/soc.h>
#include "rt5677.h"
#include "rt5677-spi.h"
#define DRV_NAME "rt5677spi"
......@@ -111,10 +112,16 @@ static int rt5677_spi_pcm_close(
struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *codec_component =
snd_soc_rtdcom_lookup(rtd, "rt5677");
struct rt5677_priv *rt5677 =
snd_soc_component_get_drvdata(codec_component);
struct rt5677_dsp *rt5677_dsp =
snd_soc_component_get_drvdata(component);
cancel_delayed_work_sync(&rt5677_dsp->copy_work);
rt5677->set_dsp_vad(codec_component, false);
return 0;
}
......@@ -154,9 +161,15 @@ static int rt5677_spi_prepare(
struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_component *rt5677_component =
snd_soc_rtdcom_lookup(rtd, "rt5677");
struct rt5677_priv *rt5677 =
snd_soc_component_get_drvdata(rt5677_component);
struct rt5677_dsp *rt5677_dsp =
snd_soc_component_get_drvdata(component);
rt5677->set_dsp_vad(rt5677_component, true);
rt5677_dsp->dma_offset = 0;
rt5677_dsp->avail_bytes = 0;
return 0;
......
This diff is collapsed.
......@@ -1730,6 +1730,7 @@ enum {
RT5677_AIF4,
RT5677_AIF5,
RT5677_AIFS,
RT5677_DSPBUFF,
};
enum {
......@@ -1845,14 +1846,17 @@ struct rt5677_priv {
#ifdef CONFIG_GPIOLIB
struct gpio_chip gpio_chip;
#endif
bool dsp_vad_en;
bool dsp_vad_en; /* DSP VAD enable/disable request */
bool is_dsp_mode;
bool is_vref_slow;
struct delayed_work dsp_work;
/* Interrupt handling */
struct irq_domain *domain;
struct mutex irq_lock;
unsigned int irq_en;
int (*set_dsp_vad)(struct snd_soc_component *component, bool on);
};
int rt5677_sel_asrc_clk_src(struct snd_soc_component *component,
......
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