Lines Matching +full:sama7g5 +full:- +full:spdifrx
1 // SPDX-License-Identifier: GPL-2.0
20 * ---- S/PDIF Receiver Controller Register map ----
44 * ---- Control Register (Write-only) ----
49 * ---- Mode Register (Read/Write) ----
76 (((6 - (width) / 4) << 4) & SPDIFRX_MR_DATAWIDTH_MASK)
94 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
112 * ---- Receiver Status Register (Read/Write) ----
124 * ---- Version Register (Read-only) ----
247 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_channel_status_read()
248 u8 *ch_stat = &ctrl->ch_stat[channel].data[0]; in mchp_spdifrx_channel_status_read()
252 for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat[channel].data) / 4; i++) { in mchp_spdifrx_channel_status_read()
253 regmap_read(dev->regmap, SPDIFRX_CHSR(channel, i), &val); in mchp_spdifrx_channel_status_read()
264 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_channel_user_data_read()
265 u8 *user_data = &ctrl->user_data[channel].data[0]; in mchp_spdifrx_channel_user_data_read()
269 for (i = 0; i < ARRAY_SIZE(ctrl->user_data[channel].data) / 4; i++) { in mchp_spdifrx_channel_user_data_read()
270 regmap_read(dev->regmap, SPDIFRX_CHUD(channel, i), &val); in mchp_spdifrx_channel_user_data_read()
278 /* called from non-atomic context only */
283 spin_lock_irqsave(&dev->blockend_lock, flags); in mchp_spdifrx_isr_blockend_en()
284 dev->blockend_refcount++; in mchp_spdifrx_isr_blockend_en()
286 if (dev->blockend_refcount == 1) in mchp_spdifrx_isr_blockend_en()
287 regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND); in mchp_spdifrx_isr_blockend_en()
288 spin_unlock_irqrestore(&dev->blockend_lock, flags); in mchp_spdifrx_isr_blockend_en()
294 spin_lock(&dev->blockend_lock); in mchp_spdifrx_isr_blockend_dis()
295 dev->blockend_refcount--; in mchp_spdifrx_isr_blockend_dis()
297 if (dev->blockend_refcount == 0) in mchp_spdifrx_isr_blockend_dis()
298 regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); in mchp_spdifrx_isr_blockend_dis()
299 spin_unlock(&dev->blockend_lock); in mchp_spdifrx_isr_blockend_dis()
305 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdif_interrupt()
310 regmap_read(dev->regmap, SPDIFRX_ISR, &sr); in mchp_spdif_interrupt()
311 regmap_read(dev->regmap, SPDIFRX_IMR, &imr); in mchp_spdif_interrupt()
313 dev_dbg(dev->dev, "ISR: %#x, IMR: %#x, pending: %#x\n", sr, imr, in mchp_spdif_interrupt()
321 spin_lock(&ctrl->user_data[ch].lock); in mchp_spdif_interrupt()
323 spin_unlock(&ctrl->user_data[ch].lock); in mchp_spdif_interrupt()
325 complete(&ctrl->user_data[ch].done); in mchp_spdif_interrupt()
334 complete(&ctrl->ch_stat[ch].done); in mchp_spdif_interrupt()
341 dev_warn(dev->dev, "Overrun detected\n"); in mchp_spdif_interrupt()
345 regmap_write(dev->regmap, SPDIFRX_IDR, idr); in mchp_spdif_interrupt()
358 regmap_read(dev->regmap, SPDIFRX_MR, &mr); in mchp_spdifrx_trigger()
369 regmap_write(dev->regmap, SPDIFRX_IER, in mchp_spdifrx_trigger()
380 regmap_write(dev->regmap, SPDIFRX_IDR, in mchp_spdifrx_trigger()
385 return -EINVAL; in mchp_spdifrx_trigger()
388 ret = regmap_write(dev->regmap, SPDIFRX_MR, mr); in mchp_spdifrx_trigger()
390 dev_err(dev->dev, "unable to enable/disable RX: %d\n", ret); in mchp_spdifrx_trigger()
405 dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", in mchp_spdifrx_hw_params()
409 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in mchp_spdifrx_hw_params()
410 dev_err(dev->dev, "Playback is not supported\n"); in mchp_spdifrx_hw_params()
411 return -EINVAL; in mchp_spdifrx_hw_params()
414 regmap_read(dev->regmap, SPDIFRX_MR, &mr); in mchp_spdifrx_hw_params()
417 dev_err(dev->dev, "PCM already running\n"); in mchp_spdifrx_hw_params()
418 return -EBUSY; in mchp_spdifrx_hw_params()
422 dev_err(dev->dev, "unsupported number of channels: %d\n", in mchp_spdifrx_hw_params()
424 return -EINVAL; in mchp_spdifrx_hw_params()
441 dev_err(dev->dev, "unsupported PCM format: %d\n", in mchp_spdifrx_hw_params()
443 return -EINVAL; in mchp_spdifrx_hw_params()
446 if (dev->gclk_enabled) { in mchp_spdifrx_hw_params()
447 clk_disable_unprepare(dev->gclk); in mchp_spdifrx_hw_params()
448 dev->gclk_enabled = 0; in mchp_spdifrx_hw_params()
450 ret = clk_set_min_rate(dev->gclk, params_rate(params) * in mchp_spdifrx_hw_params()
453 dev_err(dev->dev, in mchp_spdifrx_hw_params()
458 ret = clk_prepare_enable(dev->gclk); in mchp_spdifrx_hw_params()
460 dev_err(dev->dev, "unable to enable gclk: %d\n", ret); in mchp_spdifrx_hw_params()
463 dev->gclk_enabled = 1; in mchp_spdifrx_hw_params()
465 dev_dbg(dev->dev, "GCLK range min set to %d\n", in mchp_spdifrx_hw_params()
468 return regmap_write(dev->regmap, SPDIFRX_MR, mr); in mchp_spdifrx_hw_params()
476 if (dev->gclk_enabled) { in mchp_spdifrx_hw_free()
477 clk_disable_unprepare(dev->gclk); in mchp_spdifrx_hw_free()
478 dev->gclk_enabled = 0; in mchp_spdifrx_hw_free()
504 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in mchp_spdifrx_info()
505 uinfo->count = 1; in mchp_spdifrx_info()
514 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_cs_get()
515 struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel]; in mchp_spdifrx_cs_get()
518 regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel)); in mchp_spdifrx_cs_get()
520 ret = wait_for_completion_interruptible_timeout(&ch_stat->done, in mchp_spdifrx_cs_get()
524 dev_dbg(dev->dev, "channel status for channel %d timeout\n", in mchp_spdifrx_cs_get()
528 memcpy(uvalue->value.iec958.status, ch_stat->data, in mchp_spdifrx_cs_get()
529 sizeof(ch_stat->data)); in mchp_spdifrx_cs_get()
555 memset(uvalue->value.iec958.status, 0xff, in mchp_spdifrx_cs_mask()
556 sizeof(uvalue->value.iec958.status)); in mchp_spdifrx_cs_mask()
566 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_subcode_ch_get()
567 struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel]; in mchp_spdifrx_subcode_ch_get()
570 reinit_completion(&user_data->done); in mchp_spdifrx_subcode_ch_get()
572 ret = wait_for_completion_interruptible_timeout(&user_data->done, in mchp_spdifrx_subcode_ch_get()
576 dev_dbg(dev->dev, "user data for channel %d timeout\n", in mchp_spdifrx_subcode_ch_get()
581 spin_lock_irqsave(&user_data->lock, flags); in mchp_spdifrx_subcode_ch_get()
582 memcpy(uvalue->value.iec958.subcode, user_data->data, in mchp_spdifrx_subcode_ch_get()
583 sizeof(user_data->data)); in mchp_spdifrx_subcode_ch_get()
584 spin_unlock_irqrestore(&user_data->lock, flags); in mchp_spdifrx_subcode_ch_get()
610 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in mchp_spdifrx_boolean_info()
611 uinfo->count = 1; in mchp_spdifrx_boolean_info()
612 uinfo->value.integer.min = 0; in mchp_spdifrx_boolean_info()
613 uinfo->value.integer.max = 1; in mchp_spdifrx_boolean_info()
623 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_ulock_get()
625 bool ulock_old = ctrl->ulock; in mchp_spdifrx_ulock_get()
627 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_ulock_get()
628 ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK); in mchp_spdifrx_ulock_get()
629 uvalue->value.integer.value[0] = ctrl->ulock; in mchp_spdifrx_ulock_get()
631 return ulock_old != ctrl->ulock; in mchp_spdifrx_ulock_get()
639 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_badf_get()
641 bool badf_old = ctrl->badf; in mchp_spdifrx_badf_get()
643 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_badf_get()
644 ctrl->badf = !!(val & SPDIFRX_RSR_BADF); in mchp_spdifrx_badf_get()
645 uvalue->value.integer.value[0] = ctrl->badf; in mchp_spdifrx_badf_get()
647 return badf_old != ctrl->badf; in mchp_spdifrx_badf_get()
655 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_signal_get()
657 bool signal_old = ctrl->signal; in mchp_spdifrx_signal_get()
659 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_signal_get()
660 ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL); in mchp_spdifrx_signal_get()
661 uvalue->value.integer.value[0] = ctrl->signal; in mchp_spdifrx_signal_get()
663 return signal_old != ctrl->signal; in mchp_spdifrx_signal_get()
669 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in mchp_spdifrx_rate_info()
670 uinfo->count = 1; in mchp_spdifrx_rate_info()
671 uinfo->value.integer.min = 0; in mchp_spdifrx_rate_info()
672 uinfo->value.integer.max = 192000; in mchp_spdifrx_rate_info()
685 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_rate_get()
689 ucontrol->value.integer.value[0] = 0; in mchp_spdifrx_rate_get()
693 rate = clk_get_rate(dev->gclk); in mchp_spdifrx_rate_get()
695 ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val)); in mchp_spdifrx_rate_get()
785 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_dai_probe()
789 err = clk_prepare_enable(dev->pclk); in mchp_spdifrx_dai_probe()
791 dev_err(dev->dev, in mchp_spdifrx_dai_probe()
796 snd_soc_dai_init_dma_data(dai, NULL, &dev->capture); in mchp_spdifrx_dai_probe()
799 regmap_write(dev->regmap, SPDIFRX_CR, SPDIFRX_CR_SWRST); in mchp_spdifrx_dai_probe()
802 regmap_write(dev->regmap, SPDIFRX_MR, in mchp_spdifrx_dai_probe()
808 dev->blockend_refcount = 0; in mchp_spdifrx_dai_probe()
810 init_completion(&ctrl->ch_stat[ch].done); in mchp_spdifrx_dai_probe()
811 init_completion(&ctrl->user_data[ch].done); in mchp_spdifrx_dai_probe()
812 spin_lock_init(&ctrl->user_data[ch].lock); in mchp_spdifrx_dai_probe()
827 regmap_write(dev->regmap, SPDIFRX_IDR, 0xFF); in mchp_spdifrx_dai_remove()
829 clk_disable_unprepare(dev->pclk); in mchp_spdifrx_dai_remove()
835 .name = "mchp-spdifrx",
849 .name = "mchp-spdifrx",
854 .compatible = "microchip,sama7g5-spdifrx",
871 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in mchp_spdifrx_probe()
873 return -ENOMEM; in mchp_spdifrx_probe()
880 regmap = devm_regmap_init_mmio(&pdev->dev, base, in mchp_spdifrx_probe()
890 err = devm_request_irq(&pdev->dev, irq, mchp_spdif_interrupt, 0, in mchp_spdifrx_probe()
891 dev_name(&pdev->dev), dev); in mchp_spdifrx_probe()
896 dev->pclk = devm_clk_get(&pdev->dev, "pclk"); in mchp_spdifrx_probe()
897 if (IS_ERR(dev->pclk)) { in mchp_spdifrx_probe()
898 err = PTR_ERR(dev->pclk); in mchp_spdifrx_probe()
899 dev_err(&pdev->dev, "failed to get the peripheral clock: %d\n", in mchp_spdifrx_probe()
905 dev->gclk = devm_clk_get(&pdev->dev, "gclk"); in mchp_spdifrx_probe()
906 if (IS_ERR(dev->gclk)) { in mchp_spdifrx_probe()
907 err = PTR_ERR(dev->gclk); in mchp_spdifrx_probe()
908 dev_err(&pdev->dev, in mchp_spdifrx_probe()
912 spin_lock_init(&dev->blockend_lock); in mchp_spdifrx_probe()
914 dev->dev = &pdev->dev; in mchp_spdifrx_probe()
915 dev->regmap = regmap; in mchp_spdifrx_probe()
918 dev->capture.addr = (dma_addr_t)mem->start + SPDIFRX_RHR; in mchp_spdifrx_probe()
919 dev->capture.maxburst = 1; in mchp_spdifrx_probe()
921 err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in mchp_spdifrx_probe()
923 dev_err(&pdev->dev, "failed to register PMC: %d\n", err); in mchp_spdifrx_probe()
927 err = devm_snd_soc_register_component(&pdev->dev, in mchp_spdifrx_probe()
931 dev_err(&pdev->dev, "fail to register dai\n"); in mchp_spdifrx_probe()
936 dev_info(&pdev->dev, "hw version: %#lx\n", vers & SPDIFRX_VERSION_MASK); in mchp_spdifrx_probe()