OSDN Git Service

ASoC: dwc: Add helper functions to disable/enable irqs
authorJose Abreu <Jose.Abreu@synopsys.com>
Mon, 23 May 2016 10:02:22 +0000 (11:02 +0100)
committerMark Brown <broonie@kernel.org>
Mon, 30 May 2016 15:15:21 +0000 (16:15 +0100)
Helper functions to disable and enable the I2S interrupts were
added. Only the interrupts of the used channels are enabled.

Also, there is no need to enable irqs at dw_i2s_config(), they
are already enabled at startup.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: Carlos Palminha <palminha@synopsys.com>
Cc: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Rob Herring <robh@kernel.org>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: linux-snps-arc@lists.infradead.org
Cc: alsa-devel@alsa-project.org
Cc: devicetree@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/dwc/designware_i2s.c

index 0db69b7..4c4f0dc 100644 (file)
@@ -145,26 +145,54 @@ static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
        }
 }
 
-static void i2s_start(struct dw_i2s_dev *dev,
-                     struct snd_pcm_substream *substream)
+static inline void i2s_disable_irqs(struct dw_i2s_dev *dev, u32 stream,
+                                   int chan_nr)
 {
-       struct i2s_clk_config_data *config = &dev->config;
        u32 i, irq;
-       i2s_write_reg(dev->i2s_base, IER, 1);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               for (i = 0; i < (config->chan_nr / 2); i++) {
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               for (i = 0; i < (chan_nr / 2); i++) {
+                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
+                       i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
+               }
+       } else {
+               for (i = 0; i < (chan_nr / 2); i++) {
+                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
+                       i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
+               }
+       }
+}
+
+static inline void i2s_enable_irqs(struct dw_i2s_dev *dev, u32 stream,
+                                  int chan_nr)
+{
+       u32 i, irq;
+
+       if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               for (i = 0; i < (chan_nr / 2); i++) {
                        irq = i2s_read_reg(dev->i2s_base, IMR(i));
                        i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x30);
                }
-               i2s_write_reg(dev->i2s_base, ITER, 1);
        } else {
-               for (i = 0; i < (config->chan_nr / 2); i++) {
+               for (i = 0; i < (chan_nr / 2); i++) {
                        irq = i2s_read_reg(dev->i2s_base, IMR(i));
                        i2s_write_reg(dev->i2s_base, IMR(i), irq & ~0x03);
                }
-               i2s_write_reg(dev->i2s_base, IRER, 1);
        }
+}
+
+static void i2s_start(struct dw_i2s_dev *dev,
+                     struct snd_pcm_substream *substream)
+{
+       struct i2s_clk_config_data *config = &dev->config;
+
+       i2s_write_reg(dev->i2s_base, IER, 1);
+       i2s_enable_irqs(dev, substream->stream, config->chan_nr);
+
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+               i2s_write_reg(dev->i2s_base, ITER, 1);
+       else
+               i2s_write_reg(dev->i2s_base, IRER, 1);
 
        i2s_write_reg(dev->i2s_base, CER, 1);
 }
@@ -172,24 +200,14 @@ static void i2s_start(struct dw_i2s_dev *dev,
 static void i2s_stop(struct dw_i2s_dev *dev,
                struct snd_pcm_substream *substream)
 {
-       u32 i = 0, irq;
 
        i2s_clear_irqs(dev, substream->stream);
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
                i2s_write_reg(dev->i2s_base, ITER, 0);
-
-               for (i = 0; i < 4; i++) {
-                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
-                       i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
-               }
-       } else {
+       else
                i2s_write_reg(dev->i2s_base, IRER, 0);
 
-               for (i = 0; i < 4; i++) {
-                       irq = i2s_read_reg(dev->i2s_base, IMR(i));
-                       i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
-               }
-       }
+       i2s_disable_irqs(dev, substream->stream, 8);
 
        if (!dev->active) {
                i2s_write_reg(dev->i2s_base, CER, 0);
@@ -223,7 +241,7 @@ static int dw_i2s_startup(struct snd_pcm_substream *substream,
 
 static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
 {
-       u32 ch_reg, irq;
+       u32 ch_reg;
        struct i2s_clk_config_data *config = &dev->config;
 
 
@@ -235,16 +253,12 @@ static void dw_i2s_config(struct dw_i2s_dev *dev, int stream)
                                      dev->xfer_resolution);
                        i2s_write_reg(dev->i2s_base, TFCR(ch_reg),
                                      dev->fifo_th - 1);
-                       irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
-                       i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
                        i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
                } else {
                        i2s_write_reg(dev->i2s_base, RCR(ch_reg),
                                      dev->xfer_resolution);
                        i2s_write_reg(dev->i2s_base, RFCR(ch_reg),
                                      dev->fifo_th - 1);
-                       irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
-                       i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
                        i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
                }