hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/sound/soc/rockchip/rockchip_sai.c
....@@ -24,6 +24,10 @@
2424
2525 #define FW_RATIO_MAX 8
2626 #define FW_RATIO_MIN 1
27
+#define MAXBURST_PER_FIFO 8
28
+
29
+#define DEFAULT_FS 48000
30
+#define QUIRK_ALWAYS_ON BIT(0)
2731
2832 enum fpw_mode {
2933 FPW_ONE_BCLK_WIDTH,
....@@ -41,14 +45,28 @@
4145 struct snd_dmaengine_dai_dma_data capture_dma_data;
4246 struct snd_dmaengine_dai_dma_data playback_dma_data;
4347 struct snd_pcm_substream *substreams[SNDRV_PCM_STREAM_LAST + 1];
48
+ unsigned int tx_lanes;
49
+ unsigned int rx_lanes;
50
+ unsigned int quirks;
4451 enum fpw_mode fpw;
45
- int fw_ratio;
52
+ int fw_ratio;
4653 bool has_capture;
4754 bool has_playback;
4855 bool is_master_mode;
56
+ bool is_tdm;
4957 };
5058
51
-static int sai_runtime_suspend(struct device *dev)
59
+static const struct sai_of_quirks {
60
+ char *quirk;
61
+ int id;
62
+} of_quirks[] = {
63
+ {
64
+ .quirk = "rockchip,always-on",
65
+ .id = QUIRK_ALWAYS_ON,
66
+ },
67
+};
68
+
69
+static int rockchip_sai_runtime_suspend(struct device *dev)
5270 {
5371 struct rk_sai_dev *sai = dev_get_drvdata(dev);
5472 unsigned int val;
....@@ -68,14 +86,19 @@
6886
6987 regcache_cache_only(sai->regmap, true);
7088 clk_disable_unprepare(sai->mclk);
89
+ clk_disable_unprepare(sai->hclk);
7190
7291 return 0;
7392 }
7493
75
-static int sai_runtime_resume(struct device *dev)
94
+static int rockchip_sai_runtime_resume(struct device *dev)
7695 {
7796 struct rk_sai_dev *sai = dev_get_drvdata(dev);
7897 int ret;
98
+
99
+ ret = clk_prepare_enable(sai->hclk);
100
+ if (ret)
101
+ goto err_hclk;
79102
80103 ret = clk_prepare_enable(sai->mclk);
81104 if (ret)
....@@ -99,6 +122,8 @@
99122 err_regmap:
100123 clk_disable_unprepare(sai->mclk);
101124 err_mclk:
125
+ clk_disable_unprepare(sai->hclk);
126
+err_hclk:
102127 return ret;
103128 }
104129
....@@ -359,19 +384,42 @@
359384 return ret;
360385 }
361386
387
+static unsigned int rockchip_sai_lanes_auto(struct snd_pcm_hw_params *params,
388
+ struct snd_soc_dai *dai)
389
+{
390
+ struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
391
+ unsigned int lanes = 1;
392
+
393
+ if (!sai->is_tdm)
394
+ lanes = DIV_ROUND_UP(params_channels(params), 2);
395
+
396
+ return lanes;
397
+}
398
+
362399 static int rockchip_sai_hw_params(struct snd_pcm_substream *substream,
363400 struct snd_pcm_hw_params *params,
364401 struct snd_soc_dai *dai)
365402 {
366403 struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
404
+ struct snd_dmaengine_dai_dma_data *dma_data;
367405 unsigned int mclk_rate, bclk_rate, div_bclk;
368406 unsigned int ch_per_lane, lanes, slot_width;
369407 unsigned int val, fscr, reg;
370408
371
- if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
409
+ dma_data = snd_soc_dai_get_dma_data(dai, substream);
410
+ dma_data->maxburst = MAXBURST_PER_FIFO * params_channels(params) / 2;
411
+
412
+ lanes = rockchip_sai_lanes_auto(params, dai);
413
+
414
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
372415 reg = SAI_TXCR;
373
- else
416
+ if (sai->tx_lanes)
417
+ lanes = sai->tx_lanes;
418
+ } else {
374419 reg = SAI_RXCR;
420
+ if (sai->rx_lanes)
421
+ lanes = sai->rx_lanes;
422
+ }
375423
376424 switch (params_format(params)) {
377425 case SNDRV_PCM_FORMAT_S8:
....@@ -391,12 +439,13 @@
391439 return -EINVAL;
392440 }
393441
394
- regmap_update_bits(sai->regmap, reg, SAI_XCR_VDW_MASK, val);
442
+ val |= SAI_XCR_CSR(lanes);
443
+
444
+ regmap_update_bits(sai->regmap, reg, SAI_XCR_VDW_MASK | SAI_XCR_CSR_MASK, val);
395445
396446 regmap_read(sai->regmap, reg, &val);
397447
398448 slot_width = SAI_XCR_SBW_V(val);
399
- lanes = SAI_XCR_CSR_V(val);
400449 ch_per_lane = params_channels(params) / lanes;
401450
402451 regmap_update_bits(sai->regmap, reg, SAI_XCR_SNB_MASK,
....@@ -525,6 +574,8 @@
525574 regmap_update_bits(sai->regmap, SAI_RXCR, SAI_XCR_SBW_MASK,
526575 SAI_XCR_SBW(slot_width));
527576 pm_runtime_put(dai->dev);
577
+
578
+ sai->is_tdm = true;
528579
529580 return 0;
530581 }
....@@ -699,7 +750,7 @@
699750
700751 sai->playback_dma_data.addr = res->start + SAI_TXDR;
701752 sai->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
702
- sai->playback_dma_data.maxburst = 8;
753
+ sai->playback_dma_data.maxburst = MAXBURST_PER_FIFO;
703754 }
704755
705756 if (sai->has_capture) {
....@@ -714,7 +765,7 @@
714765
715766 sai->capture_dma_data.addr = res->start + SAI_RXDR;
716767 sai->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
717
- sai->capture_dma_data.maxburst = 8;
768
+ sai->capture_dma_data.maxburst = MAXBURST_PER_FIFO;
718769 }
719770
720771 regmap_update_bits(sai->regmap, SAI_DMACR, SAI_DMACR_TDL_MASK,
....@@ -728,8 +779,8 @@
728779 return 0;
729780 }
730781
731
-static const char * const tcsr_text[] = { "SDOx1", "SDOx2", "SDOx3", "SDOx4" };
732
-static const char * const rcsr_text[] = { "SDIx1", "SDIx2", "SDIx3", "SDIx4" };
782
+static const char * const tx_lanes_text[] = { "Auto", "SDOx1", "SDOx2", "SDOx3", "SDOx4" };
783
+static const char * const rx_lanes_text[] = { "Auto", "SDIx1", "SDIx2", "SDIx3", "SDIx4" };
733784 static const char * const edge_text[] = { "Rising Edge", "Dual Edge" };
734785 static const char * const edge_shift_text[] = { "Normal", "Shift 1 Edge" };
735786
....@@ -771,7 +822,8 @@
771822
772823 /* TXCR */
773824 static SOC_ENUM_SINGLE_DECL(tsft_enum, SAI_TXCR, 22, edge_shift_text);
774
-static SOC_ENUM_SINGLE_DECL(tcsr_enum, SAI_TXCR, 20, tcsr_text);
825
+static const struct soc_enum tx_lanes_enum =
826
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_lanes_text), tx_lanes_text);
775827 static SOC_ENUM_SINGLE_DECL(tsjm_enum, SAI_TXCR, 19, sjm_text);
776828 static SOC_ENUM_SINGLE_DECL(tfbm_enum, SAI_TXCR, 18, fbm_text);
777829 static SOC_ENUM_SINGLE_DECL(tvdj_enum, SAI_TXCR, 10, vdj_text);
....@@ -786,7 +838,8 @@
786838
787839 /* RXCR */
788840 static SOC_ENUM_SINGLE_DECL(rsft_enum, SAI_RXCR, 22, edge_shift_text);
789
-static SOC_ENUM_SINGLE_DECL(rcsr_enum, SAI_RXCR, 20, rcsr_text);
841
+static const struct soc_enum rx_lanes_enum =
842
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_lanes_text), rx_lanes_text);
790843 static SOC_ENUM_SINGLE_DECL(rsjm_enum, SAI_RXCR, 19, sjm_text);
791844 static SOC_ENUM_SINGLE_DECL(rfbm_enum, SAI_RXCR, 18, fbm_text);
792845 static SOC_ENUM_SINGLE_DECL(rvdj_enum, SAI_RXCR, 10, vdj_text);
....@@ -874,19 +927,75 @@
874927 return 1;
875928 }
876929
930
+static int rockchip_sai_tx_lanes_get(struct snd_kcontrol *kcontrol,
931
+ struct snd_ctl_elem_value *ucontrol)
932
+{
933
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
934
+ struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
935
+
936
+ ucontrol->value.enumerated.item[0] = sai->tx_lanes;
937
+
938
+ return 0;
939
+}
940
+
941
+static int rockchip_sai_tx_lanes_put(struct snd_kcontrol *kcontrol,
942
+ struct snd_ctl_elem_value *ucontrol)
943
+{
944
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
945
+ struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
946
+ int num;
947
+
948
+ num = ucontrol->value.enumerated.item[0];
949
+ if (num >= ARRAY_SIZE(tx_lanes_text))
950
+ return -EINVAL;
951
+
952
+ sai->tx_lanes = num;
953
+
954
+ return 1;
955
+}
956
+
957
+static int rockchip_sai_rx_lanes_get(struct snd_kcontrol *kcontrol,
958
+ struct snd_ctl_elem_value *ucontrol)
959
+{
960
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
961
+ struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
962
+
963
+ ucontrol->value.enumerated.item[0] = sai->rx_lanes;
964
+
965
+ return 0;
966
+}
967
+
968
+static int rockchip_sai_rx_lanes_put(struct snd_kcontrol *kcontrol,
969
+ struct snd_ctl_elem_value *ucontrol)
970
+{
971
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
972
+ struct rk_sai_dev *sai = snd_soc_component_get_drvdata(component);
973
+ int num;
974
+
975
+ num = ucontrol->value.enumerated.item[0];
976
+ if (num >= ARRAY_SIZE(rx_lanes_text))
977
+ return -EINVAL;
978
+
979
+ sai->rx_lanes = num;
980
+
981
+ return 1;
982
+}
983
+
877984 static DECLARE_TLV_DB_SCALE(fs_shift_tlv, 0, 8192, 0);
878985
879986 static const struct snd_kcontrol_new rockchip_sai_controls[] = {
880987
881988 SOC_ENUM("Transmit Edge Shift", tsft_enum),
882
- SOC_ENUM("Transmit SDOx Select", tcsr_enum),
989
+ SOC_ENUM_EXT("Transmit SDOx Select", tx_lanes_enum,
990
+ rockchip_sai_tx_lanes_get, rockchip_sai_tx_lanes_put),
883991 SOC_ENUM("Transmit Store Justified Mode", tsjm_enum),
884992 SOC_ENUM("Transmit First Bit Mode", tfbm_enum),
885993 SOC_ENUM("Transmit Valid Data Justified", tvdj_enum),
886994 SOC_ENUM("Transmit Slot Bit Width", tsbw_enum),
887995
888996 SOC_ENUM("Receive Edge Shift", rsft_enum),
889
- SOC_ENUM("Receive SDIx Select", rcsr_enum),
997
+ SOC_ENUM_EXT("Receive SDIx Select", rx_lanes_enum,
998
+ rockchip_sai_rx_lanes_get, rockchip_sai_rx_lanes_put),
890999 SOC_ENUM("Receive Store Justified Mode", rsjm_enum),
8911000 SOC_ENUM("Receive First Bit Mode", rfbm_enum),
8921001 SOC_ENUM("Receive Valid Data Justified", rvdj_enum),
....@@ -966,6 +1075,50 @@
9661075 return IRQ_HANDLED;
9671076 }
9681077
1078
+static int rockchip_sai_keep_clk_always_on(struct rk_sai_dev *sai)
1079
+{
1080
+ unsigned int mclk_rate, bclk_rate, div_bclk;
1081
+
1082
+ sai->is_master_mode = true;
1083
+
1084
+ /* init I2S fmt default */
1085
+ rockchip_sai_fmt_create(sai, SND_SOC_DAIFMT_I2S);
1086
+
1087
+ regmap_update_bits(sai->regmap, SAI_FSCR,
1088
+ SAI_FSCR_FW_MASK |
1089
+ SAI_FSCR_FPW_MASK,
1090
+ SAI_FSCR_FW(64) |
1091
+ SAI_FSCR_FPW(32));
1092
+
1093
+ mclk_rate = clk_get_rate(sai->mclk);
1094
+ bclk_rate = DEFAULT_FS * 64;
1095
+ div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
1096
+
1097
+ regmap_update_bits(sai->regmap, SAI_CKR, SAI_CKR_MDIV_MASK,
1098
+ SAI_CKR_MDIV(div_bclk));
1099
+
1100
+ pm_runtime_forbid(sai->dev);
1101
+
1102
+ dev_info(sai->dev, "CLK-ALWAYS-ON: mclk: %d, bclk: %d, fsync: %d\n",
1103
+ mclk_rate, bclk_rate, DEFAULT_FS);
1104
+
1105
+ return 0;
1106
+}
1107
+
1108
+static int rockchip_sai_parse_quirks(struct rk_sai_dev *sai)
1109
+{
1110
+ int ret = 0, i = 0;
1111
+
1112
+ for (i = 0; i < ARRAY_SIZE(of_quirks); i++)
1113
+ if (of_property_read_bool(sai->dev->of_node, of_quirks[i].quirk))
1114
+ sai->quirks |= of_quirks[i].id;
1115
+
1116
+ if (sai->quirks & QUIRK_ALWAYS_ON)
1117
+ ret = rockchip_sai_keep_clk_always_on(sai);
1118
+
1119
+ return ret;
1120
+}
1121
+
9691122 static int rockchip_sai_probe(struct platform_device *pdev)
9701123 {
9711124 struct device_node *node = pdev->dev.of_node;
....@@ -1022,13 +1175,13 @@
10221175 return PTR_ERR(sai->hclk);
10231176 }
10241177
1025
- ret = clk_prepare_enable(sai->hclk);
1178
+ ret = rockchip_sai_parse_quirks(sai);
10261179 if (ret)
10271180 return ret;
10281181
10291182 pm_runtime_enable(&pdev->dev);
10301183 if (!pm_runtime_enabled(&pdev->dev)) {
1031
- ret = sai_runtime_resume(&pdev->dev);
1184
+ ret = rockchip_sai_runtime_resume(&pdev->dev);
10321185 if (ret)
10331186 goto err_runtime_disable;
10341187 }
....@@ -1051,29 +1204,52 @@
10511204
10521205 err_runtime_suspend:
10531206 if (!pm_runtime_status_suspended(&pdev->dev))
1054
- sai_runtime_suspend(&pdev->dev);
1207
+ rockchip_sai_runtime_suspend(&pdev->dev);
10551208 err_runtime_disable:
10561209 pm_runtime_disable(&pdev->dev);
1057
- clk_disable_unprepare(sai->hclk);
10581210
10591211 return ret;
10601212 }
10611213
10621214 static int rockchip_sai_remove(struct platform_device *pdev)
10631215 {
1064
- struct rk_sai_dev *sai = dev_get_drvdata(&pdev->dev);
1065
-
10661216 pm_runtime_disable(&pdev->dev);
10671217 if (!pm_runtime_status_suspended(&pdev->dev))
1068
- sai_runtime_suspend(&pdev->dev);
1069
-
1070
- clk_disable_unprepare(sai->hclk);
1218
+ rockchip_sai_runtime_suspend(&pdev->dev);
10711219
10721220 return 0;
10731221 }
10741222
1223
+#ifdef CONFIG_PM_SLEEP
1224
+static int rockchip_sai_suspend(struct device *dev)
1225
+{
1226
+ struct rk_sai_dev *sai = dev_get_drvdata(dev);
1227
+
1228
+ regcache_mark_dirty(sai->regmap);
1229
+
1230
+ return 0;
1231
+}
1232
+
1233
+static int rockchip_sai_resume(struct device *dev)
1234
+{
1235
+ struct rk_sai_dev *sai = dev_get_drvdata(dev);
1236
+ int ret = pm_runtime_get_sync(dev);
1237
+
1238
+ if (ret < 0) {
1239
+ pm_runtime_put_noidle(dev);
1240
+ return ret;
1241
+ }
1242
+
1243
+ ret = regcache_sync(sai->regmap);
1244
+ pm_runtime_put(dev);
1245
+
1246
+ return ret;
1247
+}
1248
+#endif /* CONFIG_PM_SLEEP */
1249
+
10751250 static const struct dev_pm_ops rockchip_sai_pm_ops = {
1076
- SET_RUNTIME_PM_OPS(sai_runtime_suspend, sai_runtime_resume, NULL)
1251
+ SET_RUNTIME_PM_OPS(rockchip_sai_runtime_suspend, rockchip_sai_runtime_resume, NULL)
1252
+ SET_SYSTEM_SLEEP_PM_OPS(rockchip_sai_suspend, rockchip_sai_resume)
10771253 };
10781254
10791255 static struct platform_driver rockchip_sai_driver = {