forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/rockchip/rockchip_pdm.c
....@@ -1,17 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Rockchip PDM ALSA SoC Digital Audio Interface(DAI) driver
34 *
45 * Copyright (C) 2017 Fuzhou Rockchip Electronics Co., Ltd
5
- *
6
- * This software is licensed under the terms of the GNU General Public
7
- * License version 2, as published by the Free Software Foundation, and
8
- * may be copied, distributed, and modified under those terms.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
14
- *
156 */
167
178 #include <linux/module.h>
....@@ -29,20 +20,23 @@
2920 #include "rockchip_pdm.h"
3021
3122 #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */
32
-#define PDM_SIGNOFF_CLK_RATE (100000000)
23
+#define PDM_SIGNOFF_CLK_100M (100000000)
24
+#define PDM_SIGNOFF_CLK_300M (300000000)
3325 #define PDM_PATH_MAX (4)
34
-#define CLK_PPM_MIN (-1000)
35
-#define CLK_PPM_MAX (1000)
3626 #define PDM_DEFAULT_RATE (48000)
3727 #define PDM_START_DELAY_MS_DEFAULT (20)
3828 #define PDM_START_DELAY_MS_MIN (0)
3929 #define PDM_START_DELAY_MS_MAX (1000)
4030 #define PDM_FILTER_DELAY_MS_MIN (20)
4131 #define PDM_FILTER_DELAY_MS_MAX (1000)
32
+#define PDM_CLK_SHIFT_PPM_MAX (1000000) /* 1 ppm */
33
+#define CLK_PPM_MIN (-1000)
34
+#define CLK_PPM_MAX (1000)
4235
4336 enum rk_pdm_version {
37
+ RK_PDM_RK3229,
4438 RK_PDM_RK3308,
45
- RK_PDM_RK3328,
39
+ RK_PDM_RK3588,
4640 RK_PDM_RV1126,
4741 };
4842
....@@ -101,9 +95,10 @@
10195 };
10296
10397 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
104
- unsigned int *clk_src, unsigned int *clk_out)
98
+ unsigned int *clk_src, unsigned int *clk_out,
99
+ unsigned int signoff)
105100 {
106
- unsigned int i, count, clk, div, rate;
101
+ unsigned int i, count, clk, div, rate, delta;
107102
108103 clk = 0;
109104 if (!sr)
....@@ -122,7 +117,9 @@
122117 break;
123118 }
124119 rate = clk_round_rate(pdm->clk, clkref[i].clk);
125
- if (rate != clkref[i].clk)
120
+ delta = clkref[i].clk / PDM_CLK_SHIFT_PPM_MAX;
121
+ if (rate < clkref[i].clk - delta ||
122
+ rate > clkref[i].clk + delta)
126123 continue;
127124 clk = clkref[i].clk;
128125 *clk_src = clkref[i].clk;
....@@ -131,7 +128,7 @@
131128 }
132129
133130 if (!clk) {
134
- clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE);
131
+ clk = clk_round_rate(pdm->clk, signoff);
135132 *clk_src = clk;
136133 }
137134 return clk;
....@@ -277,18 +274,20 @@
277274 return ret;
278275 }
279276
280
-static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm,
281
- unsigned int samplerate)
277
+static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm, unsigned int samplerate)
282278 {
283
- unsigned int clk_rate, clk_div;
284
- unsigned int clk_src, clk_out = 0;
285
- unsigned int val = 0, div = 0, rate, delta;
279
+
280
+ unsigned int val = 0, div = 0;
281
+ unsigned int clk_rate, clk_div, rate, delta;
282
+ unsigned int clk_src = 0, clk_out = 0, signoff = PDM_SIGNOFF_CLK_100M;
286283 unsigned long m, n;
287284 uint64_t ppm;
288
- int ret;
289285 bool change;
286
+ int ret;
290287
291
- clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out);
288
+ if (pdm->version == RK_PDM_RK3588)
289
+ signoff = PDM_SIGNOFF_CLK_300M;
290
+ clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out, signoff);
292291 if (!clk_rate)
293292 return -EINVAL;
294293
....@@ -325,6 +324,7 @@
325324 return ret;
326325
327326 if (pdm->version == RK_PDM_RK3308 ||
327
+ pdm->version == RK_PDM_RK3588 ||
328328 pdm->version == RK_PDM_RV1126) {
329329 rational_best_approximation(clk_out, clk_src,
330330 GENMASK(16 - 1, 0),
....@@ -354,7 +354,7 @@
354354 val);
355355 }
356356
357
- if (pdm->version == RK_PDM_RV1126) {
357
+ if (pdm->version == RK_PDM_RK3588 || pdm->version == RK_PDM_RV1126) {
358358 val = get_pdm_cic_ratio(clk_out);
359359 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
360360 val = samplerate_to_bit(samplerate);
....@@ -364,10 +364,11 @@
364364 val = get_pdm_ds_ratio(samplerate);
365365 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
366366 }
367
- regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, PDM_HPF_CF_MSK, PDM_HPF_60HZ);
367
+
368
+ regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
369
+ PDM_HPF_CF_MSK, PDM_HPF_60HZ);
368370 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
369371 PDM_HPF_LE | PDM_HPF_RE, PDM_HPF_LE | PDM_HPF_RE);
370
-
371372 return 0;
372373 }
373374
....@@ -383,7 +384,7 @@
383384
384385 rockchip_pdm_set_samplerate(pdm, params_rate(params));
385386
386
- if (pdm->version != RK_PDM_RK3328)
387
+ if (pdm->version != RK_PDM_RK3229)
387388 regmap_update_bits(pdm->regmap, PDM_CTRL0,
388389 PDM_MODE_MSK, PDM_MODE_LJ);
389390
....@@ -411,13 +412,13 @@
411412 switch (params_channels(params)) {
412413 case 8:
413414 val |= PDM_PATH3_EN;
414
- /* fallthrough */
415
+ fallthrough;
415416 case 6:
416417 val |= PDM_PATH2_EN;
417
- /* fallthrough */
418
+ fallthrough;
418419 case 4:
419420 val |= PDM_PATH1_EN;
420
- /* fallthrough */
421
+ fallthrough;
421422 case 2:
422423 val |= PDM_PATH0_EN;
423424 break;
....@@ -489,51 +490,6 @@
489490 return ret;
490491 }
491492
492
-static int rockchip_pdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
493
- struct snd_ctl_elem_info *uinfo)
494
-{
495
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
496
- uinfo->count = 1;
497
- uinfo->value.integer.min = CLK_PPM_MIN;
498
- uinfo->value.integer.max = CLK_PPM_MAX;
499
- uinfo->value.integer.step = 1;
500
-
501
- return 0;
502
-}
503
-
504
-static int rockchip_pdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
505
- struct snd_ctl_elem_value *ucontrol)
506
-{
507
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
508
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
509
-
510
- ucontrol->value.integer.value[0] = pdm->clk_ppm;
511
-
512
- return 0;
513
-}
514
-
515
-static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
516
- struct snd_ctl_elem_value *ucontrol)
517
-{
518
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
519
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
520
- int ppm = ucontrol->value.integer.value[0];
521
-
522
- if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
523
- (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
524
- return -EINVAL;
525
-
526
- return rockchip_pdm_clk_set_rate(pdm, pdm->clk_root, pdm->clk_root_rate, ppm);
527
-}
528
-
529
-static struct snd_kcontrol_new rockchip_pdm_compensation_control = {
530
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
531
- .name = "PCM Clk Compensation In PPM",
532
- .info = rockchip_pdm_clk_compensation_info,
533
- .get = rockchip_pdm_clk_compensation_get,
534
- .put = rockchip_pdm_clk_compensation_put,
535
-};
536
-
537493 static int rockchip_pdm_start_delay_info(struct snd_kcontrol *kcontrol,
538494 struct snd_ctl_elem_info *uinfo)
539495 {
....@@ -544,7 +500,6 @@
544500 uinfo->value.integer.step = 1;
545501
546502 return 0;
547
-
548503 }
549504
550505 static int rockchip_pdm_start_delay_get(struct snd_kcontrol *kcontrol,
....@@ -628,16 +583,64 @@
628583 },
629584 };
630585
586
+static int rockchip_pdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
587
+ struct snd_ctl_elem_info *uinfo)
588
+{
589
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
590
+ uinfo->count = 1;
591
+ uinfo->value.integer.min = CLK_PPM_MIN;
592
+ uinfo->value.integer.max = CLK_PPM_MAX;
593
+ uinfo->value.integer.step = 1;
594
+
595
+ return 0;
596
+}
597
+
598
+
599
+static int rockchip_pdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
600
+ struct snd_ctl_elem_value *ucontrol)
601
+
602
+{
603
+ struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
604
+ struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
605
+
606
+ ucontrol->value.integer.value[0] = pdm->clk_ppm;
607
+
608
+ return 0;
609
+}
610
+
611
+static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
612
+ struct snd_ctl_elem_value *ucontrol)
613
+{
614
+ struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
615
+ struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
616
+
617
+ int ppm = ucontrol->value.integer.value[0];
618
+
619
+ if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
620
+ (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
621
+ return -EINVAL;
622
+
623
+ return rockchip_pdm_clk_set_rate(pdm, pdm->clk_root, pdm->clk_root_rate, ppm);
624
+}
625
+
626
+static struct snd_kcontrol_new rockchip_pdm_compensation_control = {
627
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
628
+ .name = "PDM PCM Clk Compensation In PPM",
629
+ .info = rockchip_pdm_clk_compensation_info,
630
+ .get = rockchip_pdm_clk_compensation_get,
631
+ .put = rockchip_pdm_clk_compensation_put,
632
+
633
+};
634
+
631635 static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
632636 {
633637 struct rk_pdm_dev *pdm = to_info(dai);
634638
635639 dai->capture_dma_data = &pdm->capture_dma_data;
636
-
637
- if (pdm->clk_calibrate)
638
- snd_soc_add_dai_controls(dai, &rockchip_pdm_compensation_control, 1);
639640 snd_soc_add_dai_controls(dai, rockchip_pdm_controls,
640641 ARRAY_SIZE(rockchip_pdm_controls));
642
+ if (pdm->clk_calibrate)
643
+ snd_soc_add_dai_controls(dai, &rockchip_pdm_compensation_control, 1);
641644 return 0;
642645 }
643646
....@@ -748,6 +751,7 @@
748751 return ret;
749752 }
750753
754
+ rockchip_pdm_rxctrl(pdm, 0);
751755 regcache_cache_only(pdm->regmap, false);
752756 regcache_mark_dirty(pdm->regmap);
753757 ret = regcache_sync(pdm->regmap);
....@@ -844,31 +848,21 @@
844848 .cache_type = REGCACHE_FLAT,
845849 };
846850
847
-static const struct of_device_id rockchip_pdm_match[] = {
848
-#ifdef CONFIG_CPU_PX30
851
+static const struct of_device_id rockchip_pdm_match[] __maybe_unused = {
852
+ { .compatible = "rockchip,pdm",
853
+ .data = (void *)RK_PDM_RK3229 },
849854 { .compatible = "rockchip,px30-pdm",
850855 .data = (void *)RK_PDM_RK3308 },
851
-#endif
852
-#ifdef CONFIG_CPU_RK1808
853856 { .compatible = "rockchip,rk1808-pdm",
854857 .data = (void *)RK_PDM_RK3308 },
855
-#endif
856
-#ifdef CONFIG_CPU_RK3308
857858 { .compatible = "rockchip,rk3308-pdm",
858859 .data = (void *)RK_PDM_RK3308 },
859
-#endif
860
-#ifdef CONFIG_CPU_RK3328
861
- { .compatible = "rockchip,rk3328-pdm",
862
- .data = (void *)RK_PDM_RK3328 },
863
-#endif
864
-#ifdef CONFIG_CPU_RK3568
865860 { .compatible = "rockchip,rk3568-pdm",
866861 .data = (void *)RK_PDM_RV1126 },
867
-#endif
868
-#ifdef CONFIG_CPU_RV1126
862
+ { .compatible = "rockchip,rk3588-pdm",
863
+ .data = (void *)RK_PDM_RK3588 },
869864 { .compatible = "rockchip,rv1126-pdm",
870865 .data = (void *)RK_PDM_RV1126 },
871
-#endif
872866 {},
873867 };
874868 MODULE_DEVICE_TABLE(of, rockchip_pdm_match);
....@@ -923,8 +917,7 @@
923917 return PTR_ERR(pdm->reset);
924918 }
925919
926
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
927
- regs = devm_ioremap_resource(&pdev->dev, res);
920
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
928921 if (IS_ERR(regs))
929922 return PTR_ERR(regs);
930923
....@@ -940,6 +933,9 @@
940933 pdm->dev = &pdev->dev;
941934 dev_set_drvdata(&pdev->dev, pdm);
942935
936
+ pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
937
+ pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
938
+
943939 pdm->clk_calibrate =
944940 of_property_read_bool(node, "rockchip,mclk-calibrate");
945941 if (pdm->clk_calibrate) {
....@@ -950,9 +946,6 @@
950946 pdm->clk_root_initial_rate = clk_get_rate(pdm->clk_root);
951947 pdm->clk_root_rate = pdm->clk_root_initial_rate;
952948 }
953
-
954
- pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
955
- pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
956949
957950 pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
958951 if (IS_ERR(pdm->clk))