From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
R-Car Sound can use pin sharing and multi-SSI for SSI0/1/2/3/4/9. Because complex HW settings and spaghetti code, the settings for SSI9 pin sharing with SSI0 doesn't work.
This patch tidyup settings for it.
Reported-by: Hien Dang hien.dang.eb@renesas.com Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com Tested-by: Chaoliang Qin chaoliang.qin.jg@renesas.com --- sound/soc/sh/rcar/ssiu.c | 92 +++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 48 deletions(-)
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c index 2347f34..f35d882 100644 --- a/sound/soc/sh/rcar/ssiu.c +++ b/sound/soc/sh/rcar/ssiu.c @@ -60,11 +60,11 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, struct rsnd_priv *priv) { struct rsnd_dai *rdai = rsnd_io_to_rdai(io); - u32 multi_ssi_slaves = rsnd_ssi_multi_slaves_runtime(io); + u32 ssis = rsnd_ssi_multi_slaves_runtime(io); int use_busif = rsnd_ssi_use_busif(io); int id = rsnd_mod_id(mod); - u32 mask1, val1; - u32 mask2, val2; + int is_clk_master = rsnd_rdai_is_clk_master(rdai); + u32 val1, val2; int i;
/* clear status */ @@ -89,57 +89,53 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod, rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
/* - * SSI_MODE1 + * SSI_MODE1 / SSI_MODE2 + * + * FIXME + * sharing/multi with SSI0 are mainly supported */ - mask1 = (1 << 4) | (1 << 20); /* mask sync bit */ - mask2 = (1 << 4); /* mask sync bit */ - val1 = val2 = 0; - if (id == 8) { - /* - * SSI8 pin is sharing with SSI7, nothing to do. - */ - } else if (rsnd_ssi_is_pin_sharing(io)) { - int shift = -1; - - switch (id) { - case 1: - shift = 0; - break; - case 2: - shift = 2; - break; - case 4: - shift = 16; - break; - default: - return -EINVAL; - } - - mask1 |= 0x3 << shift; - val1 = rsnd_rdai_is_clk_master(rdai) ? - 0x2 << shift : 0x1 << shift; + val1 = rsnd_mod_read(mod, SSI_MODE1); + val2 = rsnd_mod_read(mod, SSI_MODE2); + if (rsnd_ssi_is_pin_sharing(io)) {
- } else if (multi_ssi_slaves) { + ssis |= (1 << id);
- mask2 |= 0x00000007; - mask1 |= 0x0000000f; - - switch (multi_ssi_slaves) { - case 0x0206: /* SSI0/1/2/9 */ - val2 = (1 << 4) | /* SSI0129 sync */ - (rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1); - /* fall through */ - case 0x0006: /* SSI0/1/2 */ - val1 = rsnd_rdai_is_clk_master(rdai) ? - 0xa : 0x5; + } else if (ssis) { + /* + * Multi SSI + * + * set synchronized bit here + */
- if (!val2) /* SSI012 sync */ - val1 |= (1 << 4); - } + /* SSI4 is synchronized with SSI3 */ + if (ssis & (1 << 4)) + val1 |= (1 << 20); + /* SSI012 are synchronized */ + if (ssis == 0x0006) + val1 |= (1 << 4); + /* SSI0129 are synchronized */ + if (ssis == 0x0206) + val2 |= (1 << 4); }
- rsnd_mod_bset(mod, SSI_MODE1, mask1, val1); - rsnd_mod_bset(mod, SSI_MODE2, mask2, val2); + /* SSI1 is sharing pin with SSI0 */ + if (ssis & (1 << 1)) + val1 |= is_clk_master ? 0x2 : 0x1; + + /* SSI2 is sharing pin with SSI0 */ + if (ssis & (1 << 2)) + val1 |= is_clk_master ? 0x2 << 2 : + 0x1 << 2; + /* SSI4 is sharing pin with SSI3 */ + if (ssis & (1 << 4)) + val1 |= is_clk_master ? 0x2 << 16 : + 0x1 << 16; + /* SSI9 is sharing pin with SSI0 */ + if (ssis & (1 << 9)) + val2 |= is_clk_master ? 0x2 : 0x1; + + rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1); + rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2);
return 0; }