Lines Matching +full:sama7g5 +full:- +full:spdiftx
1 // SPDX-License-Identifier: GPL-2.0
20 * ---- S/PDIF Transmitter Controller Register map ----
37 * ---- Control Register (Write-only) ----
43 * ---- Mode Register (Read/Write) ----
91 ((((bytes) - 1) << 28) & SPDIFTX_MR_BPS_MASK)
94 * ---- Interrupt Enable/Disable/Mask/Status Register (Write/Read-only) ----
207 regmap_read(dev->regmap, SPDIFTX_MR, &mr); in mchp_spdiftx_is_running()
213 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_channel_status_write()
217 for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat) / 4; i++) { in mchp_spdiftx_channel_status_write()
218 val = (ctrl->ch_stat[(i * 4) + 0] << 0) | in mchp_spdiftx_channel_status_write()
219 (ctrl->ch_stat[(i * 4) + 1] << 8) | in mchp_spdiftx_channel_status_write()
220 (ctrl->ch_stat[(i * 4) + 2] << 16) | in mchp_spdiftx_channel_status_write()
221 (ctrl->ch_stat[(i * 4) + 3] << 24); in mchp_spdiftx_channel_status_write()
223 regmap_write(dev->regmap, SPDIFTX_CH1S(i), val); in mchp_spdiftx_channel_status_write()
229 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_user_data_write()
233 for (i = 0; i < ARRAY_SIZE(ctrl->user_data) / 4; i++) { in mchp_spdiftx_user_data_write()
234 val = (ctrl->user_data[(i * 4) + 0] << 0) | in mchp_spdiftx_user_data_write()
235 (ctrl->user_data[(i * 4) + 1] << 8) | in mchp_spdiftx_user_data_write()
236 (ctrl->user_data[(i * 4) + 2] << 16) | in mchp_spdiftx_user_data_write()
237 (ctrl->user_data[(i * 4) + 3] << 24); in mchp_spdiftx_user_data_write()
239 regmap_write(dev->regmap, SPDIFTX_CH1UD(i), val); in mchp_spdiftx_user_data_write()
246 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_interrupt()
249 regmap_read(dev->regmap, SPDIFTX_ISR, &sr); in mchp_spdiftx_interrupt()
250 regmap_read(dev->regmap, SPDIFTX_IMR, &imr); in mchp_spdiftx_interrupt()
257 dev_warn(dev->dev, "underflow detected\n"); in mchp_spdiftx_interrupt()
262 dev_warn(dev->dev, "overflow detected\n"); in mchp_spdiftx_interrupt()
267 spin_lock(&ctrl->lock); in mchp_spdiftx_interrupt()
269 spin_unlock(&ctrl->lock); in mchp_spdiftx_interrupt()
274 spin_lock(&ctrl->lock); in mchp_spdiftx_interrupt()
276 spin_unlock(&ctrl->lock); in mchp_spdiftx_interrupt()
280 regmap_write(dev->regmap, SPDIFTX_IDR, idr); in mchp_spdiftx_interrupt()
291 regmap_write(dev->regmap, SPDIFTX_CR, in mchp_spdiftx_dai_startup()
303 regmap_write(dev->regmap, SPDIFTX_IDR, 0xffffffff); in mchp_spdiftx_dai_shutdown()
310 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_trigger()
316 spin_lock(&ctrl->lock); in mchp_spdiftx_trigger()
317 regmap_read(dev->regmap, SPDIFTX_MR, &mr); in mchp_spdiftx_trigger()
338 spin_unlock(&ctrl->lock); in mchp_spdiftx_trigger()
339 return -EINVAL; in mchp_spdiftx_trigger()
342 ret = regmap_write(dev->regmap, SPDIFTX_MR, mr); in mchp_spdiftx_trigger()
343 spin_unlock(&ctrl->lock); in mchp_spdiftx_trigger()
345 dev_err(dev->dev, "unable to disable TX: %d\n", ret); in mchp_spdiftx_trigger()
358 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_hw_params()
363 dev_dbg(dev->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", in mchp_spdiftx_hw_params()
367 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in mchp_spdiftx_hw_params()
368 dev_err(dev->dev, "Capture is not supported\n"); in mchp_spdiftx_hw_params()
369 return -EINVAL; in mchp_spdiftx_hw_params()
372 regmap_read(dev->regmap, SPDIFTX_MR, &mr); in mchp_spdiftx_hw_params()
375 dev_err(dev->dev, "PCM already running\n"); in mchp_spdiftx_hw_params()
376 return -EBUSY; in mchp_spdiftx_hw_params()
381 dev->playback.maxburst = 1; in mchp_spdiftx_hw_params()
389 dev->playback.maxburst = 2; in mchp_spdiftx_hw_params()
392 dev_err(dev->dev, "unsupported number of channels: %d\n", in mchp_spdiftx_hw_params()
394 return -EINVAL; in mchp_spdiftx_hw_params()
396 mr |= SPDIFTX_MR_CHUNK(dev->playback.maxburst); in mchp_spdiftx_hw_params()
439 dev_err(dev->dev, "unsupported PCM format: %d\n", in mchp_spdiftx_hw_params()
441 return -EINVAL; in mchp_spdiftx_hw_params()
446 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_hw_params()
447 ctrl->ch_stat[3] &= ~IEC958_AES3_CON_FS; in mchp_spdiftx_hw_params()
450 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_22050; in mchp_spdiftx_hw_params()
453 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_24000; in mchp_spdiftx_hw_params()
456 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_32000; in mchp_spdiftx_hw_params()
459 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_44100; in mchp_spdiftx_hw_params()
462 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_48000; in mchp_spdiftx_hw_params()
465 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_88200; in mchp_spdiftx_hw_params()
468 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_96000; in mchp_spdiftx_hw_params()
471 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_176400; in mchp_spdiftx_hw_params()
474 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_192000; in mchp_spdiftx_hw_params()
480 ctrl->ch_stat[3] |= IEC958_AES3_CON_FS_NOTID; in mchp_spdiftx_hw_params()
483 dev_err(dev->dev, "unsupported sample frequency: %u\n", in mchp_spdiftx_hw_params()
485 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_hw_params()
486 return -EINVAL; in mchp_spdiftx_hw_params()
489 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_hw_params()
491 if (dev->gclk_enabled) { in mchp_spdiftx_hw_params()
492 clk_disable_unprepare(dev->gclk); in mchp_spdiftx_hw_params()
493 dev->gclk_enabled = 0; in mchp_spdiftx_hw_params()
495 ret = clk_set_rate(dev->gclk, params_rate(params) * in mchp_spdiftx_hw_params()
498 dev_err(dev->dev, in mchp_spdiftx_hw_params()
503 ret = clk_prepare_enable(dev->gclk); in mchp_spdiftx_hw_params()
505 dev_err(dev->dev, "unable to enable gclk: %d\n", ret); in mchp_spdiftx_hw_params()
508 dev->gclk_enabled = 1; in mchp_spdiftx_hw_params()
509 dev_dbg(dev->dev, "%s(): GCLK set to %d\n", __func__, in mchp_spdiftx_hw_params()
513 regmap_write(dev->regmap, SPDIFTX_IER, in mchp_spdiftx_hw_params()
516 regmap_write(dev->regmap, SPDIFTX_MR, mr); in mchp_spdiftx_hw_params()
526 regmap_write(dev->regmap, SPDIFTX_IDR, in mchp_spdiftx_hw_free()
528 if (dev->gclk_enabled) { in mchp_spdiftx_hw_free()
529 clk_disable_unprepare(dev->gclk); in mchp_spdiftx_hw_free()
530 dev->gclk_enabled = 0; in mchp_spdiftx_hw_free()
533 return regmap_write(dev->regmap, SPDIFTX_CR, in mchp_spdiftx_hw_free()
565 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; in mchp_spdiftx_info()
566 uinfo->count = 1; in mchp_spdiftx_info()
577 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_cs_get()
579 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_cs_get()
580 memcpy(uvalue->value.iec958.status, ctrl->ch_stat, in mchp_spdiftx_cs_get()
581 sizeof(ctrl->ch_stat)); in mchp_spdiftx_cs_get()
582 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_cs_get()
593 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_cs_put()
597 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_cs_put()
598 for (i = 0; i < ARRAY_SIZE(ctrl->ch_stat); i++) { in mchp_spdiftx_cs_put()
599 if (ctrl->ch_stat[i] != uvalue->value.iec958.status[i]) in mchp_spdiftx_cs_put()
601 ctrl->ch_stat[i] = uvalue->value.iec958.status[i]; in mchp_spdiftx_cs_put()
611 regmap_write(dev->regmap, SPDIFTX_IER, in mchp_spdiftx_cs_put()
617 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_cs_put()
625 memset(uvalue->value.iec958.status, 0xff, in mchp_spdiftx_cs_mask()
626 sizeof(uvalue->value.iec958.status)); in mchp_spdiftx_cs_mask()
636 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_subcode_get()
639 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_subcode_get()
640 memcpy(uvalue->value.iec958.subcode, ctrl->user_data, in mchp_spdiftx_subcode_get()
641 sizeof(ctrl->user_data)); in mchp_spdiftx_subcode_get()
642 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_subcode_get()
653 struct mchp_spdiftx_mixer_control *ctrl = &dev->control; in mchp_spdiftx_subcode_put()
657 spin_lock_irqsave(&ctrl->lock, flags); in mchp_spdiftx_subcode_put()
658 for (i = 0; i < ARRAY_SIZE(ctrl->user_data); i++) { in mchp_spdiftx_subcode_put()
659 if (ctrl->user_data[i] != uvalue->value.iec958.subcode[i]) in mchp_spdiftx_subcode_put()
662 ctrl->user_data[i] = uvalue->value.iec958.subcode[i]; in mchp_spdiftx_subcode_put()
670 regmap_write(dev->regmap, SPDIFTX_IER, in mchp_spdiftx_subcode_put()
676 spin_unlock_irqrestore(&ctrl->lock, flags); in mchp_spdiftx_subcode_put()
716 snd_soc_dai_init_dma_data(dai, &dev->playback, NULL); in mchp_spdiftx_dai_probe()
718 ret = clk_prepare_enable(dev->pclk); in mchp_spdiftx_dai_probe()
720 dev_err(dev->dev, in mchp_spdiftx_dai_probe()
736 clk_disable_unprepare(dev->pclk); in mchp_spdiftx_dai_remove()
742 .name = "mchp-spdiftx",
756 .name = "mchp-spdiftx",
761 .compatible = "microchip,sama7g5-spdiftx",
769 struct device_node *np = pdev->dev.of_node; in mchp_spdiftx_probe()
780 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); in mchp_spdiftx_probe()
782 return -ENOMEM; in mchp_spdiftx_probe()
787 dev->caps = match->data; in mchp_spdiftx_probe()
794 regmap = devm_regmap_init_mmio(&pdev->dev, base, in mchp_spdiftx_probe()
804 err = devm_request_irq(&pdev->dev, irq, mchp_spdiftx_interrupt, 0, in mchp_spdiftx_probe()
805 dev_name(&pdev->dev), dev); in mchp_spdiftx_probe()
810 dev->pclk = devm_clk_get(&pdev->dev, "pclk"); in mchp_spdiftx_probe()
811 if (IS_ERR(dev->pclk)) { in mchp_spdiftx_probe()
812 err = PTR_ERR(dev->pclk); in mchp_spdiftx_probe()
813 dev_err(&pdev->dev, in mchp_spdiftx_probe()
819 dev->gclk = devm_clk_get(&pdev->dev, "gclk"); in mchp_spdiftx_probe()
820 if (IS_ERR(dev->gclk)) { in mchp_spdiftx_probe()
821 err = PTR_ERR(dev->gclk); in mchp_spdiftx_probe()
822 dev_err(&pdev->dev, in mchp_spdiftx_probe()
827 ctrl = &dev->control; in mchp_spdiftx_probe()
828 spin_lock_init(&ctrl->lock); in mchp_spdiftx_probe()
831 ctrl->ch_stat[0] = IEC958_AES0_CON_NOT_COPYRIGHT | in mchp_spdiftx_probe()
834 dev->dev = &pdev->dev; in mchp_spdiftx_probe()
835 dev->regmap = regmap; in mchp_spdiftx_probe()
838 dev->playback.addr = (dma_addr_t)mem->start + SPDIFTX_CDR; in mchp_spdiftx_probe()
839 dev->playback.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in mchp_spdiftx_probe()
841 err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in mchp_spdiftx_probe()
843 dev_err(&pdev->dev, "failed to register PMC: %d\n", err); in mchp_spdiftx_probe()
847 err = devm_snd_soc_register_component(&pdev->dev, in mchp_spdiftx_probe()
851 dev_err(&pdev->dev, "failed to register component: %d\n", err); in mchp_spdiftx_probe()