hc
2024-01-05 071106ecf68c401173c58808b1cf5f68cc50d390
kernel/sound/soc/rockchip/rockchip_i2s_tdm.c
....@@ -19,6 +19,7 @@
1919 #include <linux/clk.h>
2020 #include <linux/clk-provider.h>
2121 #include <linux/clk/rockchip.h>
22
+#include <linux/pinctrl/consumer.h>
2223 #include <linux/pm_runtime.h>
2324 #include <linux/regmap.h>
2425 #include <linux/reset.h>
....@@ -27,11 +28,41 @@
2728 #include <sound/dmaengine_pcm.h>
2829
2930 #include "rockchip_i2s_tdm.h"
31
+#include "rockchip_dlp_pcm.h"
32
+#include "rockchip_utils.h"
3033
3134 #define DRV_NAME "rockchip-i2s-tdm"
3235
3336 #if IS_ENABLED(CONFIG_CPU_PX30) || IS_ENABLED(CONFIG_CPU_RK1808) || IS_ENABLED(CONFIG_CPU_RK3308)
3437 #define HAVE_SYNC_RESET
38
+#endif
39
+
40
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
41
+/*
42
+ * Example: RK3588
43
+ *
44
+ * Use I2S2_2CH as Clk-Gen to serve TDM_MULTI_LANES
45
+ *
46
+ * I2S2_2CH ----> BCLK,I2S_LRCK --------> I2S0_8CH_TX (Slave TRCM-TXONLY)
47
+ * |
48
+ * |--------> BCLK,TDM_SYNC --------> TDM Device (Slave)
49
+ *
50
+ * Note:
51
+ *
52
+ * I2S2_2CH_MCLK: BCLK
53
+ * I2S2_2CH_SCLK: I2S_LRCK (GPIO2_B7)
54
+ * I2S2_2CH_LRCK: TDM_SYNC (GPIO2_C0)
55
+ *
56
+ */
57
+
58
+#define CLK_MAX_COUNT 1000
59
+#define NSAMPLES 4
60
+#define XFER_EN 0x3
61
+#define XFER_DIS 0x0
62
+#define CKR_V(m, r, t) ((m - 1) << 16 | (r - 1) << 8 | (t - 1) << 0)
63
+#define I2S_XCR_IBM_V(v) ((v) & I2S_TXCR_IBM_MASK)
64
+#define I2S_XCR_IBM_NORMAL I2S_TXCR_IBM_NORMAL
65
+#define I2S_XCR_IBM_LSJM I2S_TXCR_IBM_LSJM
3566 #endif
3667
3768 #define DEFAULT_MCLK_FS 256
....@@ -41,6 +72,7 @@
4172 #define CLK_PPM_MIN (-1000)
4273 #define CLK_PPM_MAX (1000)
4374 #define MAXBURST_PER_FIFO 8
75
+#define WAIT_TIME_MS_MAX 10000
4476
4577 #define QUIRK_ALWAYS_ON BIT(0)
4678 #define QUIRK_HDMI_PATH BIT(1)
....@@ -85,8 +117,11 @@
85117 struct snd_dmaengine_dai_dma_data capture_dma_data;
86118 struct snd_dmaengine_dai_dma_data playback_dma_data;
87119 struct snd_pcm_substream *substreams[SNDRV_PCM_STREAM_LAST + 1];
120
+ unsigned int wait_time[SNDRV_PCM_STREAM_LAST + 1];
88121 struct reset_control *tx_reset;
89122 struct reset_control *rx_reset;
123
+ struct pinctrl *pinctrl;
124
+ struct pinctrl_state *clk_state;
90125 const struct rk_i2s_soc_data *soc_data;
91126 #ifdef HAVE_SYNC_RESET
92127 void __iomem *cru_base;
....@@ -98,6 +133,7 @@
98133 bool mclk_calibrate;
99134 bool tdm_mode;
100135 bool tdm_fsync_half_frame;
136
+ bool is_dma_active[SNDRV_PCM_STREAM_LAST + 1];
101137 unsigned int mclk_rx_freq;
102138 unsigned int mclk_tx_freq;
103139 unsigned int mclk_root0_freq;
....@@ -109,9 +145,19 @@
109145 unsigned int i2s_sdis[CH_GRP_MAX];
110146 unsigned int i2s_sdos[CH_GRP_MAX];
111147 unsigned int quirks;
148
+ unsigned int lrck_ratio;
112149 int clk_ppm;
113150 atomic_t refcount;
114151 spinlock_t lock; /* xfer lock */
152
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
153
+ struct snd_soc_dai *clk_src_dai;
154
+ struct gpio_desc *i2s_lrck_gpio;
155
+ struct gpio_desc *tdm_fsync_gpio;
156
+ unsigned int tx_lanes;
157
+ unsigned int rx_lanes;
158
+ void __iomem *clk_src_base;
159
+ bool is_tdm_multi_lanes;
160
+#endif
115161 };
116162
117163 static struct i2s_of_quirks {
....@@ -159,6 +205,20 @@
159205 clk_disable_unprepare(i2s_tdm->mclk_tx);
160206 clk_disable_unprepare(i2s_tdm->mclk_rx);
161207
208
+ pinctrl_pm_select_idle_state(dev);
209
+
210
+ return 0;
211
+}
212
+
213
+static int rockchip_i2s_tdm_pinctrl_select_clk_state(struct device *dev)
214
+{
215
+ struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
216
+
217
+ if (IS_ERR_OR_NULL(i2s_tdm->pinctrl) || !i2s_tdm->clk_state)
218
+ return 0;
219
+
220
+ pinctrl_select_state(i2s_tdm->pinctrl, i2s_tdm->clk_state);
221
+
162222 return 0;
163223 }
164224
....@@ -166,6 +226,13 @@
166226 {
167227 struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
168228 int ret;
229
+
230
+ /*
231
+ * pinctrl default state is invoked by ASoC framework, so,
232
+ * we just handle clk state here if DT assigned.
233
+ */
234
+ if (i2s_tdm->is_master_mode)
235
+ rockchip_i2s_tdm_pinctrl_select_clk_state(dev);
169236
170237 ret = clk_prepare_enable(i2s_tdm->mclk_tx);
171238 if (ret)
....@@ -180,6 +247,13 @@
180247 ret = regcache_sync(i2s_tdm->regmap);
181248 if (ret)
182249 goto err_regmap;
250
+
251
+ /*
252
+ * should be placed after regcache sync done to back
253
+ * to the slave mode and then enable clk state.
254
+ */
255
+ if (!i2s_tdm->is_master_mode)
256
+ rockchip_i2s_tdm_pinctrl_select_clk_state(dev);
183257
184258 return 0;
185259
....@@ -206,6 +280,18 @@
206280 return (val & I2S_XFER_TXS_START);
207281 else
208282 return (val & I2S_XFER_RXS_START);
283
+}
284
+
285
+static inline bool is_dma_active(struct rk_i2s_tdm_dev *i2s_tdm, int stream)
286
+{
287
+ unsigned int val;
288
+
289
+ regmap_read(i2s_tdm->regmap, I2S_DMACR, &val);
290
+
291
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK)
292
+ return (val & I2S_DMACR_TDE_MASK);
293
+ else
294
+ return (val & I2S_DMACR_RDE_MASK);
209295 }
210296
211297 #ifdef HAVE_SYNC_RESET
....@@ -266,7 +352,7 @@
266352 writeq(val, addr);
267353 break;
268354 }
269
- /* fallthrough */
355
+ fallthrough;
270356 default:
271357 local_irq_save(flags);
272358 writel(BIT(tx_offset) | (BIT(tx_offset) << 16),
....@@ -328,7 +414,7 @@
328414 writeq(val, addr);
329415 break;
330416 }
331
- /* fallthrough */
417
+ fallthrough;
332418 default:
333419 local_irq_save(flags);
334420 writel((BIT(tx_offset) << 16),
....@@ -395,6 +481,12 @@
395481 default:
396482 return -EINVAL;
397483 }
484
+
485
+ regmap_update_bits(i2s_tdm->regmap, I2S_CLR, clr, clr);
486
+ ret = regmap_read_poll_timeout_atomic(i2s_tdm->regmap, I2S_CLR, val,
487
+ !(val & clr), 10, 100);
488
+ if (ret == 0)
489
+ return 0;
398490
399491 /*
400492 * Workaround for FIFO clear on SLAVE mode:
....@@ -508,9 +600,289 @@
508600 rockchip_i2s_tdm_fifo_xrun_detect(i2s_tdm, stream, 1);
509601 }
510602
603
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
604
+static const char * const tx_lanes_text[] = { "Auto", "SDOx1", "SDOx2", "SDOx3", "SDOx4" };
605
+static const char * const rx_lanes_text[] = { "Auto", "SDIx1", "SDIx2", "SDIx3", "SDIx4" };
606
+static const struct soc_enum tx_lanes_enum =
607
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_lanes_text), tx_lanes_text);
608
+static const struct soc_enum rx_lanes_enum =
609
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_lanes_text), rx_lanes_text);
610
+
611
+static int rockchip_i2s_tdm_tx_lanes_get(struct snd_kcontrol *kcontrol,
612
+ struct snd_ctl_elem_value *ucontrol)
613
+{
614
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
615
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
616
+
617
+ ucontrol->value.enumerated.item[0] = i2s_tdm->tx_lanes;
618
+
619
+ return 0;
620
+}
621
+
622
+static int rockchip_i2s_tdm_tx_lanes_put(struct snd_kcontrol *kcontrol,
623
+ struct snd_ctl_elem_value *ucontrol)
624
+{
625
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
626
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
627
+ int num;
628
+
629
+ num = ucontrol->value.enumerated.item[0];
630
+ if (num >= ARRAY_SIZE(tx_lanes_text))
631
+ return -EINVAL;
632
+
633
+ i2s_tdm->tx_lanes = num;
634
+
635
+ return 1;
636
+}
637
+
638
+static int rockchip_i2s_tdm_rx_lanes_get(struct snd_kcontrol *kcontrol,
639
+ struct snd_ctl_elem_value *ucontrol)
640
+{
641
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
642
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
643
+
644
+ ucontrol->value.enumerated.item[0] = i2s_tdm->rx_lanes;
645
+
646
+ return 0;
647
+}
648
+
649
+static int rockchip_i2s_tdm_rx_lanes_put(struct snd_kcontrol *kcontrol,
650
+ struct snd_ctl_elem_value *ucontrol)
651
+{
652
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
653
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
654
+ int num;
655
+
656
+ num = ucontrol->value.enumerated.item[0];
657
+ if (num >= ARRAY_SIZE(rx_lanes_text))
658
+ return -EINVAL;
659
+
660
+ i2s_tdm->rx_lanes = num;
661
+
662
+ return 1;
663
+}
664
+
665
+static int rockchip_i2s_tdm_get_lanes(struct rk_i2s_tdm_dev *i2s_tdm, int stream)
666
+{
667
+ unsigned int lanes = 1;
668
+
669
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
670
+ if (i2s_tdm->tx_lanes)
671
+ lanes = i2s_tdm->tx_lanes;
672
+ } else {
673
+ if (i2s_tdm->rx_lanes)
674
+ lanes = i2s_tdm->rx_lanes;
675
+ }
676
+
677
+ return lanes;
678
+}
679
+
680
+static struct snd_soc_dai *rockchip_i2s_tdm_find_dai(struct device_node *np)
681
+{
682
+ struct snd_soc_dai_link_component dai_component = { 0 };
683
+
684
+ dai_component.of_node = np;
685
+
686
+ return snd_soc_find_dai_with_mutex(&dai_component);
687
+}
688
+
689
+static int rockchip_i2s_tdm_multi_lanes_set_clk(struct snd_pcm_substream *substream,
690
+ struct snd_pcm_hw_params *params,
691
+ struct snd_soc_dai *cpu_dai)
692
+{
693
+ struct rk_i2s_tdm_dev *i2s_tdm = to_info(cpu_dai);
694
+ struct snd_soc_dai *dai = i2s_tdm->clk_src_dai;
695
+ unsigned int div, mclk_rate;
696
+ unsigned int lanes, ch_per_lane;
697
+
698
+ lanes = rockchip_i2s_tdm_get_lanes(i2s_tdm, substream->stream);
699
+ ch_per_lane = params_channels(params) / lanes;
700
+ mclk_rate = ch_per_lane * params_rate(params) * 32;
701
+ div = ch_per_lane / 2;
702
+
703
+ /* Do nothing when use external clk src */
704
+ if (dai && dai->driver->ops) {
705
+ if (dai->driver->ops->set_sysclk)
706
+ dai->driver->ops->set_sysclk(dai, substream->stream, mclk_rate, 0);
707
+
708
+ writel(XFER_DIS, i2s_tdm->clk_src_base + I2S_XFER);
709
+ writel(CKR_V(64, div, div), i2s_tdm->clk_src_base + I2S_CKR);
710
+ writel(XFER_EN, i2s_tdm->clk_src_base + I2S_XFER);
711
+ }
712
+
713
+ i2s_tdm->lrck_ratio = div;
714
+ i2s_tdm->mclk_tx_freq = mclk_rate;
715
+ i2s_tdm->mclk_rx_freq = mclk_rate;
716
+
717
+ return 0;
718
+}
719
+
720
+static inline int tdm_multi_lanes_clk_assert_h(const struct gpio_desc *desc)
721
+{
722
+ int cnt = CLK_MAX_COUNT;
723
+
724
+ while (gpiod_get_raw_value(desc) && --cnt)
725
+ ;
726
+
727
+ return cnt;
728
+}
729
+
730
+static inline int tdm_multi_lanes_clk_assert_l(const struct gpio_desc *desc)
731
+{
732
+ int cnt = CLK_MAX_COUNT;
733
+
734
+ while (!gpiod_get_raw_value(desc) && --cnt)
735
+ ;
736
+
737
+ return cnt;
738
+}
739
+
740
+static inline bool rockchip_i2s_tdm_clk_valid(struct rk_i2s_tdm_dev *i2s_tdm)
741
+{
742
+ int dc_h = CLK_MAX_COUNT, dc_l = CLK_MAX_COUNT;
743
+
744
+ /*
745
+ * TBD: optimize debounce and get value
746
+ *
747
+ * debounce at least one cycle found, otherwise, the clk ref maybe
748
+ * not on the fly.
749
+ */
750
+
751
+ /* check HIGH-Level */
752
+ dc_h = tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
753
+ if (!dc_h)
754
+ return false;
755
+
756
+ /* check LOW-Level */
757
+ dc_l = tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
758
+ if (!dc_l)
759
+ return false;
760
+
761
+ /* check HIGH-Level */
762
+ dc_h = tdm_multi_lanes_clk_assert_h(i2s_tdm->tdm_fsync_gpio);
763
+ if (!dc_h)
764
+ return false;
765
+
766
+ /* check LOW-Level */
767
+ dc_l = tdm_multi_lanes_clk_assert_l(i2s_tdm->tdm_fsync_gpio);
768
+ if (!dc_l)
769
+ return false;
770
+
771
+ return true;
772
+}
773
+
774
+static void __maybe_unused rockchip_i2s_tdm_gpio_clk_meas(struct rk_i2s_tdm_dev *i2s_tdm,
775
+ const struct gpio_desc *desc,
776
+ const char *name)
777
+{
778
+ int h[NSAMPLES], l[NSAMPLES], i;
779
+
780
+ dev_dbg(i2s_tdm->dev, "%s:\n", name);
781
+
782
+ if (!rockchip_i2s_tdm_clk_valid(i2s_tdm))
783
+ return;
784
+
785
+ for (i = 0; i < NSAMPLES; i++) {
786
+ h[i] = tdm_multi_lanes_clk_assert_h(desc);
787
+ l[i] = tdm_multi_lanes_clk_assert_l(desc);
788
+ }
789
+
790
+ for (i = 0; i < NSAMPLES; i++)
791
+ dev_dbg(i2s_tdm->dev, "H[%d]: %2d, L[%d]: %2d\n",
792
+ i, CLK_MAX_COUNT - h[i], i, CLK_MAX_COUNT - l[i]);
793
+}
794
+
795
+static int rockchip_i2s_tdm_multi_lanes_start(struct rk_i2s_tdm_dev *i2s_tdm, int stream)
796
+{
797
+ unsigned int tdm_h = 0, tdm_l = 0, i2s_h = 0, i2s_l = 0;
798
+ unsigned int msk, val, reg, fmt;
799
+ unsigned long flags;
800
+
801
+ if (!i2s_tdm->tdm_fsync_gpio || !i2s_tdm->i2s_lrck_gpio)
802
+ return -ENOSYS;
803
+
804
+ if (i2s_tdm->lrck_ratio != 4 && i2s_tdm->lrck_ratio != 8)
805
+ return -EINVAL;
806
+
807
+ if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
808
+ msk = I2S_XFER_TXS_MASK;
809
+ val = I2S_XFER_TXS_START;
810
+ reg = I2S_TXCR;
811
+ } else {
812
+ msk = I2S_XFER_RXS_MASK;
813
+ val = I2S_XFER_RXS_START;
814
+ reg = I2S_RXCR;
815
+ }
816
+
817
+ regmap_read(i2s_tdm->regmap, reg, &fmt);
818
+ fmt = I2S_XCR_IBM_V(fmt);
819
+
820
+ local_irq_save(flags);
821
+
822
+ if (!rockchip_i2s_tdm_clk_valid(i2s_tdm)) {
823
+ local_irq_restore(flags);
824
+ dev_err(i2s_tdm->dev, "Invalid LRCK / FSYNC measured by ref IO\n");
825
+ return -EINVAL;
826
+ }
827
+
828
+ switch (fmt) {
829
+ case I2S_XCR_IBM_NORMAL:
830
+ tdm_h = tdm_multi_lanes_clk_assert_h(i2s_tdm->tdm_fsync_gpio);
831
+ tdm_l = tdm_multi_lanes_clk_assert_l(i2s_tdm->tdm_fsync_gpio);
832
+
833
+ if (i2s_tdm->lrck_ratio == 8) {
834
+ tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
835
+ tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
836
+ tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
837
+ tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
838
+ }
839
+
840
+ i2s_l = tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
841
+
842
+ if (stream == SNDRV_PCM_STREAM_CAPTURE)
843
+ i2s_h = tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
844
+ break;
845
+ case I2S_XCR_IBM_LSJM:
846
+ tdm_l = tdm_multi_lanes_clk_assert_l(i2s_tdm->tdm_fsync_gpio);
847
+ tdm_h = tdm_multi_lanes_clk_assert_h(i2s_tdm->tdm_fsync_gpio);
848
+
849
+ if (i2s_tdm->lrck_ratio == 8) {
850
+ tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
851
+ tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
852
+ tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
853
+ tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
854
+ }
855
+
856
+ tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
857
+
858
+ i2s_l = tdm_multi_lanes_clk_assert_l(i2s_tdm->i2s_lrck_gpio);
859
+ i2s_h = tdm_multi_lanes_clk_assert_h(i2s_tdm->i2s_lrck_gpio);
860
+ break;
861
+ default:
862
+ local_irq_restore(flags);
863
+ return -EINVAL;
864
+ }
865
+
866
+ regmap_update_bits(i2s_tdm->regmap, I2S_XFER, msk, val);
867
+ local_irq_restore(flags);
868
+
869
+ dev_dbg(i2s_tdm->dev, "STREAM[%d]: TDM-H: %d, TDM-L: %d, I2S-H: %d, I2S-L: %d\n", stream,
870
+ CLK_MAX_COUNT - tdm_h, CLK_MAX_COUNT - tdm_l,
871
+ CLK_MAX_COUNT - i2s_h, CLK_MAX_COUNT - i2s_l);
872
+
873
+ return 0;
874
+}
875
+#endif
876
+
511877 static void rockchip_i2s_tdm_xfer_start(struct rk_i2s_tdm_dev *i2s_tdm,
512878 int stream)
513879 {
880
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
881
+ if (i2s_tdm->is_tdm_multi_lanes) {
882
+ if (rockchip_i2s_tdm_multi_lanes_start(i2s_tdm, stream) != -ENOSYS)
883
+ return;
884
+ }
885
+#endif
514886 if (i2s_tdm->clk_trcm) {
515887 rockchip_i2s_tdm_reset_assert(i2s_tdm);
516888 regmap_update_bits(i2s_tdm->regmap, I2S_XFER,
....@@ -586,6 +958,9 @@
586958 int stream = substream->stream;
587959 int bstream = SNDRV_PCM_STREAM_LAST - stream;
588960
961
+ /* store the current state, prepare for resume if necessary */
962
+ i2s_tdm->is_dma_active[bstream] = is_dma_active(i2s_tdm, bstream);
963
+
589964 /* disable dma for both tx and rx */
590965 rockchip_i2s_tdm_dma_ctrl(i2s_tdm, stream, 0);
591966 rockchip_i2s_tdm_dma_ctrl(i2s_tdm, bstream, 0);
....@@ -601,7 +976,8 @@
601976 * just resume bstream, because current stream will be
602977 * startup in the trigger-cmd-START
603978 */
604
- rockchip_i2s_tdm_dma_ctrl(i2s_tdm, bstream, 1);
979
+ if (i2s_tdm->is_dma_active[bstream])
980
+ rockchip_i2s_tdm_dma_ctrl(i2s_tdm, bstream, 1);
605981 rockchip_i2s_tdm_xfer_start(i2s_tdm, bstream);
606982 }
607983
....@@ -654,6 +1030,19 @@
6541030 case SND_SOC_DAIFMT_CBM_CFM:
6551031 val = I2S_CKR_MSS_SLAVE;
6561032 i2s_tdm->is_master_mode = false;
1033
+ /*
1034
+ * TRCM require TX/RX enabled at the same time, or need the one
1035
+ * which provide clk enabled at first for master mode.
1036
+ *
1037
+ * It is quite a different for slave mode which does not have
1038
+ * these restrictions, because the BCLK / LRCK are provided by
1039
+ * external master devices.
1040
+ *
1041
+ * So, we just set the right clk path value on TRCM register on
1042
+ * stage probe and then drop the trcm value to make TX / RX work
1043
+ * independently.
1044
+ */
1045
+ i2s_tdm->clk_trcm = 0;
6571046 break;
6581047 default:
6591048 ret = -EINVAL;
....@@ -924,13 +1313,26 @@
9241313 switch (i2s_tdm->clk_trcm) {
9251314 case I2S_CKR_TRCM_TXONLY:
9261315 parent = clk_get_parent(i2s_tdm->mclk_tx);
1316
+ /*
1317
+ * API clk_has_parent is not available yet on GKI, so we
1318
+ * use clk_set_parent directly and ignore the ret value.
1319
+ * if the API has addressed on GKI, should remove it.
1320
+ */
1321
+#ifdef CONFIG_NO_GKI
9271322 if (clk_has_parent(i2s_tdm->mclk_rx, parent))
9281323 ret = clk_set_parent(i2s_tdm->mclk_rx, parent);
1324
+#else
1325
+ clk_set_parent(i2s_tdm->mclk_rx, parent);
1326
+#endif
9291327 break;
9301328 case I2S_CKR_TRCM_RXONLY:
9311329 parent = clk_get_parent(i2s_tdm->mclk_rx);
1330
+#ifdef CONFIG_NO_GKI
9321331 if (clk_has_parent(i2s_tdm->mclk_tx, parent))
9331332 ret = clk_set_parent(i2s_tdm->mclk_tx, parent);
1333
+#else
1334
+ clk_set_parent(i2s_tdm->mclk_tx, parent);
1335
+#endif
9341336 break;
9351337 }
9361338
....@@ -1202,6 +1604,32 @@
12021604 unsigned int reg_fmt, fmt;
12031605 int ret = 0;
12041606
1607
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
1608
+ if (i2s_tdm->is_tdm_multi_lanes) {
1609
+ unsigned int lanes = rockchip_i2s_tdm_get_lanes(i2s_tdm,
1610
+ substream->stream);
1611
+
1612
+ switch (lanes) {
1613
+ case 4:
1614
+ ret = I2S_CHN_8;
1615
+ break;
1616
+ case 3:
1617
+ ret = I2S_CHN_6;
1618
+ break;
1619
+ case 2:
1620
+ ret = I2S_CHN_4;
1621
+ break;
1622
+ case 1:
1623
+ ret = I2S_CHN_2;
1624
+ break;
1625
+ default:
1626
+ ret = -EINVAL;
1627
+ break;
1628
+ }
1629
+
1630
+ return ret;
1631
+ }
1632
+#endif
12051633 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
12061634 reg_fmt = I2S_TXCR;
12071635 else
....@@ -1251,6 +1679,25 @@
12511679 return ret;
12521680 }
12531681
1682
+static void rockchip_i2s_tdm_get_performance(struct snd_pcm_substream *substream,
1683
+ struct snd_pcm_hw_params *params,
1684
+ struct snd_soc_dai *dai,
1685
+ unsigned int csr)
1686
+{
1687
+ struct rk_i2s_tdm_dev *i2s_tdm = to_info(dai);
1688
+ unsigned int tdl;
1689
+ int fifo;
1690
+
1691
+ regmap_read(i2s_tdm->regmap, I2S_DMACR, &tdl);
1692
+
1693
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1694
+ fifo = I2S_DMACR_TDL_V(tdl) * I2S_TXCR_CSR_V(csr);
1695
+ else
1696
+ fifo = I2S_DMACR_RDL_V(tdl) * I2S_RXCR_CSR_V(csr);
1697
+
1698
+ rockchip_utils_get_performance(substream, params, dai, fifo);
1699
+}
1700
+
12541701 static int rockchip_i2s_tdm_hw_params(struct snd_pcm_substream *substream,
12551702 struct snd_pcm_hw_params *params,
12561703 struct snd_soc_dai *dai)
....@@ -1260,8 +1707,12 @@
12601707 struct clk *mclk;
12611708 int ret = 0;
12621709 unsigned int val = 0;
1263
- unsigned int mclk_rate, bclk_rate, div_bclk = 4, div_lrck = 64;
1710
+ unsigned int mclk_rate, bclk_rate, lrck_rate, div_bclk = 4, div_lrck = 64;
12641711
1712
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
1713
+ if (i2s_tdm->is_tdm_multi_lanes)
1714
+ rockchip_i2s_tdm_multi_lanes_set_clk(substream, params, dai);
1715
+#endif
12651716 dma_data = snd_soc_dai_get_dma_data(dai, substream);
12661717 dma_data->maxburst = MAXBURST_PER_FIFO * params_channels(params) / 2;
12671718
....@@ -1274,13 +1725,14 @@
12741725 goto err;
12751726
12761727 mclk_rate = clk_get_rate(mclk);
1277
- bclk_rate = i2s_tdm->bclk_fs * params_rate(params);
1728
+ lrck_rate = params_rate(params) * i2s_tdm->lrck_ratio;
1729
+ bclk_rate = i2s_tdm->bclk_fs * lrck_rate;
12781730 if (!bclk_rate) {
12791731 ret = -EINVAL;
12801732 goto err;
12811733 }
12821734 div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
1283
- div_lrck = bclk_rate / params_rate(params);
1735
+ div_lrck = bclk_rate / lrck_rate;
12841736
12851737 switch (params_format(params)) {
12861738 case SNDRV_PCM_FORMAT_S8:
....@@ -1308,6 +1760,8 @@
13081760 if (ret < 0)
13091761 goto err;
13101762
1763
+ rockchip_i2s_tdm_get_performance(substream, params, dai, ret);
1764
+
13111765 val |= ret;
13121766 if (!is_params_dirty(substream, dai, div_bclk, div_lrck, val))
13131767 return 0;
....@@ -1321,6 +1775,13 @@
13211775
13221776 err:
13231777 return ret;
1778
+}
1779
+static int rockchip_i2s_tdm_hw_free(struct snd_pcm_substream *substream,
1780
+ struct snd_soc_dai *dai)
1781
+{
1782
+ rockchip_utils_put_performance(substream, dai);
1783
+
1784
+ return 0;
13241785 }
13251786
13261787 static int rockchip_i2s_tdm_trigger(struct snd_pcm_substream *substream,
....@@ -1385,8 +1846,8 @@
13851846 static int rockchip_i2s_tdm_clk_compensation_get(struct snd_kcontrol *kcontrol,
13861847 struct snd_ctl_elem_value *ucontrol)
13871848 {
1388
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
1389
- struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
1849
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1850
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
13901851
13911852 ucontrol->value.integer.value[0] = i2s_tdm->clk_ppm;
13921853
....@@ -1396,8 +1857,8 @@
13961857 static int rockchip_i2s_tdm_clk_compensation_put(struct snd_kcontrol *kcontrol,
13971858 struct snd_ctl_elem_value *ucontrol)
13981859 {
1399
- struct snd_soc_dai *dai = snd_kcontrol_chip(kcontrol);
1400
- struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
1860
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
1861
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
14011862 int ret = 0, ppm = 0;
14021863
14031864 if ((ucontrol->value.integer.value[0] < CLK_PPM_MIN) ||
....@@ -1509,10 +1970,116 @@
15091970 return 0;
15101971 }
15111972
1973
+static const char * const rpaths_text[] = {
1974
+ "From SDI0", "From SDI1", "From SDI2", "From SDI3" };
1975
+
1976
+static const char * const tpaths_text[] = {
1977
+ "From PATH0", "From PATH1", "From PATH2", "From PATH3" };
1978
+
1979
+/* TXCR */
1980
+static SOC_ENUM_SINGLE_DECL(tpath3_enum, I2S_TXCR, 29, tpaths_text);
1981
+static SOC_ENUM_SINGLE_DECL(tpath2_enum, I2S_TXCR, 27, tpaths_text);
1982
+static SOC_ENUM_SINGLE_DECL(tpath1_enum, I2S_TXCR, 25, tpaths_text);
1983
+static SOC_ENUM_SINGLE_DECL(tpath0_enum, I2S_TXCR, 23, tpaths_text);
1984
+
1985
+/* RXCR */
1986
+static SOC_ENUM_SINGLE_DECL(rpath3_enum, I2S_RXCR, 23, rpaths_text);
1987
+static SOC_ENUM_SINGLE_DECL(rpath2_enum, I2S_RXCR, 21, rpaths_text);
1988
+static SOC_ENUM_SINGLE_DECL(rpath1_enum, I2S_RXCR, 19, rpaths_text);
1989
+static SOC_ENUM_SINGLE_DECL(rpath0_enum, I2S_RXCR, 17, rpaths_text);
1990
+
1991
+static int rockchip_i2s_tdm_wait_time_info(struct snd_kcontrol *kcontrol,
1992
+ struct snd_ctl_elem_info *uinfo)
1993
+{
1994
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1995
+ uinfo->count = 1;
1996
+ uinfo->value.integer.min = 0;
1997
+ uinfo->value.integer.max = WAIT_TIME_MS_MAX;
1998
+ uinfo->value.integer.step = 1;
1999
+
2000
+ return 0;
2001
+}
2002
+
2003
+static int rockchip_i2s_tdm_rd_wait_time_get(struct snd_kcontrol *kcontrol,
2004
+ struct snd_ctl_elem_value *ucontrol)
2005
+{
2006
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2007
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
2008
+
2009
+ ucontrol->value.integer.value[0] = i2s_tdm->wait_time[SNDRV_PCM_STREAM_CAPTURE];
2010
+
2011
+ return 0;
2012
+}
2013
+
2014
+static int rockchip_i2s_tdm_rd_wait_time_put(struct snd_kcontrol *kcontrol,
2015
+ struct snd_ctl_elem_value *ucontrol)
2016
+{
2017
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2018
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
2019
+
2020
+ if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX)
2021
+ return -EINVAL;
2022
+
2023
+ i2s_tdm->wait_time[SNDRV_PCM_STREAM_CAPTURE] = ucontrol->value.integer.value[0];
2024
+
2025
+ return 1;
2026
+}
2027
+
2028
+static int rockchip_i2s_tdm_wr_wait_time_get(struct snd_kcontrol *kcontrol,
2029
+ struct snd_ctl_elem_value *ucontrol)
2030
+{
2031
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2032
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
2033
+
2034
+ ucontrol->value.integer.value[0] = i2s_tdm->wait_time[SNDRV_PCM_STREAM_PLAYBACK];
2035
+
2036
+ return 0;
2037
+}
2038
+
2039
+static int rockchip_i2s_tdm_wr_wait_time_put(struct snd_kcontrol *kcontrol,
2040
+ struct snd_ctl_elem_value *ucontrol)
2041
+{
2042
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
2043
+ struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_component_get_drvdata(component);
2044
+
2045
+ if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX)
2046
+ return -EINVAL;
2047
+
2048
+ i2s_tdm->wait_time[SNDRV_PCM_STREAM_PLAYBACK] = ucontrol->value.integer.value[0];
2049
+
2050
+ return 1;
2051
+}
2052
+
2053
+#define SAI_PCM_WAIT_TIME(xname, xhandler_get, xhandler_put) \
2054
+{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, \
2055
+ .info = rockchip_i2s_tdm_wait_time_info, \
2056
+ .get = xhandler_get, .put = xhandler_put }
2057
+
15122058 static const struct snd_kcontrol_new rockchip_i2s_tdm_snd_controls[] = {
2059
+ SOC_ENUM("Receive PATH3 Source Select", rpath3_enum),
2060
+ SOC_ENUM("Receive PATH2 Source Select", rpath2_enum),
2061
+ SOC_ENUM("Receive PATH1 Source Select", rpath1_enum),
2062
+ SOC_ENUM("Receive PATH0 Source Select", rpath0_enum),
2063
+ SOC_ENUM("Transmit SDO3 Source Select", tpath3_enum),
2064
+ SOC_ENUM("Transmit SDO2 Source Select", tpath2_enum),
2065
+ SOC_ENUM("Transmit SDO1 Source Select", tpath1_enum),
2066
+ SOC_ENUM("Transmit SDO0 Source Select", tpath0_enum),
2067
+
15132068 SOC_ENUM_EXT("I2STDM Digital Loopback Mode", loopback_mode,
15142069 rockchip_i2s_tdm_loopback_get,
15152070 rockchip_i2s_tdm_loopback_put),
2071
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
2072
+ SOC_ENUM_EXT("Transmit SDOx Select", tx_lanes_enum,
2073
+ rockchip_i2s_tdm_tx_lanes_get, rockchip_i2s_tdm_tx_lanes_put),
2074
+ SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum,
2075
+ rockchip_i2s_tdm_rx_lanes_get, rockchip_i2s_tdm_rx_lanes_put),
2076
+#endif
2077
+ SAI_PCM_WAIT_TIME("PCM Read Wait Time MS",
2078
+ rockchip_i2s_tdm_rd_wait_time_get,
2079
+ rockchip_i2s_tdm_rd_wait_time_put),
2080
+ SAI_PCM_WAIT_TIME("PCM Write Wait Time MS",
2081
+ rockchip_i2s_tdm_wr_wait_time_get,
2082
+ rockchip_i2s_tdm_wr_wait_time_put),
15162083 };
15172084
15182085 static int rockchip_i2s_tdm_dai_probe(struct snd_soc_dai *dai)
....@@ -1523,7 +2090,9 @@
15232090 dai->playback_dma_data = &i2s_tdm->playback_dma_data;
15242091
15252092 if (i2s_tdm->mclk_calibrate)
1526
- snd_soc_add_dai_controls(dai, &rockchip_i2s_tdm_compensation_control, 1);
2093
+ snd_soc_add_component_controls(dai->component,
2094
+ &rockchip_i2s_tdm_compensation_control,
2095
+ 1);
15272096
15282097 return 0;
15292098 }
....@@ -1554,11 +2123,15 @@
15542123 struct snd_soc_dai *dai)
15552124 {
15562125 struct rk_i2s_tdm_dev *i2s_tdm = snd_soc_dai_get_drvdata(dai);
2126
+ int stream = substream->stream;
15572127
1558
- if (i2s_tdm->substreams[substream->stream])
2128
+ if (i2s_tdm->substreams[stream])
15592129 return -EBUSY;
15602130
1561
- i2s_tdm->substreams[substream->stream] = substream;
2131
+ if (i2s_tdm->wait_time[stream])
2132
+ substream->wait_time = msecs_to_jiffies(i2s_tdm->wait_time[stream]);
2133
+
2134
+ i2s_tdm->substreams[stream] = substream;
15622135
15632136 return 0;
15642137 }
....@@ -1575,6 +2148,7 @@
15752148 .startup = rockchip_i2s_tdm_startup,
15762149 .shutdown = rockchip_i2s_tdm_shutdown,
15772150 .hw_params = rockchip_i2s_tdm_hw_params,
2151
+ .hw_free = rockchip_i2s_tdm_hw_free,
15782152 .set_sysclk = rockchip_i2s_tdm_set_sysclk,
15792153 .set_fmt = rockchip_i2s_tdm_set_fmt,
15802154 .set_tdm_slot = rockchip_dai_tdm_slot,
....@@ -1789,6 +2363,12 @@
17892363 #ifdef CONFIG_CPU_RK3568
17902364 { .compatible = "rockchip,rk3568-i2s-tdm", .data = &rk3568_i2s_soc_data },
17912365 #endif
2366
+#ifdef CONFIG_CPU_RK3588
2367
+ { .compatible = "rockchip,rk3588-i2s-tdm", },
2368
+#endif
2369
+#ifdef CONFIG_CPU_RV1106
2370
+ { .compatible = "rockchip,rv1106-i2s-tdm", },
2371
+#endif
17922372 #ifdef CONFIG_CPU_RV1126
17932373 { .compatible = "rockchip,rv1126-i2s-tdm", .data = &rv1126_i2s_soc_data },
17942374 #endif
....@@ -1823,7 +2403,7 @@
18232403 .playback = {
18242404 .stream_name = "Playback",
18252405 .channels_min = 2,
1826
- .channels_max = 16,
2406
+ .channels_max = 64,
18272407 .rates = SNDRV_PCM_RATE_8000_192000,
18282408 .formats = (SNDRV_PCM_FMTBIT_S8 |
18292409 SNDRV_PCM_FMTBIT_S16_LE |
....@@ -1835,7 +2415,7 @@
18352415 .capture = {
18362416 .stream_name = "Capture",
18372417 .channels_min = 2,
1838
- .channels_max = 16,
2418
+ .channels_max = 64,
18392419 .rates = SNDRV_PCM_RATE_8000_192000,
18402420 .formats = (SNDRV_PCM_FMTBIT_S8 |
18412421 SNDRV_PCM_FMTBIT_S16_LE |
....@@ -1998,6 +2578,29 @@
19982578 return rockchip_i2s_tdm_path_prepare(i2s_tdm, np, 1);
19992579 }
20002580
2581
+static int rockchip_i2s_tdm_get_fifo_count(struct device *dev,
2582
+ struct snd_pcm_substream *substream)
2583
+{
2584
+ struct rk_i2s_tdm_dev *i2s_tdm = dev_get_drvdata(dev);
2585
+ int val = 0;
2586
+
2587
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2588
+ regmap_read(i2s_tdm->regmap, I2S_TXFIFOLR, &val);
2589
+ else
2590
+ regmap_read(i2s_tdm->regmap, I2S_RXFIFOLR, &val);
2591
+
2592
+ val = ((val & I2S_FIFOLR_TFL3_MASK) >> I2S_FIFOLR_TFL3_SHIFT) +
2593
+ ((val & I2S_FIFOLR_TFL2_MASK) >> I2S_FIFOLR_TFL2_SHIFT) +
2594
+ ((val & I2S_FIFOLR_TFL1_MASK) >> I2S_FIFOLR_TFL1_SHIFT) +
2595
+ ((val & I2S_FIFOLR_TFL0_MASK) >> I2S_FIFOLR_TFL0_SHIFT);
2596
+
2597
+ return val;
2598
+}
2599
+
2600
+static const struct snd_dlp_config dconfig = {
2601
+ .get_fifo_count = rockchip_i2s_tdm_get_fifo_count,
2602
+};
2603
+
20012604 static irqreturn_t rockchip_i2s_tdm_isr(int irq, void *devid)
20022605 {
20032606 struct rk_i2s_tdm_dev *i2s_tdm = (struct rk_i2s_tdm_dev *)devid;
....@@ -2009,6 +2612,9 @@
20092612 dev_warn_ratelimited(i2s_tdm->dev, "TX FIFO Underrun\n");
20102613 regmap_update_bits(i2s_tdm->regmap, I2S_INTCR,
20112614 I2S_INTCR_TXUIC, I2S_INTCR_TXUIC);
2615
+ regmap_update_bits(i2s_tdm->regmap, I2S_INTCR,
2616
+ I2S_INTCR_TXUIE_MASK,
2617
+ I2S_INTCR_TXUIE(0));
20122618 substream = i2s_tdm->substreams[SNDRV_PCM_STREAM_PLAYBACK];
20132619 if (substream)
20142620 snd_pcm_stop_xrun(substream);
....@@ -2018,12 +2624,76 @@
20182624 dev_warn_ratelimited(i2s_tdm->dev, "RX FIFO Overrun\n");
20192625 regmap_update_bits(i2s_tdm->regmap, I2S_INTCR,
20202626 I2S_INTCR_RXOIC, I2S_INTCR_RXOIC);
2627
+ regmap_update_bits(i2s_tdm->regmap, I2S_INTCR,
2628
+ I2S_INTCR_RXOIE_MASK,
2629
+ I2S_INTCR_RXOIE(0));
20212630 substream = i2s_tdm->substreams[SNDRV_PCM_STREAM_CAPTURE];
20222631 if (substream)
20232632 snd_pcm_stop_xrun(substream);
20242633 }
20252634
20262635 return IRQ_HANDLED;
2636
+}
2637
+
2638
+static int rockchip_i2s_tdm_keep_clk_always_on(struct rk_i2s_tdm_dev *i2s_tdm)
2639
+{
2640
+ unsigned int mclk_rate = DEFAULT_FS * DEFAULT_MCLK_FS;
2641
+ unsigned int bclk_rate = i2s_tdm->bclk_fs * DEFAULT_FS;
2642
+ unsigned int div_lrck = i2s_tdm->bclk_fs;
2643
+ unsigned int div_bclk;
2644
+ int ret;
2645
+
2646
+ div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
2647
+
2648
+ /* assign generic freq */
2649
+ clk_set_rate(i2s_tdm->mclk_rx, mclk_rate);
2650
+ clk_set_rate(i2s_tdm->mclk_tx, mclk_rate);
2651
+
2652
+ ret = rockchip_i2s_tdm_mclk_reparent(i2s_tdm);
2653
+ if (ret)
2654
+ return ret;
2655
+
2656
+ regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
2657
+ I2S_CLKDIV_RXM_MASK | I2S_CLKDIV_TXM_MASK,
2658
+ I2S_CLKDIV_RXM(div_bclk) | I2S_CLKDIV_TXM(div_bclk));
2659
+ regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
2660
+ I2S_CKR_RSD_MASK | I2S_CKR_TSD_MASK,
2661
+ I2S_CKR_RSD(div_lrck) | I2S_CKR_TSD(div_lrck));
2662
+
2663
+ if (i2s_tdm->clk_trcm)
2664
+ rockchip_i2s_tdm_xfer_trcm_start(i2s_tdm);
2665
+ else
2666
+ rockchip_i2s_tdm_xfer_start(i2s_tdm, SNDRV_PCM_STREAM_PLAYBACK);
2667
+
2668
+ pm_runtime_forbid(i2s_tdm->dev);
2669
+
2670
+ dev_info(i2s_tdm->dev, "CLK-ALWAYS-ON: mclk: %d, bclk: %d, fsync: %d\n",
2671
+ mclk_rate, bclk_rate, DEFAULT_FS);
2672
+
2673
+ return 0;
2674
+}
2675
+
2676
+static int rockchip_i2s_tdm_register_platform(struct device *dev)
2677
+{
2678
+ int ret = 0;
2679
+
2680
+ if (device_property_read_bool(dev, "rockchip,no-dmaengine")) {
2681
+ dev_info(dev, "Used for Multi-DAI\n");
2682
+ return 0;
2683
+ }
2684
+
2685
+ if (device_property_read_bool(dev, "rockchip,digital-loopback")) {
2686
+ ret = devm_snd_dmaengine_dlp_register(dev, &dconfig);
2687
+ if (ret)
2688
+ dev_err(dev, "Could not register DLP\n");
2689
+ return ret;
2690
+ }
2691
+
2692
+ ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
2693
+ if (ret)
2694
+ dev_err(dev, "Could not register PCM\n");
2695
+
2696
+ return ret;
20272697 }
20282698
20292699 static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
....@@ -2048,10 +2718,63 @@
20482718 return -ENOMEM;
20492719
20502720 i2s_tdm->dev = &pdev->dev;
2721
+ i2s_tdm->lrck_ratio = 1;
20512722
20522723 of_id = of_match_device(rockchip_i2s_tdm_match, &pdev->dev);
2053
- if (!of_id || !of_id->data)
2724
+ if (!of_id)
20542725 return -EINVAL;
2726
+
2727
+#ifdef CONFIG_SND_SOC_ROCKCHIP_I2S_TDM_MULTI_LANES
2728
+ i2s_tdm->is_tdm_multi_lanes =
2729
+ device_property_read_bool(i2s_tdm->dev, "rockchip,tdm-multi-lanes");
2730
+
2731
+ if (i2s_tdm->is_tdm_multi_lanes) {
2732
+ struct device_node *clk_src_node = NULL;
2733
+
2734
+ i2s_tdm->tx_lanes = 1;
2735
+ i2s_tdm->rx_lanes = 1;
2736
+
2737
+ if (!device_property_read_u32(i2s_tdm->dev, "rockchip,tdm-tx-lanes", &val)) {
2738
+ if ((val >= 1) && (val <= 4))
2739
+ i2s_tdm->tx_lanes = val;
2740
+ }
2741
+
2742
+ if (!device_property_read_u32(i2s_tdm->dev, "rockchip,tdm-rx-lanes", &val)) {
2743
+ if ((val >= 1) && (val <= 4))
2744
+ i2s_tdm->rx_lanes = val;
2745
+ }
2746
+
2747
+ i2s_tdm->i2s_lrck_gpio = devm_gpiod_get_optional(&pdev->dev, "i2s-lrck", GPIOD_IN);
2748
+ if (IS_ERR(i2s_tdm->i2s_lrck_gpio)) {
2749
+ ret = PTR_ERR(i2s_tdm->i2s_lrck_gpio);
2750
+ dev_err(&pdev->dev, "Failed to get i2s_lrck_gpio %d\n", ret);
2751
+ return ret;
2752
+ }
2753
+
2754
+ i2s_tdm->tdm_fsync_gpio = devm_gpiod_get_optional(&pdev->dev, "tdm-fsync", GPIOD_IN);
2755
+ if (IS_ERR(i2s_tdm->tdm_fsync_gpio)) {
2756
+ ret = PTR_ERR(i2s_tdm->tdm_fsync_gpio);
2757
+ dev_err(&pdev->dev, "Failed to get tdm_fsync_gpio %d\n", ret);
2758
+ return ret;
2759
+ }
2760
+
2761
+ /* It's optional, required when use soc clk src, such as: i2s2_2ch */
2762
+ clk_src_node = of_parse_phandle(node, "rockchip,clk-src", 0);
2763
+ if (clk_src_node) {
2764
+ i2s_tdm->clk_src_base = of_iomap(clk_src_node, 0);
2765
+ if (!i2s_tdm->clk_src_base)
2766
+ return -ENOENT;
2767
+
2768
+ i2s_tdm->clk_src_dai = rockchip_i2s_tdm_find_dai(clk_src_node);
2769
+ if (!i2s_tdm->clk_src_dai)
2770
+ return -EPROBE_DEFER;
2771
+
2772
+ pm_runtime_forbid(i2s_tdm->clk_src_dai->dev);
2773
+ }
2774
+
2775
+ dev_info(&pdev->dev, "Used as TDM_MULTI_LANES mode\n");
2776
+ }
2777
+#endif
20552778
20562779 spin_lock_init(&i2s_tdm->lock);
20572780 i2s_tdm->soc_data = (const struct rk_i2s_soc_data *)of_id->data;
....@@ -2084,6 +2807,15 @@
20842807 soc_dai->playback.channels_min = 0;
20852808
20862809 i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
2810
+
2811
+ i2s_tdm->pinctrl = devm_pinctrl_get(&pdev->dev);
2812
+ if (!IS_ERR_OR_NULL(i2s_tdm->pinctrl)) {
2813
+ i2s_tdm->clk_state = pinctrl_lookup_state(i2s_tdm->pinctrl, "clk");
2814
+ if (IS_ERR(i2s_tdm->clk_state)) {
2815
+ i2s_tdm->clk_state = NULL;
2816
+ dev_dbg(i2s_tdm->dev, "Have no clk pinctrl state\n");
2817
+ }
2818
+ }
20872819
20882820 #ifdef HAVE_SYNC_RESET
20892821 sync = of_device_is_compatible(node, "rockchip,px30-i2s-tdm") ||
....@@ -2170,7 +2902,7 @@
21702902 if (IS_ERR(i2s_tdm->regmap))
21712903 return PTR_ERR(i2s_tdm->regmap);
21722904
2173
- irq = platform_get_irq(pdev, 0);
2905
+ irq = platform_get_irq_optional(pdev, 0);
21742906 if (irq > 0) {
21752907 ret = devm_request_irq(&pdev->dev, irq, rockchip_i2s_tdm_isr,
21762908 IRQF_SHARED, node->name, i2s_tdm);
....@@ -2203,43 +2935,6 @@
22032935 atomic_set(&i2s_tdm->refcount, 0);
22042936 dev_set_drvdata(&pdev->dev, i2s_tdm);
22052937
2206
- pm_runtime_enable(&pdev->dev);
2207
- if (!pm_runtime_enabled(&pdev->dev)) {
2208
- ret = i2s_tdm_runtime_resume(&pdev->dev);
2209
- if (ret)
2210
- goto err_pm_disable;
2211
- }
2212
-
2213
- if (i2s_tdm->quirks & QUIRK_ALWAYS_ON) {
2214
- unsigned int rate = DEFAULT_FS * DEFAULT_MCLK_FS;
2215
- unsigned int div_bclk = DEFAULT_FS * DEFAULT_MCLK_FS;
2216
- unsigned int div_lrck = i2s_tdm->bclk_fs;
2217
-
2218
- div_bclk = DIV_ROUND_CLOSEST(rate, div_lrck * DEFAULT_FS);
2219
-
2220
- /* assign generic freq */
2221
- clk_set_rate(i2s_tdm->mclk_rx, rate);
2222
- clk_set_rate(i2s_tdm->mclk_tx, rate);
2223
-
2224
- ret = rockchip_i2s_tdm_mclk_reparent(i2s_tdm);
2225
- if (ret)
2226
- goto err_pm_disable;
2227
-
2228
- regmap_update_bits(i2s_tdm->regmap, I2S_CLKDIV,
2229
- I2S_CLKDIV_RXM_MASK | I2S_CLKDIV_TXM_MASK,
2230
- I2S_CLKDIV_RXM(div_bclk) | I2S_CLKDIV_TXM(div_bclk));
2231
- regmap_update_bits(i2s_tdm->regmap, I2S_CKR,
2232
- I2S_CKR_RSD_MASK | I2S_CKR_TSD_MASK,
2233
- I2S_CKR_RSD(div_lrck) | I2S_CKR_TSD(div_lrck));
2234
-
2235
- if (i2s_tdm->clk_trcm)
2236
- rockchip_i2s_tdm_xfer_trcm_start(i2s_tdm);
2237
- else
2238
- rockchip_i2s_tdm_xfer_start(i2s_tdm, SNDRV_PCM_STREAM_PLAYBACK);
2239
-
2240
- pm_runtime_forbid(&pdev->dev);
2241
- }
2242
-
22432938 regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
22442939 I2S_DMACR_TDL(16));
22452940 regmap_update_bits(i2s_tdm->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
....@@ -2250,24 +2945,44 @@
22502945 if (i2s_tdm->soc_data && i2s_tdm->soc_data->init)
22512946 i2s_tdm->soc_data->init(&pdev->dev, res->start);
22522947
2948
+ /*
2949
+ * CLK_ALWAYS_ON should be placed after all registers write done,
2950
+ * because this situation will enable XFER bit which will make
2951
+ * some registers(depend on XFER) write failed.
2952
+ */
2953
+ if (i2s_tdm->quirks & QUIRK_ALWAYS_ON) {
2954
+ ret = rockchip_i2s_tdm_keep_clk_always_on(i2s_tdm);
2955
+ if (ret)
2956
+ return ret;
2957
+ }
2958
+
2959
+ /*
2960
+ * MUST: after pm_runtime_enable step, any register R/W
2961
+ * should be wrapped with pm_runtime_get_sync/put.
2962
+ *
2963
+ * Another approach is to enable the regcache true to
2964
+ * avoid access HW registers.
2965
+ *
2966
+ * Alternatively, performing the registers R/W before
2967
+ * pm_runtime_enable is also a good option.
2968
+ */
2969
+ pm_runtime_enable(&pdev->dev);
2970
+ if (!pm_runtime_enabled(&pdev->dev)) {
2971
+ ret = i2s_tdm_runtime_resume(&pdev->dev);
2972
+ if (ret)
2973
+ goto err_pm_disable;
2974
+ }
2975
+
2976
+ ret = rockchip_i2s_tdm_register_platform(&pdev->dev);
2977
+ if (ret)
2978
+ goto err_suspend;
2979
+
22532980 ret = devm_snd_soc_register_component(&pdev->dev,
22542981 &rockchip_i2s_tdm_component,
22552982 soc_dai, 1);
2256
-
22572983 if (ret) {
22582984 dev_err(&pdev->dev, "Could not register DAI\n");
22592985 goto err_suspend;
2260
- }
2261
-
2262
- if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
2263
- dev_info(&pdev->dev, "Used for Multi-DAI\n");
2264
- return 0;
2265
- }
2266
-
2267
- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
2268
- if (ret) {
2269
- dev_err(&pdev->dev, "Could not register PCM\n");
2270
- return ret;
22712986 }
22722987
22732988 return 0;