Lines Matching +full:sun6i +full:- +full:a31 +full:- +full:dma
1 // SPDX-License-Identifier: GPL-2.0-or-later
169 * struct sun4i_spdif_quirks - Differences between SoC variants.
171 * @reg_dac_txdata: TX FIFO offset for DMA config.
196 const struct sun4i_spdif_quirks *quirks = host->quirks;
199 regmap_write(host->regmap, SUN4I_SPDIF_CTL, SUN4I_SPDIF_CTL_RESET);
202 regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL,
203 quirks->val_fctl_ftx, quirks->val_fctl_ftx);
206 regmap_update_bits(host->regmap, SUN4I_SPDIF_FCTL,
210 regmap_write(host->regmap, SUN4I_SPDIF_TXCNT, 0);
216 if (substream->runtime->channels == 1)
217 regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
222 regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
226 regmap_update_bits(host->regmap, SUN4I_SPDIF_INT,
230 regmap_update_bits(host->regmap, SUN4I_SPDIF_CTL,
238 regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
242 regmap_update_bits(host->regmap, SUN4I_SPDIF_INT,
246 regmap_update_bits(host->regmap, SUN4I_SPDIF_CTL,
256 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
257 return -EINVAL;
275 struct platform_device *pdev = host->pdev;
287 return -EINVAL;
290 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
294 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
304 return -EINVAL;
322 return -EINVAL;
324 mclk *= host->quirks->mclk_multiplier;
326 ret = clk_set_rate(host->spdif_clk, mclk);
328 dev_err(&pdev->dev,
354 return -EINVAL;
356 mclk_div *= host->quirks->mclk_multiplier;
362 reg_val |= SUN4I_SPDIF_TXCFG_TXRATIO(mclk_div - 1);
363 regmap_write(host->regmap, SUN4I_SPDIF_TXCFG, reg_val);
374 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
375 return -EINVAL;
391 ret = -EINVAL;
400 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
401 uinfo->count = 1;
409 u8 *status = ucontrol->value.iec958.status;
426 u8 *status = ucontrol->value.iec958.status;
430 spin_lock_irqsave(&host->lock, flags);
432 regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA0, ®);
439 regmap_read(host->regmap, SUN4I_SPDIF_TXCHSTA1, ®);
444 spin_unlock_irqrestore(&host->lock, flags);
454 u8 *status = ucontrol->value.iec958.status;
459 spin_lock_irqsave(&host->lock, flags);
466 regmap_update_bits_check(host->regmap, SUN4I_SPDIF_TXCHSTA0,
472 regmap_update_bits_check(host->regmap, SUN4I_SPDIF_TXCHSTA1,
479 regmap_update_bits(host->regmap, SUN4I_SPDIF_TXCFG,
483 spin_unlock_irqrestore(&host->lock, flags);
509 snd_soc_dai_init_dma_data(dai, &host->dma_params_tx, NULL);
577 .compatible = "allwinner,sun4i-a10-spdif",
581 .compatible = "allwinner,sun6i-a31-spdif",
585 .compatible = "allwinner,sun8i-h3-spdif",
589 .compatible = "allwinner,sun50i-h6-spdif",
593 .compatible = "allwinner,sun50i-h616-spdif",
602 .name = "sun4i-spdif",
610 clk_disable_unprepare(host->spdif_clk);
611 clk_disable_unprepare(host->apb_clk);
621 ret = clk_prepare_enable(host->spdif_clk);
624 ret = clk_prepare_enable(host->apb_clk);
626 clk_disable_unprepare(host->spdif_clk);
639 dev_dbg(&pdev->dev, "Entered %s\n", __func__);
641 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
643 return -ENOMEM;
645 host->pdev = pdev;
646 spin_lock_init(&host->lock);
649 memcpy(&host->cpu_dai_drv, &sun4i_spdif_dai, sizeof(sun4i_spdif_dai));
650 host->cpu_dai_drv.name = dev_name(&pdev->dev);
657 quirks = of_device_get_match_data(&pdev->dev);
659 dev_err(&pdev->dev, "Failed to determine the quirks to use\n");
660 return -ENODEV;
662 host->quirks = quirks;
664 host->regmap = devm_regmap_init_mmio(&pdev->dev, base,
668 host->apb_clk = devm_clk_get(&pdev->dev, "apb");
669 if (IS_ERR(host->apb_clk)) {
670 dev_err(&pdev->dev, "failed to get a apb clock.\n");
671 return PTR_ERR(host->apb_clk);
674 host->spdif_clk = devm_clk_get(&pdev->dev, "spdif");
675 if (IS_ERR(host->spdif_clk)) {
676 dev_err(&pdev->dev, "failed to get a spdif clock.\n");
677 return PTR_ERR(host->spdif_clk);
680 host->dma_params_tx.addr = res->start + quirks->reg_dac_txdata;
681 host->dma_params_tx.maxburst = 8;
682 host->dma_params_tx.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
686 if (quirks->has_reset) {
687 host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
689 if (PTR_ERR(host->rst) == -EPROBE_DEFER) {
690 ret = -EPROBE_DEFER;
691 dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
694 if (!IS_ERR(host->rst))
695 reset_control_deassert(host->rst);
698 ret = devm_snd_soc_register_component(&pdev->dev,
703 pm_runtime_enable(&pdev->dev);
704 if (!pm_runtime_enabled(&pdev->dev)) {
705 ret = sun4i_spdif_runtime_resume(&pdev->dev);
710 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
715 if (!pm_runtime_status_suspended(&pdev->dev))
716 sun4i_spdif_runtime_suspend(&pdev->dev);
718 pm_runtime_disable(&pdev->dev);
724 pm_runtime_disable(&pdev->dev);
725 if (!pm_runtime_status_suspended(&pdev->dev))
726 sun4i_spdif_runtime_suspend(&pdev->dev);
736 .name = "sun4i-spdif",
750 MODULE_ALIAS("platform:sun4i-spdif");