1 // SPDX-License-Identifier: GPL-2.0
3 * PDM driver for the StarFive JH7110 SoC
5 * Copyright (C) 2021 StarFive Technology Co., Ltd.
8 #include <linux/device.h>
9 #include <linux/reset.h>
10 #include <linux/module.h>
11 #include <linux/of_irq.h>
12 #include <linux/of_platform.h>
13 #include <linux/regmap.h>
14 #include <linux/pm_runtime.h>
15 #include <sound/soc.h>
16 #include <sound/soc-dai.h>
17 #include <sound/pcm_params.h>
18 #include <sound/initval.h>
19 #include <sound/tlv.h>
20 #include "starfive_pdm.h"
23 struct regmap *pdm_map;
25 struct clk *clk_pdm_apb;
26 struct clk *clk_pdm_mclk;
29 struct clk *clk_mclk_ext;
30 struct reset_control *rst_pdm_dmic;
31 struct reset_control *rst_pdm_apb;
32 unsigned char flag_first;
35 static const DECLARE_TLV_DB_SCALE(volume_tlv, -9450, 150, 0);
37 static const struct snd_kcontrol_new sf_pdm_snd_controls[] = {
38 SOC_SINGLE("DC compensation Control", PDM_DMIC_CTRL0, 30, 1, 0),
39 SOC_SINGLE("High Pass Filter Control", PDM_DMIC_CTRL0, 28, 1, 0),
40 SOC_SINGLE("Left Channel Volume Control", PDM_DMIC_CTRL0, 23, 1, 0),
41 SOC_SINGLE("Right Channel Volume Control", PDM_DMIC_CTRL0, 22, 1, 0),
42 SOC_SINGLE_TLV("Volume", PDM_DMIC_CTRL0, 16, 0x3F, 1, volume_tlv),
43 SOC_SINGLE("Data MSB Shift", PDM_DMIC_CTRL0, 1, 7, 0),
44 SOC_SINGLE("SCALE", PDM_DC_SCALE0, 0, 0x3F, 0),
45 SOC_SINGLE("DC offset", PDM_DC_SCALE0, 8, 0xFFFFF, 0),
48 static void sf_pdm_enable(struct regmap *map)
50 /* Left and Right Channel Volume Control Enable */
51 regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_RVOL_MASK, 0);
52 regmap_update_bits(map, PDM_DMIC_CTRL0, PDM_DMIC_LVOL_MASK, 0);
55 static void sf_pdm_disable(struct regmap *map)
57 /* Left and Right Channel Volume Control Disable */
58 regmap_update_bits(map, PDM_DMIC_CTRL0,
59 PDM_DMIC_RVOL_MASK, PDM_DMIC_RVOL_MASK);
60 regmap_update_bits(map, PDM_DMIC_CTRL0,
61 PDM_DMIC_LVOL_MASK, PDM_DMIC_LVOL_MASK);
64 static int sf_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
65 struct snd_soc_dai *dai)
67 struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
70 case SNDRV_PCM_TRIGGER_START:
71 case SNDRV_PCM_TRIGGER_RESUME:
72 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
73 if (priv->flag_first) {
77 sf_pdm_enable(priv->pdm_map);
80 case SNDRV_PCM_TRIGGER_STOP:
81 case SNDRV_PCM_TRIGGER_SUSPEND:
82 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
83 sf_pdm_disable(priv->pdm_map);
91 static int sf_pdm_hw_params(struct snd_pcm_substream *substream,
92 struct snd_pcm_hw_params *params,
93 struct snd_soc_dai *dai)
95 struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
96 unsigned int sample_rate;
97 unsigned int data_width;
99 const int pdm_mul = 128;
101 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
104 sample_rate = params_rate(params);
105 switch (sample_rate) {
111 pr_err("PDM: not support sample rate:%d\n", sample_rate);
115 data_width = params_width(params);
116 switch (data_width) {
121 pr_err("PDM: not support bit width %d\n", data_width);
125 /* set pdm_mclk, PDM MCLK = 128 * LRCLK */
126 ret = clk_set_rate(priv->clk_pdm_mclk, pdm_mul * sample_rate);
128 dev_info(priv->dev, "Can't set pdm_mclk: %d\n", ret);
135 static const struct snd_soc_dai_ops sf_pdm_dai_ops = {
136 .trigger = sf_pdm_trigger,
137 .hw_params = sf_pdm_hw_params,
140 static int sf_pdm_dai_probe(struct snd_soc_dai *dai)
142 struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
145 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
146 PDM_SW_RST_MASK, 0x00);
147 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
148 PDM_SW_RST_MASK, PDM_SW_RST_RELEASE);
150 /* Make sure the device is initially disabled */
151 sf_pdm_disable(priv->pdm_map);
154 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
155 PDM_DMIC_VOL_MASK, PDM_VOL_DB_MUTE);
158 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
159 PDM_DMIC_VOL_MASK, PDM_VOL_DB_MAX);
161 /* enable high pass filter */
162 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
163 PDM_DMIC_HPF_EN, PDM_DMIC_HPF_EN);
166 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
167 PDM_DMIC_I2S_SLAVE, PDM_DMIC_I2S_SLAVE);
169 /* disable fast mode */
170 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
171 PDM_DMIC_FASTMODE_MASK, 0);
173 /* dmic msb shift 0 */
174 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
175 PDM_DMIC_MSB_MASK, 0);
178 regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
179 DMIC_SCALE_MASK, DMIC_SCALE_DEF_VAL);
181 regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
182 DMIC_DCOFF1_MASK, DMIC_DCOFF1_VAL);
184 regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
185 DMIC_DCOFF3_MASK, DMIC_DCOFF3_VAL);
188 regmap_update_bits(priv->pdm_map, PDM_DC_SCALE0,
189 DMIC_SCALE_MASK, DMIC_SCALE_MASK);
191 /* dmic msb shift 2 */
192 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
193 PDM_DMIC_MSB_MASK, PDM_MSB_SHIFT_4);
198 static int sf_pdm_dai_remove(struct snd_soc_dai *dai)
200 struct sf_pdm *priv = snd_soc_dai_get_drvdata(dai);
203 regmap_update_bits(priv->pdm_map, PDM_DMIC_CTRL0,
204 PDM_DMIC_VOL_MASK, PDM_DMIC_VOL_MASK);
209 #define SF_PDM_RATES (SNDRV_PCM_RATE_8000 | \
210 SNDRV_PCM_RATE_11025 | \
211 SNDRV_PCM_RATE_16000)
213 #define SF_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
214 SNDRV_PCM_FMTBIT_S32_LE)
216 static struct snd_soc_dai_driver sf_pdm_dai_drv = {
220 .stream_name = "Capture",
223 .rates = SF_PDM_RATES,
224 .formats = SF_PDM_FORMATS,
226 .ops = &sf_pdm_dai_ops,
227 .probe = sf_pdm_dai_probe,
228 .remove = sf_pdm_dai_remove,
232 static int pdm_probe(struct snd_soc_component *component)
234 struct sf_pdm *priv = snd_soc_component_get_drvdata(component);
236 snd_soc_component_init_regmap(component, priv->pdm_map);
237 snd_soc_add_component_controls(component, sf_pdm_snd_controls,
238 ARRAY_SIZE(sf_pdm_snd_controls));
244 static int sf_pdm_runtime_suspend(struct device *dev)
246 struct sf_pdm *priv = dev_get_drvdata(dev);
248 clk_disable_unprepare(priv->clk_pdm_apb);
249 clk_disable_unprepare(priv->clk_pdm_mclk);
250 clk_disable_unprepare(priv->clk_mclk);
255 static int sf_pdm_runtime_resume(struct device *dev)
257 struct sf_pdm *priv = dev_get_drvdata(dev);
260 ret = clk_prepare_enable(priv->clk_mclk);
262 dev_err(dev, "failed to prepare enable clk_mclk\n");
266 ret = clk_prepare_enable(priv->clk_pdm_mclk);
268 dev_err(dev, "failed to prepare enable clk_pdm_mclk\n");
272 ret = clk_prepare_enable(priv->clk_pdm_apb);
274 dev_err(dev, "failed to prepare enable clk_pdm_apb\n");
275 goto disable_pdm_mclk;
281 clk_disable_unprepare(priv->clk_pdm_mclk);
283 clk_disable_unprepare(priv->clk_mclk);
289 #ifdef CONFIG_PM_SLEEP
290 static int sf_pdm_suspend(struct snd_soc_component *component)
292 return pm_runtime_force_suspend(component->dev);
295 static int sf_pdm_resume(struct snd_soc_component *component)
297 return pm_runtime_force_resume(component->dev);
301 #define sf_tdm_suspend NULL
302 #define sf_tdm_resume NULL
305 static const struct snd_soc_component_driver sf_pdm_component_drv = {
306 .name = "jh7110-pdm",
308 .suspend = sf_pdm_suspend,
309 .resume = sf_pdm_resume,
312 static const struct regmap_config sf_pdm_regmap_cfg = {
316 .max_register = 0x20,
319 static int sf_pdm_clock_init(struct platform_device *pdev, struct sf_pdm *priv)
323 static struct clk_bulk_data clks[] = {
324 { .id = "pdm_mclk" },
325 { .id = "clk_apb0" },
327 { .id = "clk_mclk" },
328 { .id = "mclk_ext" },
331 ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
333 dev_err(&pdev->dev, "failed to get pdm clocks\n");
337 priv->clk_pdm_mclk = clks[0].clk;
338 priv->clk_apb0 = clks[1].clk;
339 priv->clk_pdm_apb = clks[2].clk;
340 priv->clk_mclk = clks[3].clk;
341 priv->clk_mclk_ext = clks[4].clk;
343 priv->rst_pdm_dmic = devm_reset_control_get_exclusive(&pdev->dev, "pdm_dmic");
344 if (IS_ERR(priv->rst_pdm_dmic)) {
345 dev_err(&pdev->dev, "failed to get pdm_dmic reset control\n");
346 ret = PTR_ERR(priv->rst_pdm_dmic);
350 priv->rst_pdm_apb = devm_reset_control_get_exclusive(&pdev->dev, "pdm_apb");
351 if (IS_ERR(priv->rst_pdm_apb)) {
352 dev_err(&pdev->dev, "failed to get pdm_apb reset control\n");
353 ret = PTR_ERR(priv->rst_pdm_apb);
357 /* Enable PDM Clock */
358 ret = reset_control_assert(priv->rst_pdm_apb);
360 dev_err(&pdev->dev, "failed to assert rst_pdm_apb\n");
364 ret = clk_prepare_enable(priv->clk_mclk);
366 dev_err(&pdev->dev, "failed to prepare enable clk_mclk\n");
370 ret = clk_prepare_enable(priv->clk_pdm_mclk);
372 dev_err(&pdev->dev, "failed to prepare enable clk_pdm_mclk\n");
373 goto err_dis_pdm_mclk;
376 ret = clk_prepare_enable(priv->clk_apb0);
378 dev_err(&pdev->dev, "failed to prepare enable clk_apb0\n");
382 ret = clk_prepare_enable(priv->clk_pdm_apb);
384 dev_err(&pdev->dev, "failed to prepare enable clk_pdm_apb\n");
385 goto err_dis_pdm_apb;
388 ret = reset_control_deassert(priv->rst_pdm_dmic);
390 dev_err(&pdev->dev, "failed to deassert pdm_dmic\n");
391 goto err_clk_disable;
394 ret = reset_control_deassert(priv->rst_pdm_apb);
396 dev_err(&pdev->dev, "failed to deassert pdm_apb\n");
397 goto err_clk_disable;
400 ret = clk_set_parent(priv->clk_mclk, priv->clk_mclk_ext);
402 dev_err(&pdev->dev, "failed to set parent clk_mclk ret=%d\n", ret);
403 goto err_clk_disable;
409 clk_disable_unprepare(priv->clk_pdm_apb);
411 clk_disable_unprepare(priv->clk_apb0);
413 clk_disable_unprepare(priv->clk_pdm_mclk);
415 clk_disable_unprepare(priv->clk_mclk);
421 static int sf_pdm_probe(struct platform_device *pdev)
424 struct resource *res;
428 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
431 platform_set_drvdata(pdev, priv);
433 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pdm");
434 regs = devm_ioremap_resource(&pdev->dev, res);
436 return PTR_ERR(regs);
438 priv->pdm_map = devm_regmap_init_mmio(&pdev->dev, regs, &sf_pdm_regmap_cfg);
439 if (IS_ERR(priv->pdm_map)) {
440 dev_err(&pdev->dev, "failed to init regmap: %ld\n",
441 PTR_ERR(priv->pdm_map));
442 return PTR_ERR(priv->pdm_map);
445 priv->dev = &pdev->dev;
446 priv->flag_first = 1;
448 ret = sf_pdm_clock_init(pdev, priv);
450 dev_err(&pdev->dev, "failed to enable audio-pdm clock\n");
454 dev_set_drvdata(&pdev->dev, priv);
456 ret = devm_snd_soc_register_component(&pdev->dev, &sf_pdm_component_drv,
459 dev_err(&pdev->dev, "failed to register pdm dai\n");
463 pm_runtime_enable(&pdev->dev);
467 static int sf_pdm_dev_remove(struct platform_device *pdev)
469 pm_runtime_disable(&pdev->dev);
473 static const struct of_device_id sf_pdm_of_match[] = {
474 {.compatible = "starfive,jh7110-pdm",},
477 MODULE_DEVICE_TABLE(of, sf_pdm_of_match);
479 static const struct dev_pm_ops sf_pdm_pm_ops = {
480 SET_RUNTIME_PM_OPS(sf_pdm_runtime_suspend,
481 sf_pdm_runtime_resume, NULL)
484 static struct platform_driver sf_pdm_driver = {
486 .name = "jh7110-pdm",
487 .of_match_table = sf_pdm_of_match,
489 .pm = &sf_pdm_pm_ops,
492 .probe = sf_pdm_probe,
493 .remove = sf_pdm_dev_remove,
495 module_platform_driver(sf_pdm_driver);
497 MODULE_AUTHOR("Walker Chen <walker.chen@starfivetech.com>");
498 MODULE_DESCRIPTION("Starfive PDM Controller Driver");
499 MODULE_LICENSE("GPL v2");