Lines Matching +full:pdm +full:- +full:clk +full:- +full:map

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Rockchip PDM ALSA SoC Digital Audio Interface(DAI) driver
9 #include <linux/clk.h>
32 struct clk *clk;
33 struct clk *hclk;
42 unsigned int clk;
77 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
80 unsigned int i, count, clk, div, rate;
82 clk = 0;
84 return clk;
91 if ((div & (div - 1)) == 0) {
93 rate = clk_round_rate(pdm->clk, clkref[i].clk);
94 if (rate != clkref[i].clk)
96 clk = clkref[i].clk;
97 *clk_src = clkref[i].clk;
102 if (!clk) {
103 clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE);
104 *clk_src = clk;
106 return clk;
125 static unsigned int get_pdm_cic_ratio(unsigned int clk)
127 switch (clk) {
179 static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on)
182 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
184 regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
187 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
189 regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
199 struct rk_pdm_dev *pdm = to_info(dai);
207 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
211 clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out);
213 return -EINVAL;
215 ret = clk_set_rate(pdm->clk, clk_src);
217 return -EINVAL;
219 if (pdm->version == RK_PDM_RK3308 ||
220 pdm->version == RK_PDM_RV1126) {
222 GENMASK(16 - 1, 0),
223 GENMASK(16 - 1, 0),
228 regmap_update_bits_check(pdm->regmap, PDM_CTRL1,
233 reset_control_assert(pdm->reset);
234 reset_control_deassert(pdm->reset);
235 rockchip_pdm_rxctrl(pdm, 0);
243 return -EINVAL;
244 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL,
249 if (pdm->version == RK_PDM_RV1126) {
251 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
253 regmap_update_bits(pdm->regmap, PDM_CTRL0,
257 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
260 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
262 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
264 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CLK_EN, PDM_CLK_EN);
265 if (pdm->version != RK_PDM_RK3229)
266 regmap_update_bits(pdm->regmap, PDM_CTRL0,
287 return -EINVAL;
304 dev_err(pdm->dev, "invalid channel: %d\n",
306 return -EINVAL;
309 regmap_update_bits(pdm->regmap, PDM_CTRL0,
313 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, PDM_DMA_RDL_MSK,
322 struct rk_pdm_dev *pdm = to_info(cpu_dai);
334 return -EINVAL;
337 pm_runtime_get_sync(cpu_dai->dev);
338 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val);
339 pm_runtime_put(cpu_dai->dev);
347 struct rk_pdm_dev *pdm = to_info(dai);
354 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
355 rockchip_pdm_rxctrl(pdm, 1);
360 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
361 rockchip_pdm_rxctrl(pdm, 0);
364 ret = -EINVAL;
373 struct rk_pdm_dev *pdm = to_info(dai);
375 snd_soc_dai_dma_data_set_capture(dai, &pdm->capture_dma_data);
406 .name = "rockchip-pdm",
412 struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
414 clk_disable_unprepare(pdm->clk);
415 clk_disable_unprepare(pdm->hclk);
422 struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
425 ret = clk_prepare_enable(pdm->clk);
427 dev_err(pdm->dev, "clock enable failed %d\n", ret);
431 ret = clk_prepare_enable(pdm->hclk);
433 clk_disable_unprepare(pdm->clk);
434 dev_err(pdm->dev, "hclock enable failed %d\n", ret);
528 { .compatible = "rockchip,pdm",
530 { .compatible = "rockchip,px30-pdm",
532 { .compatible = "rockchip,rk1808-pdm",
534 { .compatible = "rockchip,rk3308-pdm",
536 { .compatible = "rockchip,rk3568-pdm",
538 { .compatible = "rockchip,rv1126-pdm",
544 static int rockchip_pdm_path_parse(struct rk_pdm_dev *pdm, struct device_node *node)
549 cnt = of_count_phandle_with_args(node, "rockchip,path-map",
554 ret = of_property_read_u32_array(node, "rockchip,path-map",
561 return -EINVAL;
566 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, msk, val);
573 struct device_node *node = pdev->dev.of_node;
574 struct rk_pdm_dev *pdm;
579 pdm = devm_kzalloc(&pdev->dev, sizeof(*pdm), GFP_KERNEL);
580 if (!pdm)
581 return -ENOMEM;
583 pdm->version = (enum rk_pdm_version)device_get_match_data(&pdev->dev);
584 if (pdm->version == RK_PDM_RK3308) {
585 pdm->reset = devm_reset_control_get(&pdev->dev, "pdm-m");
586 if (IS_ERR(pdm->reset))
587 return PTR_ERR(pdm->reset);
594 pdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
596 if (IS_ERR(pdm->regmap))
597 return PTR_ERR(pdm->regmap);
599 pdm->capture_dma_data.addr = res->start + PDM_RXFIFO_DATA;
600 pdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
601 pdm->capture_dma_data.maxburst = PDM_DMA_BURST_SIZE;
603 pdm->dev = &pdev->dev;
604 dev_set_drvdata(&pdev->dev, pdm);
606 pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
607 if (IS_ERR(pdm->clk))
608 return PTR_ERR(pdm->clk);
610 pdm->hclk = devm_clk_get(&pdev->dev, "pdm_hclk");
611 if (IS_ERR(pdm->hclk))
612 return PTR_ERR(pdm->hclk);
614 ret = clk_prepare_enable(pdm->hclk);
618 pm_runtime_enable(&pdev->dev);
619 if (!pm_runtime_enabled(&pdev->dev)) {
620 ret = rockchip_pdm_runtime_resume(&pdev->dev);
625 ret = devm_snd_soc_register_component(&pdev->dev,
630 dev_err(&pdev->dev, "could not register dai: %d\n", ret);
634 rockchip_pdm_rxctrl(pdm, 0);
636 ret = rockchip_pdm_path_parse(pdm, node);
637 if (ret != 0 && ret != -ENOENT)
640 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
642 dev_err(&pdev->dev, "could not register pcm: %d\n", ret);
649 if (!pm_runtime_status_suspended(&pdev->dev))
650 rockchip_pdm_runtime_suspend(&pdev->dev);
652 pm_runtime_disable(&pdev->dev);
654 clk_disable_unprepare(pdm->hclk);
661 struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev);
663 pm_runtime_disable(&pdev->dev);
664 if (!pm_runtime_status_suspended(&pdev->dev))
665 rockchip_pdm_runtime_suspend(&pdev->dev);
667 clk_disable_unprepare(pdm->clk);
668 clk_disable_unprepare(pdm->hclk);
673 struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
675 regcache_mark_dirty(pdm->regmap);
682 struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
689 ret = regcache_sync(pdm->regmap);
706 .name = "rockchip-pdm",
714 MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>");
715 MODULE_DESCRIPTION("Rockchip PDM Controller Driver");