1 // SPDX-License-Identifier: GPL-2.0-only
3 * Rockchip PDM ALSA SoC Digital Audio Interface(DAI) driver
5 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
8 #include <linux/module.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/rational.h>
13 #include <linux/regmap.h>
14 #include <linux/reset.h>
15 #include <sound/dmaengine_pcm.h>
16 #include <sound/pcm_params.h>
18 #include "rockchip_pdm.h"
20 #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */
21 #define PDM_SIGNOFF_CLK_RATE (100000000)
22 #define PDM_PATH_MAX (4)
34 struct regmap
*regmap
;
35 struct snd_dmaengine_dai_dma_data capture_dma_data
;
36 struct reset_control
*reset
;
37 enum rk_pdm_version version
;
40 struct rk_pdm_clkref
{
46 struct rk_pdm_ds_ratio
{
51 static struct rk_pdm_clkref clkref
[] = {
52 { 8000, 40960000, 2048000 },
53 { 11025, 56448000, 2822400 },
54 { 12000, 61440000, 3072000 },
55 { 8000, 98304000, 2048000 },
56 { 12000, 98304000, 3072000 },
59 static struct rk_pdm_ds_ratio ds_ratio
[] = {
77 static unsigned int get_pdm_clk(struct rk_pdm_dev
*pdm
, unsigned int sr
,
78 unsigned int *clk_src
, unsigned int *clk_out
)
80 unsigned int i
, count
, clk
, div
, rate
;
86 count
= ARRAY_SIZE(clkref
);
87 for (i
= 0; i
< count
; i
++) {
88 if (sr
% clkref
[i
].sr
)
90 div
= sr
/ clkref
[i
].sr
;
91 if ((div
& (div
- 1)) == 0) {
92 *clk_out
= clkref
[i
].clk_out
;
93 rate
= clk_round_rate(pdm
->clk
, clkref
[i
].clk
);
94 if (rate
!= clkref
[i
].clk
)
97 *clk_src
= clkref
[i
].clk
;
103 clk
= clk_round_rate(pdm
->clk
, PDM_SIGNOFF_CLK_RATE
);
109 static unsigned int get_pdm_ds_ratio(unsigned int sr
)
111 unsigned int i
, count
, ratio
;
117 count
= ARRAY_SIZE(ds_ratio
);
118 for (i
= 0; i
< count
; i
++) {
119 if (sr
== ds_ratio
[i
].sr
)
120 ratio
= ds_ratio
[i
].ratio
;
125 static unsigned int get_pdm_cic_ratio(unsigned int clk
)
145 static unsigned int samplerate_to_bit(unsigned int samplerate
)
147 switch (samplerate
) {
174 static inline struct rk_pdm_dev
*to_info(struct snd_soc_dai
*dai
)
176 return snd_soc_dai_get_drvdata(dai
);
179 static void rockchip_pdm_rxctrl(struct rk_pdm_dev
*pdm
, int on
)
182 regmap_update_bits(pdm
->regmap
, PDM_DMA_CTRL
,
183 PDM_DMA_RD_MSK
, PDM_DMA_RD_EN
);
184 regmap_update_bits(pdm
->regmap
, PDM_SYSCONFIG
,
185 PDM_RX_MASK
, PDM_RX_START
);
187 regmap_update_bits(pdm
->regmap
, PDM_DMA_CTRL
,
188 PDM_DMA_RD_MSK
, PDM_DMA_RD_DIS
);
189 regmap_update_bits(pdm
->regmap
, PDM_SYSCONFIG
,
190 PDM_RX_MASK
| PDM_RX_CLR_MASK
,
191 PDM_RX_STOP
| PDM_RX_CLR_WR
);
195 static int rockchip_pdm_hw_params(struct snd_pcm_substream
*substream
,
196 struct snd_pcm_hw_params
*params
,
197 struct snd_soc_dai
*dai
)
199 struct rk_pdm_dev
*pdm
= to_info(dai
);
200 unsigned int val
= 0;
201 unsigned int clk_rate
, clk_div
, samplerate
;
202 unsigned int clk_src
, clk_out
= 0;
207 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
210 samplerate
= params_rate(params
);
211 clk_rate
= get_pdm_clk(pdm
, samplerate
, &clk_src
, &clk_out
);
215 ret
= clk_set_rate(pdm
->clk
, clk_src
);
219 if (pdm
->version
== RK_PDM_RK3308
||
220 pdm
->version
== RK_PDM_RV1126
) {
221 rational_best_approximation(clk_out
, clk_src
,
226 val
= (m
<< PDM_FD_NUMERATOR_SFT
) |
227 (n
<< PDM_FD_DENOMINATOR_SFT
);
228 regmap_update_bits_check(pdm
->regmap
, PDM_CTRL1
,
229 PDM_FD_NUMERATOR_MSK
|
230 PDM_FD_DENOMINATOR_MSK
,
233 reset_control_assert(pdm
->reset
);
234 reset_control_deassert(pdm
->reset
);
235 rockchip_pdm_rxctrl(pdm
, 0);
239 val
= PDM_CLK_FD_RATIO_40
;
240 else if (clk_div
<= 35)
241 val
= PDM_CLK_FD_RATIO_35
;
244 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
,
245 PDM_CLK_FD_RATIO_MSK
,
249 if (pdm
->version
== RK_PDM_RV1126
) {
250 val
= get_pdm_cic_ratio(clk_out
);
251 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
, PDM_CIC_RATIO_MSK
, val
);
252 val
= samplerate_to_bit(samplerate
);
253 regmap_update_bits(pdm
->regmap
, PDM_CTRL0
,
254 PDM_SAMPLERATE_MSK
, PDM_SAMPLERATE(val
));
256 val
= get_pdm_ds_ratio(samplerate
);
257 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
, PDM_DS_RATIO_MSK
, val
);
260 regmap_update_bits(pdm
->regmap
, PDM_HPF_CTRL
,
261 PDM_HPF_CF_MSK
, PDM_HPF_60HZ
);
262 regmap_update_bits(pdm
->regmap
, PDM_HPF_CTRL
,
263 PDM_HPF_LE
| PDM_HPF_RE
, PDM_HPF_LE
| PDM_HPF_RE
);
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
,
267 PDM_MODE_MSK
, PDM_MODE_LJ
);
270 switch (params_format(params
)) {
271 case SNDRV_PCM_FORMAT_S8
:
274 case SNDRV_PCM_FORMAT_S16_LE
:
277 case SNDRV_PCM_FORMAT_S20_3LE
:
280 case SNDRV_PCM_FORMAT_S24_LE
:
283 case SNDRV_PCM_FORMAT_S32_LE
:
290 switch (params_channels(params
)) {
304 dev_err(pdm
->dev
, "invalid channel: %d\n",
305 params_channels(params
));
309 regmap_update_bits(pdm
->regmap
, PDM_CTRL0
,
310 PDM_PATH_MSK
| PDM_VDW_MSK
,
312 /* all channels share the single FIFO */
313 regmap_update_bits(pdm
->regmap
, PDM_DMA_CTRL
, PDM_DMA_RDL_MSK
,
314 PDM_DMA_RDL(8 * params_channels(params
)));
319 static int rockchip_pdm_set_fmt(struct snd_soc_dai
*cpu_dai
,
322 struct rk_pdm_dev
*pdm
= to_info(cpu_dai
);
323 unsigned int mask
= 0, val
= 0;
326 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
327 case SND_SOC_DAIFMT_NB_NF
:
328 val
= PDM_CKP_NORMAL
;
330 case SND_SOC_DAIFMT_IB_NF
:
331 val
= PDM_CKP_INVERTED
;
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
);
344 static int rockchip_pdm_trigger(struct snd_pcm_substream
*substream
, int cmd
,
345 struct snd_soc_dai
*dai
)
347 struct rk_pdm_dev
*pdm
= to_info(dai
);
351 case SNDRV_PCM_TRIGGER_START
:
352 case SNDRV_PCM_TRIGGER_RESUME
:
353 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
354 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
355 rockchip_pdm_rxctrl(pdm
, 1);
357 case SNDRV_PCM_TRIGGER_SUSPEND
:
358 case SNDRV_PCM_TRIGGER_STOP
:
359 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
360 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
361 rockchip_pdm_rxctrl(pdm
, 0);
371 static int rockchip_pdm_dai_probe(struct snd_soc_dai
*dai
)
373 struct rk_pdm_dev
*pdm
= to_info(dai
);
375 snd_soc_dai_dma_data_set_capture(dai
, &pdm
->capture_dma_data
);
380 static const struct snd_soc_dai_ops rockchip_pdm_dai_ops
= {
381 .probe
= rockchip_pdm_dai_probe
,
382 .set_fmt
= rockchip_pdm_set_fmt
,
383 .trigger
= rockchip_pdm_trigger
,
384 .hw_params
= rockchip_pdm_hw_params
,
387 #define ROCKCHIP_PDM_RATES SNDRV_PCM_RATE_8000_192000
388 #define ROCKCHIP_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
389 SNDRV_PCM_FMTBIT_S20_3LE | \
390 SNDRV_PCM_FMTBIT_S24_LE | \
391 SNDRV_PCM_FMTBIT_S32_LE)
393 static struct snd_soc_dai_driver rockchip_pdm_dai
= {
395 .stream_name
= "Capture",
398 .rates
= ROCKCHIP_PDM_RATES
,
399 .formats
= ROCKCHIP_PDM_FORMATS
,
401 .ops
= &rockchip_pdm_dai_ops
,
405 static const struct snd_soc_component_driver rockchip_pdm_component
= {
406 .name
= "rockchip-pdm",
407 .legacy_dai_naming
= 1,
410 static int rockchip_pdm_runtime_suspend(struct device
*dev
)
412 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
414 clk_disable_unprepare(pdm
->clk
);
415 clk_disable_unprepare(pdm
->hclk
);
420 static int rockchip_pdm_runtime_resume(struct device
*dev
)
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
);
441 static bool rockchip_pdm_wr_reg(struct device
*dev
, unsigned int reg
)
460 static bool rockchip_pdm_rd_reg(struct device
*dev
, unsigned int reg
)
474 case PDM_RXFIFO_DATA
:
482 static bool rockchip_pdm_volatile_reg(struct device
*dev
, unsigned int reg
)
489 case PDM_RXFIFO_DATA
:
496 static bool rockchip_pdm_precious_reg(struct device
*dev
, unsigned int reg
)
499 case PDM_RXFIFO_DATA
:
506 static const struct reg_default rockchip_pdm_reg_defaults
[] = {
507 { PDM_CTRL0
, 0x78000017 },
508 { PDM_CTRL1
, 0x0bb8ea60 },
509 { PDM_CLK_CTRL
, 0x0000e401 },
510 { PDM_DMA_CTRL
, 0x0000001f },
513 static const struct regmap_config rockchip_pdm_regmap_config
= {
517 .max_register
= PDM_VERSION
,
518 .reg_defaults
= rockchip_pdm_reg_defaults
,
519 .num_reg_defaults
= ARRAY_SIZE(rockchip_pdm_reg_defaults
),
520 .writeable_reg
= rockchip_pdm_wr_reg
,
521 .readable_reg
= rockchip_pdm_rd_reg
,
522 .volatile_reg
= rockchip_pdm_volatile_reg
,
523 .precious_reg
= rockchip_pdm_precious_reg
,
524 .cache_type
= REGCACHE_FLAT
,
527 static const struct of_device_id rockchip_pdm_match
[] __maybe_unused
= {
528 { .compatible
= "rockchip,pdm",
529 .data
= (void *)RK_PDM_RK3229
},
530 { .compatible
= "rockchip,px30-pdm",
531 .data
= (void *)RK_PDM_RK3308
},
532 { .compatible
= "rockchip,rk1808-pdm",
533 .data
= (void *)RK_PDM_RK3308
},
534 { .compatible
= "rockchip,rk3308-pdm",
535 .data
= (void *)RK_PDM_RK3308
},
536 { .compatible
= "rockchip,rk3568-pdm",
537 .data
= (void *)RK_PDM_RV1126
},
538 { .compatible
= "rockchip,rv1126-pdm",
539 .data
= (void *)RK_PDM_RV1126
},
542 MODULE_DEVICE_TABLE(of
, rockchip_pdm_match
);
544 static int rockchip_pdm_path_parse(struct rk_pdm_dev
*pdm
, struct device_node
*node
)
546 unsigned int path
[PDM_PATH_MAX
];
547 int cnt
= 0, ret
= 0, i
= 0, val
= 0, msk
= 0;
549 cnt
= of_count_phandle_with_args(node
, "rockchip,path-map",
551 if (cnt
!= PDM_PATH_MAX
)
554 ret
= of_property_read_u32_array(node
, "rockchip,path-map",
559 for (i
= 0; i
< cnt
; i
++) {
560 if (path
[i
] >= PDM_PATH_MAX
)
562 msk
|= PDM_PATH_MASK(i
);
563 val
|= PDM_PATH(i
, path
[i
]);
566 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
, msk
, val
);
571 static int rockchip_pdm_probe(struct platform_device
*pdev
)
573 struct device_node
*node
= pdev
->dev
.of_node
;
574 struct rk_pdm_dev
*pdm
;
575 struct resource
*res
;
579 pdm
= devm_kzalloc(&pdev
->dev
, sizeof(*pdm
), GFP_KERNEL
);
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
);
590 regs
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res
);
592 return PTR_ERR(regs
);
594 pdm
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, regs
,
595 &rockchip_pdm_regmap_config
);
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
,
626 &rockchip_pdm_component
,
627 &rockchip_pdm_dai
, 1);
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
);
659 static void rockchip_pdm_remove(struct platform_device
*pdev
)
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
);
671 #ifdef CONFIG_PM_SLEEP
672 static int rockchip_pdm_suspend(struct device
*dev
)
674 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
676 regcache_mark_dirty(pdm
->regmap
);
681 static int rockchip_pdm_resume(struct device
*dev
)
683 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
686 ret
= pm_runtime_resume_and_get(dev
);
690 ret
= regcache_sync(pdm
->regmap
);
698 static const struct dev_pm_ops rockchip_pdm_pm_ops
= {
699 SET_RUNTIME_PM_OPS(rockchip_pdm_runtime_suspend
,
700 rockchip_pdm_runtime_resume
, NULL
)
701 SET_SYSTEM_SLEEP_PM_OPS(rockchip_pdm_suspend
, rockchip_pdm_resume
)
704 static struct platform_driver rockchip_pdm_driver
= {
705 .probe
= rockchip_pdm_probe
,
706 .remove
= rockchip_pdm_remove
,
708 .name
= "rockchip-pdm",
709 .of_match_table
= of_match_ptr(rockchip_pdm_match
),
710 .pm
= &rockchip_pdm_pm_ops
,
714 module_platform_driver(rockchip_pdm_driver
);
716 MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>");
717 MODULE_DESCRIPTION("Rockchip PDM Controller Driver");
718 MODULE_LICENSE("GPL v2");