Lines Matching +full:spdif +full:- +full:in
1 // SPDX-License-Identifier: GPL-2.0-only
3 * IMG SPDIF input controller driver
86 /* Write-only registers */
92 struct img_spdif_in *spdif = dev_get_drvdata(dev); in img_spdif_in_runtime_suspend() local
94 clk_disable_unprepare(spdif->clk_sys); in img_spdif_in_runtime_suspend()
101 struct img_spdif_in *spdif = dev_get_drvdata(dev); in img_spdif_in_runtime_resume() local
104 ret = clk_prepare_enable(spdif->clk_sys); in img_spdif_in_runtime_resume()
113 static inline void img_spdif_in_writel(struct img_spdif_in *spdif, in img_spdif_in_writel() argument
116 writel(val, spdif->base + reg); in img_spdif_in_writel()
119 static inline u32 img_spdif_in_readl(struct img_spdif_in *spdif, u32 reg) in img_spdif_in_readl() argument
121 return readl(spdif->base + reg); in img_spdif_in_readl()
124 static inline void img_spdif_in_aclkgen_writel(struct img_spdif_in *spdif, in img_spdif_in_aclkgen_writel() argument
127 img_spdif_in_writel(spdif, spdif->aclkgen_regs[index], in img_spdif_in_aclkgen_writel()
131 static int img_spdif_in_check_max_rate(struct img_spdif_in *spdif, in img_spdif_in_check_max_rate() argument
139 freq_t = clk_get_rate(spdif->clk_sys); in img_spdif_in_check_max_rate()
142 return -EINVAL; in img_spdif_in_check_max_rate()
160 return -EINVAL; in img_spdif_in_do_clkgen_calc()
165 return -EINVAL; in img_spdif_in_do_clkgen_calc()
169 hld = 4096 - (--nom * (ori - 1)); in img_spdif_in_do_clkgen_calc()
178 static int img_spdif_in_do_clkgen_single(struct img_spdif_in *spdif, in img_spdif_in_do_clkgen_single() argument
186 ret = img_spdif_in_check_max_rate(spdif, rate, &clk_rate); in img_spdif_in_do_clkgen_single()
199 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_do_clkgen_single()
201 if (spdif->active) { in img_spdif_in_do_clkgen_single()
202 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_do_clkgen_single()
203 return -EBUSY; in img_spdif_in_do_clkgen_single()
206 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CLKGEN); in img_spdif_in_do_clkgen_single()
208 spdif->single_freq = rate; in img_spdif_in_do_clkgen_single()
210 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_do_clkgen_single()
215 static int img_spdif_in_do_clkgen_multi(struct img_spdif_in *spdif, in img_spdif_in_do_clkgen_multi() argument
227 ret = img_spdif_in_check_max_rate(spdif, max_rate, &clk_rate); in img_spdif_in_do_clkgen_multi()
245 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_do_clkgen_multi()
247 if (spdif->active) { in img_spdif_in_do_clkgen_multi()
248 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_do_clkgen_multi()
249 return -EBUSY; in img_spdif_in_do_clkgen_multi()
252 trk_reg = spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT; in img_spdif_in_do_clkgen_multi()
255 spdif->aclkgen_regs[i] = temp_regs[i] | trk_reg; in img_spdif_in_do_clkgen_multi()
256 img_spdif_in_aclkgen_writel(spdif, i); in img_spdif_in_do_clkgen_multi()
259 spdif->multi_freq = true; in img_spdif_in_do_clkgen_multi()
260 spdif->multi_freqs[0] = multi_freqs[0]; in img_spdif_in_do_clkgen_multi()
261 spdif->multi_freqs[1] = multi_freqs[1]; in img_spdif_in_do_clkgen_multi()
262 spdif->multi_freqs[2] = multi_freqs[2]; in img_spdif_in_do_clkgen_multi()
263 spdif->multi_freqs[3] = multi_freqs[3]; in img_spdif_in_do_clkgen_multi()
265 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_do_clkgen_multi()
273 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in img_spdif_in_iec958_info()
274 uinfo->count = 1; in img_spdif_in_iec958_info()
282 ucontrol->value.iec958.status[0] = 0xff; in img_spdif_in_get_status_mask()
283 ucontrol->value.iec958.status[1] = 0xff; in img_spdif_in_get_status_mask()
284 ucontrol->value.iec958.status[2] = 0xff; in img_spdif_in_get_status_mask()
285 ucontrol->value.iec958.status[3] = 0xff; in img_spdif_in_get_status_mask()
286 ucontrol->value.iec958.status[4] = 0xff; in img_spdif_in_get_status_mask()
295 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_get_status() local
298 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSL); in img_spdif_in_get_status()
299 ucontrol->value.iec958.status[0] = reg & 0xff; in img_spdif_in_get_status()
300 ucontrol->value.iec958.status[1] = (reg >> 8) & 0xff; in img_spdif_in_get_status()
301 ucontrol->value.iec958.status[2] = (reg >> 16) & 0xff; in img_spdif_in_get_status()
302 ucontrol->value.iec958.status[3] = (reg >> 24) & 0xff; in img_spdif_in_get_status()
303 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CSH); in img_spdif_in_get_status()
304 ucontrol->value.iec958.status[4] = (reg & IMG_SPDIF_IN_CSH_MASK) in img_spdif_in_get_status()
313 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in img_spdif_in_info_multi_freq()
314 uinfo->count = IMG_SPDIF_IN_NUM_ACLKGEN; in img_spdif_in_info_multi_freq()
315 uinfo->value.integer.min = 0; in img_spdif_in_info_multi_freq()
316 uinfo->value.integer.max = LONG_MAX; in img_spdif_in_info_multi_freq()
325 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_get_multi_freq() local
328 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_get_multi_freq()
329 if (spdif->multi_freq) { in img_spdif_in_get_multi_freq()
330 ucontrol->value.integer.value[0] = spdif->multi_freqs[0]; in img_spdif_in_get_multi_freq()
331 ucontrol->value.integer.value[1] = spdif->multi_freqs[1]; in img_spdif_in_get_multi_freq()
332 ucontrol->value.integer.value[2] = spdif->multi_freqs[2]; in img_spdif_in_get_multi_freq()
333 ucontrol->value.integer.value[3] = spdif->multi_freqs[3]; in img_spdif_in_get_multi_freq()
335 ucontrol->value.integer.value[0] = 0; in img_spdif_in_get_multi_freq()
336 ucontrol->value.integer.value[1] = 0; in img_spdif_in_get_multi_freq()
337 ucontrol->value.integer.value[2] = 0; in img_spdif_in_get_multi_freq()
338 ucontrol->value.integer.value[3] = 0; in img_spdif_in_get_multi_freq()
340 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_get_multi_freq()
349 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_set_multi_freq() local
354 if ((ucontrol->value.integer.value[0] == 0) && in img_spdif_in_set_multi_freq()
355 (ucontrol->value.integer.value[1] == 0) && in img_spdif_in_set_multi_freq()
356 (ucontrol->value.integer.value[2] == 0) && in img_spdif_in_set_multi_freq()
357 (ucontrol->value.integer.value[3] == 0)) { in img_spdif_in_set_multi_freq()
360 multi_freqs[0] = ucontrol->value.integer.value[0]; in img_spdif_in_set_multi_freq()
361 multi_freqs[1] = ucontrol->value.integer.value[1]; in img_spdif_in_set_multi_freq()
362 multi_freqs[2] = ucontrol->value.integer.value[2]; in img_spdif_in_set_multi_freq()
363 multi_freqs[3] = ucontrol->value.integer.value[3]; in img_spdif_in_set_multi_freq()
368 return img_spdif_in_do_clkgen_multi(spdif, multi_freqs); in img_spdif_in_set_multi_freq()
370 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_set_multi_freq()
372 if (spdif->active) { in img_spdif_in_set_multi_freq()
373 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_multi_freq()
374 return -EBUSY; in img_spdif_in_set_multi_freq()
377 spdif->multi_freq = false; in img_spdif_in_set_multi_freq()
379 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_multi_freq()
387 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in img_spdif_in_info_lock_freq()
388 uinfo->count = 1; in img_spdif_in_info_lock_freq()
389 uinfo->value.integer.min = 0; in img_spdif_in_info_lock_freq()
390 uinfo->value.integer.max = LONG_MAX; in img_spdif_in_info_lock_freq()
399 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_get_lock_freq() local
404 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_get_lock_freq()
406 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_STATUS); in img_spdif_in_get_lock_freq()
408 if (spdif->multi_freq) { in img_spdif_in_get_lock_freq()
410 IMG_SPDIF_IN_STATUS_SAM_SHIFT) - 1; in img_spdif_in_get_lock_freq()
411 uc->value.integer.value[0] = spdif->multi_freqs[i]; in img_spdif_in_get_lock_freq()
413 uc->value.integer.value[0] = spdif->single_freq; in img_spdif_in_get_lock_freq()
416 uc->value.integer.value[0] = 0; in img_spdif_in_get_lock_freq()
419 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_get_lock_freq()
427 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in img_spdif_in_info_trk()
428 uinfo->count = 1; in img_spdif_in_info_trk()
429 uinfo->value.integer.min = 0; in img_spdif_in_info_trk()
430 uinfo->value.integer.max = 255; in img_spdif_in_info_trk()
439 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_get_trk() local
441 ucontrol->value.integer.value[0] = spdif->trk; in img_spdif_in_get_trk()
450 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_set_trk() local
455 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_set_trk()
457 if (spdif->active) { in img_spdif_in_set_trk()
458 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_trk()
459 return -EBUSY; in img_spdif_in_set_trk()
462 spdif->trk = ucontrol->value.integer.value[0]; in img_spdif_in_set_trk()
464 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); in img_spdif_in_set_trk()
466 reg |= spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT; in img_spdif_in_set_trk()
467 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); in img_spdif_in_set_trk()
470 spdif->aclkgen_regs[i] = (spdif->aclkgen_regs[i] & in img_spdif_in_set_trk()
472 (spdif->trk << IMG_SPDIF_IN_ACLKGEN_TRK_SHIFT); in img_spdif_in_set_trk()
474 img_spdif_in_aclkgen_writel(spdif, i); in img_spdif_in_set_trk()
477 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_trk()
485 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in img_spdif_in_info_lock()
486 uinfo->count = 1; in img_spdif_in_info_lock()
487 uinfo->value.integer.min = -128; in img_spdif_in_info_lock()
488 uinfo->value.integer.max = 127; in img_spdif_in_info_lock()
497 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_get_lock_acquire() local
499 ucontrol->value.integer.value[0] = spdif->lock_acquire; in img_spdif_in_get_lock_acquire()
508 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_set_lock_acquire() local
512 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_set_lock_acquire()
514 if (spdif->active) { in img_spdif_in_set_lock_acquire()
515 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_lock_acquire()
516 return -EBUSY; in img_spdif_in_set_lock_acquire()
519 spdif->lock_acquire = ucontrol->value.integer.value[0]; in img_spdif_in_set_lock_acquire()
521 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); in img_spdif_in_set_lock_acquire()
523 reg |= (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) & in img_spdif_in_set_lock_acquire()
525 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); in img_spdif_in_set_lock_acquire()
527 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_lock_acquire()
536 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_get_lock_release() local
538 ucontrol->value.integer.value[0] = spdif->lock_release; in img_spdif_in_get_lock_release()
547 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(cpu_dai); in img_spdif_in_set_lock_release() local
551 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_set_lock_release()
553 if (spdif->active) { in img_spdif_in_set_lock_release()
554 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_lock_release()
555 return -EBUSY; in img_spdif_in_set_lock_release()
558 spdif->lock_release = ucontrol->value.integer.value[0]; in img_spdif_in_set_lock_release()
560 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); in img_spdif_in_set_lock_release()
562 reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) & in img_spdif_in_set_lock_release()
564 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); in img_spdif_in_set_lock_release()
566 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_set_lock_release()
589 .name = "SPDIF In Multi Frequency Acquire",
598 .name = "SPDIF In Lock Frequency",
604 .name = "SPDIF In Lock TRK",
611 .name = "SPDIF In Lock Acquire Threshold",
618 .name = "SPDIF In Lock Release Threshold",
629 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai); in img_spdif_in_trigger() local
633 spin_lock_irqsave(&spdif->lock, flags); in img_spdif_in_trigger()
639 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); in img_spdif_in_trigger()
640 if (spdif->multi_freq) in img_spdif_in_trigger()
645 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); in img_spdif_in_trigger()
646 spdif->active = true; in img_spdif_in_trigger()
651 reg = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); in img_spdif_in_trigger()
653 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); in img_spdif_in_trigger()
654 spdif->active = false; in img_spdif_in_trigger()
657 ret = -EINVAL; in img_spdif_in_trigger()
660 spin_unlock_irqrestore(&spdif->lock, flags); in img_spdif_in_trigger()
668 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai); in img_spdif_in_hw_params() local
677 return -EINVAL; in img_spdif_in_hw_params()
680 return -EINVAL; in img_spdif_in_hw_params()
682 return img_spdif_in_do_clkgen_single(spdif, rate); in img_spdif_in_hw_params()
687 struct img_spdif_in *spdif = snd_soc_dai_get_drvdata(dai); in img_spdif_in_dai_probe() local
689 snd_soc_dai_init_dma_data(dai, NULL, &spdif->dma_data); in img_spdif_in_dai_probe()
714 .name = "img-spdif-in",
720 struct img_spdif_in *spdif; in img_spdif_in_probe() local
726 struct device *dev = &pdev->dev; in img_spdif_in_probe()
728 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL); in img_spdif_in_probe()
729 if (!spdif) in img_spdif_in_probe()
730 return -ENOMEM; in img_spdif_in_probe()
732 platform_set_drvdata(pdev, spdif); in img_spdif_in_probe()
734 spdif->dev = &pdev->dev; in img_spdif_in_probe()
740 spdif->base = base; in img_spdif_in_probe()
742 spdif->clk_sys = devm_clk_get(dev, "sys"); in img_spdif_in_probe()
743 if (IS_ERR(spdif->clk_sys)) in img_spdif_in_probe()
744 return dev_err_probe(dev, PTR_ERR(spdif->clk_sys), in img_spdif_in_probe()
747 pm_runtime_enable(&pdev->dev); in img_spdif_in_probe()
748 if (!pm_runtime_enabled(&pdev->dev)) { in img_spdif_in_probe()
749 ret = img_spdif_in_runtime_resume(&pdev->dev); in img_spdif_in_probe()
753 ret = pm_runtime_resume_and_get(&pdev->dev); in img_spdif_in_probe()
757 rst = devm_reset_control_get_exclusive(&pdev->dev, "rst"); in img_spdif_in_probe()
759 if (PTR_ERR(rst) == -EPROBE_DEFER) { in img_spdif_in_probe()
760 ret = -EPROBE_DEFER; in img_spdif_in_probe()
764 img_spdif_in_writel(spdif, IMG_SPDIF_IN_SOFT_RESET_MASK, in img_spdif_in_probe()
766 img_spdif_in_writel(spdif, 0, IMG_SPDIF_IN_SOFT_RESET); in img_spdif_in_probe()
772 spin_lock_init(&spdif->lock); in img_spdif_in_probe()
774 spdif->dma_data.addr = res->start + IMG_SPDIF_IN_RX_FIFO_OFFSET; in img_spdif_in_probe()
775 spdif->dma_data.addr_width = 4; in img_spdif_in_probe()
776 spdif->dma_data.maxburst = 4; in img_spdif_in_probe()
777 spdif->trk = 0x80; in img_spdif_in_probe()
778 spdif->lock_acquire = 4; in img_spdif_in_probe()
779 spdif->lock_release = -128; in img_spdif_in_probe()
781 reg = (spdif->lock_acquire << IMG_SPDIF_IN_CTL_LOCKHI_SHIFT) & in img_spdif_in_probe()
783 reg |= (spdif->lock_release << IMG_SPDIF_IN_CTL_LOCKLO_SHIFT) & in img_spdif_in_probe()
785 reg |= (spdif->trk << IMG_SPDIF_IN_CTL_TRK_SHIFT) & in img_spdif_in_probe()
787 img_spdif_in_writel(spdif, reg, IMG_SPDIF_IN_CTL); in img_spdif_in_probe()
789 pm_runtime_put(&pdev->dev); in img_spdif_in_probe()
791 ret = devm_snd_soc_register_component(&pdev->dev, in img_spdif_in_probe()
796 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in img_spdif_in_probe()
803 pm_runtime_put(&pdev->dev); in img_spdif_in_probe()
805 if (!pm_runtime_enabled(&pdev->dev)) in img_spdif_in_probe()
806 img_spdif_in_runtime_suspend(&pdev->dev); in img_spdif_in_probe()
808 pm_runtime_disable(&pdev->dev); in img_spdif_in_probe()
815 pm_runtime_disable(&pdev->dev); in img_spdif_in_dev_remove()
816 if (!pm_runtime_status_suspended(&pdev->dev)) in img_spdif_in_dev_remove()
817 img_spdif_in_runtime_suspend(&pdev->dev); in img_spdif_in_dev_remove()
823 struct img_spdif_in *spdif = dev_get_drvdata(dev); in img_spdif_in_suspend() local
832 spdif->suspend_clkgen = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CLKGEN); in img_spdif_in_suspend()
833 spdif->suspend_ctl = img_spdif_in_readl(spdif, IMG_SPDIF_IN_CTL); in img_spdif_in_suspend()
842 struct img_spdif_in *spdif = dev_get_drvdata(dev); in img_spdif_in_resume() local
850 img_spdif_in_aclkgen_writel(spdif, i); in img_spdif_in_resume()
852 img_spdif_in_writel(spdif, spdif->suspend_clkgen, IMG_SPDIF_IN_CLKGEN); in img_spdif_in_resume()
853 img_spdif_in_writel(spdif, spdif->suspend_ctl, IMG_SPDIF_IN_CTL); in img_spdif_in_resume()
863 { .compatible = "img,spdif-in" },
876 .name = "img-spdif-in",
886 MODULE_DESCRIPTION("IMG SPDIF Input driver");