Lines Matching full:spdifrx

207  * struct stm32_spdifrx_data - private data of SPDIFRX
210 * @regmap: SPDIFRX register map pointer
211 * @regmap_conf: SPDIFRX register map configuration pointer
213 * @kclk: kernel clock feeding the SPDIFRX clock generator
220 * @phys_addr: SPDIFRX registers physical base address
225 * @irq: SPDIFRX interrupt line
252 struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)data; in stm32_spdifrx_dma_complete() local
253 struct platform_device *pdev = spdifrx->pdev; in stm32_spdifrx_dma_complete()
254 u32 *p_start = (u32 *)spdifrx->dmab->area; in stm32_spdifrx_dma_complete()
257 u16 *ub_ptr = (short *)spdifrx->ub; in stm32_spdifrx_dma_complete()
260 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_dma_complete()
264 if (!spdifrx->dmab->area) in stm32_spdifrx_dma_complete()
279 spdifrx->cs[i] = (unsigned char)SPDIFRX_CSR_CSGET(*ptr); in stm32_spdifrx_dma_complete()
288 complete(&spdifrx->cs_completion); in stm32_spdifrx_dma_complete()
291 static int stm32_spdifrx_dma_ctrl_start(struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_dma_ctrl_start() argument
296 spdifrx->desc = dmaengine_prep_slave_single(spdifrx->ctrl_chan, in stm32_spdifrx_dma_ctrl_start()
297 spdifrx->dmab->addr, in stm32_spdifrx_dma_ctrl_start()
301 if (!spdifrx->desc) in stm32_spdifrx_dma_ctrl_start()
304 spdifrx->desc->callback = stm32_spdifrx_dma_complete; in stm32_spdifrx_dma_ctrl_start()
305 spdifrx->desc->callback_param = spdifrx; in stm32_spdifrx_dma_ctrl_start()
306 cookie = dmaengine_submit(spdifrx->desc); in stm32_spdifrx_dma_ctrl_start()
311 dma_async_issue_pending(spdifrx->ctrl_chan); in stm32_spdifrx_dma_ctrl_start()
316 static void stm32_spdifrx_dma_ctrl_stop(struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_dma_ctrl_stop() argument
318 dmaengine_terminate_async(spdifrx->ctrl_chan); in stm32_spdifrx_dma_ctrl_stop()
321 static int stm32_spdifrx_start_sync(struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_start_sync() argument
328 ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR, imr, imr); in stm32_spdifrx_start_sync()
332 spin_lock_irqsave(&spdifrx->lock, flags); in stm32_spdifrx_start_sync()
334 spdifrx->refcount++; in stm32_spdifrx_start_sync()
336 regmap_read(spdifrx->regmap, STM32_SPDIFRX_CR, &cr); in stm32_spdifrx_start_sync()
340 * Start sync if SPDIFRX is still in idle state. in stm32_spdifrx_start_sync()
341 * SPDIFRX reception enabled when sync done in stm32_spdifrx_start_sync()
343 dev_dbg(&spdifrx->pdev->dev, "start synchronization\n"); in stm32_spdifrx_start_sync()
346 * SPDIFRX configuration: in stm32_spdifrx_start_sync()
360 ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_start_sync()
363 dev_err(&spdifrx->pdev->dev, in stm32_spdifrx_start_sync()
367 spin_unlock_irqrestore(&spdifrx->lock, flags); in stm32_spdifrx_start_sync()
372 static void stm32_spdifrx_stop(struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_stop() argument
377 spin_lock_irqsave(&spdifrx->lock, flags); in stm32_spdifrx_stop()
379 if (--spdifrx->refcount) { in stm32_spdifrx_stop()
380 spin_unlock_irqrestore(&spdifrx->lock, flags); in stm32_spdifrx_stop()
387 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, cr_mask, cr); in stm32_spdifrx_stop()
389 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR, in stm32_spdifrx_stop()
392 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IFCR, in stm32_spdifrx_stop()
396 regmap_read(spdifrx->regmap, STM32_SPDIFRX_DR, &reg); in stm32_spdifrx_stop()
397 regmap_read(spdifrx->regmap, STM32_SPDIFRX_CSR, &reg); in stm32_spdifrx_stop()
399 spin_unlock_irqrestore(&spdifrx->lock, flags); in stm32_spdifrx_stop()
403 struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_dma_ctrl_register() argument
407 spdifrx->ctrl_chan = dma_request_chan(dev, "rx-ctrl"); in stm32_spdifrx_dma_ctrl_register()
408 if (IS_ERR(spdifrx->ctrl_chan)) { in stm32_spdifrx_dma_ctrl_register()
409 if (PTR_ERR(spdifrx->ctrl_chan) != -EPROBE_DEFER) in stm32_spdifrx_dma_ctrl_register()
411 PTR_ERR(spdifrx->ctrl_chan)); in stm32_spdifrx_dma_ctrl_register()
412 return PTR_ERR(spdifrx->ctrl_chan); in stm32_spdifrx_dma_ctrl_register()
415 spdifrx->dmab = devm_kzalloc(dev, sizeof(struct snd_dma_buffer), in stm32_spdifrx_dma_ctrl_register()
417 if (!spdifrx->dmab) in stm32_spdifrx_dma_ctrl_register()
420 spdifrx->dmab->dev.type = SNDRV_DMA_TYPE_DEV_IRAM; in stm32_spdifrx_dma_ctrl_register()
421 spdifrx->dmab->dev.dev = dev; in stm32_spdifrx_dma_ctrl_register()
422 ret = snd_dma_alloc_pages(spdifrx->dmab->dev.type, dev, in stm32_spdifrx_dma_ctrl_register()
423 SPDIFRX_CSR_BUF_LENGTH, spdifrx->dmab); in stm32_spdifrx_dma_ctrl_register()
429 spdifrx->slave_config.direction = DMA_DEV_TO_MEM; in stm32_spdifrx_dma_ctrl_register()
430 spdifrx->slave_config.src_addr = (dma_addr_t)(spdifrx->phys_addr + in stm32_spdifrx_dma_ctrl_register()
432 spdifrx->slave_config.dst_addr = spdifrx->dmab->addr; in stm32_spdifrx_dma_ctrl_register()
433 spdifrx->slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in stm32_spdifrx_dma_ctrl_register()
434 spdifrx->slave_config.src_maxburst = 1; in stm32_spdifrx_dma_ctrl_register()
436 ret = dmaengine_slave_config(spdifrx->ctrl_chan, in stm32_spdifrx_dma_ctrl_register()
437 &spdifrx->slave_config); in stm32_spdifrx_dma_ctrl_register()
440 spdifrx->ctrl_chan = NULL; in stm32_spdifrx_dma_ctrl_register()
481 static int stm32_spdifrx_get_ctrl_data(struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_get_ctrl_data() argument
485 memset(spdifrx->cs, 0, SPDIFRX_CS_BYTES_NB); in stm32_spdifrx_get_ctrl_data()
486 memset(spdifrx->ub, 0, SPDIFRX_UB_BYTES_NB); in stm32_spdifrx_get_ctrl_data()
488 ret = stm32_spdifrx_dma_ctrl_start(spdifrx); in stm32_spdifrx_get_ctrl_data()
492 ret = clk_prepare_enable(spdifrx->kclk); in stm32_spdifrx_get_ctrl_data()
494 dev_err(&spdifrx->pdev->dev, "Enable kclk failed: %d\n", ret); in stm32_spdifrx_get_ctrl_data()
498 ret = regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_get_ctrl_data()
503 ret = stm32_spdifrx_start_sync(spdifrx); in stm32_spdifrx_get_ctrl_data()
507 if (wait_for_completion_interruptible_timeout(&spdifrx->cs_completion, in stm32_spdifrx_get_ctrl_data()
510 dev_dbg(&spdifrx->pdev->dev, "Failed to get control data\n"); in stm32_spdifrx_get_ctrl_data()
514 stm32_spdifrx_stop(spdifrx); in stm32_spdifrx_get_ctrl_data()
515 stm32_spdifrx_dma_ctrl_stop(spdifrx); in stm32_spdifrx_get_ctrl_data()
518 clk_disable_unprepare(spdifrx->kclk); in stm32_spdifrx_get_ctrl_data()
527 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); in stm32_spdifrx_capture_get() local
529 stm32_spdifrx_get_ctrl_data(spdifrx); in stm32_spdifrx_capture_get()
531 ucontrol->value.iec958.status[0] = spdifrx->cs[0]; in stm32_spdifrx_capture_get()
532 ucontrol->value.iec958.status[1] = spdifrx->cs[1]; in stm32_spdifrx_capture_get()
533 ucontrol->value.iec958.status[2] = spdifrx->cs[2]; in stm32_spdifrx_capture_get()
534 ucontrol->value.iec958.status[3] = spdifrx->cs[3]; in stm32_spdifrx_capture_get()
535 ucontrol->value.iec958.status[4] = spdifrx->cs[4]; in stm32_spdifrx_capture_get()
544 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); in stm32_spdif_user_bits_get() local
546 stm32_spdifrx_get_ctrl_data(spdifrx); in stm32_spdif_user_bits_get()
548 ucontrol->value.iec958.status[0] = spdifrx->ub[0]; in stm32_spdif_user_bits_get()
549 ucontrol->value.iec958.status[1] = spdifrx->ub[1]; in stm32_spdif_user_bits_get()
550 ucontrol->value.iec958.status[2] = spdifrx->ub[2]; in stm32_spdif_user_bits_get()
551 ucontrol->value.iec958.status[3] = spdifrx->ub[3]; in stm32_spdif_user_bits_get()
552 ucontrol->value.iec958.status[4] = spdifrx->ub[4]; in stm32_spdif_user_bits_get()
579 SOC_ENUM("SPDIFRX input", ctrl_enum_input),
580 SOC_ENUM("SPDIFRX CS channel", ctrl_enum_cs_channel),
599 struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(cpu_dai->dev); in stm32_spdifrx_dai_probe() local
601 spdifrx->dma_params.addr = (dma_addr_t)(spdifrx->phys_addr + in stm32_spdifrx_dai_probe()
603 spdifrx->dma_params.maxburst = 1; in stm32_spdifrx_dai_probe()
605 snd_soc_dai_init_dma_data(cpu_dai, NULL, &spdifrx->dma_params); in stm32_spdifrx_dai_probe()
669 struct stm32_spdifrx_data *spdifrx = (struct stm32_spdifrx_data *)devid; in stm32_spdifrx_isr() local
670 struct platform_device *pdev = spdifrx->pdev; in stm32_spdifrx_isr()
675 regmap_read(spdifrx->regmap, STM32_SPDIFRX_SR, &sr); in stm32_spdifrx_isr()
676 regmap_read(spdifrx->regmap, STM32_SPDIFRX_IMR, &imr); in stm32_spdifrx_isr()
691 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IFCR, in stm32_spdifrx_isr()
710 /* Enable spdifrx */ in stm32_spdifrx_isr()
712 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_isr()
732 regmap_read(spdifrx->regmap, STM32_SPDIFRX_CR, &cr); in stm32_spdifrx_isr()
736 /* SPDIFRX is in STATE_STOP. Disable SPDIFRX to clear errors */ in stm32_spdifrx_isr()
738 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_isr()
741 /* If SPDIFRX was in STATE_SYNC, retry synchro */ in stm32_spdifrx_isr()
744 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_isr()
749 spin_lock(&spdifrx->irq_lock); in stm32_spdifrx_isr()
750 if (spdifrx->substream) in stm32_spdifrx_isr()
751 snd_pcm_stop(spdifrx->substream, in stm32_spdifrx_isr()
753 spin_unlock(&spdifrx->irq_lock); in stm32_spdifrx_isr()
758 spin_lock(&spdifrx->irq_lock); in stm32_spdifrx_isr()
759 if (err_xrun && spdifrx->substream) in stm32_spdifrx_isr()
760 snd_pcm_stop_xrun(spdifrx->substream); in stm32_spdifrx_isr()
761 spin_unlock(&spdifrx->irq_lock); in stm32_spdifrx_isr()
769 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); in stm32_spdifrx_startup() local
773 spin_lock_irqsave(&spdifrx->irq_lock, flags); in stm32_spdifrx_startup()
774 spdifrx->substream = substream; in stm32_spdifrx_startup()
775 spin_unlock_irqrestore(&spdifrx->irq_lock, flags); in stm32_spdifrx_startup()
777 ret = clk_prepare_enable(spdifrx->kclk); in stm32_spdifrx_startup()
779 dev_err(&spdifrx->pdev->dev, "Enable kclk failed: %d\n", ret); in stm32_spdifrx_startup()
788 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); in stm32_spdifrx_hw_params() local
800 dev_err(&spdifrx->pdev->dev, "Unexpected data format\n"); in stm32_spdifrx_hw_params()
809 spdifrx->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in stm32_spdifrx_hw_params()
810 snd_soc_dai_init_dma_data(cpu_dai, NULL, &spdifrx->dma_params); in stm32_spdifrx_hw_params()
812 return regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_hw_params()
820 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); in stm32_spdifrx_trigger() local
827 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_IMR, in stm32_spdifrx_trigger()
830 regmap_update_bits(spdifrx->regmap, STM32_SPDIFRX_CR, in stm32_spdifrx_trigger()
833 ret = stm32_spdifrx_start_sync(spdifrx); in stm32_spdifrx_trigger()
838 stm32_spdifrx_stop(spdifrx); in stm32_spdifrx_trigger()
850 struct stm32_spdifrx_data *spdifrx = snd_soc_dai_get_drvdata(cpu_dai); in stm32_spdifrx_shutdown() local
853 spin_lock_irqsave(&spdifrx->irq_lock, flags); in stm32_spdifrx_shutdown()
854 spdifrx->substream = NULL; in stm32_spdifrx_shutdown()
855 spin_unlock_irqrestore(&spdifrx->irq_lock, flags); in stm32_spdifrx_shutdown()
857 clk_disable_unprepare(spdifrx->kclk); in stm32_spdifrx_shutdown()
892 .name = "stm32-spdifrx",
902 .compatible = "st,stm32h7-spdifrx",
909 struct stm32_spdifrx_data *spdifrx) in stm32_spdifrx_parse_of() argument
920 spdifrx->regmap_conf = in stm32_spdifrx_parse_of()
926 spdifrx->base = devm_ioremap_resource(&pdev->dev, res); in stm32_spdifrx_parse_of()
927 if (IS_ERR(spdifrx->base)) in stm32_spdifrx_parse_of()
928 return PTR_ERR(spdifrx->base); in stm32_spdifrx_parse_of()
930 spdifrx->phys_addr = res->start; in stm32_spdifrx_parse_of()
932 spdifrx->kclk = devm_clk_get(&pdev->dev, "kclk"); in stm32_spdifrx_parse_of()
933 if (IS_ERR(spdifrx->kclk)) { in stm32_spdifrx_parse_of()
934 if (PTR_ERR(spdifrx->kclk) != -EPROBE_DEFER) in stm32_spdifrx_parse_of()
936 PTR_ERR(spdifrx->kclk)); in stm32_spdifrx_parse_of()
937 return PTR_ERR(spdifrx->kclk); in stm32_spdifrx_parse_of()
940 spdifrx->irq = platform_get_irq(pdev, 0); in stm32_spdifrx_parse_of()
941 if (spdifrx->irq < 0) in stm32_spdifrx_parse_of()
942 return spdifrx->irq; in stm32_spdifrx_parse_of()
949 struct stm32_spdifrx_data *spdifrx = platform_get_drvdata(pdev); in stm32_spdifrx_remove() local
951 if (spdifrx->ctrl_chan) in stm32_spdifrx_remove()
952 dma_release_channel(spdifrx->ctrl_chan); in stm32_spdifrx_remove()
954 if (spdifrx->dmab) in stm32_spdifrx_remove()
955 snd_dma_free_pages(spdifrx->dmab); in stm32_spdifrx_remove()
965 struct stm32_spdifrx_data *spdifrx; in stm32_spdifrx_probe() local
971 spdifrx = devm_kzalloc(&pdev->dev, sizeof(*spdifrx), GFP_KERNEL); in stm32_spdifrx_probe()
972 if (!spdifrx) in stm32_spdifrx_probe()
975 spdifrx->pdev = pdev; in stm32_spdifrx_probe()
976 init_completion(&spdifrx->cs_completion); in stm32_spdifrx_probe()
977 spin_lock_init(&spdifrx->lock); in stm32_spdifrx_probe()
978 spin_lock_init(&spdifrx->irq_lock); in stm32_spdifrx_probe()
980 platform_set_drvdata(pdev, spdifrx); in stm32_spdifrx_probe()
982 ret = stm32_spdifrx_parse_of(pdev, spdifrx); in stm32_spdifrx_probe()
986 spdifrx->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "kclk", in stm32_spdifrx_probe()
987 spdifrx->base, in stm32_spdifrx_probe()
988 spdifrx->regmap_conf); in stm32_spdifrx_probe()
989 if (IS_ERR(spdifrx->regmap)) { in stm32_spdifrx_probe()
990 if (PTR_ERR(spdifrx->regmap) != -EPROBE_DEFER) in stm32_spdifrx_probe()
992 PTR_ERR(spdifrx->regmap)); in stm32_spdifrx_probe()
993 return PTR_ERR(spdifrx->regmap); in stm32_spdifrx_probe()
996 ret = devm_request_irq(&pdev->dev, spdifrx->irq, stm32_spdifrx_isr, 0, in stm32_spdifrx_probe()
997 dev_name(&pdev->dev), spdifrx); in stm32_spdifrx_probe()
1031 ret = stm32_spdifrx_dma_ctrl_register(&pdev->dev, spdifrx); in stm32_spdifrx_probe()
1035 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_IDR, &idr); in stm32_spdifrx_probe()
1040 ret = regmap_read(spdifrx->regmap, STM32_SPDIFRX_VERR, &ver); in stm32_spdifrx_probe()
1044 dev_dbg(&pdev->dev, "SPDIFRX version: %lu.%lu registered\n", in stm32_spdifrx_probe()
1062 struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev); in stm32_spdifrx_suspend() local
1064 regcache_cache_only(spdifrx->regmap, true); in stm32_spdifrx_suspend()
1065 regcache_mark_dirty(spdifrx->regmap); in stm32_spdifrx_suspend()
1072 struct stm32_spdifrx_data *spdifrx = dev_get_drvdata(dev); in stm32_spdifrx_resume() local
1074 regcache_cache_only(spdifrx->regmap, false); in stm32_spdifrx_resume()
1076 return regcache_sync(spdifrx->regmap); in stm32_spdifrx_resume()
1086 .name = "st,stm32-spdifrx",
1096 MODULE_DESCRIPTION("STM32 Soc spdifrx Interface");
1098 MODULE_ALIAS("platform:stm32-spdifrx");