diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-06-07 00:20:47 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-06-07 20:30:38 +0100 |
commit | a97a06c7efc1ee34f500171f1c4e9608295bb79a (patch) | |
tree | 15e994db97d5abb80f8b1dfdef5661c0dc1a3b9a /sound/soc/sh/rcar/ssi.c | |
parent | 9bc3b4ff18d130da09ad608718d4afcda01b3e56 (diff) |
ASoC: rsnd: cleanup pointer related code
Current rsnd driver is sharing pointer related code between
PIO / DMA. But, it is used only PIO mode now, no longer needed.
This patch cleanup these.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sh/rcar/ssi.c')
-rw-r--r-- | sound/soc/sh/rcar/ssi.c | 67 |
1 files changed, 64 insertions, 3 deletions
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 59ca6e3f46bc..f7df3b5e2985 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c @@ -77,6 +77,11 @@ struct rsnd_ssi { int rate; int irq; unsigned int usrcnt; + + int byte_pos; + int period_pos; + int byte_per_period; + int next_period_byte; }; /* flags */ @@ -374,6 +379,59 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod) ssi->cr_mode); /* without EN */ } +static void rsnd_ssi_pointer_init(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + + ssi->byte_pos = 0; + ssi->period_pos = 0; + ssi->byte_per_period = runtime->period_size * + runtime->channels * + samples_to_bytes(runtime, 1); + ssi->next_period_byte = ssi->byte_per_period; +} + +static int rsnd_ssi_pointer_offset(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + int additional) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + int pos = ssi->byte_pos + additional; + + pos %= (runtime->periods * ssi->byte_per_period); + + return pos; +} + +static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod, + struct rsnd_dai_stream *io, + int byte) +{ + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); + + ssi->byte_pos += byte; + + if (ssi->byte_pos >= ssi->next_period_byte) { + struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); + + ssi->period_pos++; + ssi->next_period_byte += ssi->byte_per_period; + + if (ssi->period_pos >= runtime->periods) { + ssi->byte_pos = 0; + ssi->period_pos = 0; + ssi->next_period_byte = ssi->byte_per_period; + } + + return true; + } + + return false; +} + /* * SSI mod common functions */ @@ -387,6 +445,8 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, if (!rsnd_ssi_is_run_mods(mod, io)) return 0; + rsnd_ssi_pointer_init(mod, io); + ssi->usrcnt++; rsnd_mod_power_on(mod); @@ -566,7 +626,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, if (!is_dma && (status & DIRQ)) { struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); u32 *buf = (u32 *)(runtime->dma_area + - rsnd_dai_pointer_offset(io, 0)); + rsnd_ssi_pointer_offset(mod, io, 0)); int shift = 0; switch (runtime->sample_bits) { @@ -585,7 +645,7 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, else *buf = (rsnd_mod_read(mod, SSIRDR) >> shift); - elapsed = rsnd_dai_pointer_update(io, sizeof(*buf)); + elapsed = rsnd_ssi_pointer_update(mod, io, sizeof(*buf)); } /* DMA only */ @@ -696,9 +756,10 @@ static int rsnd_ssi_pointer(struct rsnd_mod *mod, struct rsnd_dai_stream *io, snd_pcm_uframes_t *pointer) { + struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); - *pointer = bytes_to_frames(runtime, io->byte_pos); + *pointer = bytes_to_frames(runtime, ssi->byte_pos); return 0; } |