summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorHsin-Yu Chao <hychao@chromium.org>2017-09-13 05:54:28 -0400
committerMark Brown <broonie@kernel.org>2017-09-13 12:40:30 -0400
commit659178f5d1bb5164480c35e5a749c4fe1dde5867 (patch)
tree5b8fc69ab881f39faeead04b3a433de2a89273fd /sound
parentf5fd4a67bef5f2c5c2c9eb0cb2900e12d192ae23 (diff)
ASoC: rt5514-spi: check irq status to schedule data copy
For wake on voice use case, we need to copy data from DSP buffer to PCM stream when system wakes up by voice. However the edge triggered IRQ could be missed when system wakes up, in that case the irq function will not be called. Fix that by checking the irq status bit and schedule data copy accordingly. Signed-off-by: Hsin-Yu Chao <hychao@chromium.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/rt5514-spi.c17
-rw-r--r--sound/soc/codecs/rt5514-spi.h3
2 files changed, 18 insertions, 2 deletions
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c
index ed6e5373916c..12f2ecf3a4fe 100644
--- a/sound/soc/codecs/rt5514-spi.c
+++ b/sound/soc/codecs/rt5514-spi.c
@@ -145,9 +145,8 @@ done:
145 mutex_unlock(&rt5514_dsp->dma_lock); 145 mutex_unlock(&rt5514_dsp->dma_lock);
146} 146}
147 147
148static irqreturn_t rt5514_spi_irq(int irq, void *data) 148static void rt5514_schedule_copy(struct rt5514_dsp *rt5514_dsp)
149{ 149{
150 struct rt5514_dsp *rt5514_dsp = data;
151 u8 buf[8]; 150 u8 buf[8];
152 151
153 rt5514_dsp->get_size = 0; 152 rt5514_dsp->get_size = 0;
@@ -180,6 +179,13 @@ static irqreturn_t rt5514_spi_irq(int irq, void *data)
180 if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit && 179 if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
181 rt5514_dsp->buf_rp && rt5514_dsp->buf_size) 180 rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
182 schedule_delayed_work(&rt5514_dsp->copy_work, 0); 181 schedule_delayed_work(&rt5514_dsp->copy_work, 0);
182}
183
184static irqreturn_t rt5514_spi_irq(int irq, void *data)
185{
186 struct rt5514_dsp *rt5514_dsp = data;
187
188 rt5514_schedule_copy(rt5514_dsp);
183 189
184 return IRQ_HANDLED; 190 return IRQ_HANDLED;
185} 191}
@@ -199,12 +205,19 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
199 struct rt5514_dsp *rt5514_dsp = 205 struct rt5514_dsp *rt5514_dsp =
200 snd_soc_platform_get_drvdata(rtd->platform); 206 snd_soc_platform_get_drvdata(rtd->platform);
201 int ret; 207 int ret;
208 u8 buf[8];
202 209
203 mutex_lock(&rt5514_dsp->dma_lock); 210 mutex_lock(&rt5514_dsp->dma_lock);
204 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream, 211 ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
205 params_buffer_bytes(hw_params)); 212 params_buffer_bytes(hw_params));
206 rt5514_dsp->substream = substream; 213 rt5514_dsp->substream = substream;
207 rt5514_dsp->dma_offset = 0; 214 rt5514_dsp->dma_offset = 0;
215
216 /* Read IRQ status and schedule copy accordingly. */
217 rt5514_spi_burst_read(RT5514_IRQ_CTRL, (u8 *)&buf, sizeof(buf));
218 if (buf[0] & RT5514_IRQ_STATUS_BIT)
219 rt5514_schedule_copy(rt5514_dsp);
220
208 mutex_unlock(&rt5514_dsp->dma_lock); 221 mutex_unlock(&rt5514_dsp->dma_lock);
209 222
210 return ret; 223 return ret;
diff --git a/sound/soc/codecs/rt5514-spi.h b/sound/soc/codecs/rt5514-spi.h
index a6434ee6ff03..c1a36647c119 100644
--- a/sound/soc/codecs/rt5514-spi.h
+++ b/sound/soc/codecs/rt5514-spi.h
@@ -20,6 +20,9 @@
20#define RT5514_BUFFER_VOICE_BASE 0x18000200 20#define RT5514_BUFFER_VOICE_BASE 0x18000200
21#define RT5514_BUFFER_VOICE_LIMIT 0x18000204 21#define RT5514_BUFFER_VOICE_LIMIT 0x18000204
22#define RT5514_BUFFER_VOICE_WP 0x1800020c 22#define RT5514_BUFFER_VOICE_WP 0x1800020c
23#define RT5514_IRQ_CTRL 0x18002094
24
25#define RT5514_IRQ_STATUS_BIT (0x1 << 5)
23 26
24/* SPI Command */ 27/* SPI Command */
25enum { 28enum {