0001
0002
0003
0004
0005
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)
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
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");