Skip to content

Commit

Permalink
ASoC: dwc: Add helper functions to disable/enable irqs
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jose Abreu authored and Mark Brown committed May 30, 2016
1 parent 1a695a9 commit b1d32fe
Showing 1 changed file with 41 additions and 27 deletions.
68 changes: 41 additions & 27 deletions sound/soc/dwc/designware_i2s.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,51 +145,69 @@ 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);
}

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);
Expand Down Expand Up @@ -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;


Expand All @@ -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);
}

Expand Down

0 comments on commit b1d32fe

Please sign in to comment.