Lines Matching +full:ssiu +full:- +full:2
1 // SPDX-License-Identifier: GPL-2.0
3 // Renesas R-Car SSIU/SSI support
34 #define CHNL_6 (2 << 22) /* Channels */
39 #define DWL_18 (2 << 19) /* Data Word Length */
49 #define SWL_24 (2 << 16) /* R/W System Word Length */
102 #define RSND_SSI_PROBED (1 << 2)
107 ((pos) = ((struct rsnd_ssi *)(priv)->ssi + i)); \
110 #define rsnd_ssi_get(priv, id) ((struct rsnd_ssi *)(priv->ssi) + id)
111 #define rsnd_ssi_nr(priv) ((priv)->ssi_nr)
234 1, 2, 4, 8, 16, 6, 12, in rsnd_ssi_clk_query()
294 if (ssi->usrcnt > 0) { in rsnd_ssi_master_clk_start()
295 if (ssi->rate != rate) { in rsnd_ssi_master_clk_start()
297 return -EINVAL; in rsnd_ssi_master_clk_start()
300 if (ssi->chan != chan) { in rsnd_ssi_master_clk_start()
302 return -EINVAL; in rsnd_ssi_master_clk_start()
311 return -EIO; in rsnd_ssi_master_clk_start()
328 ssi->cr_clk = FORCE | rsnd_rdai_width_to_swl(rdai) | in rsnd_ssi_master_clk_start()
330 ssi->wsr = CONT; in rsnd_ssi_master_clk_start()
331 ssi->rate = rate; in rsnd_ssi_master_clk_start()
332 ssi->chan = chan; in rsnd_ssi_master_clk_start()
352 if (ssi->usrcnt > 1) in rsnd_ssi_master_clk_stop()
355 ssi->cr_clk = 0; in rsnd_ssi_master_clk_stop()
356 ssi->rate = 0; in rsnd_ssi_master_clk_stop()
357 ssi->chan = 0; in rsnd_ssi_master_clk_stop()
370 u32 cr_own = ssi->cr_own; in rsnd_ssi_config_init()
371 u32 cr_mode = ssi->cr_mode; in rsnd_ssi_config_init()
372 u32 wsr = ssi->wsr; in rsnd_ssi_config_init()
389 if (rdai->bit_clk_inv) in rsnd_ssi_config_init()
391 if (rdai->frm_clk_inv && !is_tdm) in rsnd_ssi_config_init()
393 if (rdai->data_alignment) in rsnd_ssi_config_init()
395 if (rdai->sys_delay) in rsnd_ssi_config_init()
403 wsr = ssi->wsr; in rsnd_ssi_config_init()
420 width = snd_pcm_format_width(runtime->format); in rsnd_ssi_config_init()
423 * The SWL and DWL bits in SSICR should be fixed at 32-bit in rsnd_ssi_config_init()
458 case 2: in rsnd_ssi_config_init()
463 SSI_SYS_INT_ENABLE(i * 2)); in rsnd_ssi_config_init()
466 SSI_SYS_INT_ENABLE(i * 2), in rsnd_ssi_config_init()
474 SSI_SYS_INT_ENABLE((i * 2) + 1)); in rsnd_ssi_config_init()
477 SSI_SYS_INT_ENABLE((i * 2) + 1), in rsnd_ssi_config_init()
486 ssi->cr_own = cr_own; in rsnd_ssi_config_init()
487 ssi->cr_mode = cr_mode; in rsnd_ssi_config_init()
488 ssi->wsr = wsr; in rsnd_ssi_config_init()
495 rsnd_mod_write(mod, SSIWSR, ssi->wsr); in rsnd_ssi_register_setup()
496 rsnd_mod_write(mod, SSICR, ssi->cr_own | in rsnd_ssi_register_setup()
497 ssi->cr_clk | in rsnd_ssi_register_setup()
498 ssi->cr_mode | in rsnd_ssi_register_setup()
499 ssi->cr_en); in rsnd_ssi_register_setup()
519 ssi->usrcnt++; in rsnd_ssi_init()
552 if (!ssi->usrcnt) { in rsnd_ssi_quit()
554 return -EIO; in rsnd_ssi_quit()
561 ssi->usrcnt--; in rsnd_ssi_quit()
563 if (!ssi->usrcnt) { in rsnd_ssi_quit()
564 ssi->cr_own = 0; in rsnd_ssi_quit()
565 ssi->cr_mode = 0; in rsnd_ssi_quit()
566 ssi->wsr = 0; in rsnd_ssi_quit()
574 case 2: in rsnd_ssi_quit()
579 SSI_SYS_INT_ENABLE(i * 2)); in rsnd_ssi_quit()
582 SSI_SYS_INT_ENABLE(i * 2), in rsnd_ssi_quit()
590 SSI_SYS_INT_ENABLE((i * 2) + 1)); in rsnd_ssi_quit()
593 SSI_SYS_INT_ENABLE((i * 2) + 1), in rsnd_ssi_quit()
612 if (fmt_width > rdai->chan_width) { in rsnd_ssi_hw_params()
616 dev_err(dev, "invalid combination of slot-width and format-data-width\n"); in rsnd_ssi_hw_params()
617 return -EINVAL; in rsnd_ssi_hw_params()
633 * EN will be set via SSIU :: SSI_CONTROL in rsnd_ssi_start()
646 ssi->cr_en = EN; in rsnd_ssi_start()
648 rsnd_mod_write(mod, SSICR, ssi->cr_own | in rsnd_ssi_start()
649 ssi->cr_clk | in rsnd_ssi_start()
650 ssi->cr_mode | in rsnd_ssi_start()
651 ssi->cr_en); in rsnd_ssi_start()
669 cr = ssi->cr_own | in rsnd_ssi_stop()
670 ssi->cr_clk; in rsnd_ssi_stop()
678 rsnd_mod_write(mod, SSICR, cr | ssi->cr_en); in rsnd_ssi_stop()
682 /* In multi-SSI mode, stop is performed by setting ssi0129 in in rsnd_ssi_stop()
695 ssi->cr_en = 0; in rsnd_ssi_stop()
728 case 2: in rsnd_ssi_irq()
760 spin_lock(&priv->lock); in __rsnd_ssi_interrupt()
786 case 2: in __rsnd_ssi_interrupt()
791 SSI_SYS_STATUS(i * 2)); in __rsnd_ssi_interrupt()
799 SSI_SYS_STATUS(i * 2), in __rsnd_ssi_interrupt()
808 SSI_SYS_STATUS((i * 2) + 1)); in __rsnd_ssi_interrupt()
816 SSI_SYS_STATUS((i * 2) + 1), in __rsnd_ssi_interrupt()
827 spin_unlock(&priv->lock); in __rsnd_ssi_interrupt()
833 snd_pcm_stop_xrun(io->substream); in __rsnd_ssi_interrupt()
852 * 2nd SSI might doesn't start. see also rsnd_mod_call() in rsnd_ssi_get_status()
860 * 1) start Capture -> SSI0/SSI1 are started. in rsnd_ssi_get_status()
861 * 2) start Playback -> SSI0 doesn't work, because it is already in rsnd_ssi_get_status()
865 * It doesn't need to start in 2nd start in rsnd_ssi_get_status()
867 * IO-0: SRC0 -> CTU1 -+-> MUX -> DVC -> SSIU -> SSI0 in rsnd_ssi_get_status()
869 * IO-1: SRC1 -> CTU2 -+ in rsnd_ssi_get_status()
871 * 1) start IO-0 -> start SSI0 in rsnd_ssi_get_status()
872 * 2) start IO-1 -> SSI0 doesn't need to start, because it is in rsnd_ssi_get_status()
876 return &io->parent_ssi_status; in rsnd_ssi_get_status()
901 case 2: in rsnd_ssi_parent_attach()
937 * SSIP/SSIU/IRQ are not needed on in rsnd_ssi_common_probe()
955 * mod->status. in rsnd_ssi_common_probe()
960 ret = request_irq(ssi->irq, in rsnd_ssi_common_probe()
984 free_irq(ssi->irq, mod); in rsnd_ssi_common_remove()
1000 u32 *buf = (u32 *)(runtime->dma_area + ssi->byte_pos); in rsnd_ssi_pio_interrupt()
1005 if (snd_pcm_format_width(runtime->format) == 24) in rsnd_ssi_pio_interrupt()
1018 byte_pos = ssi->byte_pos + sizeof(*buf); in rsnd_ssi_pio_interrupt()
1020 if (byte_pos >= ssi->next_period_byte) { in rsnd_ssi_pio_interrupt()
1021 int period_pos = byte_pos / ssi->byte_per_period; in rsnd_ssi_pio_interrupt()
1023 if (period_pos >= runtime->periods) { in rsnd_ssi_pio_interrupt()
1028 ssi->next_period_byte = (period_pos + 1) * ssi->byte_per_period; in rsnd_ssi_pio_interrupt()
1033 WRITE_ONCE(ssi->byte_pos, byte_pos); in rsnd_ssi_pio_interrupt()
1046 ssi->byte_pos = 0; in rsnd_ssi_pio_init()
1047 ssi->byte_per_period = runtime->period_size * in rsnd_ssi_pio_init()
1048 runtime->channels * in rsnd_ssi_pio_init()
1050 ssi->next_period_byte = ssi->byte_per_period; in rsnd_ssi_pio_init()
1063 *pointer = bytes_to_frames(runtime, READ_ONCE(ssi->byte_pos)); in rsnd_ssi_pio_pointer()
1090 * SSIP/SSIU/IRQ/DMA are not needed on in rsnd_ssi_dma_probe()
1101 ret = rsnd_dma_attach(io, mod, &io->dma); in rsnd_ssi_dma_probe()
1119 mod->ops = &rsnd_ssi_pio_ops; in rsnd_ssi_fallback()
1134 * It should use "rcar_sound,ssiu" on DT. in rsnd_ssi_dma_req()
1137 * If it has "rcar_sound.ssiu", it will be used. in rsnd_ssi_dma_req()
1171 return mod->ops == &rsnd_ssi_dma_ops; in rsnd_ssi_is_dma_mode()
1190 /* try SSI -> SSIM1 -> SSIM2 -> SSIM3 */ in rsnd_ssi_connect()
1195 rsnd_rdai_channels_set(rdai, (i + 1) * 2); in rsnd_ssi_connect()
1220 rsnd_ssi_connect(mod, &rdai->playback); in rsnd_parse_connect_ssi()
1222 rsnd_ssi_connect(mod, &rdai->capture); in rsnd_parse_connect_ssi()
1258 return -EINVAL; in rsnd_ssi_probe()
1262 ret = -EINVAL; in rsnd_ssi_probe()
1268 ret = -ENOMEM; in rsnd_ssi_probe()
1272 priv->ssi = ssi; in rsnd_ssi_probe()
1273 priv->ssi_nr = nr; in rsnd_ssi_probe()
1292 if (of_get_property(np, "shared-pin", NULL)) in rsnd_ssi_probe()
1295 if (of_get_property(np, "no-busif", NULL)) in rsnd_ssi_probe()
1298 ssi->irq = irq_of_parse_and_map(np, 0); in rsnd_ssi_probe()
1299 if (!ssi->irq) { in rsnd_ssi_probe()
1300 ret = -EINVAL; in rsnd_ssi_probe()
1305 if (of_property_read_bool(np, "pio-transfer")) in rsnd_ssi_probe()