hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
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>
....@@ -19,6 +10,7 @@
1910 #include <linux/clk/rockchip.h>
2011 #include <linux/of.h>
2112 #include <linux/of_device.h>
13
+#include <linux/pinctrl/consumer.h>
2214 #include <linux/pm_runtime.h>
2315 #include <linux/rational.h>
2416 #include <linux/regmap.h>
....@@ -29,20 +21,25 @@
2921 #include "rockchip_pdm.h"
3022
3123 #define PDM_DMA_BURST_SIZE (8) /* size * width: 8*4 = 32 bytes */
32
-#define PDM_SIGNOFF_CLK_RATE (100000000)
24
+#define PDM_SIGNOFF_CLK_100M (100000000)
25
+#define PDM_SIGNOFF_CLK_300M (300000000)
3326 #define PDM_PATH_MAX (4)
34
-#define CLK_PPM_MIN (-1000)
35
-#define CLK_PPM_MAX (1000)
3627 #define PDM_DEFAULT_RATE (48000)
3728 #define PDM_START_DELAY_MS_DEFAULT (20)
3829 #define PDM_START_DELAY_MS_MIN (0)
3930 #define PDM_START_DELAY_MS_MAX (1000)
4031 #define PDM_FILTER_DELAY_MS_MIN (20)
4132 #define PDM_FILTER_DELAY_MS_MAX (1000)
33
+#define PDM_CLK_SHIFT_PPM_MAX (1000000) /* 1 ppm */
34
+#define CLK_PPM_MIN (-1000)
35
+#define CLK_PPM_MAX (1000)
36
+
37
+#define QUIRK_ALWAYS_ON BIT(0)
4238
4339 enum rk_pdm_version {
40
+ RK_PDM_RK3229,
4441 RK_PDM_RK3308,
45
- RK_PDM_RK3328,
42
+ RK_PDM_RK3588,
4643 RK_PDM_RV1126,
4744 };
4845
....@@ -54,11 +51,14 @@
5451 struct regmap *regmap;
5552 struct snd_dmaengine_dai_dma_data capture_dma_data;
5653 struct reset_control *reset;
54
+ struct pinctrl *pinctrl;
55
+ struct pinctrl_state *clk_state;
5756 unsigned int start_delay_ms;
5857 unsigned int filter_delay_ms;
5958 enum rk_pdm_version version;
6059 unsigned int clk_root_rate;
6160 unsigned int clk_root_initial_rate;
61
+ unsigned int quirks;
6262 int clk_ppm;
6363 bool clk_calibrate;
6464 };
....@@ -100,10 +100,21 @@
100100 { 4, 8000 },
101101 };
102102
103
+static const struct pdm_of_quirks {
104
+ char *quirk;
105
+ int id;
106
+} of_quirks[] = {
107
+ {
108
+ .quirk = "rockchip,always-on",
109
+ .id = QUIRK_ALWAYS_ON,
110
+ },
111
+};
112
+
103113 static unsigned int get_pdm_clk(struct rk_pdm_dev *pdm, unsigned int sr,
104
- unsigned int *clk_src, unsigned int *clk_out)
114
+ unsigned int *clk_src, unsigned int *clk_out,
115
+ unsigned int signoff)
105116 {
106
- unsigned int i, count, clk, div, rate;
117
+ unsigned int i, count, clk, div, rate, delta;
107118
108119 clk = 0;
109120 if (!sr)
....@@ -122,7 +133,9 @@
122133 break;
123134 }
124135 rate = clk_round_rate(pdm->clk, clkref[i].clk);
125
- if (rate != clkref[i].clk)
136
+ delta = clkref[i].clk / PDM_CLK_SHIFT_PPM_MAX;
137
+ if (rate < clkref[i].clk - delta ||
138
+ rate > clkref[i].clk + delta)
126139 continue;
127140 clk = clkref[i].clk;
128141 *clk_src = clkref[i].clk;
....@@ -131,7 +144,7 @@
131144 }
132145
133146 if (!clk) {
134
- clk = clk_round_rate(pdm->clk, PDM_SIGNOFF_CLK_RATE);
147
+ clk = clk_round_rate(pdm->clk, signoff);
135148 *clk_src = clk;
136149 }
137150 return clk;
....@@ -277,18 +290,20 @@
277290 return ret;
278291 }
279292
280
-static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm,
281
- unsigned int samplerate)
293
+static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm, unsigned int samplerate)
282294 {
283
- unsigned int clk_rate, clk_div;
284
- unsigned int clk_src, clk_out = 0;
285
- unsigned int val = 0, div = 0, rate, delta;
295
+
296
+ unsigned int val = 0, div = 0;
297
+ unsigned int clk_rate, clk_div, rate, delta;
298
+ unsigned int clk_src = 0, clk_out = 0, signoff = PDM_SIGNOFF_CLK_100M;
286299 unsigned long m, n;
287300 uint64_t ppm;
288
- int ret;
289301 bool change;
302
+ int ret;
290303
291
- clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out);
304
+ if (pdm->version == RK_PDM_RK3588)
305
+ signoff = PDM_SIGNOFF_CLK_300M;
306
+ clk_rate = get_pdm_clk(pdm, samplerate, &clk_src, &clk_out, signoff);
292307 if (!clk_rate)
293308 return -EINVAL;
294309
....@@ -325,6 +340,7 @@
325340 return ret;
326341
327342 if (pdm->version == RK_PDM_RK3308 ||
343
+ pdm->version == RK_PDM_RK3588 ||
328344 pdm->version == RK_PDM_RV1126) {
329345 rational_best_approximation(clk_out, clk_src,
330346 GENMASK(16 - 1, 0),
....@@ -354,7 +370,7 @@
354370 val);
355371 }
356372
357
- if (pdm->version == RK_PDM_RV1126) {
373
+ if (pdm->version == RK_PDM_RK3588 || pdm->version == RK_PDM_RV1126) {
358374 val = get_pdm_cic_ratio(clk_out);
359375 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
360376 val = samplerate_to_bit(samplerate);
....@@ -364,10 +380,11 @@
364380 val = get_pdm_ds_ratio(samplerate);
365381 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
366382 }
367
- regmap_update_bits(pdm->regmap, PDM_HPF_CTRL, PDM_HPF_CF_MSK, PDM_HPF_60HZ);
383
+
384
+ regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
385
+ PDM_HPF_CF_MSK, PDM_HPF_60HZ);
368386 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
369387 PDM_HPF_LE | PDM_HPF_RE, PDM_HPF_LE | PDM_HPF_RE);
370
-
371388 return 0;
372389 }
373390
....@@ -383,7 +400,7 @@
383400
384401 rockchip_pdm_set_samplerate(pdm, params_rate(params));
385402
386
- if (pdm->version != RK_PDM_RK3328)
403
+ if (pdm->version != RK_PDM_RK3229)
387404 regmap_update_bits(pdm->regmap, PDM_CTRL0,
388405 PDM_MODE_MSK, PDM_MODE_LJ);
389406
....@@ -411,13 +428,13 @@
411428 switch (params_channels(params)) {
412429 case 8:
413430 val |= PDM_PATH3_EN;
414
- /* fallthrough */
431
+ fallthrough;
415432 case 6:
416433 val |= PDM_PATH2_EN;
417
- /* fallthrough */
434
+ fallthrough;
418435 case 4:
419436 val |= PDM_PATH1_EN;
420
- /* fallthrough */
437
+ fallthrough;
421438 case 2:
422439 val |= PDM_PATH0_EN;
423440 break;
....@@ -489,51 +506,6 @@
489506 return ret;
490507 }
491508
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
-
537509 static int rockchip_pdm_start_delay_info(struct snd_kcontrol *kcontrol,
538510 struct snd_ctl_elem_info *uinfo)
539511 {
....@@ -544,14 +516,13 @@
544516 uinfo->value.integer.step = 1;
545517
546518 return 0;
547
-
548519 }
549520
550521 static int rockchip_pdm_start_delay_get(struct snd_kcontrol *kcontrol,
551522 struct snd_ctl_elem_value *ucontrol)
552523 {
553
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
554
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
524
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
525
+ struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
555526
556527 ucontrol->value.integer.value[0] = pdm->start_delay_ms;
557528
....@@ -561,8 +532,8 @@
561532 static int rockchip_pdm_start_delay_put(struct snd_kcontrol *kcontrol,
562533 struct snd_ctl_elem_value *ucontrol)
563534 {
564
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
565
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
535
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
536
+ struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
566537
567538 if ((ucontrol->value.integer.value[0] < PDM_START_DELAY_MS_MIN) ||
568539 (ucontrol->value.integer.value[0] > PDM_START_DELAY_MS_MAX))
....@@ -588,8 +559,8 @@
588559 static int rockchip_pdm_filter_delay_get(struct snd_kcontrol *kcontrol,
589560 struct snd_ctl_elem_value *ucontrol)
590561 {
591
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
592
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
562
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
563
+ struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
593564
594565 ucontrol->value.integer.value[0] = pdm->filter_delay_ms;
595566
....@@ -599,8 +570,8 @@
599570 static int rockchip_pdm_filter_delay_put(struct snd_kcontrol *kcontrol,
600571 struct snd_ctl_elem_value *ucontrol)
601572 {
602
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
603
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
573
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
574
+ struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
604575
605576 if ((ucontrol->value.integer.value[0] < PDM_FILTER_DELAY_MS_MIN) ||
606577 (ucontrol->value.integer.value[0] > PDM_FILTER_DELAY_MS_MAX))
....@@ -611,7 +582,31 @@
611582 return 1;
612583 }
613584
585
+static const char * const rpaths_text[] = {
586
+ "From SDI0", "From SDI1", "From SDI2", "From SDI3" };
587
+
588
+static SOC_ENUM_SINGLE_DECL(rpath3_enum, PDM_CLK_CTRL, 14, rpaths_text);
589
+static SOC_ENUM_SINGLE_DECL(rpath2_enum, PDM_CLK_CTRL, 12, rpaths_text);
590
+static SOC_ENUM_SINGLE_DECL(rpath1_enum, PDM_CLK_CTRL, 10, rpaths_text);
591
+static SOC_ENUM_SINGLE_DECL(rpath0_enum, PDM_CLK_CTRL, 8, rpaths_text);
592
+
593
+static const char * const hpf_cutoff_text[] = {
594
+ "3.79Hz", "60Hz", "243Hz", "493Hz",
595
+};
596
+
597
+static SOC_ENUM_SINGLE_DECL(hpf_cutoff_enum, PDM_HPF_CTRL,
598
+ 0, hpf_cutoff_text);
599
+
614600 static const struct snd_kcontrol_new rockchip_pdm_controls[] = {
601
+ SOC_ENUM("Receive PATH3 Source Select", rpath3_enum),
602
+ SOC_ENUM("Receive PATH2 Source Select", rpath2_enum),
603
+ SOC_ENUM("Receive PATH1 Source Select", rpath1_enum),
604
+ SOC_ENUM("Receive PATH0 Source Select", rpath0_enum),
605
+
606
+ SOC_ENUM("HPF Cutoff", hpf_cutoff_enum),
607
+ SOC_SINGLE("HPFL Switch", PDM_HPF_CTRL, 3, 1, 0),
608
+ SOC_SINGLE("HPFR Switch", PDM_HPF_CTRL, 2, 1, 0),
609
+
615610 {
616611 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
617612 .name = "PDM Start Delay Ms",
....@@ -628,6 +623,55 @@
628623 },
629624 };
630625
626
+static int rockchip_pdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
627
+ struct snd_ctl_elem_info *uinfo)
628
+{
629
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
630
+ uinfo->count = 1;
631
+ uinfo->value.integer.min = CLK_PPM_MIN;
632
+ uinfo->value.integer.max = CLK_PPM_MAX;
633
+ uinfo->value.integer.step = 1;
634
+
635
+ return 0;
636
+}
637
+
638
+
639
+static int rockchip_pdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
640
+ struct snd_ctl_elem_value *ucontrol)
641
+
642
+{
643
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
644
+ struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
645
+
646
+ ucontrol->value.integer.value[0] = pdm->clk_ppm;
647
+
648
+ return 0;
649
+}
650
+
651
+static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
652
+ struct snd_ctl_elem_value *ucontrol)
653
+{
654
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
655
+ struct rk_pdm_dev *pdm = snd_soc_component_get_drvdata(component);
656
+
657
+ int ppm = ucontrol->value.integer.value[0];
658
+
659
+ if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
660
+ (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
661
+ return -EINVAL;
662
+
663
+ return rockchip_pdm_clk_set_rate(pdm, pdm->clk_root, pdm->clk_root_rate, ppm);
664
+}
665
+
666
+static struct snd_kcontrol_new rockchip_pdm_compensation_control = {
667
+ .iface = SNDRV_CTL_ELEM_IFACE_PCM,
668
+ .name = "PDM PCM Clk Compensation In PPM",
669
+ .info = rockchip_pdm_clk_compensation_info,
670
+ .get = rockchip_pdm_clk_compensation_get,
671
+ .put = rockchip_pdm_clk_compensation_put,
672
+
673
+};
674
+
631675 static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
632676 {
633677 struct rk_pdm_dev *pdm = to_info(dai);
....@@ -635,9 +679,10 @@
635679 dai->capture_dma_data = &pdm->capture_dma_data;
636680
637681 if (pdm->clk_calibrate)
638
- snd_soc_add_dai_controls(dai, &rockchip_pdm_compensation_control, 1);
639
- snd_soc_add_dai_controls(dai, rockchip_pdm_controls,
640
- ARRAY_SIZE(rockchip_pdm_controls));
682
+ snd_soc_add_component_controls(dai->component,
683
+ &rockchip_pdm_compensation_control,
684
+ 1);
685
+
641686 return 0;
642687 }
643688
....@@ -718,7 +763,34 @@
718763
719764 static const struct snd_soc_component_driver rockchip_pdm_component = {
720765 .name = "rockchip-pdm",
766
+ .controls = rockchip_pdm_controls,
767
+ .num_controls = ARRAY_SIZE(rockchip_pdm_controls),
721768 };
769
+
770
+static int rockchip_pdm_pinctrl_select_clk_state(struct device *dev)
771
+{
772
+ struct rk_pdm_dev *pdm = dev_get_drvdata(dev);
773
+
774
+ if (IS_ERR_OR_NULL(pdm->pinctrl) || !pdm->clk_state)
775
+ return 0;
776
+
777
+ /*
778
+ * A necessary delay to make sure the correct
779
+ * frac div has been applied when resume from
780
+ * power down.
781
+ */
782
+ udelay(10);
783
+
784
+ /*
785
+ * Must disable the clk to avoid clk glitch
786
+ * when pinctrl switch from gpio to pdm clk.
787
+ */
788
+ clk_disable_unprepare(pdm->clk);
789
+ pinctrl_select_state(pdm->pinctrl, pdm->clk_state);
790
+ clk_prepare_enable(pdm->clk);
791
+
792
+ return 0;
793
+}
722794
723795 static int rockchip_pdm_runtime_suspend(struct device *dev)
724796 {
....@@ -727,6 +799,8 @@
727799 regcache_cache_only(pdm->regmap, true);
728800 clk_disable_unprepare(pdm->clk);
729801 clk_disable_unprepare(pdm->hclk);
802
+
803
+ pinctrl_pm_select_idle_state(dev);
730804
731805 return 0;
732806 }
....@@ -737,25 +811,31 @@
737811 int ret;
738812
739813 ret = clk_prepare_enable(pdm->clk);
740
- if (ret) {
741
- dev_err(pdm->dev, "clock enable failed %d\n", ret);
742
- return ret;
743
- }
814
+ if (ret)
815
+ goto err_clk;
744816
745817 ret = clk_prepare_enable(pdm->hclk);
746
- if (ret) {
747
- dev_err(pdm->dev, "hclock enable failed %d\n", ret);
748
- return ret;
749
- }
818
+ if (ret)
819
+ goto err_hclk;
750820
751821 regcache_cache_only(pdm->regmap, false);
752822 regcache_mark_dirty(pdm->regmap);
753823 ret = regcache_sync(pdm->regmap);
754
- if (ret) {
755
- clk_disable_unprepare(pdm->clk);
756
- clk_disable_unprepare(pdm->hclk);
757
- }
824
+ if (ret)
825
+ goto err_regmap;
826
+
827
+ rockchip_pdm_rxctrl(pdm, 0);
828
+
829
+ rockchip_pdm_pinctrl_select_clk_state(dev);
830
+
758831 return 0;
832
+
833
+err_regmap:
834
+ clk_disable_unprepare(pdm->hclk);
835
+err_hclk:
836
+ clk_disable_unprepare(pdm->clk);
837
+err_clk:
838
+ return ret;
759839 }
760840
761841 static bool rockchip_pdm_wr_reg(struct device *dev, unsigned int reg)
....@@ -844,31 +924,21 @@
844924 .cache_type = REGCACHE_FLAT,
845925 };
846926
847
-static const struct of_device_id rockchip_pdm_match[] = {
848
-#ifdef CONFIG_CPU_PX30
927
+static const struct of_device_id rockchip_pdm_match[] __maybe_unused = {
928
+ { .compatible = "rockchip,pdm",
929
+ .data = (void *)RK_PDM_RK3229 },
849930 { .compatible = "rockchip,px30-pdm",
850931 .data = (void *)RK_PDM_RK3308 },
851
-#endif
852
-#ifdef CONFIG_CPU_RK1808
853932 { .compatible = "rockchip,rk1808-pdm",
854933 .data = (void *)RK_PDM_RK3308 },
855
-#endif
856
-#ifdef CONFIG_CPU_RK3308
857934 { .compatible = "rockchip,rk3308-pdm",
858935 .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
865936 { .compatible = "rockchip,rk3568-pdm",
866937 .data = (void *)RK_PDM_RV1126 },
867
-#endif
868
-#ifdef CONFIG_CPU_RV1126
938
+ { .compatible = "rockchip,rk3588-pdm",
939
+ .data = (void *)RK_PDM_RK3588 },
869940 { .compatible = "rockchip,rv1126-pdm",
870941 .data = (void *)RK_PDM_RV1126 },
871
-#endif
872942 {},
873943 };
874944 MODULE_DEVICE_TABLE(of, rockchip_pdm_match);
....@@ -900,6 +970,29 @@
900970 return 0;
901971 }
902972
973
+static int rockchip_pdm_keep_clk_always_on(struct rk_pdm_dev *pdm)
974
+{
975
+ pm_runtime_forbid(pdm->dev);
976
+
977
+ dev_info(pdm->dev, "CLK-ALWAYS-ON: samplerate: %d\n", PDM_DEFAULT_RATE);
978
+
979
+ return 0;
980
+}
981
+
982
+static int rockchip_pdm_parse_quirks(struct rk_pdm_dev *pdm)
983
+{
984
+ int ret = 0, i = 0;
985
+
986
+ for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
987
+ if (device_property_read_bool(pdm->dev, of_quirks[i].quirk))
988
+ pdm->quirks |= of_quirks[i].id;
989
+
990
+ if (pdm->quirks & QUIRK_ALWAYS_ON)
991
+ ret = rockchip_pdm_keep_clk_always_on(pdm);
992
+
993
+ return ret;
994
+}
995
+
903996 static int rockchip_pdm_probe(struct platform_device *pdev)
904997 {
905998 struct device_node *node = pdev->dev.of_node;
....@@ -923,8 +1016,7 @@
9231016 return PTR_ERR(pdm->reset);
9241017 }
9251018
926
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
927
- regs = devm_ioremap_resource(&pdev->dev, res);
1019
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
9281020 if (IS_ERR(regs))
9291021 return PTR_ERR(regs);
9301022
....@@ -940,6 +1032,18 @@
9401032 pdm->dev = &pdev->dev;
9411033 dev_set_drvdata(&pdev->dev, pdm);
9421034
1035
+ pdm->pinctrl = devm_pinctrl_get(&pdev->dev);
1036
+ if (!IS_ERR_OR_NULL(pdm->pinctrl)) {
1037
+ pdm->clk_state = pinctrl_lookup_state(pdm->pinctrl, "clk");
1038
+ if (IS_ERR(pdm->clk_state)) {
1039
+ pdm->clk_state = NULL;
1040
+ dev_dbg(pdm->dev, "Have no clk pinctrl state\n");
1041
+ }
1042
+ }
1043
+
1044
+ pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
1045
+ pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
1046
+
9431047 pdm->clk_calibrate =
9441048 of_property_read_bool(node, "rockchip,mclk-calibrate");
9451049 if (pdm->clk_calibrate) {
....@@ -950,9 +1054,6 @@
9501054 pdm->clk_root_initial_rate = clk_get_rate(pdm->clk_root);
9511055 pdm->clk_root_rate = pdm->clk_root_initial_rate;
9521056 }
953
-
954
- pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
955
- pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
9561057
9571058 pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
9581059 if (IS_ERR(pdm->clk))
....@@ -966,6 +1067,27 @@
9661067 if (ret)
9671068 return ret;
9681069
1070
+ rockchip_pdm_set_samplerate(pdm, PDM_DEFAULT_RATE);
1071
+ rockchip_pdm_rxctrl(pdm, 0);
1072
+
1073
+ ret = rockchip_pdm_path_parse(pdm, node);
1074
+ if (ret != 0 && ret != -ENOENT)
1075
+ goto err_clk;
1076
+
1077
+ ret = rockchip_pdm_parse_quirks(pdm);
1078
+ if (ret)
1079
+ goto err_clk;
1080
+
1081
+ /*
1082
+ * MUST: after pm_runtime_enable step, any register R/W
1083
+ * should be wrapped with pm_runtime_get_sync/put.
1084
+ *
1085
+ * Another approach is to enable the regcache true to
1086
+ * avoid access HW registers.
1087
+ *
1088
+ * Alternatively, performing the registers R/W before
1089
+ * pm_runtime_enable is also a good option.
1090
+ */
9691091 pm_runtime_enable(&pdev->dev);
9701092 if (!pm_runtime_enabled(&pdev->dev)) {
9711093 ret = rockchip_pdm_runtime_resume(&pdev->dev);
....@@ -982,13 +1104,6 @@
9821104 goto err_suspend;
9831105 }
9841106
985
- rockchip_pdm_set_samplerate(pdm, PDM_DEFAULT_RATE);
986
- rockchip_pdm_rxctrl(pdm, 0);
987
-
988
- ret = rockchip_pdm_path_parse(pdm, node);
989
- if (ret != 0 && ret != -ENOENT)
990
- goto err_suspend;
991
-
9921107 if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
9931108 dev_info(&pdev->dev, "Used for Multi-DAI\n");
9941109 return 0;
....@@ -1000,6 +1115,8 @@
10001115 goto err_suspend;
10011116 }
10021117
1118
+ clk_disable_unprepare(pdm->hclk);
1119
+
10031120 return 0;
10041121
10051122 err_suspend:
....@@ -1007,7 +1124,7 @@
10071124 rockchip_pdm_runtime_suspend(&pdev->dev);
10081125 err_pm_disable:
10091126 pm_runtime_disable(&pdev->dev);
1010
-
1127
+err_clk:
10111128 clk_disable_unprepare(pdm->hclk);
10121129
10131130 return ret;
....@@ -1015,14 +1132,9 @@
10151132
10161133 static int rockchip_pdm_remove(struct platform_device *pdev)
10171134 {
1018
- struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev);
1019
-
10201135 pm_runtime_disable(&pdev->dev);
10211136 if (!pm_runtime_status_suspended(&pdev->dev))
10221137 rockchip_pdm_runtime_suspend(&pdev->dev);
1023
-
1024
- clk_disable_unprepare(pdm->clk);
1025
- clk_disable_unprepare(pdm->hclk);
10261138
10271139 return 0;
10281140 }