Merge series "ASoC: rsnd: tidyup Renesas sound" from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

Hi Mark

These are tidyup patches for Renesas sound drivers.

Kuninori Morimoto (5):
  ASoC: rsnd: call rsnd_ssi_master_clk_start() from rsnd_ssi_init()
  ASoC: rsnd: check all BUSIF status when error
  ASoC: rsnd: add rsnd_ssi_busif_err_status_clear()
  ASoC: rsnd: add rsnd_ssi_busif_err_irq_enable/disable()
  ASoC: rsnd: add usage for SRC

 sound/soc/sh/rcar/src.c |   9 ++
 sound/soc/sh/rcar/ssi.c | 225 ++++++++++++++++++----------------------
 2 files changed, 110 insertions(+), 124 deletions(-)

--
2.25.1
This commit is contained in:
Mark Brown 2021-04-14 16:29:34 +01:00
commit 8577bf61a6
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
2 changed files with 110 additions and 124 deletions

View File

@ -5,6 +5,15 @@
// Copyright (C) 2013 Renesas Solutions Corp.
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
/*
* You can use Synchronous Sampling Rate Convert (if no DVC)
*
* amixer set "SRC Out Rate" on
* aplay xxx.wav &
* amixer set "SRC Out Rate" 96000 // convert rate to 96000Hz
* amixer set "SRC Out Rate" 22050 // convert rate to 22050Hz
*/
/*
* you can enable below define if you don't need
* SSI interrupt status debug message when debugging

View File

@ -359,6 +359,96 @@ static void rsnd_ssi_master_clk_stop(struct rsnd_mod *mod,
rsnd_adg_ssi_clk_stop(mod);
}
/* enable busif buffer over/under run interrupt. */
#define rsnd_ssi_busif_err_irq_enable(mod) rsnd_ssi_busif_err_irq_ctrl(mod, 1)
#define rsnd_ssi_busif_err_irq_disable(mod) rsnd_ssi_busif_err_irq_ctrl(mod, 0)
static void rsnd_ssi_busif_err_irq_ctrl(struct rsnd_mod *mod, int enable)
{
u32 sys_int_enable = 0;
int id = rsnd_mod_id(mod);
int i;
switch (id) {
case 0:
case 1:
case 2:
case 3:
case 4:
for (i = 0; i < 4; i++) {
sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE(i * 2));
if (enable)
sys_int_enable |= 0xf << (id * 4);
else
sys_int_enable &= ~(0xf << (id * 4));
rsnd_mod_write(mod,
SSI_SYS_INT_ENABLE(i * 2),
sys_int_enable);
}
break;
case 9:
for (i = 0; i < 4; i++) {
sys_int_enable = rsnd_mod_read(mod, SSI_SYS_INT_ENABLE((i * 2) + 1));
if (enable)
sys_int_enable |= 0xf << 4;
else
sys_int_enable &= ~(0xf << 4);
rsnd_mod_write(mod,
SSI_SYS_INT_ENABLE((i * 2) + 1),
sys_int_enable);
}
break;
}
}
static bool rsnd_ssi_busif_err_status_clear(struct rsnd_mod *mod)
{
struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
struct device *dev = rsnd_priv_to_dev(priv);
u32 status;
bool stop = false;
int id = rsnd_mod_id(mod);
int i;
switch (id) {
case 0:
case 1:
case 2:
case 3:
case 4:
for (i = 0; i < 4; i++) {
status = rsnd_mod_read(mod, SSI_SYS_STATUS(i * 2));
status &= 0xf << (id * 4);
if (status) {
rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
rsnd_mod_name(mod), status);
rsnd_mod_write(mod,
SSI_SYS_STATUS(i * 2),
0xf << (id * 4));
stop = true;
}
}
break;
case 9:
for (i = 0; i < 4; i++) {
status = rsnd_mod_read(mod, SSI_SYS_STATUS((i * 2) + 1));
status &= 0xf << 4;
if (status) {
rsnd_dbg_irq_status(dev, "%s err status : 0x%08x\n",
rsnd_mod_name(mod), status);
rsnd_mod_write(mod,
SSI_SYS_STATUS((i * 2) + 1),
0xf << 4);
stop = true;
}
}
break;
}
return stop;
}
static void rsnd_ssi_config_init(struct rsnd_mod *mod,
struct rsnd_dai_stream *io)
{
@ -372,9 +462,6 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
u32 wsr = ssi->wsr;
int width;
int is_tdm, is_tdm_split;
int id = rsnd_mod_id(mod);
int i;
u32 sys_int_enable = 0;
is_tdm = rsnd_runtime_is_tdm(io);
is_tdm_split = rsnd_runtime_is_tdm_split(io);
@ -450,36 +537,8 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod,
}
/* enable busif buffer over/under run interrupt. */
if (is_tdm || is_tdm_split) {
switch (id) {
case 0:
case 1:
case 2:
case 3:
case 4:
for (i = 0; i < 4; i++) {
sys_int_enable = rsnd_mod_read(mod,
SSI_SYS_INT_ENABLE(i * 2));
sys_int_enable |= 0xf << (id * 4);
rsnd_mod_write(mod,
SSI_SYS_INT_ENABLE(i * 2),
sys_int_enable);
}
break;
case 9:
for (i = 0; i < 4; i++) {
sys_int_enable = rsnd_mod_read(mod,
SSI_SYS_INT_ENABLE((i * 2) + 1));
sys_int_enable |= 0xf << 4;
rsnd_mod_write(mod,
SSI_SYS_INT_ENABLE((i * 2) + 1),
sys_int_enable);
}
break;
}
}
if (is_tdm || is_tdm_split)
rsnd_ssi_busif_err_irq_enable(mod);
init_end:
ssi->cr_own = cr_own;
@ -506,10 +565,15 @@ static int rsnd_ssi_init(struct rsnd_mod *mod,
struct rsnd_priv *priv)
{
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
int ret;
if (!rsnd_ssi_is_run_mods(mod, io))
return 0;
ret = rsnd_ssi_master_clk_start(mod, io);
if (ret < 0)
return ret;
ssi->usrcnt++;
rsnd_mod_power_on(mod);
@ -531,8 +595,6 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod);
struct device *dev = rsnd_priv_to_dev(priv);
int is_tdm, is_tdm_split;
int id = rsnd_mod_id(mod);
u32 sys_int_enable = 0;
is_tdm = rsnd_runtime_is_tdm(io);
is_tdm_split = rsnd_runtime_is_tdm_split(io);
@ -558,38 +620,8 @@ static int rsnd_ssi_quit(struct rsnd_mod *mod,
}
/* disable busif buffer over/under run interrupt. */
if (is_tdm || is_tdm_split) {
int i;
switch (id) {
case 0:
case 1:
case 2:
case 3:
case 4:
for (i = 0; i < 4; i++) {
sys_int_enable = rsnd_mod_read(mod,
SSI_SYS_INT_ENABLE(i * 2));
sys_int_enable &= ~(0xf << (id * 4));
rsnd_mod_write(mod,
SSI_SYS_INT_ENABLE(i * 2),
sys_int_enable);
}
break;
case 9:
for (i = 0; i < 4; i++) {
sys_int_enable = rsnd_mod_read(mod,
SSI_SYS_INT_ENABLE((i * 2) + 1));
sys_int_enable &= ~(0xf << 4);
rsnd_mod_write(mod,
SSI_SYS_INT_ENABLE((i * 2) + 1),
sys_int_enable);
}
break;
}
}
if (is_tdm || is_tdm_split)
rsnd_ssi_busif_err_irq_disable(mod);
return 0;
}
@ -743,8 +775,6 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
u32 status;
bool elapsed = false;
bool stop = false;
int id = rsnd_mod_id(mod);
int i;
int is_tdm, is_tdm_split;
is_tdm = rsnd_runtime_is_tdm(io);
@ -770,52 +800,8 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod,
stop = true;
}
status = 0;
if (is_tdm || is_tdm_split) {
switch (id) {
case 0:
case 1:
case 2:
case 3:
case 4:
for (i = 0; i < 4; i++) {
status = rsnd_mod_read(mod,
SSI_SYS_STATUS(i * 2));
status &= 0xf << (id * 4);
if (status) {
rsnd_dbg_irq_status(dev,
"%s err status : 0x%08x\n",
rsnd_mod_name(mod), status);
rsnd_mod_write(mod,
SSI_SYS_STATUS(i * 2),
0xf << (id * 4));
stop = true;
break;
}
}
break;
case 9:
for (i = 0; i < 4; i++) {
status = rsnd_mod_read(mod,
SSI_SYS_STATUS((i * 2) + 1));
status &= 0xf << 4;
if (status) {
rsnd_dbg_irq_status(dev,
"%s err status : 0x%08x\n",
rsnd_mod_name(mod), status);
rsnd_mod_write(mod,
SSI_SYS_STATUS((i * 2) + 1),
0xf << 4);
stop = true;
break;
}
}
break;
}
}
if (is_tdm || is_tdm_split)
stop |= rsnd_ssi_busif_err_status_clear(mod);
rsnd_ssi_status_clear(mod);
rsnd_ssi_interrupt_out:
@ -1060,13 +1046,6 @@ static int rsnd_ssi_pio_pointer(struct rsnd_mod *mod,
return 0;
}
static int rsnd_ssi_prepare(struct rsnd_mod *mod,
struct rsnd_dai_stream *io,
struct rsnd_priv *priv)
{
return rsnd_ssi_master_clk_start(mod, io);
}
static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
.name = SSI_NAME,
.probe = rsnd_ssi_common_probe,
@ -1079,7 +1058,6 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = {
.pointer = rsnd_ssi_pio_pointer,
.pcm_new = rsnd_ssi_pcm_new,
.hw_params = rsnd_ssi_hw_params,
.prepare = rsnd_ssi_prepare,
.get_status = rsnd_ssi_get_status,
};
@ -1166,7 +1144,6 @@ static struct rsnd_mod_ops rsnd_ssi_dma_ops = {
.pcm_new = rsnd_ssi_pcm_new,
.fallback = rsnd_ssi_fallback,
.hw_params = rsnd_ssi_hw_params,
.prepare = rsnd_ssi_prepare,
.get_status = rsnd_ssi_get_status,
};