Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Rockchip PDM ALSA SoC Digital Audio Interface(DAI)  driver
0004  *
0005  * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/clk.h>
0010 #include <linux/of.h>
0011 #include <linux/of_device.h>
0012 #include <linux/pm_runtime.h>
0013 #include <linux/rational.h>
0014 #include <linux/regmap.h>
0015 #include <linux/reset.h>
0016 #include <sound/dmaengine_pcm.h>
0017 #include <sound/pcm_params.h>
0018 
0019 #include "rockchip_pdm.h"
0020 
0021 #define PDM_DMA_BURST_SIZE  (8) /* size * width: 8*4 = 32 bytes */
0022 #define PDM_SIGNOFF_CLK_RATE    (100000000)
0023 #define PDM_PATH_MAX        (4)
0024 
0025 enum rk_pdm_version {
0026     RK_PDM_RK3229,
0027     RK_PDM_RK3308,
0028     RK_PDM_RV1126,
0029 };
0030 
0031 struct rk_pdm_dev {
0032     struct device *dev;
0033     struct clk *clk;
0034     struct clk *hclk;
0035     struct regmap *regmap;
0036     struct snd_dmaengine_dai_dma_data capture_dma_data;
0037     struct reset_control *reset;
0038     enum rk_pdm_version version;
0039 };
0040 
0041 struct rk_pdm_clkref {
0042     unsigned int sr;
0043     unsigned int clk;
0044     unsigned int clk_out;
0045 };
0046 
0047 struct rk_pdm_ds_ratio {
0048     unsigned int ratio;
0049     unsigned int sr;
0050 };
0051 
0052 static struct rk_pdm_clkref clkref[] = {
0053     { 8000, 40960000, 2048000 },
0054     { 11025, 56448000, 2822400 },
0055     { 12000, 61440000, 3072000 },
0056     { 8000, 98304000, 2048000 },
0057     { 12000, 98304000, 3072000 },
0058 };
0059 
0060 static struct rk_pdm_ds_ratio ds_ratio[] = {
0061     { 0, 192000 },
0062     { 0, 176400 },
0063     { 0, 128000 },
0064     { 1, 96000 },
0065     { 1, 88200 },
0066     { 1, 64000 },
0067     { 2, 48000 },
0068     { 2, 44100 },
0069     { 2, 32000 },
0070     { 3, 24000 },
0071     { 3, 22050 },
0072     { 3, 16000 },
0073     { 4, 12000 },
0074     { 4, 11025 },
0075     { 4, 8000 },
0076 };
0077 
0078 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
0079                 unsigned int *clk_src, unsigned int *clk_out)
0080 {
0081     unsigned int i, count, clk, div, rate;
0082 
0083     clk = 0;
0084     if (!sr)
0085         return clk;
0086 
0087     count = ARRAY_SIZE(clkref);
0088     for (i = 0; i < count; i++) {
0089         if (sr % clkref[i].sr)
0090             continue;
0091         div = sr / clkref[i].sr;
0092         if ((div & (div - 1)) == 0) {
0093             *clk_out = clkref[i].clk_out;
0094             rate = clk_round_rate(pdm->clk, clkref[i].clk);
0095             if (rate != clkref[i].clk)
0096                 continue;
0097             clk = clkref[i].clk;
0098             *clk_src = clkref[i].clk;
0099             break;
0100         }
0101     }
0102 
0103     if (!clk) {
0104         clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE);
0105         *clk_src = clk;
0106     }
0107     return clk;
0108 }
0109 
0110 static unsigned int get_pdm_ds_ratio(unsigned int sr)
0111 {
0112     unsigned int i, count, ratio;
0113 
0114     ratio = 0;
0115     if (!sr)
0116         return ratio;
0117 
0118     count = ARRAY_SIZE(ds_ratio);
0119     for (i = 0; i < count; i++) {
0120         if (sr == ds_ratio[i].sr)
0121             ratio = ds_ratio[i].ratio;
0122     }
0123     return ratio;
0124 }
0125 
0126 static unsigned int get_pdm_cic_ratio(unsigned int clk)
0127 {
0128     switch (clk) {
0129     case 4096000:
0130     case 5644800:
0131     case 6144000:
0132         return 0;
0133     case 2048000:
0134     case 2822400:
0135     case 3072000:
0136         return 1;
0137     case 1024000:
0138     case 1411200:
0139     case 1536000:
0140         return 2;
0141     default:
0142         return 1;
0143     }
0144 }
0145 
0146 static unsigned int samplerate_to_bit(unsigned int samplerate)
0147 {
0148     switch (samplerate) {
0149     case 8000:
0150     case 11025:
0151     case 12000:
0152         return 0;
0153     case 16000:
0154     case 22050:
0155     case 24000:
0156         return 1;
0157     case 32000:
0158         return 2;
0159     case 44100:
0160     case 48000:
0161         return 3;
0162     case 64000:
0163     case 88200:
0164     case 96000:
0165         return 4;
0166     case 128000:
0167     case 176400:
0168     case 192000:
0169         return 5;
0170     default:
0171         return 1;
0172     }
0173 }
0174 
0175 static inline struct rk_pdm_dev *to_info(struct snd_soc_dai *dai)
0176 {
0177     return snd_soc_dai_get_drvdata(dai);
0178 }
0179 
0180 static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on)
0181 {
0182     if (on) {
0183         regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
0184                    PDM_DMA_RD_MSK, PDM_DMA_RD_EN);
0185         regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
0186                    PDM_RX_MASK, PDM_RX_START);
0187     } else {
0188         regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
0189                    PDM_DMA_RD_MSK, PDM_DMA_RD_DIS);
0190         regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
0191                    PDM_RX_MASK | PDM_RX_CLR_MASK,
0192                    PDM_RX_STOP | PDM_RX_CLR_WR);
0193     }
0194 }
0195 
0196 static int rockchip_pdm_hw_params(struct snd_pcm_substream *substream,
0197                   struct snd_pcm_hw_params *params,
0198                   struct snd_soc_dai *dai)
0199 {
0200     struct rk_pdm_dev *pdm = to_info(dai);
0201     unsigned int val = 0;
0202     unsigned int clk_rate, clk_div, samplerate;
0203     unsigned int clk_src, clk_out = 0;
0204     unsigned long m, n;
0205     bool change;
0206     int ret;
0207 
0208     if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
0209         return 0;
0210 
0211     samplerate = params_rate(params);
0212     clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out);
0213     if (!clk_rate)
0214         return -EINVAL;
0215 
0216     ret = clk_set_rate(pdm->clk, clk_src);
0217     if (ret)
0218         return -EINVAL;
0219 
0220     if (pdm->version == RK_PDM_RK3308 ||
0221         pdm->version == RK_PDM_RV1126) {
0222         rational_best_approximation(clk_out, clk_src,
0223                         GENMASK(16 - 1, 0),
0224                         GENMASK(16 - 1, 0),
0225                         &m, &n);
0226 
0227         val = (m << PDM_FD_NUMERATOR_SFT) |
0228             (n << PDM_FD_DENOMINATOR_SFT);
0229         regmap_update_bits_check(pdm->regmap, PDM_CTRL1,
0230                      PDM_FD_NUMERATOR_MSK |
0231                      PDM_FD_DENOMINATOR_MSK,
0232                      val, &change);
0233         if (change) {
0234             reset_control_assert(pdm->reset);
0235             reset_control_deassert(pdm->reset);
0236             rockchip_pdm_rxctrl(pdm, 0);
0237         }
0238         clk_div = n / m;
0239         if (clk_div >= 40)
0240             val = PDM_CLK_FD_RATIO_40;
0241         else if (clk_div <= 35)
0242             val = PDM_CLK_FD_RATIO_35;
0243         else
0244             return -EINVAL;
0245         regmap_update_bits(pdm->regmap, PDM_CLK_CTRL,
0246                    PDM_CLK_FD_RATIO_MSK,
0247                    val);
0248     }
0249 
0250     if (pdm->version == RK_PDM_RV1126) {
0251         val = get_pdm_cic_ratio(clk_out);
0252         regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
0253         val = samplerate_to_bit(samplerate);
0254         regmap_update_bits(pdm->regmap, PDM_CTRL0,
0255                    PDM_SAMPLERATE_MSK, PDM_SAMPLERATE(val));
0256     } else {
0257         val = get_pdm_ds_ratio(samplerate);
0258         regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
0259     }
0260 
0261     regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
0262                PDM_HPF_CF_MSK, PDM_HPF_60HZ);
0263     regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
0264                PDM_HPF_LE | PDM_HPF_RE, PDM_HPF_LE | PDM_HPF_RE);
0265     regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CLK_EN, PDM_CLK_EN);
0266     if (pdm->version != RK_PDM_RK3229)
0267         regmap_update_bits(pdm->regmap, PDM_CTRL0,
0268                    PDM_MODE_MSK, PDM_MODE_LJ);
0269 
0270     val = 0;
0271     switch (params_format(params)) {
0272     case SNDRV_PCM_FORMAT_S8:
0273         val |= PDM_VDW(8);
0274         break;
0275     case SNDRV_PCM_FORMAT_S16_LE:
0276         val |= PDM_VDW(16);
0277         break;
0278     case SNDRV_PCM_FORMAT_S20_3LE:
0279         val |= PDM_VDW(20);
0280         break;
0281     case SNDRV_PCM_FORMAT_S24_LE:
0282         val |= PDM_VDW(24);
0283         break;
0284     case SNDRV_PCM_FORMAT_S32_LE:
0285         val |= PDM_VDW(32);
0286         break;
0287     default:
0288         return -EINVAL;
0289     }
0290 
0291     switch (params_channels(params)) {
0292     case 8:
0293         val |= PDM_PATH3_EN;
0294         fallthrough;
0295     case 6:
0296         val |= PDM_PATH2_EN;
0297         fallthrough;
0298     case 4:
0299         val |= PDM_PATH1_EN;
0300         fallthrough;
0301     case 2:
0302         val |= PDM_PATH0_EN;
0303         break;
0304     default:
0305         dev_err(pdm->dev, "invalid channel: %d\n",
0306             params_channels(params));
0307         return -EINVAL;
0308     }
0309 
0310     regmap_update_bits(pdm->regmap, PDM_CTRL0,
0311                PDM_PATH_MSK | PDM_VDW_MSK,
0312                val);
0313     /* all channels share the single FIFO */
0314     regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, PDM_DMA_RDL_MSK,
0315                PDM_DMA_RDL(8 * params_channels(params)));
0316 
0317     return 0;
0318 }
0319 
0320 static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai,
0321                 unsigned int fmt)
0322 {
0323     struct rk_pdm_dev *pdm = to_info(cpu_dai);
0324     unsigned int mask = 0, val = 0;
0325 
0326     mask = PDM_CKP_MSK;
0327     switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0328     case SND_SOC_DAIFMT_NB_NF:
0329         val = PDM_CKP_NORMAL;
0330         break;
0331     case SND_SOC_DAIFMT_IB_NF:
0332         val = PDM_CKP_INVERTED;
0333         break;
0334     default:
0335         return -EINVAL;
0336     }
0337 
0338     pm_runtime_get_sync(cpu_dai->dev);
0339     regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, mask, val);
0340     pm_runtime_put(cpu_dai->dev);
0341 
0342     return 0;
0343 }
0344 
0345 static int rockchip_pdm_trigger(struct snd_pcm_substream *substream, int cmd,
0346                 struct snd_soc_dai *dai)
0347 {
0348     struct rk_pdm_dev *pdm = to_info(dai);
0349     int ret = 0;
0350 
0351     switch (cmd) {
0352     case SNDRV_PCM_TRIGGER_START:
0353     case SNDRV_PCM_TRIGGER_RESUME:
0354     case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
0355         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
0356             rockchip_pdm_rxctrl(pdm, 1);
0357         break;
0358     case SNDRV_PCM_TRIGGER_SUSPEND:
0359     case SNDRV_PCM_TRIGGER_STOP:
0360     case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
0361         if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
0362             rockchip_pdm_rxctrl(pdm, 0);
0363         break;
0364     default:
0365         ret = -EINVAL;
0366         break;
0367     }
0368 
0369     return ret;
0370 }
0371 
0372 static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
0373 {
0374     struct rk_pdm_dev *pdm = to_info(dai);
0375 
0376     dai->capture_dma_data = &pdm->capture_dma_data;
0377 
0378     return 0;
0379 }
0380 
0381 static const struct snd_soc_dai_ops rockchip_pdm_dai_ops = {
0382     .set_fmt = rockchip_pdm_set_fmt,
0383     .trigger = rockchip_pdm_trigger,
0384     .hw_params = rockchip_pdm_hw_params,
0385 };
0386 
0387 #define ROCKCHIP_PDM_RATES SNDRV_PCM_RATE_8000_192000
0388 #define ROCKCHIP_PDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
0389                   SNDRV_PCM_FMTBIT_S20_3LE | \
0390                   SNDRV_PCM_FMTBIT_S24_LE | \
0391                   SNDRV_PCM_FMTBIT_S32_LE)
0392 
0393 static struct snd_soc_dai_driver rockchip_pdm_dai = {
0394     .probe = rockchip_pdm_dai_probe,
0395     .capture = {
0396         .stream_name = "Capture",
0397         .channels_min = 2,
0398         .channels_max = 8,
0399         .rates = ROCKCHIP_PDM_RATES,
0400         .formats = ROCKCHIP_PDM_FORMATS,
0401     },
0402     .ops = &rockchip_pdm_dai_ops,
0403     .symmetric_rate = 1,
0404 };
0405 
0406 static const struct snd_soc_component_driver rockchip_pdm_component = {
0407     .name = "rockchip-pdm",
0408     .legacy_dai_naming = 1,
0409 };
0410 
0411 static int rockchip_pdm_runtime_suspend(struct device *dev)
0412 {
0413     struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
0414 
0415     clk_disable_unprepare(pdm->clk);
0416     clk_disable_unprepare(pdm->hclk);
0417 
0418     return 0;
0419 }
0420 
0421 static int rockchip_pdm_runtime_resume(struct device *dev)
0422 {
0423     struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
0424     int ret;
0425 
0426     ret = clk_prepare_enable(pdm->clk);
0427     if (ret) {
0428         dev_err(pdm->dev, "clock enable failed %d\n", ret);
0429         return ret;
0430     }
0431 
0432     ret = clk_prepare_enable(pdm->hclk);
0433     if (ret) {
0434         dev_err(pdm->dev, "hclock enable failed %d\n", ret);
0435         return ret;
0436     }
0437 
0438     return 0;
0439 }
0440 
0441 static bool rockchip_pdm_wr_reg(struct device *dev, unsigned int reg)
0442 {
0443     switch (reg) {
0444     case PDM_SYSCONFIG:
0445     case PDM_CTRL0:
0446     case PDM_CTRL1:
0447     case PDM_CLK_CTRL:
0448     case PDM_HPF_CTRL:
0449     case PDM_FIFO_CTRL:
0450     case PDM_DMA_CTRL:
0451     case PDM_INT_EN:
0452     case PDM_INT_CLR:
0453     case PDM_DATA_VALID:
0454         return true;
0455     default:
0456         return false;
0457     }
0458 }
0459 
0460 static bool rockchip_pdm_rd_reg(struct device *dev, unsigned int reg)
0461 {
0462     switch (reg) {
0463     case PDM_SYSCONFIG:
0464     case PDM_CTRL0:
0465     case PDM_CTRL1:
0466     case PDM_CLK_CTRL:
0467     case PDM_HPF_CTRL:
0468     case PDM_FIFO_CTRL:
0469     case PDM_DMA_CTRL:
0470     case PDM_INT_EN:
0471     case PDM_INT_CLR:
0472     case PDM_INT_ST:
0473     case PDM_DATA_VALID:
0474     case PDM_RXFIFO_DATA:
0475     case PDM_VERSION:
0476         return true;
0477     default:
0478         return false;
0479     }
0480 }
0481 
0482 static bool rockchip_pdm_volatile_reg(struct device *dev, unsigned int reg)
0483 {
0484     switch (reg) {
0485     case PDM_SYSCONFIG:
0486     case PDM_FIFO_CTRL:
0487     case PDM_INT_CLR:
0488     case PDM_INT_ST:
0489     case PDM_RXFIFO_DATA:
0490         return true;
0491     default:
0492         return false;
0493     }
0494 }
0495 
0496 static bool rockchip_pdm_precious_reg(struct device *dev, unsigned int reg)
0497 {
0498     switch (reg) {
0499     case PDM_RXFIFO_DATA:
0500         return true;
0501     default:
0502         return false;
0503     }
0504 }
0505 
0506 static const struct reg_default rockchip_pdm_reg_defaults[] = {
0507     { PDM_CTRL0, 0x78000017 },
0508     { PDM_CTRL1, 0x0bb8ea60 },
0509     { PDM_CLK_CTRL, 0x0000e401 },
0510     { PDM_DMA_CTRL, 0x0000001f },
0511 };
0512 
0513 static const struct regmap_config rockchip_pdm_regmap_config = {
0514     .reg_bits = 32,
0515     .reg_stride = 4,
0516     .val_bits = 32,
0517     .max_register = PDM_VERSION,
0518     .reg_defaults = rockchip_pdm_reg_defaults,
0519     .num_reg_defaults = ARRAY_SIZE(rockchip_pdm_reg_defaults),
0520     .writeable_reg = rockchip_pdm_wr_reg,
0521     .readable_reg = rockchip_pdm_rd_reg,
0522     .volatile_reg = rockchip_pdm_volatile_reg,
0523     .precious_reg = rockchip_pdm_precious_reg,
0524     .cache_type = REGCACHE_FLAT,
0525 };
0526 
0527 static const struct of_device_id rockchip_pdm_match[] __maybe_unused = {
0528     { .compatible = "rockchip,pdm",
0529       .data = (void *)RK_PDM_RK3229 },
0530     { .compatible = "rockchip,px30-pdm",
0531       .data = (void *)RK_PDM_RK3308 },
0532     { .compatible = "rockchip,rk1808-pdm",
0533       .data = (void *)RK_PDM_RK3308 },
0534     { .compatible = "rockchip,rk3308-pdm",
0535       .data = (void *)RK_PDM_RK3308 },
0536     { .compatible = "rockchip,rk3568-pdm",
0537       .data = (void *)RK_PDM_RV1126 },
0538     { .compatible = "rockchip,rv1126-pdm",
0539       .data = (void *)RK_PDM_RV1126 },
0540     {},
0541 };
0542 MODULE_DEVICE_TABLE(of, rockchip_pdm_match);
0543 
0544 static int rockchip_pdm_path_parse(struct rk_pdm_dev *pdm, struct device_node *node)
0545 {
0546     unsigned int path[PDM_PATH_MAX];
0547     int cnt = 0, ret = 0, i = 0, val = 0, msk = 0;
0548 
0549     cnt = of_count_phandle_with_args(node, "rockchip,path-map",
0550                      NULL);
0551     if (cnt != PDM_PATH_MAX)
0552         return cnt;
0553 
0554     ret = of_property_read_u32_array(node, "rockchip,path-map",
0555                      path, cnt);
0556     if (ret)
0557         return ret;
0558 
0559     for (i = 0; i < cnt; i++) {
0560         if (path[i] >= PDM_PATH_MAX)
0561             return -EINVAL;
0562         msk |= PDM_PATH_MASK(i);
0563         val |= PDM_PATH(i, path[i]);
0564     }
0565 
0566     regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, msk, val);
0567 
0568     return 0;
0569 }
0570 
0571 static int rockchip_pdm_probe(struct platform_device *pdev)
0572 {
0573     struct device_node *node = pdev->dev.of_node;
0574     const struct of_device_id *match;
0575     struct rk_pdm_dev *pdm;
0576     struct resource *res;
0577     void __iomem *regs;
0578     int ret;
0579 
0580     pdm = devm_kzalloc(&pdev->dev, sizeof(*pdm), GFP_KERNEL);
0581     if (!pdm)
0582         return -ENOMEM;
0583 
0584     match = of_match_device(rockchip_pdm_match, &pdev->dev);
0585     if (match)
0586         pdm->version = (enum rk_pdm_version)match->data;
0587 
0588     if (pdm->version == RK_PDM_RK3308) {
0589         pdm->reset = devm_reset_control_get(&pdev->dev, "pdm-m");
0590         if (IS_ERR(pdm->reset))
0591             return PTR_ERR(pdm->reset);
0592     }
0593 
0594     regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
0595     if (IS_ERR(regs))
0596         return PTR_ERR(regs);
0597 
0598     pdm->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
0599                         &rockchip_pdm_regmap_config);
0600     if (IS_ERR(pdm->regmap))
0601         return PTR_ERR(pdm->regmap);
0602 
0603     pdm->capture_dma_data.addr = res->start + PDM_RXFIFO_DATA;
0604     pdm->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
0605     pdm->capture_dma_data.maxburst = PDM_DMA_BURST_SIZE;
0606 
0607     pdm->dev = &pdev->dev;
0608     dev_set_drvdata(&pdev->dev, pdm);
0609 
0610     pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
0611     if (IS_ERR(pdm->clk))
0612         return PTR_ERR(pdm->clk);
0613 
0614     pdm->hclk = devm_clk_get(&pdev->dev, "pdm_hclk");
0615     if (IS_ERR(pdm->hclk))
0616         return PTR_ERR(pdm->hclk);
0617 
0618     ret = clk_prepare_enable(pdm->hclk);
0619     if (ret)
0620         return ret;
0621 
0622     pm_runtime_enable(&pdev->dev);
0623     if (!pm_runtime_enabled(&pdev->dev)) {
0624         ret = rockchip_pdm_runtime_resume(&pdev->dev);
0625         if (ret)
0626             goto err_pm_disable;
0627     }
0628 
0629     ret = devm_snd_soc_register_component(&pdev->dev,
0630                           &rockchip_pdm_component,
0631                           &rockchip_pdm_dai, 1);
0632 
0633     if (ret) {
0634         dev_err(&pdev->dev, "could not register dai: %d\n", ret);
0635         goto err_suspend;
0636     }
0637 
0638     rockchip_pdm_rxctrl(pdm, 0);
0639 
0640     ret = rockchip_pdm_path_parse(pdm, node);
0641     if (ret != 0 && ret != -ENOENT)
0642         goto err_suspend;
0643 
0644     ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
0645     if (ret) {
0646         dev_err(&pdev->dev, "could not register pcm: %d\n", ret);
0647         goto err_suspend;
0648     }
0649 
0650     return 0;
0651 
0652 err_suspend:
0653     if (!pm_runtime_status_suspended(&pdev->dev))
0654         rockchip_pdm_runtime_suspend(&pdev->dev);
0655 err_pm_disable:
0656     pm_runtime_disable(&pdev->dev);
0657 
0658     clk_disable_unprepare(pdm->hclk);
0659 
0660     return ret;
0661 }
0662 
0663 static int rockchip_pdm_remove(struct platform_device *pdev)
0664 {
0665     struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev);
0666 
0667     pm_runtime_disable(&pdev->dev);
0668     if (!pm_runtime_status_suspended(&pdev->dev))
0669         rockchip_pdm_runtime_suspend(&pdev->dev);
0670 
0671     clk_disable_unprepare(pdm->clk);
0672     clk_disable_unprepare(pdm->hclk);
0673 
0674     return 0;
0675 }
0676 
0677 #ifdef CONFIG_PM_SLEEP
0678 static int rockchip_pdm_suspend(struct device *dev)
0679 {
0680     struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
0681 
0682     regcache_mark_dirty(pdm->regmap);
0683 
0684     return 0;
0685 }
0686 
0687 static int rockchip_pdm_resume(struct device *dev)
0688 {
0689     struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
0690     int ret;
0691 
0692     ret = pm_runtime_resume_and_get(dev);
0693     if (ret < 0)
0694         return ret;
0695 
0696     ret = regcache_sync(pdm->regmap);
0697 
0698     pm_runtime_put(dev);
0699 
0700     return ret;
0701 }
0702 #endif
0703 
0704 static const struct dev_pm_ops rockchip_pdm_pm_ops = {
0705     SET_RUNTIME_PM_OPS(rockchip_pdm_runtime_suspend,
0706                rockchip_pdm_runtime_resume, NULL)
0707     SET_SYSTEM_SLEEP_PM_OPS(rockchip_pdm_suspend, rockchip_pdm_resume)
0708 };
0709 
0710 static struct platform_driver rockchip_pdm_driver = {
0711     .probe  = rockchip_pdm_probe,
0712     .remove = rockchip_pdm_remove,
0713     .driver = {
0714         .name = "rockchip-pdm",
0715         .of_match_table = of_match_ptr(rockchip_pdm_match),
0716         .pm = &rockchip_pdm_pm_ops,
0717     },
0718 };
0719 
0720 module_platform_driver(rockchip_pdm_driver);
0721 
0722 MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>");
0723 MODULE_DESCRIPTION("Rockchip PDM Controller Driver");
0724 MODULE_LICENSE("GPL v2");