Lines Matching +full:sama7g5 +full:- +full:spdifrx

1 // SPDX-License-Identifier: GPL-2.0
21 * ---- S/PDIF Receiver Controller Register map ----
45 * ---- Control Register (Write-only) ----
50 * ---- Mode Register (Read/Write) ----
77 (((6 - (width) / 4) << 4) & SPDIFRX_MR_DATAWIDTH_MASK)
95 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
113 * ---- Receiver Status Register (Read/Write) ----
125 * ---- Version Register (Read-only) ----
253 * struct mchp_spdifrx_ch_stat: MCHP SPDIFRX channel status
263 * struct mchp_spdifrx_user_data: MCHP SPDIFRX user data
273 * struct mchp_spdifrx_mixer_control: MCHP SPDIFRX mixer control data structure
289 * struct mchp_spdifrx_dev: MCHP SPDIFRX device data structure
313 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_channel_status_read()
314 u8 *ch_stat = &ctrl->ch_stat[channel].data[0]; in mchp_spdifrx_channel_status_read()
318 for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat[channel].data) / 4; i++) { in mchp_spdifrx_channel_status_read()
319 regmap_read(dev->regmap, SPDIFRX_CHSR(channel, i), &val); in mchp_spdifrx_channel_status_read()
330 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_channel_user_data_read()
331 u8 *user_data = &ctrl->user_data[channel].data[0]; in mchp_spdifrx_channel_user_data_read()
335 for (i = 0; i < ARRAY_SIZE(ctrl->user_data[channel].data) / 4; i++) { in mchp_spdifrx_channel_user_data_read()
336 regmap_read(dev->regmap, SPDIFRX_CHUD(channel, i), &val); in mchp_spdifrx_channel_user_data_read()
347 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdif_interrupt()
352 regmap_read(dev->regmap, SPDIFRX_ISR, &sr); in mchp_spdif_interrupt()
353 regmap_read(dev->regmap, SPDIFRX_IMR, &imr); in mchp_spdif_interrupt()
355 dev_dbg(dev->dev, "ISR: %#x, IMR: %#x, pending: %#x\n", sr, imr, in mchp_spdif_interrupt()
364 complete(&ctrl->user_data[ch].done); in mchp_spdif_interrupt()
366 regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); in mchp_spdif_interrupt()
373 complete(&ctrl->ch_stat[ch].done); in mchp_spdif_interrupt()
374 regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(ch)); in mchp_spdif_interrupt()
380 dev_warn(dev->dev, "Overrun detected\n"); in mchp_spdif_interrupt()
397 mutex_lock(&dev->mlock); in mchp_spdifrx_trigger()
399 regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_OVERRUN); in mchp_spdifrx_trigger()
402 regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, in mchp_spdifrx_trigger()
404 dev->trigger_enabled = true; in mchp_spdifrx_trigger()
405 mutex_unlock(&dev->mlock); in mchp_spdifrx_trigger()
410 mutex_lock(&dev->mlock); in mchp_spdifrx_trigger()
412 regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_OVERRUN); in mchp_spdifrx_trigger()
415 regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, in mchp_spdifrx_trigger()
417 dev->trigger_enabled = false; in mchp_spdifrx_trigger()
418 mutex_unlock(&dev->mlock); in mchp_spdifrx_trigger()
421 ret = -EINVAL; in mchp_spdifrx_trigger()
435 dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", in mchp_spdifrx_hw_params()
439 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in mchp_spdifrx_hw_params()
440 dev_err(dev->dev, "Playback is not supported\n"); in mchp_spdifrx_hw_params()
441 return -EINVAL; in mchp_spdifrx_hw_params()
445 dev_err(dev->dev, "unsupported number of channels: %d\n", in mchp_spdifrx_hw_params()
447 return -EINVAL; in mchp_spdifrx_hw_params()
464 dev_err(dev->dev, "unsupported PCM format: %d\n", in mchp_spdifrx_hw_params()
466 return -EINVAL; in mchp_spdifrx_hw_params()
469 mutex_lock(&dev->mlock); in mchp_spdifrx_hw_params()
470 if (dev->trigger_enabled) { in mchp_spdifrx_hw_params()
471 dev_err(dev->dev, "PCM already running\n"); in mchp_spdifrx_hw_params()
472 ret = -EBUSY; in mchp_spdifrx_hw_params()
477 clk_disable_unprepare(dev->gclk); in mchp_spdifrx_hw_params()
479 ret = clk_set_min_rate(dev->gclk, params_rate(params) * in mchp_spdifrx_hw_params()
482 dev_err(dev->dev, in mchp_spdifrx_hw_params()
486 clk_prepare_enable(dev->gclk); in mchp_spdifrx_hw_params()
489 ret = clk_prepare_enable(dev->gclk); in mchp_spdifrx_hw_params()
491 dev_err(dev->dev, "unable to enable gclk: %d\n", ret); in mchp_spdifrx_hw_params()
495 dev_dbg(dev->dev, "GCLK range min set to %d\n", in mchp_spdifrx_hw_params()
498 ret = regmap_write(dev->regmap, SPDIFRX_MR, mr); in mchp_spdifrx_hw_params()
501 mutex_unlock(&dev->mlock); in mchp_spdifrx_hw_params()
521 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in mchp_spdifrx_info()
522 uinfo->count = 1; in mchp_spdifrx_info()
531 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_cs_get()
532 struct mchp_spdifrx_ch_stat *ch_stat = &ctrl->ch_stat[channel]; in mchp_spdifrx_cs_get()
535 mutex_lock(&dev->mlock); in mchp_spdifrx_cs_get()
537 ret = pm_runtime_resume_and_get(dev->dev); in mchp_spdifrx_cs_get()
544 * timeout check the dev->trigger_enabled. in mchp_spdifrx_cs_get()
547 * - if the receiver is enabled CSC IRQ will update the data in software in mchp_spdifrx_cs_get()
548 * caches (ch_stat->data) in mchp_spdifrx_cs_get()
549 * - otherwise we just update it here the software caches with latest in mchp_spdifrx_cs_get()
555 if (dev->trigger_enabled) { in mchp_spdifrx_cs_get()
556 reinit_completion(&ch_stat->done); in mchp_spdifrx_cs_get()
557 regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_CSC(channel)); in mchp_spdifrx_cs_get()
559 ret = wait_for_completion_interruptible_timeout(&ch_stat->done, in mchp_spdifrx_cs_get()
563 dev_dbg(dev->dev, "channel status for channel %d timeout\n", in mchp_spdifrx_cs_get()
565 regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_CSC(channel)); in mchp_spdifrx_cs_get()
566 ret = ret ? : -ETIMEDOUT; in mchp_spdifrx_cs_get()
576 memcpy(uvalue->value.iec958.status, ch_stat->data, in mchp_spdifrx_cs_get()
577 sizeof(ch_stat->data)); in mchp_spdifrx_cs_get()
580 pm_runtime_put_autosuspend(dev->dev); in mchp_spdifrx_cs_get()
582 mutex_unlock(&dev->mlock); in mchp_spdifrx_cs_get()
607 memset(uvalue->value.iec958.status, 0xff, in mchp_spdifrx_cs_mask()
608 sizeof(uvalue->value.iec958.status)); in mchp_spdifrx_cs_mask()
617 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_subcode_ch_get()
618 struct mchp_spdifrx_user_data *user_data = &ctrl->user_data[channel]; in mchp_spdifrx_subcode_ch_get()
621 mutex_lock(&dev->mlock); in mchp_spdifrx_subcode_ch_get()
623 ret = pm_runtime_resume_and_get(dev->dev); in mchp_spdifrx_subcode_ch_get()
630 * check here the dev->trigger_enabled flag. in mchp_spdifrx_subcode_ch_get()
633 * - if the receiver is enabled we need to wait for blockend IRQ to read in mchp_spdifrx_subcode_ch_get()
635 * - otherwise reading the SPDIFRX_CHUD() registers is enough. in mchp_spdifrx_subcode_ch_get()
638 if (dev->trigger_enabled) { in mchp_spdifrx_subcode_ch_get()
639 reinit_completion(&user_data->done); in mchp_spdifrx_subcode_ch_get()
640 regmap_write(dev->regmap, SPDIFRX_IER, SPDIFRX_IR_BLOCKEND); in mchp_spdifrx_subcode_ch_get()
641 ret = wait_for_completion_interruptible_timeout(&user_data->done, in mchp_spdifrx_subcode_ch_get()
645 dev_dbg(dev->dev, "user data for channel %d timeout\n", in mchp_spdifrx_subcode_ch_get()
647 regmap_write(dev->regmap, SPDIFRX_IDR, SPDIFRX_IR_BLOCKEND); in mchp_spdifrx_subcode_ch_get()
648 ret = ret ? : -ETIMEDOUT; in mchp_spdifrx_subcode_ch_get()
658 memcpy(uvalue->value.iec958.subcode, user_data->data, in mchp_spdifrx_subcode_ch_get()
659 sizeof(user_data->data)); in mchp_spdifrx_subcode_ch_get()
662 pm_runtime_put_autosuspend(dev->dev); in mchp_spdifrx_subcode_ch_get()
664 mutex_unlock(&dev->mlock); in mchp_spdifrx_subcode_ch_get()
689 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; in mchp_spdifrx_boolean_info()
690 uinfo->count = 1; in mchp_spdifrx_boolean_info()
691 uinfo->value.integer.min = 0; in mchp_spdifrx_boolean_info()
692 uinfo->value.integer.max = 1; in mchp_spdifrx_boolean_info()
702 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_ulock_get()
705 bool ulock_old = ctrl->ulock; in mchp_spdifrx_ulock_get()
707 mutex_lock(&dev->mlock); in mchp_spdifrx_ulock_get()
709 ret = pm_runtime_resume_and_get(dev->dev); in mchp_spdifrx_ulock_get()
716 * dev->trigger_enabled here to return a real status. in mchp_spdifrx_ulock_get()
718 if (dev->trigger_enabled) { in mchp_spdifrx_ulock_get()
719 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_ulock_get()
720 ctrl->ulock = !(val & SPDIFRX_RSR_ULOCK); in mchp_spdifrx_ulock_get()
722 ctrl->ulock = 0; in mchp_spdifrx_ulock_get()
725 uvalue->value.integer.value[0] = ctrl->ulock; in mchp_spdifrx_ulock_get()
727 pm_runtime_put_autosuspend(dev->dev); in mchp_spdifrx_ulock_get()
729 mutex_unlock(&dev->mlock); in mchp_spdifrx_ulock_get()
731 return ulock_old != ctrl->ulock; in mchp_spdifrx_ulock_get()
739 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_badf_get()
742 bool badf_old = ctrl->badf; in mchp_spdifrx_badf_get()
744 mutex_lock(&dev->mlock); in mchp_spdifrx_badf_get()
746 ret = pm_runtime_resume_and_get(dev->dev); in mchp_spdifrx_badf_get()
753 * dev->trigger_enabled here to return a real status. in mchp_spdifrx_badf_get()
755 if (dev->trigger_enabled) { in mchp_spdifrx_badf_get()
756 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_badf_get()
757 ctrl->badf = !!(val & SPDIFRX_RSR_BADF); in mchp_spdifrx_badf_get()
759 ctrl->badf = 0; in mchp_spdifrx_badf_get()
762 pm_runtime_put_autosuspend(dev->dev); in mchp_spdifrx_badf_get()
764 mutex_unlock(&dev->mlock); in mchp_spdifrx_badf_get()
766 uvalue->value.integer.value[0] = ctrl->badf; in mchp_spdifrx_badf_get()
768 return badf_old != ctrl->badf; in mchp_spdifrx_badf_get()
776 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_signal_get()
779 bool signal_old = ctrl->signal; in mchp_spdifrx_signal_get()
781 mutex_lock(&dev->mlock); in mchp_spdifrx_signal_get()
783 ret = pm_runtime_resume_and_get(dev->dev); in mchp_spdifrx_signal_get()
792 if (!dev->trigger_enabled) { in mchp_spdifrx_signal_get()
793 regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, in mchp_spdifrx_signal_get()
797 while (--loops) { in mchp_spdifrx_signal_get()
798 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_signal_get()
804 regmap_update_bits(dev->regmap, SPDIFRX_MR, SPDIFRX_MR_RXEN_MASK, in mchp_spdifrx_signal_get()
807 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_signal_get()
810 pm_runtime_put_autosuspend(dev->dev); in mchp_spdifrx_signal_get()
813 mutex_unlock(&dev->mlock); in mchp_spdifrx_signal_get()
816 ctrl->signal = !(val & SPDIFRX_RSR_NOSIGNAL); in mchp_spdifrx_signal_get()
818 ctrl->signal = 0; in mchp_spdifrx_signal_get()
819 uvalue->value.integer.value[0] = ctrl->signal; in mchp_spdifrx_signal_get()
821 return signal_old != ctrl->signal; in mchp_spdifrx_signal_get()
827 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; in mchp_spdifrx_rate_info()
828 uinfo->count = 1; in mchp_spdifrx_rate_info()
829 uinfo->value.integer.min = 0; in mchp_spdifrx_rate_info()
830 uinfo->value.integer.max = 192000; in mchp_spdifrx_rate_info()
844 mutex_lock(&dev->mlock); in mchp_spdifrx_rate_get()
846 ret = pm_runtime_resume_and_get(dev->dev); in mchp_spdifrx_rate_get()
853 * dev->trigger_enabled here to return a real status. in mchp_spdifrx_rate_get()
855 if (dev->trigger_enabled) { in mchp_spdifrx_rate_get()
856 regmap_read(dev->regmap, SPDIFRX_RSR, &val); in mchp_spdifrx_rate_get()
859 ucontrol->value.integer.value[0] = 0; in mchp_spdifrx_rate_get()
864 ucontrol->value.integer.value[0] = 0; in mchp_spdifrx_rate_get()
868 rate = clk_get_rate(dev->gclk); in mchp_spdifrx_rate_get()
870 ucontrol->value.integer.value[0] = rate / (32 * SPDIFRX_RSR_IFS(val)); in mchp_spdifrx_rate_get()
873 pm_runtime_put_autosuspend(dev->dev); in mchp_spdifrx_rate_get()
875 mutex_unlock(&dev->mlock); in mchp_spdifrx_rate_get()
964 struct mchp_spdifrx_mixer_control *ctrl = &dev->control; in mchp_spdifrx_dai_probe()
967 snd_soc_dai_init_dma_data(dai, NULL, &dev->capture); in mchp_spdifrx_dai_probe()
970 regmap_write(dev->regmap, SPDIFRX_CR, SPDIFRX_CR_SWRST); in mchp_spdifrx_dai_probe()
973 regmap_write(dev->regmap, SPDIFRX_MR, in mchp_spdifrx_dai_probe()
980 init_completion(&ctrl->ch_stat[ch].done); in mchp_spdifrx_dai_probe()
981 init_completion(&ctrl->user_data[ch].done); in mchp_spdifrx_dai_probe()
996 regmap_write(dev->regmap, SPDIFRX_IDR, GENMASK(14, 0)); in mchp_spdifrx_dai_remove()
1009 .name = "mchp-spdifrx",
1021 .name = "mchp-spdifrx",
1027 .compatible = "microchip,sama7g5-spdifrx",
1035 struct mchp_spdifrx_dev *spdifrx = dev_get_drvdata(dev); in mchp_spdifrx_runtime_suspend() local
1037 regcache_cache_only(spdifrx->regmap, true); in mchp_spdifrx_runtime_suspend()
1038 clk_disable_unprepare(spdifrx->gclk); in mchp_spdifrx_runtime_suspend()
1039 clk_disable_unprepare(spdifrx->pclk); in mchp_spdifrx_runtime_suspend()
1046 struct mchp_spdifrx_dev *spdifrx = dev_get_drvdata(dev); in mchp_spdifrx_runtime_resume() local
1049 ret = clk_prepare_enable(spdifrx->pclk); in mchp_spdifrx_runtime_resume()
1053 ret = clk_prepare_enable(spdifrx->gclk); in mchp_spdifrx_runtime_resume()
1057 regcache_cache_only(spdifrx->regmap, false); in mchp_spdifrx_runtime_resume()
1058 regcache_mark_dirty(spdifrx->regmap); in mchp_spdifrx_runtime_resume()
1059 ret = regcache_sync(spdifrx->regmap); in mchp_spdifrx_runtime_resume()
1061 regcache_cache_only(spdifrx->regmap, true); in mchp_spdifrx_runtime_resume()
1062 clk_disable_unprepare(spdifrx->gclk); in mchp_spdifrx_runtime_resume()
1064 clk_disable_unprepare(spdifrx->pclk); in mchp_spdifrx_runtime_resume()
1086 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in mchp_spdifrx_probe()
1088 return -ENOMEM; in mchp_spdifrx_probe()
1095 regmap = devm_regmap_init_mmio(&pdev->dev, base, in mchp_spdifrx_probe()
1105 err = devm_request_irq(&pdev->dev, irq, mchp_spdif_interrupt, 0, in mchp_spdifrx_probe()
1106 dev_name(&pdev->dev), dev); in mchp_spdifrx_probe()
1111 dev->pclk = devm_clk_get(&pdev->dev, "pclk"); in mchp_spdifrx_probe()
1112 if (IS_ERR(dev->pclk)) { in mchp_spdifrx_probe()
1113 err = PTR_ERR(dev->pclk); in mchp_spdifrx_probe()
1114 dev_err(&pdev->dev, "failed to get the peripheral clock: %d\n", in mchp_spdifrx_probe()
1120 dev->gclk = devm_clk_get(&pdev->dev, "gclk"); in mchp_spdifrx_probe()
1121 if (IS_ERR(dev->gclk)) { in mchp_spdifrx_probe()
1122 err = PTR_ERR(dev->gclk); in mchp_spdifrx_probe()
1123 dev_err(&pdev->dev, in mchp_spdifrx_probe()
1135 clk_set_min_rate(dev->gclk, 48000 * SPDIFRX_GCLK_RATIO_MIN + 1); in mchp_spdifrx_probe()
1137 mutex_init(&dev->mlock); in mchp_spdifrx_probe()
1139 dev->dev = &pdev->dev; in mchp_spdifrx_probe()
1140 dev->regmap = regmap; in mchp_spdifrx_probe()
1143 pm_runtime_enable(dev->dev); in mchp_spdifrx_probe()
1144 if (!pm_runtime_enabled(dev->dev)) { in mchp_spdifrx_probe()
1145 err = mchp_spdifrx_runtime_resume(dev->dev); in mchp_spdifrx_probe()
1150 dev->capture.addr = (dma_addr_t)mem->start + SPDIFRX_RHR; in mchp_spdifrx_probe()
1151 dev->capture.maxburst = 1; in mchp_spdifrx_probe()
1153 err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in mchp_spdifrx_probe()
1155 dev_err(&pdev->dev, "failed to register PCM: %d\n", err); in mchp_spdifrx_probe()
1159 err = devm_snd_soc_register_component(&pdev->dev, in mchp_spdifrx_probe()
1163 dev_err(&pdev->dev, "fail to register dai\n"); in mchp_spdifrx_probe()
1168 dev_info(&pdev->dev, "hw version: %#lx\n", vers & SPDIFRX_VERSION_MASK); in mchp_spdifrx_probe()
1173 if (!pm_runtime_status_suspended(dev->dev)) in mchp_spdifrx_probe()
1174 mchp_spdifrx_runtime_suspend(dev->dev); in mchp_spdifrx_probe()
1176 pm_runtime_disable(dev->dev); in mchp_spdifrx_probe()
1184 pm_runtime_disable(dev->dev); in mchp_spdifrx_remove()
1185 if (!pm_runtime_status_suspended(dev->dev)) in mchp_spdifrx_remove()
1186 mchp_spdifrx_runtime_suspend(dev->dev); in mchp_spdifrx_remove()