hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/sound/soc/rockchip/rockchip_i2s.c
....@@ -27,6 +27,13 @@
2727 #define CLK_PPM_MIN (-1000)
2828 #define CLK_PPM_MAX (1000)
2929
30
+#define DEFAULT_MCLK_FS 256
31
+#define DEFAULT_FS 48000
32
+
33
+#define WAIT_TIME_MS_MAX 10000
34
+
35
+#define QUIRK_ALWAYS_ON BIT(0)
36
+
3037 struct rk_i2s_pins {
3138 u32 reg_offset;
3239 u32 shift;
....@@ -44,6 +51,9 @@
4451
4552 struct regmap *regmap;
4653 struct regmap *grf;
54
+
55
+ struct snd_pcm_substream *substreams[SNDRV_PCM_STREAM_LAST + 1];
56
+ unsigned int wait_time[SNDRV_PCM_STREAM_LAST + 1];
4757
4858 bool has_capture;
4959 bool has_playback;
....@@ -66,6 +76,17 @@
6676 int clk_ppm;
6777 bool mclk_calibrate;
6878
79
+ unsigned int quirks;
80
+};
81
+
82
+static struct i2s_of_quirks {
83
+ char *quirk;
84
+ int id;
85
+} of_quirks[] = {
86
+ {
87
+ .quirk = "rockchip,always-on",
88
+ .id = QUIRK_ALWAYS_ON,
89
+ },
6990 };
7091
7192 static int i2s_runtime_suspend(struct device *dev)
....@@ -157,7 +178,7 @@
157178 regmap_update_bits(i2s->regmap, I2S_DMACR,
158179 I2S_DMACR_TDE_ENABLE, I2S_DMACR_TDE_DISABLE);
159180
160
- if (!i2s->rx_start) {
181
+ if (!i2s->rx_start && !(i2s->quirks & QUIRK_ALWAYS_ON)) {
161182 regmap_update_bits(i2s->regmap, I2S_XFER,
162183 I2S_XFER_TXS_START |
163184 I2S_XFER_RXS_START,
....@@ -189,7 +210,7 @@
189210 regmap_update_bits(i2s->regmap, I2S_DMACR,
190211 I2S_DMACR_RDE_ENABLE, I2S_DMACR_RDE_DISABLE);
191212
192
- if (!i2s->tx_start) {
213
+ if (!i2s->tx_start && !(i2s->quirks & QUIRK_ALWAYS_ON)) {
193214 regmap_update_bits(i2s->regmap, I2S_XFER,
194215 I2S_XFER_TXS_START |
195216 I2S_XFER_RXS_START,
....@@ -353,6 +374,7 @@
353374 val |= I2S_TXCR_VDW(24);
354375 break;
355376 case SNDRV_PCM_FORMAT_S32_LE:
377
+ case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
356378 val |= I2S_TXCR_VDW(32);
357379 break;
358380 default:
....@@ -588,12 +610,41 @@
588610 i2s->has_capture ? &i2s->capture_dma_data : NULL);
589611
590612 if (i2s->mclk_calibrate)
591
- snd_soc_add_dai_controls(dai, &rockchip_i2s_compensation_control, 1);
613
+ snd_soc_add_component_controls(dai->component,
614
+ &rockchip_i2s_compensation_control,
615
+ 1);
592616
593617 return 0;
594618 }
595619
620
+static int rockchip_i2s_startup(struct snd_pcm_substream *substream,
621
+ struct snd_soc_dai *dai)
622
+{
623
+ struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
624
+ int stream = substream->stream;
625
+
626
+ if (i2s->substreams[stream])
627
+ return -EBUSY;
628
+
629
+ if (i2s->wait_time[stream])
630
+ substream->wait_time = msecs_to_jiffies(i2s->wait_time[stream]);
631
+
632
+ i2s->substreams[stream] = substream;
633
+
634
+ return 0;
635
+}
636
+
637
+static void rockchip_i2s_shutdown(struct snd_pcm_substream *substream,
638
+ struct snd_soc_dai *dai)
639
+{
640
+ struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai);
641
+
642
+ i2s->substreams[substream->stream] = NULL;
643
+}
644
+
596645 static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = {
646
+ .startup = rockchip_i2s_startup,
647
+ .shutdown = rockchip_i2s_shutdown,
597648 .hw_params = rockchip_i2s_hw_params,
598649 .set_bclk_ratio = rockchip_i2s_set_bclk_ratio,
599650 .set_sysclk = rockchip_i2s_set_sysclk,
....@@ -606,8 +657,116 @@
606657 .ops = &rockchip_i2s_dai_ops,
607658 };
608659
660
+static int rockchip_i2s_get_bclk_ratio(struct snd_kcontrol *kcontrol,
661
+ struct snd_ctl_elem_value *ucontrol)
662
+{
663
+ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
664
+ struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(compnt);
665
+
666
+ ucontrol->value.integer.value[0] = i2s->bclk_ratio;
667
+
668
+ return 0;
669
+}
670
+
671
+static int rockchip_i2s_put_bclk_ratio(struct snd_kcontrol *kcontrol,
672
+ struct snd_ctl_elem_value *ucontrol)
673
+{
674
+ struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol);
675
+ struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(compnt);
676
+ int value = ucontrol->value.integer.value[0];
677
+
678
+ if (value == i2s->bclk_ratio)
679
+ return 0;
680
+
681
+ i2s->bclk_ratio = value;
682
+
683
+ return 1;
684
+}
685
+
686
+static int rockchip_i2s_wait_time_info(struct snd_kcontrol *kcontrol,
687
+ struct snd_ctl_elem_info *uinfo)
688
+{
689
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
690
+ uinfo->count = 1;
691
+ uinfo->value.integer.min = 0;
692
+ uinfo->value.integer.max = WAIT_TIME_MS_MAX;
693
+ uinfo->value.integer.step = 1;
694
+
695
+ return 0;
696
+}
697
+
698
+static int rockchip_i2s_rd_wait_time_get(struct snd_kcontrol *kcontrol,
699
+ struct snd_ctl_elem_value *ucontrol)
700
+{
701
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
702
+ struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(component);
703
+
704
+ ucontrol->value.integer.value[0] = i2s->wait_time[SNDRV_PCM_STREAM_CAPTURE];
705
+
706
+ return 0;
707
+}
708
+
709
+static int rockchip_i2s_rd_wait_time_put(struct snd_kcontrol *kcontrol,
710
+ struct snd_ctl_elem_value *ucontrol)
711
+{
712
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
713
+ struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(component);
714
+
715
+ if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX)
716
+ return -EINVAL;
717
+
718
+ i2s->wait_time[SNDRV_PCM_STREAM_CAPTURE] = ucontrol->value.integer.value[0];
719
+
720
+ return 1;
721
+}
722
+
723
+static int rockchip_i2s_wr_wait_time_get(struct snd_kcontrol *kcontrol,
724
+ struct snd_ctl_elem_value *ucontrol)
725
+{
726
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
727
+ struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(component);
728
+
729
+ ucontrol->value.integer.value[0] = i2s->wait_time[SNDRV_PCM_STREAM_PLAYBACK];
730
+
731
+ return 0;
732
+}
733
+
734
+static int rockchip_i2s_wr_wait_time_put(struct snd_kcontrol *kcontrol,
735
+ struct snd_ctl_elem_value *ucontrol)
736
+{
737
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
738
+ struct rk_i2s_dev *i2s = snd_soc_component_get_drvdata(component);
739
+
740
+ if (ucontrol->value.integer.value[0] > WAIT_TIME_MS_MAX)
741
+ return -EINVAL;
742
+
743
+ i2s->wait_time[SNDRV_PCM_STREAM_PLAYBACK] = ucontrol->value.integer.value[0];
744
+
745
+ return 1;
746
+}
747
+
748
+#define SAI_PCM_WAIT_TIME(xname, xhandler_get, xhandler_put) \
749
+{ .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = xname, \
750
+ .info = rockchip_i2s_wait_time_info, \
751
+ .get = xhandler_get, .put = xhandler_put }
752
+
753
+static const struct snd_kcontrol_new rockchip_i2s_snd_controls[] = {
754
+ SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0,
755
+ rockchip_i2s_get_bclk_ratio,
756
+ rockchip_i2s_put_bclk_ratio),
757
+
758
+ SAI_PCM_WAIT_TIME("PCM Read Wait Time MS",
759
+ rockchip_i2s_rd_wait_time_get,
760
+ rockchip_i2s_rd_wait_time_put),
761
+ SAI_PCM_WAIT_TIME("PCM Write Wait Time MS",
762
+ rockchip_i2s_wr_wait_time_get,
763
+ rockchip_i2s_wr_wait_time_put),
764
+};
765
+
609766 static const struct snd_soc_component_driver rockchip_i2s_component = {
610767 .name = DRV_NAME,
768
+ .controls = rockchip_i2s_snd_controls,
769
+ .num_controls = ARRAY_SIZE(rockchip_i2s_snd_controls),
611770 };
612771
613772 static bool rockchip_i2s_wr_reg(struct device *dev, unsigned int reg)
....@@ -772,7 +931,8 @@
772931 SNDRV_PCM_FMTBIT_S16_LE |
773932 SNDRV_PCM_FMTBIT_S20_3LE |
774933 SNDRV_PCM_FMTBIT_S24_LE |
775
- SNDRV_PCM_FMTBIT_S32_LE;
934
+ SNDRV_PCM_FMTBIT_S32_LE |
935
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
776936
777937 i2s->playback_dma_data.addr = res->start + I2S_TXDR;
778938 i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
....@@ -793,7 +953,8 @@
793953 SNDRV_PCM_FMTBIT_S16_LE |
794954 SNDRV_PCM_FMTBIT_S20_3LE |
795955 SNDRV_PCM_FMTBIT_S24_LE |
796
- SNDRV_PCM_FMTBIT_S32_LE;
956
+ SNDRV_PCM_FMTBIT_S32_LE |
957
+ SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
797958
798959 i2s->capture_dma_data.addr = res->start + I2S_RXDR;
799960 i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
....@@ -823,6 +984,38 @@
823984 return 0;
824985 }
825986
987
+static int rockchip_i2s_keep_clk_always_on(struct rk_i2s_dev *i2s)
988
+{
989
+ unsigned int mclk_rate = DEFAULT_FS * DEFAULT_MCLK_FS;
990
+ unsigned int bclk_rate = i2s->bclk_ratio * DEFAULT_FS;
991
+ unsigned int div_lrck = i2s->bclk_ratio;
992
+ unsigned int div_bclk;
993
+
994
+ div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
995
+
996
+ /* assign generic freq */
997
+ clk_set_rate(i2s->mclk, mclk_rate);
998
+
999
+ regmap_update_bits(i2s->regmap, I2S_CKR,
1000
+ I2S_CKR_MDIV_MASK,
1001
+ I2S_CKR_MDIV(div_bclk));
1002
+ regmap_update_bits(i2s->regmap, I2S_CKR,
1003
+ I2S_CKR_TSD_MASK |
1004
+ I2S_CKR_RSD_MASK,
1005
+ I2S_CKR_TSD(div_lrck) |
1006
+ I2S_CKR_RSD(div_lrck));
1007
+ regmap_update_bits(i2s->regmap, I2S_XFER,
1008
+ I2S_XFER_TXS_START | I2S_XFER_RXS_START,
1009
+ I2S_XFER_TXS_START | I2S_XFER_RXS_START);
1010
+
1011
+ pm_runtime_forbid(i2s->dev);
1012
+
1013
+ dev_info(i2s->dev, "CLK-ALWAYS-ON: mclk: %d, bclk: %d, fsync: %d\n",
1014
+ mclk_rate, bclk_rate, DEFAULT_FS);
1015
+
1016
+ return 0;
1017
+}
1018
+
8261019 static int rockchip_i2s_probe(struct platform_device *pdev)
8271020 {
8281021 struct device_node *node = pdev->dev.of_node;
....@@ -831,7 +1024,7 @@
8311024 struct snd_soc_dai_driver *dai;
8321025 struct resource *res;
8331026 void __iomem *regs;
834
- int ret;
1027
+ int ret, i, val;
8351028
8361029 i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
8371030 if (!i2s)
....@@ -849,6 +1042,10 @@
8491042 i2s->pins = of_id->data;
8501043 }
8511044
1045
+ for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
1046
+ if (device_property_read_bool(i2s->dev, of_quirks[i].quirk))
1047
+ i2s->quirks |= of_quirks[i].id;
1048
+
8521049 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
8531050 if (IS_ERR(regs))
8541051 return PTR_ERR(regs);
....@@ -862,6 +1059,10 @@
8621059 }
8631060
8641061 i2s->bclk_ratio = 64;
1062
+ if (!device_property_read_u32(&pdev->dev, "rockchip,bclk-fs", &val)) {
1063
+ if ((val >= 32) && (val % 2 == 0))
1064
+ i2s->bclk_ratio = val;
1065
+ }
8651066
8661067 dev_set_drvdata(&pdev->dev, i2s);
8671068
....@@ -894,16 +1095,37 @@
8941095 return ret;
8951096 }
8961097
1098
+ ret = rockchip_i2s_init_dai(i2s, res, &dai);
1099
+ if (ret)
1100
+ goto err_clk;
1101
+
1102
+ /*
1103
+ * CLK_ALWAYS_ON should be placed after all registers write done,
1104
+ * because this situation will enable XFER bit which will make
1105
+ * some registers(depend on XFER) write failed.
1106
+ */
1107
+ if (i2s->quirks & QUIRK_ALWAYS_ON) {
1108
+ ret = rockchip_i2s_keep_clk_always_on(i2s);
1109
+ if (ret)
1110
+ goto err_clk;
1111
+ }
1112
+
1113
+ /*
1114
+ * MUST: after pm_runtime_enable step, any register R/W
1115
+ * should be wrapped with pm_runtime_get_sync/put.
1116
+ *
1117
+ * Another approach is to enable the regcache true to
1118
+ * avoid access HW registers.
1119
+ *
1120
+ * Alternatively, performing the registers R/W before
1121
+ * pm_runtime_enable is also a good option.
1122
+ */
8971123 pm_runtime_enable(&pdev->dev);
8981124 if (!pm_runtime_enabled(&pdev->dev)) {
8991125 ret = i2s_runtime_resume(&pdev->dev);
9001126 if (ret)
9011127 goto err_pm_disable;
9021128 }
903
-
904
- ret = rockchip_i2s_init_dai(i2s, res, &dai);
905
- if (ret)
906
- goto err_pm_disable;
9071129
9081130 ret = devm_snd_soc_register_component(&pdev->dev,
9091131 &rockchip_i2s_component,
....@@ -932,7 +1154,7 @@
9321154 i2s_runtime_suspend(&pdev->dev);
9331155 err_pm_disable:
9341156 pm_runtime_disable(&pdev->dev);
935
-
1157
+err_clk:
9361158 clk_disable_unprepare(i2s->hclk);
9371159
9381160 return ret;