Lines Matching refs:ssi
97 int (*transfer)(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm);
165 static inline bool rz_ssi_stream_is_play(struct rz_ssi_priv *ssi, in rz_ssi_stream_is_play() argument
172 rz_ssi_stream_get(struct rz_ssi_priv *ssi, struct snd_pcm_substream *substream) in rz_ssi_stream_get() argument
174 struct rz_ssi_stream *stream = &ssi->playback; in rz_ssi_stream_get()
177 stream = &ssi->capture; in rz_ssi_stream_get()
182 static inline bool rz_ssi_is_dma_enabled(struct rz_ssi_priv *ssi) in rz_ssi_is_dma_enabled() argument
184 return (ssi->playback.dma_ch && (ssi->dma_rt || ssi->capture.dma_ch)); in rz_ssi_is_dma_enabled()
190 struct rz_ssi_priv *ssi = strm->priv; in rz_ssi_set_substream() local
193 spin_lock_irqsave(&ssi->lock, flags); in rz_ssi_set_substream()
195 spin_unlock_irqrestore(&ssi->lock, flags); in rz_ssi_set_substream()
198 static bool rz_ssi_stream_is_valid(struct rz_ssi_priv *ssi, in rz_ssi_stream_is_valid() argument
204 spin_lock_irqsave(&ssi->lock, flags); in rz_ssi_stream_is_valid()
206 spin_unlock_irqrestore(&ssi->lock, flags); in rz_ssi_stream_is_valid()
230 static void rz_ssi_stream_quit(struct rz_ssi_priv *ssi, in rz_ssi_stream_quit() argument
244 static int rz_ssi_clk_setup(struct rz_ssi_priv *ssi, unsigned int rate, in rz_ssi_clk_setup() argument
257 rz_ssi_reg_writel(ssi, SSIFCR, 0); in rz_ssi_clk_setup()
260 rz_ssi_reg_writel(ssi, SSIOFR, SSIOFR_LRCONT); in rz_ssi_clk_setup()
261 if (ssi->audio_clk_1 && ssi->audio_clk_2) { in rz_ssi_clk_setup()
262 if (ssi->audio_clk_1 % bclk_rate) in rz_ssi_clk_setup()
263 ssi->audio_mck = ssi->audio_clk_2; in rz_ssi_clk_setup()
265 ssi->audio_mck = ssi->audio_clk_1; in rz_ssi_clk_setup()
270 if (ssi->audio_mck == ssi->audio_clk_1) in rz_ssi_clk_setup()
272 if (ssi->bckp_rise) in rz_ssi_clk_setup()
274 if (ssi->lrckp_fsync_fall) in rz_ssi_clk_setup()
279 div = ssi->audio_mck / bclk_rate; in rz_ssi_clk_setup()
289 dev_err(ssi->dev, "Rate not divisible by audio clock source\n"); in rz_ssi_clk_setup()
299 rz_ssi_reg_writel(ssi, SSICR, ssicr); in rz_ssi_clk_setup()
300 rz_ssi_reg_writel(ssi, SSIFCR, in rz_ssi_clk_setup()
306 static int rz_ssi_start(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) in rz_ssi_start() argument
308 bool is_play = rz_ssi_stream_is_play(ssi, strm->substream); in rz_ssi_start()
311 ssicr = rz_ssi_reg_readl(ssi, SSICR); in rz_ssi_start()
312 ssifcr = rz_ssi_reg_readl(ssi, SSIFCR) & ~0xF; in rz_ssi_start()
315 if (rz_ssi_is_dma_enabled(ssi)) in rz_ssi_start()
316 rz_ssi_reg_writel(ssi, SSISCR, 0); in rz_ssi_start()
318 rz_ssi_reg_writel(ssi, SSISCR, in rz_ssi_start()
331 rz_ssi_reg_writel(ssi, SSICR, ssicr); in rz_ssi_start()
332 rz_ssi_reg_writel(ssi, SSIFCR, ssifcr); in rz_ssi_start()
335 rz_ssi_reg_mask_setl(ssi, SSISR, in rz_ssi_start()
341 rz_ssi_reg_writel(ssi, SSICR, ssicr); in rz_ssi_start()
346 static int rz_ssi_stop(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) in rz_ssi_stop() argument
353 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TEN | SSICR_REN, 0); in rz_ssi_stop()
356 if (rz_ssi_is_dma_enabled(ssi)) in rz_ssi_stop()
360 rz_ssi_reg_mask_setl(ssi, SSICR, SSICR_TUIEN | SSICR_TOIEN | in rz_ssi_stop()
362 rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_TIE | SSIFCR_RIE, 0); in rz_ssi_stop()
365 rz_ssi_reg_mask_setl(ssi, SSISR, in rz_ssi_stop()
372 if (rz_ssi_reg_readl(ssi, SSISR) & SSISR_IIRQ) in rz_ssi_stop()
378 dev_info(ssi->dev, "timeout waiting for SSI idle\n"); in rz_ssi_stop()
381 rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, in rz_ssi_stop()
411 static int rz_ssi_pio_recv(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) in rz_ssi_pio_recv() argument
421 if (!rz_ssi_stream_is_valid(ssi, strm)) in rz_ssi_pio_recv()
434 fifo_samples = (rz_ssi_reg_readl(ssi, SSIFSR) >> in rz_ssi_pio_recv()
455 *buf++ = (u16)(rz_ssi_reg_readl(ssi, SSIFRDR) >> 16); in rz_ssi_pio_recv()
457 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0); in rz_ssi_pio_recv()
464 static int rz_ssi_pio_send(struct rz_ssi_priv *ssi, struct rz_ssi_stream *strm) in rz_ssi_pio_send() argument
475 if (!rz_ssi_stream_is_valid(ssi, strm)) in rz_ssi_pio_send()
485 ssifsr = rz_ssi_reg_readl(ssi, SSIFSR); in rz_ssi_pio_send()
505 rz_ssi_reg_writel(ssi, SSIFTDR, ((u32)(*buf++) << 16)); in rz_ssi_pio_send()
507 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_TDE, 0); in rz_ssi_pio_send()
516 struct rz_ssi_priv *ssi = data; in rz_ssi_interrupt() local
517 u32 ssisr = rz_ssi_reg_readl(ssi, SSISR); in rz_ssi_interrupt()
519 if (ssi->playback.substream) in rz_ssi_interrupt()
520 strm = &ssi->playback; in rz_ssi_interrupt()
521 else if (ssi->capture.substream) in rz_ssi_interrupt()
522 strm = &ssi->capture; in rz_ssi_interrupt()
526 if (irq == ssi->irq_int) { /* error or idle */ in rz_ssi_interrupt()
540 rz_ssi_stop(ssi, strm); in rz_ssi_interrupt()
543 rz_ssi_reg_mask_setl(ssi, SSISR, SSISR_TOIRQ | in rz_ssi_interrupt()
548 strm->transfer(ssi, strm); in rz_ssi_interrupt()
551 rz_ssi_start(ssi, strm); in rz_ssi_interrupt()
559 if (irq == ssi->irq_tx) in rz_ssi_interrupt()
560 strm->transfer(ssi, &ssi->playback); in rz_ssi_interrupt()
563 if (irq == ssi->irq_rx) { in rz_ssi_interrupt()
564 strm->transfer(ssi, &ssi->capture); in rz_ssi_interrupt()
565 rz_ssi_reg_mask_setl(ssi, SSIFSR, SSIFSR_RDF, 0); in rz_ssi_interrupt()
571 static int rz_ssi_dma_slave_config(struct rz_ssi_priv *ssi, in rz_ssi_dma_slave_config() argument
579 cfg.dst_addr = ssi->phys + SSIFTDR; in rz_ssi_dma_slave_config()
580 cfg.src_addr = ssi->phys + SSIFRDR; in rz_ssi_dma_slave_config()
587 static int rz_ssi_dma_transfer(struct rz_ssi_priv *ssi, in rz_ssi_dma_transfer() argument
597 if (!rz_ssi_stream_is_valid(ssi, strm)) in rz_ssi_dma_transfer()
609 dir = rz_ssi_stream_is_play(ssi, substream) ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; in rz_ssi_dma_transfer()
622 dev_err(ssi->dev, "dmaengine_prep_slave_single() fail\n"); in rz_ssi_dma_transfer()
630 dev_err(ssi->dev, "dmaengine_submit() fail\n"); in rz_ssi_dma_transfer()
659 static void rz_ssi_release_dma_channels(struct rz_ssi_priv *ssi) in rz_ssi_release_dma_channels() argument
661 if (ssi->playback.dma_ch) { in rz_ssi_release_dma_channels()
662 dma_release_channel(ssi->playback.dma_ch); in rz_ssi_release_dma_channels()
663 ssi->playback.dma_ch = NULL; in rz_ssi_release_dma_channels()
664 if (ssi->dma_rt) in rz_ssi_release_dma_channels()
665 ssi->dma_rt = false; in rz_ssi_release_dma_channels()
668 if (ssi->capture.dma_ch) { in rz_ssi_release_dma_channels()
669 dma_release_channel(ssi->capture.dma_ch); in rz_ssi_release_dma_channels()
670 ssi->capture.dma_ch = NULL; in rz_ssi_release_dma_channels()
674 static int rz_ssi_dma_request(struct rz_ssi_priv *ssi, struct device *dev) in rz_ssi_dma_request() argument
676 ssi->playback.dma_ch = dma_request_chan(dev, "tx"); in rz_ssi_dma_request()
677 if (IS_ERR(ssi->playback.dma_ch)) in rz_ssi_dma_request()
678 ssi->playback.dma_ch = NULL; in rz_ssi_dma_request()
680 ssi->capture.dma_ch = dma_request_chan(dev, "rx"); in rz_ssi_dma_request()
681 if (IS_ERR(ssi->capture.dma_ch)) in rz_ssi_dma_request()
682 ssi->capture.dma_ch = NULL; in rz_ssi_dma_request()
684 if (!ssi->playback.dma_ch && !ssi->capture.dma_ch) { in rz_ssi_dma_request()
685 ssi->playback.dma_ch = dma_request_chan(dev, "rt"); in rz_ssi_dma_request()
686 if (IS_ERR(ssi->playback.dma_ch)) { in rz_ssi_dma_request()
687 ssi->playback.dma_ch = NULL; in rz_ssi_dma_request()
691 ssi->dma_rt = true; in rz_ssi_dma_request()
694 if (!rz_ssi_is_dma_enabled(ssi)) in rz_ssi_dma_request()
697 if (ssi->playback.dma_ch && in rz_ssi_dma_request()
698 (rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch, true) < 0)) in rz_ssi_dma_request()
701 if (ssi->capture.dma_ch && in rz_ssi_dma_request()
702 (rz_ssi_dma_slave_config(ssi, ssi->capture.dma_ch, false) < 0)) in rz_ssi_dma_request()
708 rz_ssi_release_dma_channels(ssi); in rz_ssi_dma_request()
716 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); in rz_ssi_dai_trigger() local
717 struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream); in rz_ssi_dai_trigger()
723 rz_ssi_reg_mask_setl(ssi, SSIFCR, 0, SSIFCR_SSIRST); in rz_ssi_dai_trigger()
724 rz_ssi_reg_mask_setl(ssi, SSIFCR, SSIFCR_SSIRST, 0); in rz_ssi_dai_trigger()
729 if (ssi->dma_rt) { in rz_ssi_dai_trigger()
732 is_playback = rz_ssi_stream_is_play(ssi, substream); in rz_ssi_dai_trigger()
733 ret = rz_ssi_dma_slave_config(ssi, ssi->playback.dma_ch, in rz_ssi_dai_trigger()
737 ssi->playback.transfer = rz_ssi_pio_send; in rz_ssi_dai_trigger()
738 ssi->capture.transfer = rz_ssi_pio_recv; in rz_ssi_dai_trigger()
739 rz_ssi_release_dma_channels(ssi); in rz_ssi_dai_trigger()
744 if (rz_ssi_is_dma_enabled(ssi)) in rz_ssi_dai_trigger()
748 ret = strm->transfer(ssi, strm); in rz_ssi_dai_trigger()
753 ret = rz_ssi_start(ssi, strm); in rz_ssi_dai_trigger()
756 rz_ssi_stop(ssi, strm); in rz_ssi_dai_trigger()
757 rz_ssi_stream_quit(ssi, strm); in rz_ssi_dai_trigger()
767 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); in rz_ssi_dai_set_fmt() local
773 dev_err(ssi->dev, "Codec should be clk and frame consumer\n"); in rz_ssi_dai_set_fmt()
785 ssi->bckp_rise = false; in rz_ssi_dai_set_fmt()
786 ssi->lrckp_fsync_fall = false; in rz_ssi_dai_set_fmt()
789 ssi->bckp_rise = false; in rz_ssi_dai_set_fmt()
790 ssi->lrckp_fsync_fall = true; in rz_ssi_dai_set_fmt()
793 ssi->bckp_rise = true; in rz_ssi_dai_set_fmt()
794 ssi->lrckp_fsync_fall = false; in rz_ssi_dai_set_fmt()
797 ssi->bckp_rise = true; in rz_ssi_dai_set_fmt()
798 ssi->lrckp_fsync_fall = true; in rz_ssi_dai_set_fmt()
809 dev_err(ssi->dev, "Only I2S mode is supported.\n"); in rz_ssi_dai_set_fmt()
820 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); in rz_ssi_dai_hw_params() local
826 dev_err(ssi->dev, "Unsupported sample width: %d\n", in rz_ssi_dai_hw_params()
832 dev_err(ssi->dev, "Number of channels not matched: %d\n", in rz_ssi_dai_hw_params()
837 return rz_ssi_clk_setup(ssi, params_rate(params), in rz_ssi_dai_hw_params()
874 struct rz_ssi_priv *ssi = snd_soc_dai_get_drvdata(dai); in rz_ssi_pcm_pointer() local
875 struct rz_ssi_stream *strm = rz_ssi_stream_get(ssi, substream); in rz_ssi_pcm_pointer()
918 struct rz_ssi_priv *ssi; in rz_ssi_probe() local
923 ssi = devm_kzalloc(&pdev->dev, sizeof(*ssi), GFP_KERNEL); in rz_ssi_probe()
924 if (!ssi) in rz_ssi_probe()
927 ssi->pdev = pdev; in rz_ssi_probe()
928 ssi->dev = &pdev->dev; in rz_ssi_probe()
929 ssi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); in rz_ssi_probe()
930 if (IS_ERR(ssi->base)) in rz_ssi_probe()
931 return PTR_ERR(ssi->base); in rz_ssi_probe()
933 ssi->phys = res->start; in rz_ssi_probe()
934 ssi->clk = devm_clk_get(&pdev->dev, "ssi"); in rz_ssi_probe()
935 if (IS_ERR(ssi->clk)) in rz_ssi_probe()
936 return PTR_ERR(ssi->clk); in rz_ssi_probe()
938 ssi->sfr_clk = devm_clk_get(&pdev->dev, "ssi_sfr"); in rz_ssi_probe()
939 if (IS_ERR(ssi->sfr_clk)) in rz_ssi_probe()
940 return PTR_ERR(ssi->sfr_clk); in rz_ssi_probe()
947 ssi->audio_clk_1 = clk_get_rate(audio_clk); in rz_ssi_probe()
953 ssi->audio_clk_2 = clk_get_rate(audio_clk); in rz_ssi_probe()
954 if (!(ssi->audio_clk_1 || ssi->audio_clk_2)) in rz_ssi_probe()
958 ssi->audio_mck = ssi->audio_clk_1 ? ssi->audio_clk_1 : ssi->audio_clk_2; in rz_ssi_probe()
961 ret = rz_ssi_dma_request(ssi, &pdev->dev); in rz_ssi_probe()
964 ssi->playback.transfer = rz_ssi_pio_send; in rz_ssi_probe()
965 ssi->capture.transfer = rz_ssi_pio_recv; in rz_ssi_probe()
968 ssi->playback.transfer = rz_ssi_dma_transfer; in rz_ssi_probe()
969 ssi->capture.transfer = rz_ssi_dma_transfer; in rz_ssi_probe()
972 ssi->playback.priv = ssi; in rz_ssi_probe()
973 ssi->capture.priv = ssi; in rz_ssi_probe()
975 spin_lock_init(&ssi->lock); in rz_ssi_probe()
976 dev_set_drvdata(&pdev->dev, ssi); in rz_ssi_probe()
979 ssi->irq_int = platform_get_irq_byname(pdev, "int_req"); in rz_ssi_probe()
980 if (ssi->irq_int < 0) { in rz_ssi_probe()
981 rz_ssi_release_dma_channels(ssi); in rz_ssi_probe()
982 return ssi->irq_int; in rz_ssi_probe()
985 ret = devm_request_irq(&pdev->dev, ssi->irq_int, &rz_ssi_interrupt, in rz_ssi_probe()
986 0, dev_name(&pdev->dev), ssi); in rz_ssi_probe()
988 rz_ssi_release_dma_channels(ssi); in rz_ssi_probe()
993 if (!rz_ssi_is_dma_enabled(ssi)) { in rz_ssi_probe()
995 ssi->irq_tx = platform_get_irq_byname(pdev, "dma_tx"); in rz_ssi_probe()
996 if (ssi->irq_tx < 0) in rz_ssi_probe()
997 return ssi->irq_tx; in rz_ssi_probe()
999 ret = devm_request_irq(&pdev->dev, ssi->irq_tx, in rz_ssi_probe()
1001 dev_name(&pdev->dev), ssi); in rz_ssi_probe()
1006 ssi->irq_rx = platform_get_irq_byname(pdev, "dma_rx"); in rz_ssi_probe()
1007 if (ssi->irq_rx < 0) in rz_ssi_probe()
1008 return ssi->irq_rx; in rz_ssi_probe()
1010 ret = devm_request_irq(&pdev->dev, ssi->irq_rx, in rz_ssi_probe()
1012 dev_name(&pdev->dev), ssi); in rz_ssi_probe()
1018 ssi->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); in rz_ssi_probe()
1019 if (IS_ERR(ssi->rstc)) { in rz_ssi_probe()
1020 ret = PTR_ERR(ssi->rstc); in rz_ssi_probe()
1024 reset_control_deassert(ssi->rstc); in rz_ssi_probe()
1043 pm_runtime_put(ssi->dev); in rz_ssi_probe()
1045 pm_runtime_disable(ssi->dev); in rz_ssi_probe()
1046 reset_control_assert(ssi->rstc); in rz_ssi_probe()
1048 rz_ssi_release_dma_channels(ssi); in rz_ssi_probe()
1055 struct rz_ssi_priv *ssi = dev_get_drvdata(&pdev->dev); in rz_ssi_remove() local
1057 rz_ssi_release_dma_channels(ssi); in rz_ssi_remove()
1059 pm_runtime_put(ssi->dev); in rz_ssi_remove()
1060 pm_runtime_disable(ssi->dev); in rz_ssi_remove()
1061 reset_control_assert(ssi->rstc); in rz_ssi_remove()