aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2019-06-25 21:58:56 -0400
committerMark Brown <broonie@kernel.org>2019-06-26 07:28:14 -0400
commitdfea7b2c5c7eaf657086bb95d61814d7e04d1409 (patch)
treebb094a8015153460db80348db3a8f4093b4a4501
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>
-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,
60 struct rsnd_priv *priv) 60 struct rsnd_priv *priv)
61{ 61{
62 struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 62 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
63 u32 multi_ssi_slaves = rsnd_ssi_multi_slaves_runtime(io); 63 u32 ssis = rsnd_ssi_multi_slaves_runtime(io);
64 int use_busif = rsnd_ssi_use_busif(io); 64 int use_busif = rsnd_ssi_use_busif(io);
65 int id = rsnd_mod_id(mod); 65 int id = rsnd_mod_id(mod);
66 u32 mask1, val1; 66 int is_clk_master = rsnd_rdai_is_clk_master(rdai);
67 u32 mask2, val2; 67 u32 val1, val2;
68 int i; 68 int i;
69 69
70 /* clear status */ 70 /* clear status */
@@ -89,57 +89,53 @@ static int rsnd_ssiu_init(struct rsnd_mod *mod,
89 rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id); 89 rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
90 90
91 /* 91 /*
92 * SSI_MODE1 92 * SSI_MODE1 / SSI_MODE2
93 *
94 * FIXME
95 * sharing/multi with SSI0 are mainly supported
93 */ 96 */
94 mask1 = (1 << 4) | (1 << 20); /* mask sync bit */ 97 val1 = rsnd_mod_read(mod, SSI_MODE1);
95 mask2 = (1 << 4); /* mask sync bit */ 98 val2 = rsnd_mod_read(mod, SSI_MODE2);
96 val1 = val2 = 0; 99 if (rsnd_ssi_is_pin_sharing(io)) {
97 if (id == 8) {
98 /*
99 * SSI8 pin is sharing with SSI7, nothing to do.
100 */
101 } else if (rsnd_ssi_is_pin_sharing(io)) {
102 int shift = -1;
103
104 switch (id) {
105 case 1:
106 shift = 0;
107 break;
108 case 2:
109 shift = 2;
110 break;
111 case 4:
112 shift = 16;
113 break;
114 default:
115 return -EINVAL;
116 }
117
118 mask1 |= 0x3 << shift;
119 val1 = rsnd_rdai_is_clk_master(rdai) ?
120 0x2 << shift : 0x1 << shift;
121 100
122 } else if (multi_ssi_slaves) { 101 ssis |= (1 << id);
123 102
124 mask2 |= 0x00000007; 103 } else if (ssis) {
125 mask1 |= 0x0000000f; 104 /*
126 105 * Multi SSI
127 switch (multi_ssi_slaves) { 106 *
128 case 0x0206: /* SSI0/1/2/9 */ 107 * set synchronized bit here
129 val2 = (1 << 4) | /* SSI0129 sync */ 108 */
130 (rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1);
131 /* fall through */
132 case 0x0006: /* SSI0/1/2 */
133 val1 = rsnd_rdai_is_clk_master(rdai) ?
134 0xa : 0x5;
135 109
136 if (!val2) /* SSI012 sync */ 110 /* SSI4 is synchronized with SSI3 */
137 val1 |= (1 << 4); 111 if (ssis & (1 << 4))
138 } 112 val1 |= (1 << 20);
113 /* SSI012 are synchronized */
114 if (ssis == 0x0006)
115 val1 |= (1 << 4);
116 /* SSI0129 are synchronized */
117 if (ssis == 0x0206)
118 val2 |= (1 << 4);
139 } 119 }
140 120
141 rsnd_mod_bset(mod, SSI_MODE1, mask1, val1); 121 /* SSI1 is sharing pin with SSI0 */
142 rsnd_mod_bset(mod, SSI_MODE2, mask2, val2); 122 if (ssis & (1 << 1))
123 val1 |= is_clk_master ? 0x2 : 0x1;
124
125 /* SSI2 is sharing pin with SSI0 */
126 if (ssis & (1 << 2))
127 val1 |= is_clk_master ? 0x2 << 2 :
128 0x1 << 2;
129 /* SSI4 is sharing pin with SSI3 */
130 if (ssis & (1 << 4))
131 val1 |= is_clk_master ? 0x2 << 16 :
132 0x1 << 16;
133 /* SSI9 is sharing pin with SSI0 */
134 if (ssis & (1 << 9))
135 val2 |= is_clk_master ? 0x2 : 0x1;
136
137 rsnd_mod_bset(mod, SSI_MODE1, 0x0013001f, val1);
138 rsnd_mod_bset(mod, SSI_MODE2, 0x00000017, val2);
143 139
144 return 0; 140 return 0;
145} 141}