1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Rockchip PDM ALSA SoC Digital Audio Interface(DAI) driver 4 * 5 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd 6 */ 7 8 #include <linux/module.h> 9 #include <linux/clk.h> 10 #include <linux/of.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> 18 19 #include "rockchip_pdm.h" 20 21 #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */ 22 #define PDM_SIGNOFF_CLK_RATE (100000000) 23 24 enum rk_pdm_version { 25 RK_PDM_RK3229, 26 RK_PDM_RK3308, 27 }; 28 29 struct rk_pdm_dev { 30 struct device *dev; 31 struct clk *clk; 32 struct clk *hclk; 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; 37 }; 38 39 struct rk_pdm_clkref { 40 unsigned int sr; 41 unsigned int clk; 42 unsigned int clk_out; 43 }; 44 45 struct rk_pdm_ds_ratio { 46 unsigned int ratio; 47 unsigned int sr; 48 }; 49 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 }, 56 }; 57 58 static struct rk_pdm_ds_ratio ds_ratio[] = { 59 { 0, 192000 }, 60 { 0, 176400 }, 61 { 0, 128000 }, 62 { 1, 96000 }, 63 { 1, 88200 }, 64 { 1, 64000 }, 65 { 2, 48000 }, 66 { 2, 44100 }, 67 { 2, 32000 }, 68 { 3, 24000 }, 69 { 3, 22050 }, 70 { 3, 16000 }, 71 { 4, 12000 }, 72 { 4, 11025 }, 73 { 4, 8000 }, 74 }; 75 76 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr, 77 unsigned int *clk_src, unsigned int *clk_out) 78 { 79 unsigned int i, count, clk, div, rate; 80 81 clk = 0; 82 if (!sr) 83 return clk; 84 85 count = ARRAY_SIZE(clkref); 86 for (i = 0; i < count; i++) { 87 if (sr % clkref[i].sr) 88 continue; 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) 94 continue; 95 clk = clkref[i].clk; 96 *clk_src = clkref[i].clk; 97 break; 98 } 99 } 100 101 if (!clk) { 102 clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE); 103 *clk_src = clk; 104 } 105 return clk; 106 } 107 108 static unsigned int get_pdm_ds_ratio(unsigned int sr) 109 { 110 unsigned int i, count, ratio; 111 112 ratio = 0; 113 if (!sr) 114 return ratio; 115 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; 120 } 121 return ratio; 122 } 123 124 static inline struct rk_pdm_dev *to_info(struct snd_soc_dai *dai) 125 { 126 return snd_soc_dai_get_drvdata(dai); 127 } 128 129 static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on) 130 { 131 if (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); 136 } else { 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); 142 } 143 } 144 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) 148 { 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; 153 unsigned long m, n; 154 bool change; 155 int ret; 156 157 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 158 return 0; 159 160 samplerate = params_rate(params); 161 clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out); 162 if (!clk_rate) 163 return -EINVAL; 164 165 ret = clk_set_rate(pdm->clk, clk_src); 166 if (ret) 167 return -EINVAL; 168 169 if (pdm->version == RK_PDM_RK3308) { 170 rational_best_approximation(clk_out, clk_src, 171 GENMASK(16 - 1, 0), 172 GENMASK(16 - 1, 0), 173 &m, &n); 174 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, 180 val, &change); 181 if (change) { 182 reset_control_assert(pdm->reset); 183 reset_control_deassert(pdm->reset); 184 rockchip_pdm_rxctrl(pdm, 0); 185 } 186 clk_div = n / m; 187 if (clk_div >= 40) 188 val = PDM_CLK_FD_RATIO_40; 189 else if (clk_div <= 35) 190 val = PDM_CLK_FD_RATIO_35; 191 else 192 return -EINVAL; 193 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, 194 PDM_CLK_FD_RATIO_MSK, 195 val); 196 } 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); 207 208 val = 0; 209 switch (params_format(params)) { 210 case SNDRV_PCM_FORMAT_S8: 211 val |= PDM_VDW(8); 212 break; 213 case SNDRV_PCM_FORMAT_S16_LE: 214 val |= PDM_VDW(16); 215 break; 216 case SNDRV_PCM_FORMAT_S20_3LE: 217 val |= PDM_VDW(20); 218 break; 219 case SNDRV_PCM_FORMAT_S24_LE: 220 val |= PDM_VDW(24); 221 break; 222 case SNDRV_PCM_FORMAT_S32_LE: 223 val |= PDM_VDW(32); 224 break; 225 default: 226 return -EINVAL; 227 } 228 229 switch (params_channels(params)) { 230 case 8: 231 val |= PDM_PATH3_EN; 232 fallthrough; 233 case 6: 234 val |= PDM_PATH2_EN; 235 fallthrough; 236 case 4: 237 val |= PDM_PATH1_EN; 238 fallthrough; 239 case 2: 240 val |= PDM_PATH0_EN; 241 break; 242 default: 243 dev_err(pdm->dev, "invalid channel: %d\n", 244 params_channels(params)); 245 return -EINVAL; 246 } 247 248 regmap_update_bits(pdm->regmap, PDM_CTRL0, 249 PDM_PATH_MSK | PDM_VDW_MSK, 250 val); 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))); 254 255 return 0; 256 } 257 258 static int rockchip_pdm_set_fmt(struct snd_soc_dai *cpu_dai, 259 unsigned int fmt) 260 { 261 struct rk_pdm_dev *pdm = to_info(cpu_dai); 262 unsigned int mask = 0, val = 0; 263 264 mask = PDM_CKP_MSK; 265 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 266 case SND_SOC_DAIFMT_NB_NF: 267 val = PDM_CKP_NORMAL; 268 break; 269 case SND_SOC_DAIFMT_IB_NF: 270 val = PDM_CKP_INVERTED; 271 break; 272 default: 273 return -EINVAL; 274 } 275 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); 279 280 return 0; 281 } 282 283 static int rockchip_pdm_trigger(struct snd_pcm_substream *substream, int cmd, 284 struct snd_soc_dai *dai) 285 { 286 struct rk_pdm_dev *pdm = to_info(dai); 287 int ret = 0; 288 289 switch (cmd) { 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); 295 break; 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); 301 break; 302 default: 303 ret = -EINVAL; 304 break; 305 } 306 307 return ret; 308 } 309 310 static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai) 311 { 312 struct rk_pdm_dev *pdm = to_info(dai); 313 314 dai->capture_dma_data = &pdm->capture_dma_data; 315 316 return 0; 317 } 318 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, 323 }; 324 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) 330 331 static struct snd_soc_dai_driver rockchip_pdm_dai = { 332 .probe = rockchip_pdm_dai_probe, 333 .capture = { 334 .stream_name = "Capture", 335 .channels_min = 2, 336 .channels_max = 8, 337 .rates = ROCKCHIP_PDM_RATES, 338 .formats = ROCKCHIP_PDM_FORMATS, 339 }, 340 .ops = &rockchip_pdm_dai_ops, 341 .symmetric_rates = 1, 342 }; 343 344 static const struct snd_soc_component_driver rockchip_pdm_component = { 345 .name = "rockchip-pdm", 346 }; 347 348 static int rockchip_pdm_runtime_suspend(struct device *dev) 349 { 350 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); 351 352 clk_disable_unprepare(pdm->clk); 353 clk_disable_unprepare(pdm->hclk); 354 355 return 0; 356 } 357 358 static int rockchip_pdm_runtime_resume(struct device *dev) 359 { 360 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); 361 int ret; 362 363 ret = clk_prepare_enable(pdm->clk); 364 if (ret) { 365 dev_err(pdm->dev, "clock enable failed %d\n", ret); 366 return ret; 367 } 368 369 ret = clk_prepare_enable(pdm->hclk); 370 if (ret) { 371 dev_err(pdm->dev, "hclock enable failed %d\n", ret); 372 return ret; 373 } 374 375 return 0; 376 } 377 378 static bool rockchip_pdm_wr_reg(struct device *dev, unsigned int reg) 379 { 380 switch (reg) { 381 case PDM_SYSCONFIG: 382 case PDM_CTRL0: 383 case PDM_CTRL1: 384 case PDM_CLK_CTRL: 385 case PDM_HPF_CTRL: 386 case PDM_FIFO_CTRL: 387 case PDM_DMA_CTRL: 388 case PDM_INT_EN: 389 case PDM_INT_CLR: 390 case PDM_DATA_VALID: 391 return true; 392 default: 393 return false; 394 } 395 } 396 397 static bool rockchip_pdm_rd_reg(struct device *dev, unsigned int reg) 398 { 399 switch (reg) { 400 case PDM_SYSCONFIG: 401 case PDM_CTRL0: 402 case PDM_CTRL1: 403 case PDM_CLK_CTRL: 404 case PDM_HPF_CTRL: 405 case PDM_FIFO_CTRL: 406 case PDM_DMA_CTRL: 407 case PDM_INT_EN: 408 case PDM_INT_CLR: 409 case PDM_INT_ST: 410 case PDM_DATA_VALID: 411 case PDM_RXFIFO_DATA: 412 case PDM_VERSION: 413 return true; 414 default: 415 return false; 416 } 417 } 418 419 static bool rockchip_pdm_volatile_reg(struct device *dev, unsigned int reg) 420 { 421 switch (reg) { 422 case PDM_SYSCONFIG: 423 case PDM_FIFO_CTRL: 424 case PDM_INT_CLR: 425 case PDM_INT_ST: 426 case PDM_RXFIFO_DATA: 427 return true; 428 default: 429 return false; 430 } 431 } 432 433 static bool rockchip_pdm_precious_reg(struct device *dev, unsigned int reg) 434 { 435 switch (reg) { 436 case PDM_RXFIFO_DATA: 437 return true; 438 default: 439 return false; 440 } 441 } 442 443 static const struct reg_default rockchip_pdm_reg_defaults[] = { 444 {0x04, 0x78000017}, 445 {0x08, 0x0bb8ea60}, 446 {0x18, 0x0000001f}, 447 }; 448 449 static const struct regmap_config rockchip_pdm_regmap_config = { 450 .reg_bits = 32, 451 .reg_stride = 4, 452 .val_bits = 32, 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, 461 }; 462 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 }, 472 {}, 473 }; 474 MODULE_DEVICE_TABLE(of, rockchip_pdm_match); 475 476 static int rockchip_pdm_probe(struct platform_device *pdev) 477 { 478 const struct of_device_id *match; 479 struct rk_pdm_dev *pdm; 480 struct resource *res; 481 void __iomem *regs; 482 int ret; 483 484 pdm = devm_kzalloc(&pdev->dev, sizeof(*pdm), GFP_KERNEL); 485 if (!pdm) 486 return -ENOMEM; 487 488 match = of_match_device(rockchip_pdm_match, &pdev->dev); 489 if (match) 490 pdm->version = (enum rk_pdm_version)match->data; 491 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); 496 } 497 498 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 499 regs = devm_ioremap_resource(&pdev->dev, res); 500 if (IS_ERR(regs)) 501 return PTR_ERR(regs); 502 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); 507 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; 511 512 pdm->dev = &pdev->dev; 513 dev_set_drvdata(&pdev->dev, pdm); 514 515 pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk"); 516 if (IS_ERR(pdm->clk)) 517 return PTR_ERR(pdm->clk); 518 519 pdm->hclk = devm_clk_get(&pdev->dev, "pdm_hclk"); 520 if (IS_ERR(pdm->hclk)) 521 return PTR_ERR(pdm->hclk); 522 523 ret = clk_prepare_enable(pdm->hclk); 524 if (ret) 525 return ret; 526 527 pm_runtime_enable(&pdev->dev); 528 if (!pm_runtime_enabled(&pdev->dev)) { 529 ret = rockchip_pdm_runtime_resume(&pdev->dev); 530 if (ret) 531 goto err_pm_disable; 532 } 533 534 ret = devm_snd_soc_register_component(&pdev->dev, 535 &rockchip_pdm_component, 536 &rockchip_pdm_dai, 1); 537 538 if (ret) { 539 dev_err(&pdev->dev, "could not register dai: %d\n", ret); 540 goto err_suspend; 541 } 542 543 rockchip_pdm_rxctrl(pdm, 0); 544 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); 545 if (ret) { 546 dev_err(&pdev->dev, "could not register pcm: %d\n", ret); 547 goto err_suspend; 548 } 549 550 return 0; 551 552 err_suspend: 553 if (!pm_runtime_status_suspended(&pdev->dev)) 554 rockchip_pdm_runtime_suspend(&pdev->dev); 555 err_pm_disable: 556 pm_runtime_disable(&pdev->dev); 557 558 clk_disable_unprepare(pdm->hclk); 559 560 return ret; 561 } 562 563 static int rockchip_pdm_remove(struct platform_device *pdev) 564 { 565 struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev); 566 567 pm_runtime_disable(&pdev->dev); 568 if (!pm_runtime_status_suspended(&pdev->dev)) 569 rockchip_pdm_runtime_suspend(&pdev->dev); 570 571 clk_disable_unprepare(pdm->clk); 572 clk_disable_unprepare(pdm->hclk); 573 574 return 0; 575 } 576 577 #ifdef CONFIG_PM_SLEEP 578 static int rockchip_pdm_suspend(struct device *dev) 579 { 580 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); 581 582 regcache_mark_dirty(pdm->regmap); 583 584 return 0; 585 } 586 587 static int rockchip_pdm_resume(struct device *dev) 588 { 589 struct rk_pdm_dev *pdm = dev_get_drvdata(dev); 590 int ret; 591 592 ret = pm_runtime_get_sync(dev); 593 if (ret < 0) { 594 pm_runtime_put(dev); 595 return ret; 596 } 597 598 ret = regcache_sync(pdm->regmap); 599 600 pm_runtime_put(dev); 601 602 return ret; 603 } 604 #endif 605 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) 610 }; 611 612 static struct platform_driver rockchip_pdm_driver = { 613 .probe = rockchip_pdm_probe, 614 .remove = rockchip_pdm_remove, 615 .driver = { 616 .name = "rockchip-pdm", 617 .of_match_table = of_match_ptr(rockchip_pdm_match), 618 .pm = &rockchip_pdm_pm_ops, 619 }, 620 }; 621 622 module_platform_driver(rockchip_pdm_driver); 623 624 MODULE_AUTHOR("Sugar <sugar.zhang@rock-chips.com>"); 625 MODULE_DESCRIPTION("Rockchip PDM Controller Driver"); 626 MODULE_LICENSE("GPL v2"); 627