hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/soc/rockchip/rockchip_sai.c
....@@ -19,10 +19,12 @@
1919 #include <sound/tlv.h>
2020
2121 #include "rockchip_sai.h"
22
+#include "rockchip_dlp_pcm.h"
23
+#include "rockchip_utils.h"
2224
2325 #define DRV_NAME "rockchip-sai"
2426
25
-#define CLK_SHIFT_RATE_HZ_MAX 1 /* 1 Hz */
27
+#define CLK_SHIFT_RATE_HZ_MAX 5
2628 #define FW_RATIO_MAX 8
2729 #define FW_RATIO_MIN 1
2830 #define MAXBURST_PER_FIFO 8
....@@ -422,23 +424,27 @@
422424 {
423425 struct rk_sai_dev *sai = snd_soc_dai_get_drvdata(dai);
424426 struct snd_dmaengine_dai_dma_data *dma_data;
425
- unsigned int mclk_rate, bclk_rate, div_bclk;
427
+ unsigned int mclk_rate, mclk_req_rate, bclk_rate, div_bclk;
426428 unsigned int ch_per_lane, lanes, slot_width;
427
- unsigned int val, fscr, reg;
429
+ unsigned int val, fscr, reg, fifo;
428430
429431 dma_data = snd_soc_dai_get_dma_data(dai, substream);
430432 dma_data->maxburst = MAXBURST_PER_FIFO * params_channels(params) / 2;
431433
432434 lanes = rockchip_sai_lanes_auto(params, dai);
433435
436
+ regmap_read(sai->regmap, SAI_DMACR, &val);
437
+
434438 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
435439 reg = SAI_TXCR;
436440 if (sai->tx_lanes)
437441 lanes = sai->tx_lanes;
442
+ fifo = SAI_DMACR_TDL_V(val) * lanes;
438443 } else {
439444 reg = SAI_RXCR;
440445 if (sai->rx_lanes)
441446 lanes = sai->rx_lanes;
447
+ fifo = SAI_DMACR_TDL_V(val) * lanes;
442448 }
443449
444450 switch (params_format(params)) {
....@@ -497,18 +503,29 @@
497503 if (sai->is_clk_auto)
498504 clk_set_rate(sai->mclk, bclk_rate);
499505 mclk_rate = clk_get_rate(sai->mclk);
500
- if (mclk_rate < bclk_rate - CLK_SHIFT_RATE_HZ_MAX ||
501
- mclk_rate > bclk_rate + CLK_SHIFT_RATE_HZ_MAX) {
506
+ div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
507
+ mclk_req_rate = bclk_rate * div_bclk;
508
+
509
+ if (mclk_rate < mclk_req_rate - CLK_SHIFT_RATE_HZ_MAX ||
510
+ mclk_rate > mclk_req_rate + CLK_SHIFT_RATE_HZ_MAX) {
502511 dev_err(sai->dev, "Mismatch mclk: %u, expected %u (+/- %dHz)\n",
503
- mclk_rate, bclk_rate, CLK_SHIFT_RATE_HZ_MAX);
512
+ mclk_rate, mclk_req_rate, CLK_SHIFT_RATE_HZ_MAX);
504513 return -EINVAL;
505514 }
506
-
507
- div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate);
508515
509516 regmap_update_bits(sai->regmap, SAI_CKR, SAI_CKR_MDIV_MASK,
510517 SAI_CKR_MDIV(div_bclk));
511518 }
519
+
520
+ rockchip_utils_get_performance(substream, params, dai, fifo);
521
+
522
+ return 0;
523
+}
524
+
525
+static int rockchip_sai_hw_free(struct snd_pcm_substream *substream,
526
+ struct snd_soc_dai *dai)
527
+{
528
+ rockchip_utils_put_performance(substream, dai);
512529
513530 return 0;
514531 }
....@@ -639,6 +656,7 @@
639656 .startup = rockchip_sai_startup,
640657 .shutdown = rockchip_sai_shutdown,
641658 .hw_params = rockchip_sai_hw_params,
659
+ .hw_free = rockchip_sai_hw_free,
642660 .set_sysclk = rockchip_sai_set_sysclk,
643661 .set_fmt = rockchip_sai_set_fmt,
644662 .prepare = rockchip_sai_prepare,
....@@ -879,39 +897,39 @@
879897 "From PATH0", "From PATH1", "From PATH2", "From PATH3" };
880898
881899 /* TXCR */
882
-static SOC_ENUM_SINGLE_DECL(tsft_enum, SAI_TXCR, 22, edge_shift_text);
900
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tsft_enum, SAI_TXCR, 22, edge_shift_text);
883901 static const struct soc_enum tx_lanes_enum =
884902 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tx_lanes_text), tx_lanes_text);
885
-static SOC_ENUM_SINGLE_DECL(tsjm_enum, SAI_TXCR, 19, sjm_text);
886
-static SOC_ENUM_SINGLE_DECL(tfbm_enum, SAI_TXCR, 18, fbm_text);
887
-static SOC_ENUM_SINGLE_DECL(tvdj_enum, SAI_TXCR, 10, vdj_text);
888
-static SOC_ENUM_SINGLE_DECL(tsbw_enum, SAI_TXCR, 5, sbw_text);
903
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tsjm_enum, SAI_TXCR, 19, sjm_text);
904
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tfbm_enum, SAI_TXCR, 18, fbm_text);
905
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tvdj_enum, SAI_TXCR, 10, vdj_text);
906
+static SOC_ENUM_SINGLE_DECL(__maybe_unused tsbw_enum, SAI_TXCR, 5, sbw_text);
889907
890908 /* FSCR */
891
-static SOC_ENUM_SINGLE_DECL(edge_enum, SAI_FSCR, 24, edge_text);
892
-static const struct soc_enum fpw_enum =
909
+static SOC_ENUM_SINGLE_DECL(__maybe_unused edge_enum, SAI_FSCR, 24, edge_text);
910
+static const struct soc_enum __maybe_unused fpw_enum =
893911 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fpw_text), fpw_text);
894
-static const struct soc_enum fw_ratio_enum =
912
+static const struct soc_enum __maybe_unused fw_ratio_enum =
895913 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(fw_ratio_text), fw_ratio_text);
896914
897915 /* RXCR */
898
-static SOC_ENUM_SINGLE_DECL(rsft_enum, SAI_RXCR, 22, edge_shift_text);
916
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rsft_enum, SAI_RXCR, 22, edge_shift_text);
899917 static const struct soc_enum rx_lanes_enum =
900918 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rx_lanes_text), rx_lanes_text);
901
-static SOC_ENUM_SINGLE_DECL(rsjm_enum, SAI_RXCR, 19, sjm_text);
902
-static SOC_ENUM_SINGLE_DECL(rfbm_enum, SAI_RXCR, 18, fbm_text);
903
-static SOC_ENUM_SINGLE_DECL(rvdj_enum, SAI_RXCR, 10, vdj_text);
904
-static SOC_ENUM_SINGLE_DECL(rsbw_enum, SAI_RXCR, 5, sbw_text);
919
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rsjm_enum, SAI_RXCR, 19, sjm_text);
920
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rfbm_enum, SAI_RXCR, 18, fbm_text);
921
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rvdj_enum, SAI_RXCR, 10, vdj_text);
922
+static SOC_ENUM_SINGLE_DECL(__maybe_unused rsbw_enum, SAI_RXCR, 5, sbw_text);
905923
906924 /* MONO_CR */
907925 static SOC_ENUM_SINGLE_DECL(rmono_switch, SAI_MONO_CR, 1, mono_text);
908926 static SOC_ENUM_SINGLE_DECL(tmono_switch, SAI_MONO_CR, 0, mono_text);
909927
910928 /* CKR */
911
-static const struct soc_enum mss_switch =
929
+static const struct soc_enum __maybe_unused mss_switch =
912930 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mss_text), mss_text);
913
-static SOC_ENUM_SINGLE_DECL(sp_switch, SAI_CKR, 1, ckp_text);
914
-static SOC_ENUM_SINGLE_DECL(fp_switch, SAI_CKR, 0, ckp_text);
931
+static SOC_ENUM_SINGLE_DECL(__maybe_unused sp_switch, SAI_CKR, 1, ckp_text);
932
+static SOC_ENUM_SINGLE_DECL(__maybe_unused fp_switch, SAI_CKR, 0, ckp_text);
915933
916934 /* PATH_SEL */
917935 static SOC_ENUM_SINGLE_DECL(lp3_enum, SAI_PATH_SEL, 28, lpx_text);
....@@ -1344,6 +1362,29 @@
13441362 return ret;
13451363 }
13461364
1365
+static int rockchip_sai_get_fifo_count(struct device *dev,
1366
+ struct snd_pcm_substream *substream)
1367
+{
1368
+ struct rk_sai_dev *sai = dev_get_drvdata(dev);
1369
+ int val = 0;
1370
+
1371
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1372
+ regmap_read(sai->regmap, SAI_TXFIFOLR, &val);
1373
+ else
1374
+ regmap_read(sai->regmap, SAI_RXFIFOLR, &val);
1375
+
1376
+ val = ((val & SAI_FIFOLR_XFL3_MASK) >> SAI_FIFOLR_XFL3_SHIFT) +
1377
+ ((val & SAI_FIFOLR_XFL2_MASK) >> SAI_FIFOLR_XFL2_SHIFT) +
1378
+ ((val & SAI_FIFOLR_XFL1_MASK) >> SAI_FIFOLR_XFL1_SHIFT) +
1379
+ ((val & SAI_FIFOLR_XFL0_MASK) >> SAI_FIFOLR_XFL0_SHIFT);
1380
+
1381
+ return val;
1382
+}
1383
+
1384
+static const struct snd_dlp_config dconfig = {
1385
+ .get_fifo_count = rockchip_sai_get_fifo_count,
1386
+};
1387
+
13471388 static int rockchip_sai_probe(struct platform_device *pdev)
13481389 {
13491390 struct device_node *node = pdev->dev.of_node;
....@@ -1438,7 +1479,11 @@
14381479 return 0;
14391480 }
14401481
1441
- ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1482
+ if (device_property_read_bool(&pdev->dev, "rockchip,digital-loopback"))
1483
+ ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig);
1484
+ else
1485
+ ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
1486
+
14421487 if (ret)
14431488 goto err_runtime_suspend;
14441489