1 // SPDX-License-Identifier: GPL-2.0
3 // Renesas R-Car SSIU support
5 // Copyright (c) 2015 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
9 #define SSIU_NAME "ssiu"
13 u32 busif_status[8]; /* for BUSIF0 - BUSIF7 */
20 #define TDM_EXT (1 << 0)
21 #define TDM_SPLIT (1 << 8)
23 #define rsnd_ssiu_nr(priv) ((priv)->ssiu_nr)
24 #define rsnd_mod_to_ssiu(_mod) container_of((_mod), struct rsnd_ssiu, mod)
25 #define for_each_rsnd_ssiu(pos, priv, i) \
27 (i < rsnd_ssiu_nr(priv)) && \
28 ((pos) = ((struct rsnd_ssiu *)(priv)->ssiu + i)); \
45 static const int gen2_id[] = { 0, 4, 8, 12, 13, 14, 15, 16, 17, 18 };
46 static const int gen3_id[] = { 0, 8, 16, 24, 32, 40, 41, 42, 43, 44 };
48 static u32 *rsnd_ssiu_get_status(struct rsnd_mod *mod,
49 struct rsnd_dai_stream *io,
50 enum rsnd_mod_type type)
52 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
53 int busif = rsnd_mod_id_sub(mod);
55 return &ssiu->busif_status[busif];
58 static int rsnd_ssiu_init(struct rsnd_mod *mod,
59 struct rsnd_dai_stream *io,
60 struct rsnd_priv *priv)
62 struct rsnd_dai *rdai = rsnd_io_to_rdai(io);
63 u32 multi_ssi_slaves = rsnd_ssi_multi_slaves_runtime(io);
64 int use_busif = rsnd_ssi_use_busif(io);
65 int id = rsnd_mod_id(mod);
77 for (i = 0; i < 4; i++)
78 rsnd_mod_write(mod, SSI_SYS_STATUS(i * 2), 0xf << (id * 4));
81 for (i = 0; i < 4; i++)
82 rsnd_mod_write(mod, SSI_SYS_STATUS((i * 2) + 1), 0xf << (id * 4));
89 rsnd_mod_bset(mod, SSI_MODE0, (1 << id), !use_busif << id);
94 mask1 = (1 << 4) | (1 << 20); /* mask sync bit */
95 mask2 = (1 << 4); /* mask sync bit */
99 * SSI8 pin is sharing with SSI7, nothing to do.
101 } else if (rsnd_ssi_is_pin_sharing(io)) {
118 mask1 |= 0x3 << shift;
119 val1 = rsnd_rdai_is_clk_master(rdai) ?
120 0x2 << shift : 0x1 << shift;
122 } else if (multi_ssi_slaves) {
127 switch (multi_ssi_slaves) {
128 case 0x0206: /* SSI0/1/2/9 */
129 val2 = (1 << 4) | /* SSI0129 sync */
130 (rsnd_rdai_is_clk_master(rdai) ? 0x2 : 0x1);
132 case 0x0006: /* SSI0/1/2 */
133 val1 = rsnd_rdai_is_clk_master(rdai) ?
136 if (!val2) /* SSI012 sync */
141 rsnd_mod_bset(mod, SSI_MODE1, mask1, val1);
142 rsnd_mod_bset(mod, SSI_MODE2, mask2, val2);
147 static struct rsnd_mod_ops rsnd_ssiu_ops_gen1 = {
149 .init = rsnd_ssiu_init,
150 .get_status = rsnd_ssiu_get_status,
153 static int rsnd_ssiu_init_gen2(struct rsnd_mod *mod,
154 struct rsnd_dai_stream *io,
155 struct rsnd_priv *priv)
157 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
158 u32 has_hdmi0 = rsnd_flags_has(io, RSND_STREAM_HDMI0);
159 u32 has_hdmi1 = rsnd_flags_has(io, RSND_STREAM_HDMI1);
163 ret = rsnd_ssiu_init(mod, io, priv);
170 * TDM Extend/Split Mode
172 * rsnd_ssi_config_init()
174 if (rsnd_runtime_is_tdm(io))
176 else if (rsnd_runtime_is_tdm_split(io))
179 rsnd_mod_write(mod, SSI_MODE, mode);
181 if (rsnd_ssi_use_busif(io)) {
182 int id = rsnd_mod_id(mod);
183 int busif = rsnd_mod_id_sub(mod);
188 * We can't support SSI9-4/5/6/7, because its address is
189 * out of calculation rule
191 if ((id == 9) && (busif >= 4)) {
192 struct device *dev = rsnd_priv_to_dev(priv);
194 dev_err(dev, "This driver doesn't support SSI%d-%d, so far",
198 rsnd_mod_write(mod, SSI_BUSIF_ADINR(busif),
199 rsnd_get_adinr_bit(mod, io) |
200 (rsnd_io_is_play(io) ?
201 rsnd_runtime_channel_after_ctu(io) :
202 rsnd_runtime_channel_original(io)));
203 rsnd_mod_write(mod, SSI_BUSIF_MODE(busif),
204 rsnd_get_busif_shift(io, mod) | 1);
205 rsnd_mod_write(mod, SSI_BUSIF_DALIGN(busif),
206 rsnd_get_dalign(mod, io));
209 if (has_hdmi0 || has_hdmi1) {
210 enum rsnd_mod_type rsnd_ssi_array[] = {
215 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
216 struct rsnd_mod *pos;
220 i = rsnd_mod_id(ssi_mod);
222 /* output all same SSI as default */
229 for_each_rsnd_mod_array(i, pos, io, rsnd_ssi_array) {
230 shift = (i * 4) + 16;
231 val = (val & ~(0xF << shift)) |
232 rsnd_mod_id(pos) << shift;
236 rsnd_mod_write(mod, HDMI0_SEL, val);
238 rsnd_mod_write(mod, HDMI1_SEL, val);
244 static int rsnd_ssiu_start_gen2(struct rsnd_mod *mod,
245 struct rsnd_dai_stream *io,
246 struct rsnd_priv *priv)
248 int busif = rsnd_mod_id_sub(mod);
250 if (!rsnd_ssi_use_busif(io))
253 rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 1 << (busif * 4));
255 if (rsnd_ssi_multi_slaves_runtime(io))
256 rsnd_mod_write(mod, SSI_CONTROL, 0x1);
261 static int rsnd_ssiu_stop_gen2(struct rsnd_mod *mod,
262 struct rsnd_dai_stream *io,
263 struct rsnd_priv *priv)
265 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
266 int busif = rsnd_mod_id_sub(mod);
268 if (!rsnd_ssi_use_busif(io))
271 rsnd_mod_bset(mod, SSI_CTRL, 1 << (busif * 4), 0);
276 if (rsnd_ssi_multi_slaves_runtime(io))
277 rsnd_mod_write(mod, SSI_CONTROL, 0);
282 static int rsnd_ssiu_id(struct rsnd_mod *mod)
284 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
286 /* see rsnd_ssiu_probe() */
290 static int rsnd_ssiu_id_sub(struct rsnd_mod *mod)
292 struct rsnd_ssiu *ssiu = rsnd_mod_to_ssiu(mod);
294 /* see rsnd_ssiu_probe() */
298 static struct dma_chan *rsnd_ssiu_dma_req(struct rsnd_dai_stream *io,
299 struct rsnd_mod *mod)
301 struct rsnd_priv *priv = rsnd_mod_to_priv(mod);
302 int is_play = rsnd_io_is_play(io);
306 * It should use "rcar_sound,ssiu" on DT.
307 * But, we need to keep compatibility for old version.
309 * If it has "rcar_sound.ssiu", it will be used.
310 * If not, "rcar_sound.ssi" will be used.
316 name = is_play ? "rx" : "tx";
318 return rsnd_dma_request_channel(rsnd_ssiu_of_node(priv),
322 static struct rsnd_mod_ops rsnd_ssiu_ops_gen2 = {
324 .dma_req = rsnd_ssiu_dma_req,
325 .init = rsnd_ssiu_init_gen2,
326 .start = rsnd_ssiu_start_gen2,
327 .stop = rsnd_ssiu_stop_gen2,
328 .get_status = rsnd_ssiu_get_status,
331 static struct rsnd_mod *rsnd_ssiu_mod_get(struct rsnd_priv *priv, int id)
333 if (WARN_ON(id < 0 || id >= rsnd_ssiu_nr(priv)))
336 return rsnd_mod_get((struct rsnd_ssiu *)(priv->ssiu) + id);
339 static void rsnd_parse_connect_ssiu_compatible(struct rsnd_priv *priv,
340 struct rsnd_dai_stream *io)
342 struct rsnd_mod *ssi_mod = rsnd_io_to_mod_ssi(io);
343 struct rsnd_mod *mod;
344 struct rsnd_ssiu *ssiu;
351 for_each_rsnd_ssiu(ssiu, priv, i) {
352 mod = rsnd_mod_get(ssiu);
354 if ((rsnd_mod_id(ssi_mod) == rsnd_mod_id(mod)) &&
355 (rsnd_mod_id_sub(mod) == 0)) {
356 rsnd_dai_connect(mod, io, mod->type);
362 void rsnd_parse_connect_ssiu(struct rsnd_dai *rdai,
363 struct device_node *playback,
364 struct device_node *capture)
366 struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai);
367 struct device_node *node = rsnd_ssiu_of_node(priv);
368 struct device_node *np;
369 struct rsnd_mod *mod;
370 struct rsnd_dai_stream *io_p = &rdai->playback;
371 struct rsnd_dai_stream *io_c = &rdai->capture;
374 /* use rcar_sound,ssiu if exist */
377 for_each_child_of_node(node, np) {
378 mod = rsnd_ssiu_mod_get(priv, i);
380 rsnd_dai_connect(mod, io_p, mod->type);
382 rsnd_dai_connect(mod, io_c, mod->type);
389 /* Keep DT compatibility */
390 if (!rsnd_io_to_mod_ssiu(io_p))
391 rsnd_parse_connect_ssiu_compatible(priv, io_p);
392 if (!rsnd_io_to_mod_ssiu(io_c))
393 rsnd_parse_connect_ssiu_compatible(priv, io_c);
396 int rsnd_ssiu_probe(struct rsnd_priv *priv)
398 struct device *dev = rsnd_priv_to_dev(priv);
399 struct device_node *node;
400 struct rsnd_ssiu *ssiu;
401 struct rsnd_mod_ops *ops;
402 const int *list = NULL;
406 * Keep DT compatibility.
407 * if it has "rcar_sound,ssiu", use it.
408 * if not, use "rcar_sound,ssi"
410 * rsnd_ssiu_bufsif_to_id()
412 node = rsnd_ssiu_of_node(priv);
414 nr = of_get_child_count(node);
418 ssiu = devm_kcalloc(dev, nr, sizeof(*ssiu), GFP_KERNEL);
425 if (rsnd_is_gen1(priv))
426 ops = &rsnd_ssiu_ops_gen1;
428 ops = &rsnd_ssiu_ops_gen2;
430 /* Keep compatibility */
433 (ops == &rsnd_ssiu_ops_gen2)) {
434 ops->id = rsnd_ssiu_id;
435 ops->id_sub = rsnd_ssiu_id_sub;
437 if (rsnd_is_gen2(priv)) {
439 nr = ARRAY_SIZE(gen2_id);
440 } else if (rsnd_is_gen3(priv)) {
442 nr = ARRAY_SIZE(gen3_id);
444 dev_err(dev, "unknown SSIU\n");
449 for_each_rsnd_ssiu(ssiu, priv, i) {
456 * rsnd_ssiu_get_id_sub()
458 for (j = 0; j < nr; j++) {
462 ssiu->id_sub = i - list[ssiu->id];
468 ret = rsnd_mod_init(priv, rsnd_mod_get(ssiu),
469 ops, NULL, RSND_MOD_SSIU, i);
477 void rsnd_ssiu_remove(struct rsnd_priv *priv)
479 struct rsnd_ssiu *ssiu;
482 for_each_rsnd_ssiu(ssiu, priv, i) {
483 rsnd_mod_quit(rsnd_mod_get(ssiu));