Lines Matching +full:re +full:- +full:clocked
1 // SPDX-License-Identifier: GPL-2.0-only
9 * based on davinci-mcasp.c DT support
31 #include "edma-pcm.h"
32 #include "davinci-i2s.h"
34 #define DRV_NAME "davinci-i2s"
39 * - This driver supports the "Audio Serial Port" (ASP),
42 * - But it labels it a "Multi-channel Buffered Serial Port"
44 * backward-compatible, possibly explaining that confusion.
46 * - OMAP chips have a controller called McBSP, which is
49 * - Newer DaVinci chips have a controller called McASP,
169 __raw_writel(val, dev->base + reg); in davinci_mcbsp_write_reg()
174 return __raw_readl(dev->base + reg); in davinci_mcbsp_read_reg()
183 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr ^ m); in toggle_clock()
184 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, dev->pcr); in toggle_clock()
190 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in davinci_mcbsp_start()
198 if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM)) { in davinci_mcbsp_start()
228 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | in davinci_i2s_set_dai_fmt()
229 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1); in davinci_i2s_set_dai_fmt()
231 dev->fmt = fmt; in davinci_i2s_set_dai_fmt()
249 switch (dev->clk_input_pin) { in davinci_i2s_set_dai_fmt()
258 dev_err(dev->dev, "bad clk_input_pin\n"); in davinci_i2s_set_dai_fmt()
259 return -EINVAL; in davinci_i2s_set_dai_fmt()
269 return -EINVAL; in davinci_i2s_set_dai_fmt()
294 dev->mode = MOD_DSP_A; in davinci_i2s_set_dai_fmt()
297 dev->mode = MOD_DSP_B; in davinci_i2s_set_dai_fmt()
301 return -EINVAL; in davinci_i2s_set_dai_fmt()
307 * 1 - sampled on rising edge of CLKR in davinci_i2s_set_dai_fmt()
310 * 1 - clocked on falling edge of CLKX in davinci_i2s_set_dai_fmt()
312 * FSRP Receive frame sync pol, 0 - active high in davinci_i2s_set_dai_fmt()
313 * FSXP Transmit frame sync pol, 0 - active high in davinci_i2s_set_dai_fmt()
319 * 0 - sampled on falling edge of CLKR in davinci_i2s_set_dai_fmt()
322 * 0 - clocked on rising edge of CLKX in davinci_i2s_set_dai_fmt()
324 * FSRP Receive frame sync pol, 1 - active low in davinci_i2s_set_dai_fmt()
325 * FSXP Transmit frame sync pol, 1 - active low in davinci_i2s_set_dai_fmt()
331 * 1 - sampled on rising edge of CLKR in davinci_i2s_set_dai_fmt()
334 * 1 - clocked on falling edge of CLKX in davinci_i2s_set_dai_fmt()
336 * FSRP Receive frame sync pol, 1 - active low in davinci_i2s_set_dai_fmt()
337 * FSXP Transmit frame sync pol, 1 - active low in davinci_i2s_set_dai_fmt()
344 * 0 - sampled on falling edge of CLKR in davinci_i2s_set_dai_fmt()
347 * 0 - clocked on rising edge of CLKX in davinci_i2s_set_dai_fmt()
349 * FSRP Receive frame sync pol, 0 - active high in davinci_i2s_set_dai_fmt()
350 * FSXP Transmit frame sync pol, 0 - active high in davinci_i2s_set_dai_fmt()
354 return -EINVAL; in davinci_i2s_set_dai_fmt()
359 dev->pcr = pcr; in davinci_i2s_set_dai_fmt()
370 return -ENODEV; in davinci_i2s_dai_set_clkdiv()
372 dev->clk_div = div; in davinci_i2s_dai_set_clkdiv()
390 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in davinci_i2s_hw_params()
398 master = dev->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK; in davinci_i2s_hw_params()
404 freq = clk_get_rate(dev->clk); in davinci_i2s_hw_params()
408 8 - 1); in davinci_i2s_hw_params()
409 if (dev->i2s_accurate_sck) { in davinci_i2s_hw_params()
412 framesize = (freq / (--clk_div)) / in davinci_i2s_hw_params()
413 params->rate_num * in davinci_i2s_hw_params()
414 params->rate_den; in davinci_i2s_hw_params()
417 clk_div--; in davinci_i2s_hw_params()
418 srgr |= DAVINCI_MCBSP_SRGR_FPER(framesize - 1); in davinci_i2s_hw_params()
422 params->rate_num * params->rate_den; in davinci_i2s_hw_params()
424 16 - 1); in davinci_i2s_hw_params()
431 clk_div = dev->clk_div - 1; in davinci_i2s_hw_params()
432 srgr |= DAVINCI_MCBSP_SRGR_FWID(mcbsp_word_length * 8 - 1); in davinci_i2s_hw_params()
433 srgr |= DAVINCI_MCBSP_SRGR_FPER(mcbsp_word_length * 16 - 1); in davinci_i2s_hw_params()
441 srgr |= DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1); in davinci_i2s_hw_params()
442 pr_debug("%s - %d FWID set: re-read srgr = %X\n", in davinci_i2s_hw_params()
443 __func__, __LINE__, snd_interval_value(i) - 1); in davinci_i2s_hw_params()
446 srgr |= DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1); in davinci_i2s_hw_params()
449 return -EINVAL; in davinci_i2s_hw_params()
455 if (dev->mode == MOD_DSP_B) { in davinci_i2s_hw_params()
465 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n"); in davinci_i2s_hw_params()
466 return -EINVAL; in davinci_i2s_hw_params()
471 if (double_fmt[fmt] && dev->enable_channel_combine) { in davinci_i2s_hw_params()
485 rcr |= DAVINCI_MCBSP_RCR_RFRLEN2(element_cnt - 1); in davinci_i2s_hw_params()
486 xcr |= DAVINCI_MCBSP_XCR_XFRLEN2(element_cnt - 1); in davinci_i2s_hw_params()
489 return -EINVAL; in davinci_i2s_hw_params()
502 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1); in davinci_i2s_hw_params()
503 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1); in davinci_i2s_hw_params()
506 return -EINVAL; in davinci_i2s_hw_params()
514 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in davinci_i2s_hw_params()
519 pr_debug("%s - %d srgr=%X\n", __func__, __LINE__, srgr); in davinci_i2s_hw_params()
520 pr_debug("%s - %d xcr=%X\n", __func__, __LINE__, xcr); in davinci_i2s_hw_params()
521 pr_debug("%s - %d rcr=%X\n", __func__, __LINE__, rcr); in davinci_i2s_hw_params()
529 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in davinci_i2s_prepare()
542 if (dev->pcr & (DAVINCI_MCBSP_PCR_FSXM | DAVINCI_MCBSP_PCR_FSRM | in davinci_i2s_prepare()
573 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in davinci_i2s_trigger()
587 ret = -EINVAL; in davinci_i2s_trigger()
596 int playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); in davinci_i2s_shutdown()
618 dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; in davinci_i2s_dai_probe()
619 dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; in davinci_i2s_dai_probe()
658 dev_warn(&pdev->dev, in davinci_i2s_probe()
662 dev_err(&pdev->dev, "no mem resource?\n"); in davinci_i2s_probe()
663 return -ENODEV; in davinci_i2s_probe()
667 io_base = devm_ioremap_resource(&pdev->dev, mem); in davinci_i2s_probe()
671 dev = devm_kzalloc(&pdev->dev, sizeof(struct davinci_mcbsp_dev), in davinci_i2s_probe()
674 return -ENOMEM; in davinci_i2s_probe()
676 dev->base = io_base; in davinci_i2s_probe()
679 dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; in davinci_i2s_probe()
680 dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DXR_REG); in davinci_i2s_probe()
684 dma = &dev->dma_request[SNDRV_PCM_STREAM_PLAYBACK]; in davinci_i2s_probe()
685 *dma = res->start; in davinci_i2s_probe()
686 dma_data->filter_data = dma; in davinci_i2s_probe()
687 } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { in davinci_i2s_probe()
688 dma_data->filter_data = "tx"; in davinci_i2s_probe()
690 dev_err(&pdev->dev, "Missing DMA tx resource\n"); in davinci_i2s_probe()
691 return -ENODEV; in davinci_i2s_probe()
694 dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; in davinci_i2s_probe()
695 dma_data->addr = (dma_addr_t)(mem->start + DAVINCI_MCBSP_DRR_REG); in davinci_i2s_probe()
699 dma = &dev->dma_request[SNDRV_PCM_STREAM_CAPTURE]; in davinci_i2s_probe()
700 *dma = res->start; in davinci_i2s_probe()
701 dma_data->filter_data = dma; in davinci_i2s_probe()
702 } else if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { in davinci_i2s_probe()
703 dma_data->filter_data = "rx"; in davinci_i2s_probe()
705 dev_err(&pdev->dev, "Missing DMA rx resource\n"); in davinci_i2s_probe()
706 return -ENODEV; in davinci_i2s_probe()
709 dev->clk = clk_get(&pdev->dev, NULL); in davinci_i2s_probe()
710 if (IS_ERR(dev->clk)) in davinci_i2s_probe()
711 return -ENODEV; in davinci_i2s_probe()
712 ret = clk_enable(dev->clk); in davinci_i2s_probe()
716 dev->dev = &pdev->dev; in davinci_i2s_probe()
717 dev_set_drvdata(&pdev->dev, dev); in davinci_i2s_probe()
719 ret = snd_soc_register_component(&pdev->dev, &davinci_i2s_component, in davinci_i2s_probe()
724 ret = edma_pcm_platform_register(&pdev->dev); in davinci_i2s_probe()
726 dev_err(&pdev->dev, "register PCM failed: %d\n", ret); in davinci_i2s_probe()
733 snd_soc_unregister_component(&pdev->dev); in davinci_i2s_probe()
735 clk_disable(dev->clk); in davinci_i2s_probe()
737 clk_put(dev->clk); in davinci_i2s_probe()
743 struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); in davinci_i2s_remove()
745 snd_soc_unregister_component(&pdev->dev); in davinci_i2s_remove()
747 clk_disable(dev->clk); in davinci_i2s_remove()
748 clk_put(dev->clk); in davinci_i2s_remove()
749 dev->clk = NULL; in davinci_i2s_remove()
755 { .compatible = "ti,da850-mcbsp" },
764 .name = "davinci-mcbsp",