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/of_device.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/rational.h>
14 #include <linux/regmap.h>
15 #include <linux/reset.h>
16 #include <sound/dmaengine_pcm.h>
17 #include <sound/pcm_params.h>
19 #include "rockchip_pdm.h"
21 #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */
22 #define PDM_SIGNOFF_CLK_RATE (100000000)
33 struct regmap
*regmap
;
34 struct snd_dmaengine_dai_dma_data capture_dma_data
;
35 struct reset_control
*reset
;
36 enum rk_pdm_version version
;
39 struct rk_pdm_clkref
{
45 struct rk_pdm_ds_ratio
{
50 static struct rk_pdm_clkref clkref
[] = {
51 { 8000, 40960000, 2048000 },
52 { 11025, 56448000, 2822400 },
53 { 12000, 61440000, 3072000 },
54 { 8000, 98304000, 2048000 },
55 { 12000, 98304000, 3072000 },
58 static struct rk_pdm_ds_ratio ds_ratio
[] = {
76 static unsigned int get_pdm_clk(struct rk_pdm_dev
*pdm
, unsigned int sr
,
77 unsigned int *clk_src
, unsigned int *clk_out
)
79 unsigned int i
, count
, clk
, div
, rate
;
85 count
= ARRAY_SIZE(clkref
);
86 for (i
= 0; i
< count
; i
++) {
87 if (sr
% clkref
[i
].sr
)
89 div
= sr
/ clkref
[i
].sr
;
90 if ((div
& (div
- 1)) == 0) {
91 *clk_out
= clkref
[i
].clk_out
;
92 rate
= clk_round_rate(pdm
->clk
, clkref
[i
].clk
);
93 if (rate
!= clkref
[i
].clk
)
96 *clk_src
= clkref
[i
].clk
;
102 clk
= clk_round_rate(pdm
->clk
, PDM_SIGNOFF_CLK_RATE
);
108 static unsigned int get_pdm_ds_ratio(unsigned int sr
)
110 unsigned int i
, count
, ratio
;
116 count
= ARRAY_SIZE(ds_ratio
);
117 for (i
= 0; i
< count
; i
++) {
118 if (sr
== ds_ratio
[i
].sr
)
119 ratio
= ds_ratio
[i
].ratio
;
124 static inline struct rk_pdm_dev
*to_info(struct snd_soc_dai
*dai
)
126 return snd_soc_dai_get_drvdata(dai
);
129 static void rockchip_pdm_rxctrl(struct rk_pdm_dev
*pdm
, int on
)
132 regmap_update_bits(pdm
->regmap
, PDM_DMA_CTRL
,
133 PDM_DMA_RD_MSK
, PDM_DMA_RD_EN
);
134 regmap_update_bits(pdm
->regmap
, PDM_SYSCONFIG
,
135 PDM_RX_MASK
, PDM_RX_START
);
137 regmap_update_bits(pdm
->regmap
, PDM_DMA_CTRL
,
138 PDM_DMA_RD_MSK
, PDM_DMA_RD_DIS
);
139 regmap_update_bits(pdm
->regmap
, PDM_SYSCONFIG
,
140 PDM_RX_MASK
| PDM_RX_CLR_MASK
,
141 PDM_RX_STOP
| PDM_RX_CLR_WR
);
145 static int rockchip_pdm_hw_params(struct snd_pcm_substream
*substream
,
146 struct snd_pcm_hw_params
*params
,
147 struct snd_soc_dai
*dai
)
149 struct rk_pdm_dev
*pdm
= to_info(dai
);
150 unsigned int val
= 0;
151 unsigned int clk_rate
, clk_div
, samplerate
;
152 unsigned int clk_src
, clk_out
= 0;
157 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
160 samplerate
= params_rate(params
);
161 clk_rate
= get_pdm_clk(pdm
, samplerate
, &clk_src
, &clk_out
);
165 ret
= clk_set_rate(pdm
->clk
, clk_src
);
169 if (pdm
->version
== RK_PDM_RK3308
) {
170 rational_best_approximation(clk_out
, clk_src
,
175 val
= (m
<< PDM_FD_NUMERATOR_SFT
) |
176 (n
<< PDM_FD_DENOMINATOR_SFT
);
177 regmap_update_bits_check(pdm
->regmap
, PDM_CTRL1
,
178 PDM_FD_NUMERATOR_MSK
|
179 PDM_FD_DENOMINATOR_MSK
,
182 reset_control_assert(pdm
->reset
);
183 reset_control_deassert(pdm
->reset
);
184 rockchip_pdm_rxctrl(pdm
, 0);
188 val
= PDM_CLK_FD_RATIO_40
;
189 else if (clk_div
<= 35)
190 val
= PDM_CLK_FD_RATIO_35
;
193 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
,
194 PDM_CLK_FD_RATIO_MSK
,
197 val
= get_pdm_ds_ratio(samplerate
);
198 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
, PDM_DS_RATIO_MSK
, val
);
199 regmap_update_bits(pdm
->regmap
, PDM_HPF_CTRL
,
200 PDM_HPF_CF_MSK
, PDM_HPF_60HZ
);
201 regmap_update_bits(pdm
->regmap
, PDM_HPF_CTRL
,
202 PDM_HPF_LE
| PDM_HPF_RE
, PDM_HPF_LE
| PDM_HPF_RE
);
203 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
, PDM_CLK_EN
, PDM_CLK_EN
);
204 if (pdm
->version
!= RK_PDM_RK3229
)
205 regmap_update_bits(pdm
->regmap
, PDM_CTRL0
,
206 PDM_MODE_MSK
, PDM_MODE_LJ
);
209 switch (params_format(params
)) {
210 case SNDRV_PCM_FORMAT_S8
:
213 case SNDRV_PCM_FORMAT_S16_LE
:
216 case SNDRV_PCM_FORMAT_S20_3LE
:
219 case SNDRV_PCM_FORMAT_S24_LE
:
222 case SNDRV_PCM_FORMAT_S32_LE
:
229 switch (params_channels(params
)) {
243 dev_err(pdm
->dev
, "invalid channel: %d\n",
244 params_channels(params
));
248 regmap_update_bits(pdm
->regmap
, PDM_CTRL0
,
249 PDM_PATH_MSK
| PDM_VDW_MSK
,
251 /* all channels share the single FIFO */
252 regmap_update_bits(pdm
->regmap
, PDM_DMA_CTRL
, PDM_DMA_RDL_MSK
,
253 PDM_DMA_RDL(8 * params_channels(params
)));
258 static int rockchip_pdm_set_fmt(struct snd_soc_dai
*cpu_dai
,
261 struct rk_pdm_dev
*pdm
= to_info(cpu_dai
);
262 unsigned int mask
= 0, val
= 0;
265 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
266 case SND_SOC_DAIFMT_NB_NF
:
267 val
= PDM_CKP_NORMAL
;
269 case SND_SOC_DAIFMT_IB_NF
:
270 val
= PDM_CKP_INVERTED
;
276 pm_runtime_get_sync(cpu_dai
->dev
);
277 regmap_update_bits(pdm
->regmap
, PDM_CLK_CTRL
, mask
, val
);
278 pm_runtime_put(cpu_dai
->dev
);
283 static int rockchip_pdm_trigger(struct snd_pcm_substream
*substream
, int cmd
,
284 struct snd_soc_dai
*dai
)
286 struct rk_pdm_dev
*pdm
= to_info(dai
);
290 case SNDRV_PCM_TRIGGER_START
:
291 case SNDRV_PCM_TRIGGER_RESUME
:
292 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
293 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
294 rockchip_pdm_rxctrl(pdm
, 1);
296 case SNDRV_PCM_TRIGGER_SUSPEND
:
297 case SNDRV_PCM_TRIGGER_STOP
:
298 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
299 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
)
300 rockchip_pdm_rxctrl(pdm
, 0);
310 static int rockchip_pdm_dai_probe(struct snd_soc_dai
*dai
)
312 struct rk_pdm_dev
*pdm
= to_info(dai
);
314 dai
->capture_dma_data
= &pdm
->capture_dma_data
;
319 static const struct snd_soc_dai_ops rockchip_pdm_dai_ops
= {
320 .set_fmt
= rockchip_pdm_set_fmt
,
321 .trigger
= rockchip_pdm_trigger
,
322 .hw_params
= rockchip_pdm_hw_params
,
325 #define ROCKCHIP_PDM_RATES SNDRV_PCM_RATE_8000_192000
326 #define ROCKCHIP_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
327 SNDRV_PCM_FMTBIT_S20_3LE | \
328 SNDRV_PCM_FMTBIT_S24_LE | \
329 SNDRV_PCM_FMTBIT_S32_LE)
331 static struct snd_soc_dai_driver rockchip_pdm_dai
= {
332 .probe
= rockchip_pdm_dai_probe
,
334 .stream_name
= "Capture",
337 .rates
= ROCKCHIP_PDM_RATES
,
338 .formats
= ROCKCHIP_PDM_FORMATS
,
340 .ops
= &rockchip_pdm_dai_ops
,
341 .symmetric_rates
= 1,
344 static const struct snd_soc_component_driver rockchip_pdm_component
= {
345 .name
= "rockchip-pdm",
348 static int rockchip_pdm_runtime_suspend(struct device
*dev
)
350 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
352 clk_disable_unprepare(pdm
->clk
);
353 clk_disable_unprepare(pdm
->hclk
);
358 static int rockchip_pdm_runtime_resume(struct device
*dev
)
360 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
363 ret
= clk_prepare_enable(pdm
->clk
);
365 dev_err(pdm
->dev
, "clock enable failed %d\n", ret
);
369 ret
= clk_prepare_enable(pdm
->hclk
);
371 dev_err(pdm
->dev
, "hclock enable failed %d\n", ret
);
378 static bool rockchip_pdm_wr_reg(struct device
*dev
, unsigned int reg
)
397 static bool rockchip_pdm_rd_reg(struct device
*dev
, unsigned int reg
)
411 case PDM_RXFIFO_DATA
:
419 static bool rockchip_pdm_volatile_reg(struct device
*dev
, unsigned int reg
)
426 case PDM_RXFIFO_DATA
:
433 static bool rockchip_pdm_precious_reg(struct device
*dev
, unsigned int reg
)
436 case PDM_RXFIFO_DATA
:
443 static const struct reg_default rockchip_pdm_reg_defaults
[] = {
449 static const struct regmap_config rockchip_pdm_regmap_config
= {
453 .max_register
= PDM_VERSION
,
454 .reg_defaults
= rockchip_pdm_reg_defaults
,
455 .num_reg_defaults
= ARRAY_SIZE(rockchip_pdm_reg_defaults
),
456 .writeable_reg
= rockchip_pdm_wr_reg
,
457 .readable_reg
= rockchip_pdm_rd_reg
,
458 .volatile_reg
= rockchip_pdm_volatile_reg
,
459 .precious_reg
= rockchip_pdm_precious_reg
,
460 .cache_type
= REGCACHE_FLAT
,
463 static const struct of_device_id rockchip_pdm_match
[] __maybe_unused
= {
464 { .compatible
= "rockchip,pdm",
465 .data
= (void *)RK_PDM_RK3229
},
466 { .compatible
= "rockchip,px30-pdm",
467 .data
= (void *)RK_PDM_RK3308
},
468 { .compatible
= "rockchip,rk1808-pdm",
469 .data
= (void *)RK_PDM_RK3308
},
470 { .compatible
= "rockchip,rk3308-pdm",
471 .data
= (void *)RK_PDM_RK3308
},
474 MODULE_DEVICE_TABLE(of
, rockchip_pdm_match
);
476 static int rockchip_pdm_probe(struct platform_device
*pdev
)
478 const struct of_device_id
*match
;
479 struct rk_pdm_dev
*pdm
;
480 struct resource
*res
;
484 pdm
= devm_kzalloc(&pdev
->dev
, sizeof(*pdm
), GFP_KERNEL
);
488 match
= of_match_device(rockchip_pdm_match
, &pdev
->dev
);
490 pdm
->version
= (enum rk_pdm_version
)match
->data
;
492 if (pdm
->version
== RK_PDM_RK3308
) {
493 pdm
->reset
= devm_reset_control_get(&pdev
->dev
, "pdm-m");
494 if (IS_ERR(pdm
->reset
))
495 return PTR_ERR(pdm
->reset
);
498 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
499 regs
= devm_ioremap_resource(&pdev
->dev
, res
);
501 return PTR_ERR(regs
);
503 pdm
->regmap
= devm_regmap_init_mmio(&pdev
->dev
, regs
,
504 &rockchip_pdm_regmap_config
);
505 if (IS_ERR(pdm
->regmap
))
506 return PTR_ERR(pdm
->regmap
);
508 pdm
->capture_dma_data
.addr
= res
->start
+ PDM_RXFIFO_DATA
;
509 pdm
->capture_dma_data
.addr_width
= DMA_SLAVE_BUSWIDTH_4_BYTES
;
510 pdm
->capture_dma_data
.maxburst
= PDM_DMA_BURST_SIZE
;
512 pdm
->dev
= &pdev
->dev
;
513 dev_set_drvdata(&pdev
->dev
, pdm
);
515 pdm
->clk
= devm_clk_get(&pdev
->dev
, "pdm_clk");
516 if (IS_ERR(pdm
->clk
))
517 return PTR_ERR(pdm
->clk
);
519 pdm
->hclk
= devm_clk_get(&pdev
->dev
, "pdm_hclk");
520 if (IS_ERR(pdm
->hclk
))
521 return PTR_ERR(pdm
->hclk
);
523 ret
= clk_prepare_enable(pdm
->hclk
);
527 pm_runtime_enable(&pdev
->dev
);
528 if (!pm_runtime_enabled(&pdev
->dev
)) {
529 ret
= rockchip_pdm_runtime_resume(&pdev
->dev
);
534 ret
= devm_snd_soc_register_component(&pdev
->dev
,
535 &rockchip_pdm_component
,
536 &rockchip_pdm_dai
, 1);
539 dev_err(&pdev
->dev
, "could not register dai: %d\n", ret
);
543 rockchip_pdm_rxctrl(pdm
, 0);
544 ret
= devm_snd_dmaengine_pcm_register(&pdev
->dev
, NULL
, 0);
546 dev_err(&pdev
->dev
, "could not register pcm: %d\n", ret
);
553 if (!pm_runtime_status_suspended(&pdev
->dev
))
554 rockchip_pdm_runtime_suspend(&pdev
->dev
);
556 pm_runtime_disable(&pdev
->dev
);
558 clk_disable_unprepare(pdm
->hclk
);
563 static int rockchip_pdm_remove(struct platform_device
*pdev
)
565 struct rk_pdm_dev
*pdm
= dev_get_drvdata(&pdev
->dev
);
567 pm_runtime_disable(&pdev
->dev
);
568 if (!pm_runtime_status_suspended(&pdev
->dev
))
569 rockchip_pdm_runtime_suspend(&pdev
->dev
);
571 clk_disable_unprepare(pdm
->clk
);
572 clk_disable_unprepare(pdm
->hclk
);
577 #ifdef CONFIG_PM_SLEEP
578 static int rockchip_pdm_suspend(struct device
*dev
)
580 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
582 regcache_mark_dirty(pdm
->regmap
);
587 static int rockchip_pdm_resume(struct device
*dev
)
589 struct rk_pdm_dev
*pdm
= dev_get_drvdata(dev
);
592 ret
= pm_runtime_get_sync(dev
);
598 ret
= regcache_sync(pdm
->regmap
);
606 static const struct dev_pm_ops rockchip_pdm_pm_ops
= {
607 SET_RUNTIME_PM_OPS(rockchip_pdm_runtime_suspend
,
608 rockchip_pdm_runtime_resume
, NULL
)
609 SET_SYSTEM_SLEEP_PM_OPS(rockchip_pdm_suspend
, rockchip_pdm_resume
)
612 static struct platform_driver rockchip_pdm_driver
= {
613 .probe
= rockchip_pdm_probe
,
614 .remove
= rockchip_pdm_remove
,
616 .name
= "rockchip-pdm",
617 .of_match_table
= of_match_ptr(rockchip_pdm_match
),
618 .pm
= &rockchip_pdm_pm_ops
,
622 module_platform_driver(rockchip_pdm_driver
);
624 MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>");
625 MODULE_DESCRIPTION("Rockchip PDM Controller Driver");
626 MODULE_LICENSE("GPL v2");