forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
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;
....@@ -207,22 +220,35 @@
207220 return snd_soc_dai_get_drvdata(dai);
208221 }
209222
210
-static void rockchip_pdm_drop_fifo(struct rk_pdm_dev *pdm)
211
-{
212
- int cnt, val, i;
213
-
214
- /* drop the dirty data */
215
- regmap_read(pdm->regmap, PDM_FIFO_CTRL, &cnt);
216
- for (i = 0; i < PDM_FIFO_CNT(cnt); i++)
217
- regmap_read(pdm->regmap, PDM_RXFIFO_DATA, &val);
218
-}
219
-
220223 static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on)
221224 {
225
+ unsigned long flags;
226
+
222227 if (on) {
223
- rockchip_pdm_drop_fifo(pdm);
228
+ /* The PDM device need to delete some unused data
229
+ * since the pdm of various manufacturers can not
230
+ * be stable quickly. This is done by commit "ASoC:
231
+ * rockchip: pdm: Fix pop noise in the beginning".
232
+ *
233
+ * But we do not know how many data we delete, this
234
+ * cause channel disorder. For example, we record
235
+ * two channel 24-bit sound, then delete some starting
236
+ * data. Because the deleted starting data is uncertain,
237
+ * the next data may be left or right channel and cause
238
+ * channel disorder.
239
+ *
240
+ * Luckily, we can use the PDM_RX_CLR to fix this.
241
+ * Use the PDM_RX_CLR to clear fifo written data and
242
+ * address, but can not clear the read data and address.
243
+ * In initial state, the read data and address are zero.
244
+ */
245
+ local_irq_save(flags);
246
+ regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
247
+ PDM_RX_CLR_MASK,
248
+ PDM_RX_CLR_WR);
224249 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
225250 PDM_DMA_RD_MSK, PDM_DMA_RD_EN);
251
+ local_irq_restore(flags);
226252 } else {
227253 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
228254 PDM_DMA_RD_MSK, PDM_DMA_RD_DIS);
....@@ -264,18 +290,20 @@
264290 return ret;
265291 }
266292
267
-static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm,
268
- unsigned int samplerate)
293
+static int rockchip_pdm_set_samplerate(struct rk_pdm_dev *pdm, unsigned int samplerate)
269294 {
270
- unsigned int clk_rate, clk_div;
271
- unsigned int clk_src, clk_out = 0;
272
- 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;
273299 unsigned long m, n;
274300 uint64_t ppm;
275
- int ret;
276301 bool change;
302
+ int ret;
277303
278
- 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);
279307 if (!clk_rate)
280308 return -EINVAL;
281309
....@@ -312,6 +340,7 @@
312340 return ret;
313341
314342 if (pdm->version == RK_PDM_RK3308 ||
343
+ pdm->version == RK_PDM_RK3588 ||
315344 pdm->version == RK_PDM_RV1126) {
316345 rational_best_approximation(clk_out, clk_src,
317346 GENMASK(16 - 1, 0),
....@@ -341,7 +370,7 @@
341370 val);
342371 }
343372
344
- if (pdm->version == RK_PDM_RV1126) {
373
+ if (pdm->version == RK_PDM_RK3588 || pdm->version == RK_PDM_RV1126) {
345374 val = get_pdm_cic_ratio(clk_out);
346375 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_CIC_RATIO_MSK, val);
347376 val = samplerate_to_bit(samplerate);
....@@ -351,10 +380,11 @@
351380 val = get_pdm_ds_ratio(samplerate);
352381 regmap_update_bits(pdm->regmap, PDM_CLK_CTRL, PDM_DS_RATIO_MSK, val);
353382 }
354
- 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);
355386 regmap_update_bits(pdm->regmap, PDM_HPF_CTRL,
356387 PDM_HPF_LE | PDM_HPF_RE, PDM_HPF_LE | PDM_HPF_RE);
357
-
358388 return 0;
359389 }
360390
....@@ -370,7 +400,7 @@
370400
371401 rockchip_pdm_set_samplerate(pdm, params_rate(params));
372402
373
- if (pdm->version != RK_PDM_RK3328)
403
+ if (pdm->version != RK_PDM_RK3229)
374404 regmap_update_bits(pdm->regmap, PDM_CTRL0,
375405 PDM_MODE_MSK, PDM_MODE_LJ);
376406
....@@ -398,13 +428,13 @@
398428 switch (params_channels(params)) {
399429 case 8:
400430 val |= PDM_PATH3_EN;
401
- /* fallthrough */
431
+ fallthrough;
402432 case 6:
403433 val |= PDM_PATH2_EN;
404
- /* fallthrough */
434
+ fallthrough;
405435 case 4:
406436 val |= PDM_PATH1_EN;
407
- /* fallthrough */
437
+ fallthrough;
408438 case 2:
409439 val |= PDM_PATH0_EN;
410440 break;
....@@ -476,51 +506,6 @@
476506 return ret;
477507 }
478508
479
-static int rockchip_pdm_clk_compensation_info(struct snd_kcontrol *kcontrol,
480
- struct snd_ctl_elem_info *uinfo)
481
-{
482
- uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
483
- uinfo->count = 1;
484
- uinfo->value.integer.min = CLK_PPM_MIN;
485
- uinfo->value.integer.max = CLK_PPM_MAX;
486
- uinfo->value.integer.step = 1;
487
-
488
- return 0;
489
-}
490
-
491
-static int rockchip_pdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
492
- struct snd_ctl_elem_value *ucontrol)
493
-{
494
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
495
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
496
-
497
- ucontrol->value.integer.value[0] = pdm->clk_ppm;
498
-
499
- return 0;
500
-}
501
-
502
-static int rockchip_pdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
503
- struct snd_ctl_elem_value *ucontrol)
504
-{
505
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
506
- struct rk_pdm_dev *pdm = snd_soc_dai_get_drvdata(dai);
507
- int ppm = ucontrol->value.integer.value[0];
508
-
509
- if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
510
- (ucontrol->value.integer.value[0] > CLK_PPM_MAX))
511
- return -EINVAL;
512
-
513
- return rockchip_pdm_clk_set_rate(pdm, pdm->clk_root, pdm->clk_root_rate, ppm);
514
-}
515
-
516
-static struct snd_kcontrol_new rockchip_pdm_compensation_control = {
517
- .iface = SNDRV_CTL_ELEM_IFACE_PCM,
518
- .name = "PCM Clk Compensation In PPM",
519
- .info = rockchip_pdm_clk_compensation_info,
520
- .get = rockchip_pdm_clk_compensation_get,
521
- .put = rockchip_pdm_clk_compensation_put,
522
-};
523
-
524509 static int rockchip_pdm_start_delay_info(struct snd_kcontrol *kcontrol,
525510 struct snd_ctl_elem_info *uinfo)
526511 {
....@@ -531,14 +516,13 @@
531516 uinfo->value.integer.step = 1;
532517
533518 return 0;
534
-
535519 }
536520
537521 static int rockchip_pdm_start_delay_get(struct snd_kcontrol *kcontrol,
538522 struct snd_ctl_elem_value *ucontrol)
539523 {
540
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
541
- 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);
542526
543527 ucontrol->value.integer.value[0] = pdm->start_delay_ms;
544528
....@@ -548,8 +532,8 @@
548532 static int rockchip_pdm_start_delay_put(struct snd_kcontrol *kcontrol,
549533 struct snd_ctl_elem_value *ucontrol)
550534 {
551
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
552
- 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);
553537
554538 if ((ucontrol->value.integer.value[0] < PDM_START_DELAY_MS_MIN) ||
555539 (ucontrol->value.integer.value[0] > PDM_START_DELAY_MS_MAX))
....@@ -575,8 +559,8 @@
575559 static int rockchip_pdm_filter_delay_get(struct snd_kcontrol *kcontrol,
576560 struct snd_ctl_elem_value *ucontrol)
577561 {
578
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
579
- 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);
580564
581565 ucontrol->value.integer.value[0] = pdm->filter_delay_ms;
582566
....@@ -586,8 +570,8 @@
586570 static int rockchip_pdm_filter_delay_put(struct snd_kcontrol *kcontrol,
587571 struct snd_ctl_elem_value *ucontrol)
588572 {
589
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
590
- 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);
591575
592576 if ((ucontrol->value.integer.value[0] < PDM_FILTER_DELAY_MS_MIN) ||
593577 (ucontrol->value.integer.value[0] > PDM_FILTER_DELAY_MS_MAX))
....@@ -598,7 +582,31 @@
598582 return 1;
599583 }
600584
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
+
601600 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
+
602610 {
603611 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
604612 .name = "PDM Start Delay Ms",
....@@ -615,6 +623,55 @@
615623 },
616624 };
617625
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
+
618675 static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
619676 {
620677 struct rk_pdm_dev *pdm = to_info(dai);
....@@ -622,9 +679,10 @@
622679 dai->capture_dma_data = &pdm->capture_dma_data;
623680
624681 if (pdm->clk_calibrate)
625
- snd_soc_add_dai_controls(dai, &rockchip_pdm_compensation_control, 1);
626
- snd_soc_add_dai_controls(dai, rockchip_pdm_controls,
627
- ARRAY_SIZE(rockchip_pdm_controls));
682
+ snd_soc_add_component_controls(dai->component,
683
+ &rockchip_pdm_compensation_control,
684
+ 1);
685
+
628686 return 0;
629687 }
630688
....@@ -705,7 +763,34 @@
705763
706764 static const struct snd_soc_component_driver rockchip_pdm_component = {
707765 .name = "rockchip-pdm",
766
+ .controls = rockchip_pdm_controls,
767
+ .num_controls = ARRAY_SIZE(rockchip_pdm_controls),
708768 };
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
+}
709794
710795 static int rockchip_pdm_runtime_suspend(struct device *dev)
711796 {
....@@ -714,6 +799,8 @@
714799 regcache_cache_only(pdm->regmap, true);
715800 clk_disable_unprepare(pdm->clk);
716801 clk_disable_unprepare(pdm->hclk);
802
+
803
+ pinctrl_pm_select_idle_state(dev);
717804
718805 return 0;
719806 }
....@@ -724,25 +811,31 @@
724811 int ret;
725812
726813 ret = clk_prepare_enable(pdm->clk);
727
- if (ret) {
728
- dev_err(pdm->dev, "clock enable failed %d\n", ret);
729
- return ret;
730
- }
814
+ if (ret)
815
+ goto err_clk;
731816
732817 ret = clk_prepare_enable(pdm->hclk);
733
- if (ret) {
734
- dev_err(pdm->dev, "hclock enable failed %d\n", ret);
735
- return ret;
736
- }
818
+ if (ret)
819
+ goto err_hclk;
737820
738821 regcache_cache_only(pdm->regmap, false);
739822 regcache_mark_dirty(pdm->regmap);
740823 ret = regcache_sync(pdm->regmap);
741
- if (ret) {
742
- clk_disable_unprepare(pdm->clk);
743
- clk_disable_unprepare(pdm->hclk);
744
- }
824
+ if (ret)
825
+ goto err_regmap;
826
+
827
+ rockchip_pdm_rxctrl(pdm, 0);
828
+
829
+ rockchip_pdm_pinctrl_select_clk_state(dev);
830
+
745831 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;
746839 }
747840
748841 static bool rockchip_pdm_wr_reg(struct device *dev, unsigned int reg)
....@@ -831,31 +924,21 @@
831924 .cache_type = REGCACHE_FLAT,
832925 };
833926
834
-static const struct of_device_id rockchip_pdm_match[] = {
835
-#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 },
836930 { .compatible = "rockchip,px30-pdm",
837931 .data = (void *)RK_PDM_RK3308 },
838
-#endif
839
-#ifdef CONFIG_CPU_RK1808
840932 { .compatible = "rockchip,rk1808-pdm",
841933 .data = (void *)RK_PDM_RK3308 },
842
-#endif
843
-#ifdef CONFIG_CPU_RK3308
844934 { .compatible = "rockchip,rk3308-pdm",
845935 .data = (void *)RK_PDM_RK3308 },
846
-#endif
847
-#ifdef CONFIG_CPU_RK3328
848
- { .compatible = "rockchip,rk3328-pdm",
849
- .data = (void *)RK_PDM_RK3328 },
850
-#endif
851
-#ifdef CONFIG_CPU_RK3568
852936 { .compatible = "rockchip,rk3568-pdm",
853937 .data = (void *)RK_PDM_RV1126 },
854
-#endif
855
-#ifdef CONFIG_CPU_RV1126
938
+ { .compatible = "rockchip,rk3588-pdm",
939
+ .data = (void *)RK_PDM_RK3588 },
856940 { .compatible = "rockchip,rv1126-pdm",
857941 .data = (void *)RK_PDM_RV1126 },
858
-#endif
859942 {},
860943 };
861944 MODULE_DEVICE_TABLE(of, rockchip_pdm_match);
....@@ -887,6 +970,29 @@
887970 return 0;
888971 }
889972
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
+
890996 static int rockchip_pdm_probe(struct platform_device *pdev)
891997 {
892998 struct device_node *node = pdev->dev.of_node;
....@@ -910,8 +1016,7 @@
9101016 return PTR_ERR(pdm->reset);
9111017 }
9121018
913
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
914
- regs = devm_ioremap_resource(&pdev->dev, res);
1019
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
9151020 if (IS_ERR(regs))
9161021 return PTR_ERR(regs);
9171022
....@@ -927,6 +1032,18 @@
9271032 pdm->dev = &pdev->dev;
9281033 dev_set_drvdata(&pdev->dev, pdm);
9291034
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
+
9301047 pdm->clk_calibrate =
9311048 of_property_read_bool(node, "rockchip,mclk-calibrate");
9321049 if (pdm->clk_calibrate) {
....@@ -937,9 +1054,6 @@
9371054 pdm->clk_root_initial_rate = clk_get_rate(pdm->clk_root);
9381055 pdm->clk_root_rate = pdm->clk_root_initial_rate;
9391056 }
940
-
941
- pdm->start_delay_ms = PDM_START_DELAY_MS_DEFAULT;
942
- pdm->filter_delay_ms = PDM_FILTER_DELAY_MS_MIN;
9431057
9441058 pdm->clk = devm_clk_get(&pdev->dev, "pdm_clk");
9451059 if (IS_ERR(pdm->clk))
....@@ -953,6 +1067,27 @@
9531067 if (ret)
9541068 return ret;
9551069
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
+ */
9561091 pm_runtime_enable(&pdev->dev);
9571092 if (!pm_runtime_enabled(&pdev->dev)) {
9581093 ret = rockchip_pdm_runtime_resume(&pdev->dev);
....@@ -969,21 +1104,18 @@
9691104 goto err_suspend;
9701105 }
9711106
972
- rockchip_pdm_set_samplerate(pdm, PDM_DEFAULT_RATE);
973
- rockchip_pdm_rxctrl(pdm, 0);
974
-
975
- ret = rockchip_pdm_path_parse(pdm, node);
976
- if (ret != 0 && ret != -ENOENT)
977
- goto err_suspend;
978
-
979
- if (of_property_read_bool(node, "rockchip,no-dmaengine"))
1107
+ if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
1108
+ dev_info(&pdev->dev, "Used for Multi-DAI\n");
9801109 return 0;
1110
+ }
9811111
9821112 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
9831113 if (ret) {
9841114 dev_err(&pdev->dev, "could not register pcm: %d\n", ret);
9851115 goto err_suspend;
9861116 }
1117
+
1118
+ clk_disable_unprepare(pdm->hclk);
9871119
9881120 return 0;
9891121
....@@ -992,7 +1124,7 @@
9921124 rockchip_pdm_runtime_suspend(&pdev->dev);
9931125 err_pm_disable:
9941126 pm_runtime_disable(&pdev->dev);
995
-
1127
+err_clk:
9961128 clk_disable_unprepare(pdm->hclk);
9971129
9981130 return ret;
....@@ -1000,14 +1132,9 @@
10001132
10011133 static int rockchip_pdm_remove(struct platform_device *pdev)
10021134 {
1003
- struct rk_pdm_dev *pdm = dev_get_drvdata(&pdev->dev);
1004
-
10051135 pm_runtime_disable(&pdev->dev);
10061136 if (!pm_runtime_status_suspended(&pdev->dev))
10071137 rockchip_pdm_runtime_suspend(&pdev->dev);
1008
-
1009
- clk_disable_unprepare(pdm->clk);
1010
- clk_disable_unprepare(pdm->hclk);
10111138
10121139 return 0;
10131140 }