summaryrefslogtreecommitdiff
path: root/sound/soc
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2019-06-26 10:58:56 +0900
committerMark Brown <broonie@kernel.org>2019-06-26 12:28:14 +0100
commitdfea7b2c5c7eaf657086bb95d61814d7e04d1409 (patch)
treebb094a8015153460db80348db3a8f4093b4a4501 /sound/soc
parent472e5df0137e10fbaed0eef38c9bdf99e088ff13 (diff)
ASoC: rsnd: ssiu: tidyup SSI_MODE1/2 settings
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> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/sh/rcar/ssiu.c92
1 files changed, 44 insertions, 48 deletions
diff --git a/sound/soc/sh/rcar/ssiu.c b/sound/soc/sh/rcar/ssiu.c
index 2347f3404c06..f35d88211887 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;
}