From 565ace464105cb9623cbf4eb9549d4b0c24166c9 Mon Sep 17 00:00:00 2001 From: Charles Keepax Date: Wed, 6 Jan 2016 12:33:18 +0000 Subject: ASoC: wm_adsp: Add a handler for the compressed IRQ Here support is added for responding to DSP IRQs that are used to indicate data being available on the DSP. The idea is that we check the amount of data available upon receipt of an IRQ and on subsequent calls to the pointer callback we recheck once less than one fragment is available (to avoid excessive SPI traffic), if there is truely less than one fragment available we ack the last IRQ and wait for a new one. Signed-off-by: Charles Keepax Signed-off-by: Mark Brown --- sound/soc/codecs/wm5110.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'sound/soc/codecs/wm5110.c') diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index c36409601835..dde94c4a0caa 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c @@ -2177,10 +2177,23 @@ static int wm5110_open(struct snd_compr_stream *stream) return wm_adsp_compr_open(&priv->core.adsp[n_adsp], stream); } +static irqreturn_t wm5110_adsp2_irq(int irq, void *data) +{ + struct wm5110_priv *florida = data; + int ret; + + ret = wm_adsp_compr_handle_irq(&florida->core.adsp[2]); + if (ret == -ENODEV) + return IRQ_NONE; + + return IRQ_HANDLED; +} + static int wm5110_codec_probe(struct snd_soc_codec *codec) { struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->core.arizona; int i, ret; priv->core.arizona->dapm = dapm; @@ -2189,6 +2202,14 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) arizona_init_gpio(codec); arizona_init_mono(codec); + ret = arizona_request_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, + "ADSP2 Compressed IRQ", wm5110_adsp2_irq, + priv); + if (ret != 0) { + dev_err(codec->dev, "Failed to request DSP IRQ: %d\n", ret); + return ret; + } + for (i = 0; i < WM5110_NUM_ADSP; ++i) { ret = wm_adsp2_codec_probe(&priv->core.adsp[i], codec); if (ret) @@ -2209,12 +2230,15 @@ err_adsp2_codec_probe: for (--i; i >= 0; --i) wm_adsp2_codec_remove(&priv->core.adsp[i], codec); + arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); + return ret; } static int wm5110_codec_remove(struct snd_soc_codec *codec) { struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); + struct arizona *arizona = priv->core.arizona; int i; for (i = 0; i < WM5110_NUM_ADSP; ++i) @@ -2222,6 +2246,8 @@ static int wm5110_codec_remove(struct snd_soc_codec *codec) priv->core.arizona->dapm = NULL; + arizona_free_irq(arizona, ARIZONA_IRQ_DSP_IRQ1, priv); + return 0; } @@ -2273,6 +2299,7 @@ static struct snd_compr_ops wm5110_compr_ops = { .set_params = wm_adsp_compr_set_params, .get_caps = wm_adsp_compr_get_caps, .trigger = wm_adsp_compr_trigger, + .pointer = wm_adsp_compr_pointer, }; static struct snd_soc_platform_driver wm5110_compr_platform = { -- cgit v1.2.3