Lines Matching +full:pdm +full:- +full:fmt
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Rockchip PDM ALSA SoC Digital Audio Interface(DAI) driver
78 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr, in get_pdm_clk() argument
92 if ((div & (div - 1)) == 0) { in get_pdm_clk()
94 rate = clk_round_rate(pdm->clk, clkref[i].clk); in get_pdm_clk()
104 clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE); in get_pdm_clk()
180 static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on) in rockchip_pdm_rxctrl() argument
183 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, in rockchip_pdm_rxctrl()
185 regmap_update_bits(pdm->regmap, PDM_SYSCONFIG, in rockchip_pdm_rxctrl()
188 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, in rockchip_pdm_rxctrl()
190 regmap_update_bits(pdm->regmap, PDM_SYSCONFIG, in rockchip_pdm_rxctrl()
200 struct rk_pdm_dev *pdm = to_info(dai); in rockchip_pdm_hw_params() local
208 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in rockchip_pdm_hw_params()
212 clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out); in rockchip_pdm_hw_params()
214 return -EINVAL; in rockchip_pdm_hw_params()
216 ret = clk_set_rate(pdm->clk, clk_src); in rockchip_pdm_hw_params()
218 return -EINVAL; in rockchip_pdm_hw_params()
220 if (pdm->version == RK_PDM_RK3308 || in rockchip_pdm_hw_params()
221 pdm->version == RK_PDM_RV1126) { in rockchip_pdm_hw_params()
223 GENMASK(16 - 1, 0), in rockchip_pdm_hw_params()
224 GENMASK(16 - 1, 0), in rockchip_pdm_hw_params()
229 regmap_update_bits_check(pdm->regmap, PDM_CTRL1, in rockchip_pdm_hw_params()
234 reset_control_assert(pdm->reset); in rockchip_pdm_hw_params()
235 reset_control_deassert(pdm->reset); in rockchip_pdm_hw_params()
236 rockchip_pdm_rxctrl(pdm, 0); in rockchip_pdm_hw_params()
244 return -EINVAL; in rockchip_pdm_hw_params()
245 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, in rockchip_pdm_hw_params()
250 if (pdm->version == RK_PDM_RV1126) { in rockchip_pdm_hw_params()
252 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val); in rockchip_pdm_hw_params()
254 regmap_update_bits(pdm->regmap, PDM_CTRL0, in rockchip_pdm_hw_params()
258 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val); in rockchip_pdm_hw_params()
261 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, in rockchip_pdm_hw_params()
263 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, in rockchip_pdm_hw_params()
265 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CLK_EN, PDM_CLK_EN); in rockchip_pdm_hw_params()
266 if (pdm->version != RK_PDM_RK3229) in rockchip_pdm_hw_params()
267 regmap_update_bits(pdm->regmap, PDM_CTRL0, in rockchip_pdm_hw_params()
288 return -EINVAL; in rockchip_pdm_hw_params()
305 dev_err(pdm->dev, "invalid channel: %d\n", in rockchip_pdm_hw_params()
307 return -EINVAL; in rockchip_pdm_hw_params()
310 regmap_update_bits(pdm->regmap, PDM_CTRL0, in rockchip_pdm_hw_params()
314 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, PDM_DMA_RDL_MSK, in rockchip_pdm_hw_params()
321 unsigned int fmt) in rockchip_pdm_set_fmt() argument
323 struct rk_pdm_dev *pdm = to_info(cpu_dai); in rockchip_pdm_set_fmt() local
327 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { in rockchip_pdm_set_fmt()
335 return -EINVAL; in rockchip_pdm_set_fmt()
338 pm_runtime_get_sync(cpu_dai->dev); in rockchip_pdm_set_fmt()
339 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val); in rockchip_pdm_set_fmt()
340 pm_runtime_put(cpu_dai->dev); in rockchip_pdm_set_fmt()
348 struct rk_pdm_dev *pdm = to_info(dai); in rockchip_pdm_trigger() local
355 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in rockchip_pdm_trigger()
356 rockchip_pdm_rxctrl(pdm, 1); in rockchip_pdm_trigger()
361 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in rockchip_pdm_trigger()
362 rockchip_pdm_rxctrl(pdm, 0); in rockchip_pdm_trigger()
365 ret = -EINVAL; in rockchip_pdm_trigger()
374 struct rk_pdm_dev *pdm = to_info(dai); in rockchip_pdm_dai_probe() local
376 snd_soc_dai_dma_data_set_capture(dai, &pdm->capture_dma_data); in rockchip_pdm_dai_probe()
407 .name = "rockchip-pdm",
413 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); in rockchip_pdm_runtime_suspend() local
415 clk_disable_unprepare(pdm->clk); in rockchip_pdm_runtime_suspend()
416 clk_disable_unprepare(pdm->hclk); in rockchip_pdm_runtime_suspend()
423 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); in rockchip_pdm_runtime_resume() local
426 ret = clk_prepare_enable(pdm->clk); in rockchip_pdm_runtime_resume()
428 dev_err(pdm->dev, "clock enable failed %d\n", ret); in rockchip_pdm_runtime_resume()
432 ret = clk_prepare_enable(pdm->hclk); in rockchip_pdm_runtime_resume()
434 clk_disable_unprepare(pdm->clk); in rockchip_pdm_runtime_resume()
435 dev_err(pdm->dev, "hclock enable failed %d\n", ret); in rockchip_pdm_runtime_resume()
529 { .compatible = "rockchip,pdm",
531 { .compatible = "rockchip,px30-pdm",
533 { .compatible = "rockchip,rk1808-pdm",
535 { .compatible = "rockchip,rk3308-pdm",
537 { .compatible = "rockchip,rk3568-pdm",
539 { .compatible = "rockchip,rv1126-pdm",
545 static int rockchip_pdm_path_parse(struct rk_pdm_dev *pdm, struct device_node *node) in rockchip_pdm_path_parse() argument
550 cnt = of_count_phandle_with_args(node, "rockchip,path-map", in rockchip_pdm_path_parse()
555 ret = of_property_read_u32_array(node, "rockchip,path-map", in rockchip_pdm_path_parse()
562 return -EINVAL; in rockchip_pdm_path_parse()
567 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, msk, val); in rockchip_pdm_path_parse()
574 struct device_node *node = pdev->dev.of_node; in rockchip_pdm_probe()
576 struct rk_pdm_dev *pdm; in rockchip_pdm_probe() local
581 pdm = devm_kzalloc(&pdev->dev, sizeof(*pdm), GFP_KERNEL); in rockchip_pdm_probe()
582 if (!pdm) in rockchip_pdm_probe()
583 return -ENOMEM; in rockchip_pdm_probe()
585 match = of_match_device(rockchip_pdm_match, &pdev->dev); in rockchip_pdm_probe()
587 pdm->version = (uintptr_t)match->data; in rockchip_pdm_probe()
589 if (pdm->version == RK_PDM_RK3308) { in rockchip_pdm_probe()
590 pdm->reset = devm_reset_control_get(&pdev->dev, "pdm-m"); in rockchip_pdm_probe()
591 if (IS_ERR(pdm->reset)) in rockchip_pdm_probe()
592 return PTR_ERR(pdm->reset); in rockchip_pdm_probe()
599 pdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs, in rockchip_pdm_probe()
601 if (IS_ERR(pdm->regmap)) in rockchip_pdm_probe()
602 return PTR_ERR(pdm->regmap); in rockchip_pdm_probe()
604 pdm->capture_dma_data.addr = res->start + PDM_RXFIFO_DATA; in rockchip_pdm_probe()
605 pdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; in rockchip_pdm_probe()
606 pdm->capture_dma_data.maxburst = PDM_DMA_BURST_SIZE; in rockchip_pdm_probe()
608 pdm->dev = &pdev->dev; in rockchip_pdm_probe()
609 dev_set_drvdata(&pdev->dev, pdm); in rockchip_pdm_probe()
611 pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk"); in rockchip_pdm_probe()
612 if (IS_ERR(pdm->clk)) in rockchip_pdm_probe()
613 return PTR_ERR(pdm->clk); in rockchip_pdm_probe()
615 pdm->hclk = devm_clk_get(&pdev->dev, "pdm_hclk"); in rockchip_pdm_probe()
616 if (IS_ERR(pdm->hclk)) in rockchip_pdm_probe()
617 return PTR_ERR(pdm->hclk); in rockchip_pdm_probe()
619 ret = clk_prepare_enable(pdm->hclk); in rockchip_pdm_probe()
623 pm_runtime_enable(&pdev->dev); in rockchip_pdm_probe()
624 if (!pm_runtime_enabled(&pdev->dev)) { in rockchip_pdm_probe()
625 ret = rockchip_pdm_runtime_resume(&pdev->dev); in rockchip_pdm_probe()
630 ret = devm_snd_soc_register_component(&pdev->dev, in rockchip_pdm_probe()
635 dev_err(&pdev->dev, "could not register dai: %d\n", ret); in rockchip_pdm_probe()
639 rockchip_pdm_rxctrl(pdm, 0); in rockchip_pdm_probe()
641 ret = rockchip_pdm_path_parse(pdm, node); in rockchip_pdm_probe()
642 if (ret != 0 && ret != -ENOENT) in rockchip_pdm_probe()
645 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); in rockchip_pdm_probe()
647 dev_err(&pdev->dev, "could not register pcm: %d\n", ret); in rockchip_pdm_probe()
654 if (!pm_runtime_status_suspended(&pdev->dev)) in rockchip_pdm_probe()
655 rockchip_pdm_runtime_suspend(&pdev->dev); in rockchip_pdm_probe()
657 pm_runtime_disable(&pdev->dev); in rockchip_pdm_probe()
659 clk_disable_unprepare(pdm->hclk); in rockchip_pdm_probe()
666 struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev); in rockchip_pdm_remove() local
668 pm_runtime_disable(&pdev->dev); in rockchip_pdm_remove()
669 if (!pm_runtime_status_suspended(&pdev->dev)) in rockchip_pdm_remove()
670 rockchip_pdm_runtime_suspend(&pdev->dev); in rockchip_pdm_remove()
672 clk_disable_unprepare(pdm->clk); in rockchip_pdm_remove()
673 clk_disable_unprepare(pdm->hclk); in rockchip_pdm_remove()
679 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); in rockchip_pdm_suspend() local
681 regcache_mark_dirty(pdm->regmap); in rockchip_pdm_suspend()
688 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); in rockchip_pdm_resume() local
695 ret = regcache_sync(pdm->regmap); in rockchip_pdm_resume()
713 .name = "rockchip-pdm",
721 MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>");
722 MODULE_DESCRIPTION("Rockchip PDM Controller Driver");