aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/801-audio-0051-MLK-18534-1-ASoC-fsl-sai-introduce-1-1-bclk-mclk-rat.patch
blob: 31033000c8d9bc370f674464398f055cfde6f732 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
From 2e891d3d62f5fd51e33ae6e614198ce0b3b48e95 Mon Sep 17 00:00:00 2001
From: Viorel Suman <viorel.suman@nxp.com>
Date: Wed, 6 Jun 2018 13:36:20 +0300
Subject: [PATCH] MLK-18534-1: ASoC: fsl: sai: introduce 1:1 bclk:mclk ratio
 support

Since IP version 3.01 (845s) SAI has support for 1:1
bclk:mclk ratio.

Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
---
 sound/soc/fsl/fsl_sai.c | 69 +++++++++++++++++++++++++------------------------
 sound/soc/fsl/fsl_sai.h |  2 +-
 2 files changed, 36 insertions(+), 35 deletions(-)

--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -471,7 +471,8 @@ static int fsl_sai_set_bclk(struct snd_s
 	struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai);
 	unsigned char offset = sai->soc->reg_offset;
 	unsigned long clk_rate;
-	u32 savediv = 0, ratio, savesub = freq;
+	unsigned int reg = 0;
+	u32 ratio, savesub = freq, saveratio = 0, savediv = 0;
 	u32 id;
 	int ret = 0;
 
@@ -479,6 +480,8 @@ static int fsl_sai_set_bclk(struct snd_s
 	if (sai->slave_mode[tx])
 		return 0;
 
+	fsl_sai_check_ver(dai);
+
 	for (id = 0; id < FSL_SAI_MCLK_MAX; id++) {
 		clk_rate = clk_get_rate(sai->mclk_clk[id]);
 		if (!clk_rate)
@@ -499,22 +502,21 @@ static int fsl_sai_set_bclk(struct snd_s
 			"ratio %d for freq %dHz based on clock %ldHz\n",
 			ratio, freq, clk_rate);
 
-		if (ratio % 2 == 0 && ratio >= 2 && ratio <= 512)
-			ratio /= 2;
-		else
-			continue;
+		if ((ratio % 2 == 0 && ratio >= 2 && ratio <= 512) ||
+		    (ratio == 1 && sai->verid.id >= FSL_SAI_VERID_0301)) {
 
-		if (ret < savesub) {
-			savediv = ratio;
-			sai->mclk_id[tx] = id;
-			savesub = ret;
-		}
+			if (ret < savesub) {
+				saveratio = ratio;
+				sai->mclk_id[tx] = id;
+				savesub = ret;
+			}
 
-		if (ret == 0)
-			break;
+			if (ret == 0)
+				break;
+		}
 	}
 
-	if (savediv == 0) {
+	if (saveratio == 0) {
 		dev_err(dai->dev, "failed to derive required %cx rate: %d\n",
 				tx ? 'T' : 'R', freq);
 		return -EINVAL;
@@ -530,33 +532,32 @@ static int fsl_sai_set_bclk(struct snd_s
 	 * 4) For Tx and Rx are both Synchronous with another SAI, we just
 	 *    ignore it.
 	 */
-	if ((sai->synchronous[TX] && !sai->synchronous[RX]) ||
-	    (!tx && !sai->synchronous[RX])) {
-		regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset),
-				   FSL_SAI_CR2_MSEL_MASK,
-				   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
-		regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset),
-				   FSL_SAI_CR2_DIV_MASK, savediv - 1);
-	} else if ((sai->synchronous[RX] && !sai->synchronous[TX]) ||
-		   (tx && !sai->synchronous[TX])) {
-		regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset),
-				   FSL_SAI_CR2_MSEL_MASK,
-				   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
-		regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset),
-				   FSL_SAI_CR2_DIV_MASK, savediv - 1);
+	if ((!tx || sai->synchronous[TX]) && !sai->synchronous[RX])
+		reg = FSL_SAI_RCR2(offset);
+	else if ((tx || sai->synchronous[RX]) && !sai->synchronous[TX])
+		reg = FSL_SAI_TCR2(offset);
+
+	if (reg) {
+		regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK,
+			   FSL_SAI_CR2_MSEL(sai->mclk_id[tx]));
+
+		savediv = (saveratio == 1 ? 0 : (saveratio >> 1) - 1);
+		regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_DIV_MASK, savediv);
+
+		if (sai->verid.id >= FSL_SAI_VERID_0301) {
+			regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_BYP,
+				   (saveratio == 1 ? FSL_SAI_CR2_BYP : 0));
+		}
 	}
 
-	fsl_sai_check_ver(dai);
-	switch (sai->verid.id) {
-	case FSL_SAI_VERID_0301:
+	if (sai->verid.id >= FSL_SAI_VERID_0301) {
 		/* SAI is in master mode at this point, so enable MCLK */
 		regmap_update_bits(sai->regmap, FSL_SAI_MCTL,
-				FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
-		break;
+			FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN);
 	}
 
-	dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n",
-			sai->mclk_id[tx], savediv, savesub);
+	dev_dbg(dai->dev, "best fit: clock id=%d, ratio=%d, deviation=%d\n",
+			sai->mclk_id[tx], saveratio, savesub);
 
 	return 0;
 }
--- a/sound/soc/fsl/fsl_sai.h
+++ b/sound/soc/fsl/fsl_sai.h
@@ -122,7 +122,7 @@
 #define FSL_SAI_CR2_MSEL(ID)	((ID) << 26)
 #define FSL_SAI_CR2_BCP		BIT(25)
 #define FSL_SAI_CR2_BCD_MSTR	BIT(24)
-#define FSL_SAI_CR2_BCBP	BIT(23) /* BCLK bypass */
+#define FSL_SAI_CR2_BYP		BIT(23) /* BCLK bypass */
 #define FSL_SAI_CR2_DIV_MASK	0xff
 
 /* SAI Transmit and Receive Configuration 3 Register */