forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/rockchip/rockchip_i2s.c
....@@ -1,13 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* sound/soc/rockchip/rockchip_i2s.c
23 *
34 * ALSA SoC Audio Layer - Rockchip I2S Controller driver
45 *
56 * Copyright (c) 2014 Rockchip Electronics Co. Ltd.
67 * Author: Jianqun <jay.xu@rock-chips.com>
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License version 2 as
10
- * published by the Free Software Foundation.
118 */
129
1310 #include <linux/module.h>
....@@ -19,7 +16,6 @@
1916 #include <linux/clk/rockchip.h>
2017 #include <linux/pm_runtime.h>
2118 #include <linux/regmap.h>
22
-#include <linux/reset.h>
2319 #include <linux/spinlock.h>
2420 #include <sound/pcm_params.h>
2521 #include <sound/dmaengine_pcm.h>
....@@ -48,8 +44,9 @@
4844
4945 struct regmap *regmap;
5046 struct regmap *grf;
51
- struct reset_control *reset_m;
52
- struct reset_control *reset_h;
47
+
48
+ bool has_capture;
49
+ bool has_playback;
5350
5451 /*
5552 * Used to indicate the tx/rx status.
....@@ -60,7 +57,8 @@
6057 bool rx_start;
6158 bool is_master_mode;
6259 const struct rk_i2s_pins *pins;
63
- unsigned int bclk_fs;
60
+ unsigned int bclk_ratio;
61
+ spinlock_t lock; /* tx/rx lock */
6462 unsigned int clk_trcm;
6563
6664 unsigned int mclk_root_rate;
....@@ -69,9 +67,6 @@
6967 bool mclk_calibrate;
7068
7169 };
72
-
73
-/* txctrl/rxctrl lock */
74
-static DEFINE_SPINLOCK(lock);
7570
7671 static int i2s_runtime_suspend(struct device *dev)
7772 {
....@@ -109,27 +104,44 @@
109104 return snd_soc_dai_get_drvdata(dai);
110105 }
111106
112
-static void rockchip_i2s_reset(struct rk_i2s_dev *i2s)
107
+static int rockchip_i2s_clear(struct rk_i2s_dev *i2s)
113108 {
114
- if (!IS_ERR(i2s->reset_m))
115
- reset_control_assert(i2s->reset_m);
116
- if (!IS_ERR(i2s->reset_h))
117
- reset_control_assert(i2s->reset_h);
118
- udelay(1);
119
- if (!IS_ERR(i2s->reset_m))
120
- reset_control_deassert(i2s->reset_m);
121
- if (!IS_ERR(i2s->reset_h))
122
- reset_control_deassert(i2s->reset_h);
123
- regcache_mark_dirty(i2s->regmap);
124
- regcache_sync(i2s->regmap);
109
+ unsigned int clr = I2S_CLR_TXC | I2S_CLR_RXC;
110
+ unsigned int val = 0;
111
+ int ret;
112
+
113
+ /*
114
+ * Workaround for FIFO clear on SLAVE mode:
115
+ *
116
+ * A Suggest to do reset hclk domain and then do mclk
117
+ * domain, especially for SLAVE mode without CLK in.
118
+ * at last, recovery regmap config.
119
+ *
120
+ * B Suggest to switch to MASTER, and then do FIFO clr,
121
+ * at last, bring back to SLAVE.
122
+ *
123
+ * Now we choose plan B here.
124
+ */
125
+ if (!i2s->is_master_mode)
126
+ regmap_update_bits(i2s->regmap, I2S_CKR,
127
+ I2S_CKR_MSS_MASK, I2S_CKR_MSS_MASTER);
128
+ regmap_update_bits(i2s->regmap, I2S_CLR, clr, clr);
129
+
130
+ ret = regmap_read_poll_timeout_atomic(i2s->regmap, I2S_CLR, val,
131
+ !(val & clr), 10, 100);
132
+ if (!i2s->is_master_mode)
133
+ regmap_update_bits(i2s->regmap, I2S_CKR,
134
+ I2S_CKR_MSS_MASK, I2S_CKR_MSS_SLAVE);
135
+ if (ret < 0)
136
+ dev_warn(i2s->dev, "failed to clear fifo on %s mode\n",
137
+ i2s->is_master_mode ? "master" : "slave");
138
+
139
+ return ret;
125140 }
126141
127142 static void rockchip_snd_txctrl(struct rk_i2s_dev *i2s, int on)
128143 {
129
- unsigned int val = 0;
130
- int retry = 10;
131
-
132
- spin_lock(&lock);
144
+ spin_lock(&i2s->lock);
133145 if (on) {
134146 regmap_update_bits(i2s->regmap, I2S_DMACR,
135147 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_ENABLE);
....@@ -153,33 +165,15 @@
153165 I2S_XFER_RXS_STOP);
154166
155167 udelay(150);
156
- regmap_update_bits(i2s->regmap, I2S_CLR,
157
- I2S_CLR_TXC | I2S_CLR_RXC,
158
- I2S_CLR_TXC | I2S_CLR_RXC);
159
-
160
- regmap_read(i2s->regmap, I2S_CLR, &val);
161
-
162
- /* Should wait for clear operation to finish */
163
- while (val) {
164
- regmap_read(i2s->regmap, I2S_CLR, &val);
165
- retry--;
166
- if (!retry) {
167
- dev_warn(i2s->dev, "reset\n");
168
- rockchip_i2s_reset(i2s);
169
- break;
170
- }
171
- }
168
+ rockchip_i2s_clear(i2s);
172169 }
173170 }
174
- spin_unlock(&lock);
171
+ spin_unlock(&i2s->lock);
175172 }
176173
177174 static void rockchip_snd_rxctrl(struct rk_i2s_dev *i2s, int on)
178175 {
179
- unsigned int val = 0;
180
- int retry = 10;
181
-
182
- spin_lock(&lock);
176
+ spin_lock(&i2s->lock);
183177 if (on) {
184178 regmap_update_bits(i2s->regmap, I2S_DMACR,
185179 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_ENABLE);
....@@ -203,25 +197,10 @@
203197 I2S_XFER_RXS_STOP);
204198
205199 udelay(150);
206
- regmap_update_bits(i2s->regmap, I2S_CLR,
207
- I2S_CLR_TXC | I2S_CLR_RXC,
208
- I2S_CLR_TXC | I2S_CLR_RXC);
209
-
210
- regmap_read(i2s->regmap, I2S_CLR, &val);
211
-
212
- /* Should wait for clear operation to finish */
213
- while (val) {
214
- regmap_read(i2s->regmap, I2S_CLR, &val);
215
- retry--;
216
- if (!retry) {
217
- dev_warn(i2s->dev, "reset\n");
218
- rockchip_i2s_reset(i2s);
219
- break;
220
- }
221
- }
200
+ rockchip_i2s_clear(i2s);
222201 }
223202 }
224
- spin_unlock(&lock);
203
+ spin_unlock(&i2s->lock);
225204 }
226205
227206 static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
....@@ -343,7 +322,7 @@
343322
344323 if (i2s->is_master_mode) {
345324 mclk_rate = clk_get_rate(i2s->mclk);
346
- bclk_rate = i2s->bclk_fs * params_rate(params);
325
+ bclk_rate = i2s->bclk_ratio * params_rate(params);
347326 if (!bclk_rate)
348327 return -EINVAL;
349328
....@@ -471,6 +450,16 @@
471450 return ret;
472451 }
473452
453
+static int rockchip_i2s_set_bclk_ratio(struct snd_soc_dai *dai,
454
+ unsigned int ratio)
455
+{
456
+ struct rk_i2s_dev *i2s = to_info(dai);
457
+
458
+ i2s->bclk_ratio = ratio;
459
+
460
+ return 0;
461
+}
462
+
474463 static int rockchip_i2s_clk_set_rate(struct rk_i2s_dev *i2s,
475464 struct clk *clk, unsigned long rate,
476465 int ppm)
....@@ -510,6 +499,9 @@
510499 unsigned int root_rate, div, delta;
511500 uint64_t ppm;
512501 int ret;
502
+
503
+ if (rate == 0)
504
+ return 0;
513505
514506 if (i2s->mclk_calibrate) {
515507 ret = rockchip_i2s_clk_set_rate(i2s, i2s->mclk_root,
....@@ -591,8 +583,9 @@
591583 {
592584 struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
593585
594
- dai->capture_dma_data = &i2s->capture_dma_data;
595
- dai->playback_dma_data = &i2s->playback_dma_data;
586
+ snd_soc_dai_init_dma_data(dai,
587
+ i2s->has_playback ? &i2s->playback_dma_data : NULL,
588
+ i2s->has_capture ? &i2s->capture_dma_data : NULL);
596589
597590 if (i2s->mclk_calibrate)
598591 snd_soc_add_dai_controls(dai, &rockchip_i2s_compensation_control, 1);
....@@ -602,6 +595,7 @@
602595
603596 static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
604597 .hw_params = rockchip_i2s_hw_params,
598
+ .set_bclk_ratio = rockchip_i2s_set_bclk_ratio,
605599 .set_sysclk = rockchip_i2s_set_sysclk,
606600 .set_fmt = rockchip_i2s_set_fmt,
607601 .trigger = rockchip_i2s_trigger,
....@@ -609,28 +603,6 @@
609603
610604 static struct snd_soc_dai_driver rockchip_i2s_dai = {
611605 .probe = rockchip_i2s_dai_probe,
612
- .playback = {
613
- .stream_name = "Playback",
614
- .channels_min = 2,
615
- .channels_max = 8,
616
- .rates = SNDRV_PCM_RATE_8000_192000,
617
- .formats = (SNDRV_PCM_FMTBIT_S8 |
618
- SNDRV_PCM_FMTBIT_S16_LE |
619
- SNDRV_PCM_FMTBIT_S20_3LE |
620
- SNDRV_PCM_FMTBIT_S24_LE |
621
- SNDRV_PCM_FMTBIT_S32_LE),
622
- },
623
- .capture = {
624
- .stream_name = "Capture",
625
- .channels_min = 2,
626
- .channels_max = 2,
627
- .rates = SNDRV_PCM_RATE_8000_192000,
628
- .formats = (SNDRV_PCM_FMTBIT_S8 |
629
- SNDRV_PCM_FMTBIT_S16_LE |
630
- SNDRV_PCM_FMTBIT_S20_3LE |
631
- SNDRV_PCM_FMTBIT_S24_LE |
632
- SNDRV_PCM_FMTBIT_S32_LE),
633
- },
634606 .ops = &rockchip_i2s_dai_ops,
635607 };
636608
....@@ -726,7 +698,7 @@
726698 .shift = 11,
727699 };
728700
729
-static const struct of_device_id rockchip_i2s_match[] = {
701
+static const struct of_device_id rockchip_i2s_match[] __maybe_unused = {
730702 #ifdef CONFIG_CPU_PX30
731703 { .compatible = "rockchip,px30-i2s", },
732704 #endif
....@@ -743,6 +715,9 @@
743715 #ifdef CONFIG_CPU_RK3188
744716 { .compatible = "rockchip,rk3188-i2s", },
745717 #endif
718
+#ifdef CONFIG_CPU_RK322X
719
+ { .compatible = "rockchip,rk3228-i2s", },
720
+#endif
746721 #ifdef CONFIG_CPU_RK3288
747722 { .compatible = "rockchip,rk3288-i2s", },
748723 #endif
....@@ -751,6 +726,9 @@
751726 #endif
752727 #ifdef CONFIG_CPU_RK3328
753728 { .compatible = "rockchip,rk3328-i2s", },
729
+#endif
730
+#ifdef CONFIG_CPU_RK3366
731
+ { .compatible = "rockchip,rk3366-i2s", },
754732 #endif
755733 #ifdef CONFIG_CPU_RK3368
756734 { .compatible = "rockchip,rk3368-i2s", },
....@@ -764,21 +742,102 @@
764742 {},
765743 };
766744
745
+static int rockchip_i2s_init_dai(struct rk_i2s_dev *i2s, struct resource *res,
746
+ struct snd_soc_dai_driver **dp)
747
+{
748
+ struct device_node *node = i2s->dev->of_node;
749
+ struct snd_soc_dai_driver *dai;
750
+ struct property *dma_names;
751
+ const char *dma_name;
752
+ unsigned int val;
753
+
754
+ of_property_for_each_string(node, "dma-names", dma_names, dma_name) {
755
+ if (!strcmp(dma_name, "tx"))
756
+ i2s->has_playback = true;
757
+ if (!strcmp(dma_name, "rx"))
758
+ i2s->has_capture = true;
759
+ }
760
+
761
+ dai = devm_kmemdup(i2s->dev, &rockchip_i2s_dai,
762
+ sizeof(*dai), GFP_KERNEL);
763
+ if (!dai)
764
+ return -ENOMEM;
765
+
766
+ if (i2s->has_playback) {
767
+ dai->playback.stream_name = "Playback";
768
+ dai->playback.channels_min = 2;
769
+ dai->playback.channels_max = 8;
770
+ dai->playback.rates = SNDRV_PCM_RATE_8000_192000;
771
+ dai->playback.formats = SNDRV_PCM_FMTBIT_S8 |
772
+ SNDRV_PCM_FMTBIT_S16_LE |
773
+ SNDRV_PCM_FMTBIT_S20_3LE |
774
+ SNDRV_PCM_FMTBIT_S24_LE |
775
+ SNDRV_PCM_FMTBIT_S32_LE;
776
+
777
+ i2s->playback_dma_data.addr = res->start + I2S_TXDR;
778
+ i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
779
+ i2s->playback_dma_data.maxburst = 8;
780
+
781
+ if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
782
+ if (val >= 2 && val <= 8)
783
+ dai->playback.channels_max = val;
784
+ }
785
+ }
786
+
787
+ if (i2s->has_capture) {
788
+ dai->capture.stream_name = "Capture";
789
+ dai->capture.channels_min = 2;
790
+ dai->capture.channels_max = 8;
791
+ dai->capture.rates = SNDRV_PCM_RATE_8000_192000;
792
+ dai->capture.formats = SNDRV_PCM_FMTBIT_S8 |
793
+ SNDRV_PCM_FMTBIT_S16_LE |
794
+ SNDRV_PCM_FMTBIT_S20_3LE |
795
+ SNDRV_PCM_FMTBIT_S24_LE |
796
+ SNDRV_PCM_FMTBIT_S32_LE;
797
+
798
+ i2s->capture_dma_data.addr = res->start + I2S_RXDR;
799
+ i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
800
+ i2s->capture_dma_data.maxburst = 8;
801
+
802
+ if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
803
+ if (val >= 2 && val <= 8)
804
+ dai->capture.channels_max = val;
805
+ }
806
+ }
807
+
808
+ i2s->clk_trcm = I2S_CKR_TRCM_TXRX;
809
+ if (!of_property_read_u32(node, "rockchip,clk-trcm", &val)) {
810
+ if (val >= 0 && val <= 2) {
811
+ i2s->clk_trcm = val << I2S_CKR_TRCM_SHIFT;
812
+ if (i2s->clk_trcm)
813
+ dai->symmetric_rates = 1;
814
+ }
815
+ }
816
+
817
+ regmap_update_bits(i2s->regmap, I2S_CKR,
818
+ I2S_CKR_TRCM_MASK, i2s->clk_trcm);
819
+
820
+ if (dp)
821
+ *dp = dai;
822
+
823
+ return 0;
824
+}
825
+
767826 static int rockchip_i2s_probe(struct platform_device *pdev)
768827 {
769828 struct device_node *node = pdev->dev.of_node;
770829 const struct of_device_id *of_id;
771830 struct rk_i2s_dev *i2s;
772
- struct snd_soc_dai_driver *soc_dai;
831
+ struct snd_soc_dai_driver *dai;
773832 struct resource *res;
774833 void __iomem *regs;
775834 int ret;
776
- int val;
777835
778836 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
779837 if (!i2s)
780838 return -ENOMEM;
781839
840
+ spin_lock_init(&i2s->lock);
782841 i2s->dev = &pdev->dev;
783842
784843 i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
....@@ -790,8 +849,21 @@
790849 i2s->pins = of_id->data;
791850 }
792851
793
- i2s->reset_m = devm_reset_control_get(&pdev->dev, "reset-m");
794
- i2s->reset_h = devm_reset_control_get(&pdev->dev, "reset-h");
852
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
853
+ if (IS_ERR(regs))
854
+ return PTR_ERR(regs);
855
+
856
+ i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
857
+ &rockchip_i2s_regmap_config);
858
+ if (IS_ERR(i2s->regmap)) {
859
+ dev_err(&pdev->dev,
860
+ "Failed to initialise managed register map\n");
861
+ return PTR_ERR(i2s->regmap);
862
+ }
863
+
864
+ i2s->bclk_ratio = 64;
865
+
866
+ dev_set_drvdata(&pdev->dev, i2s);
795867
796868 i2s->mclk_calibrate =
797869 of_property_read_bool(node, "rockchip,mclk-calibrate");
....@@ -802,6 +874,12 @@
802874
803875 i2s->mclk_root_initial_rate = clk_get_rate(i2s->mclk_root);
804876 i2s->mclk_root_rate = i2s->mclk_root_initial_rate;
877
+ }
878
+
879
+ i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");
880
+ if (IS_ERR(i2s->mclk)) {
881
+ dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");
882
+ return PTR_ERR(i2s->mclk);
805883 }
806884
807885 /* try to prepare related clocks */
....@@ -816,35 +894,6 @@
816894 return ret;
817895 }
818896
819
- i2s->mclk = devm_clk_get(&pdev->dev, "i2s_clk");
820
- if (IS_ERR(i2s->mclk)) {
821
- dev_err(&pdev->dev, "Can't retrieve i2s master clock\n");
822
- return PTR_ERR(i2s->mclk);
823
- }
824
-
825
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
826
- regs = devm_ioremap_resource(&pdev->dev, res);
827
- if (IS_ERR(regs))
828
- return PTR_ERR(regs);
829
-
830
- i2s->regmap = devm_regmap_init_mmio(&pdev->dev, regs,
831
- &rockchip_i2s_regmap_config);
832
- if (IS_ERR(i2s->regmap)) {
833
- dev_err(&pdev->dev,
834
- "Failed to initialise managed register map\n");
835
- return PTR_ERR(i2s->regmap);
836
- }
837
-
838
- i2s->playback_dma_data.addr = res->start + I2S_TXDR;
839
- i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
840
- i2s->playback_dma_data.maxburst = 8;
841
-
842
- i2s->capture_dma_data.addr = res->start + I2S_RXDR;
843
- i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
844
- i2s->capture_dma_data.maxburst = 8;
845
-
846
- dev_set_drvdata(&pdev->dev, i2s);
847
-
848897 pm_runtime_enable(&pdev->dev);
849898 if (!pm_runtime_enabled(&pdev->dev)) {
850899 ret = i2s_runtime_resume(&pdev->dev);
....@@ -852,57 +901,24 @@
852901 goto err_pm_disable;
853902 }
854903
855
- soc_dai = devm_kmemdup(&pdev->dev, &rockchip_i2s_dai,
856
- sizeof(*soc_dai), GFP_KERNEL);
857
- if (!soc_dai) {
858
- ret = -ENOMEM;
904
+ ret = rockchip_i2s_init_dai(i2s, res, &dai);
905
+ if (ret)
859906 goto err_pm_disable;
860
- }
861
-
862
- if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) {
863
- if (val >= 2 && val <= 8)
864
- soc_dai->playback.channels_max = val;
865
- }
866
-
867
- if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) {
868
- if (val >= 2 && val <= 8)
869
- soc_dai->capture.channels_max = val;
870
- }
871
-
872
- if (of_property_read_bool(node, "rockchip,playback-only"))
873
- soc_dai->capture.channels_min = 0;
874
- else if (of_property_read_bool(node, "rockchip,capture-only"))
875
- soc_dai->playback.channels_min = 0;
876
-
877
- i2s->bclk_fs = 64;
878
- if (!of_property_read_u32(node, "rockchip,bclk-fs", &val)) {
879
- if ((val >= 32) && (val % 2 == 0))
880
- i2s->bclk_fs = val;
881
- }
882
-
883
- i2s->clk_trcm = I2S_CKR_TRCM_TXRX;
884
- if (!of_property_read_u32(node, "rockchip,clk-trcm", &val)) {
885
- if (val >= 0 && val <= 2) {
886
- i2s->clk_trcm = val << I2S_CKR_TRCM_SHIFT;
887
- if (i2s->clk_trcm)
888
- soc_dai->symmetric_rates = 1;
889
- }
890
- }
891
-
892
- regmap_update_bits(i2s->regmap, I2S_CKR,
893
- I2S_CKR_TRCM_MASK, i2s->clk_trcm);
894907
895908 ret = devm_snd_soc_register_component(&pdev->dev,
896909 &rockchip_i2s_component,
897
- soc_dai, 1);
910
+ dai, 1);
898911
899912 if (ret) {
900913 dev_err(&pdev->dev, "Could not register DAI\n");
901914 goto err_suspend;
902915 }
903916
904
- if (of_property_read_bool(node, "rockchip,no-dmaengine"))
905
- return ret;
917
+ if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
918
+ dev_info(&pdev->dev, "Used for Multi-DAI\n");
919
+ return 0;
920
+ }
921
+
906922 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
907923 if (ret) {
908924 dev_err(&pdev->dev, "Could not register PCM\n");
....@@ -917,6 +933,8 @@
917933 err_pm_disable:
918934 pm_runtime_disable(&pdev->dev);
919935
936
+ clk_disable_unprepare(i2s->hclk);
937
+
920938 return ret;
921939 }
922940