forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 1f93a7dfd1f8d5ff7a5c53246c7534fe2332d6f4
kernel/sound/soc/rockchip/rockchip_spdif.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /* sound/soc/rockchip/rk_spdif.c
23 *
34 * ALSA SoC Audio Layer - Rockchip I2S Controller driver
....@@ -6,10 +7,6 @@
67 * Author: Jianqun <jay.xu@rock-chips.com>
78 * Copyright (c) 2015 Collabora Ltd.
89 * Author: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License version 2 as
12
- * published by the Free Software Foundation.
1310 */
1411
1512 #include <linux/module.h>
....@@ -20,6 +17,7 @@
2017 #include <linux/mfd/syscon.h>
2118 #include <linux/regmap.h>
2219 #include <sound/pcm_params.h>
20
+#include <sound/pcm_iec958.h>
2321 #include <sound/dmaengine_pcm.h>
2422
2523 #include "rockchip_spdif.h"
....@@ -31,7 +29,25 @@
3129 RK_SPDIF_RK3366,
3230 };
3331
34
-#define RK3288_GRF_SOC_CON2 0x24c
32
+/*
33
+ * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
34
+ * CS0: | Mode | d | c | b | a |
35
+ * CS1: | Category Code |
36
+ * CS2: | Channel Number | Source Number |
37
+ * CS3: | Clock Accuracy | Sample Freq |
38
+ * CS4: | Ori Sample Freq | Word Length |
39
+ * CS5: | | CGMS-A |
40
+ * CS6~CS23: Reserved
41
+ *
42
+ * a: use of channel status block
43
+ * b: linear PCM identification: 0 for lpcm, 1 for nlpcm
44
+ * c: copyright information
45
+ * d: additional format information
46
+ */
47
+#define CS_BYTE 6
48
+#define CS_FRAME(c) ((c) << 16 | (c))
49
+
50
+#define RK3288_GRF_SOC_CON2 0x24c
3551
3652 struct rk_spdif_dev {
3753 struct device *dev;
....@@ -44,7 +60,7 @@
4460 struct regmap *regmap;
4561 };
4662
47
-static const struct of_device_id rk_spdif_match[] = {
63
+static const struct of_device_id rk_spdif_match[] __maybe_unused = {
4864 { .compatible = "rockchip,rk3066-spdif",
4965 .data = (void *)RK_SPDIF_RK3066 },
5066 { .compatible = "rockchip,rk3188-spdif",
....@@ -62,6 +78,8 @@
6278 { .compatible = "rockchip,rk3399-spdif",
6379 .data = (void *)RK_SPDIF_RK3366 },
6480 { .compatible = "rockchip,rk3568-spdif",
81
+ .data = (void *)RK_SPDIF_RK3366 },
82
+ { .compatible = "rockchip,rk3588-spdif",
6583 .data = (void *)RK_SPDIF_RK3366 },
6684 {},
6785 };
....@@ -113,11 +131,25 @@
113131 {
114132 struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
115133 unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
116
- int srate, mclk;
117
- int ret;
134
+ unsigned int mclk_rate = clk_get_rate(spdif->mclk);
135
+ int bmc, div, ret, i;
136
+ u8 cs[CS_BYTE];
137
+ u16 *fc = (u16 *)cs;
118138
119
- srate = params_rate(params);
120
- mclk = srate * 128;
139
+ ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, sizeof(cs));
140
+ if (ret < 0)
141
+ return ret;
142
+
143
+ for (i = 0; i < CS_BYTE / 2; i++)
144
+ regmap_write(spdif->regmap, SPDIF_CHNSRn(i), CS_FRAME(fc[i]));
145
+
146
+ regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CSE_MASK,
147
+ SPDIF_CFGR_CSE_EN);
148
+
149
+ /* bmc = 128fs */
150
+ bmc = 128 * params_rate(params);
151
+ div = DIV_ROUND_CLOSEST(mclk_rate, bmc);
152
+ val |= SPDIF_CFGR_CLK_DIV(div);
121153
122154 switch (params_format(params)) {
123155 case SNDRV_PCM_FORMAT_S16_LE:
....@@ -128,23 +160,25 @@
128160 break;
129161 case SNDRV_PCM_FORMAT_S24_LE:
130162 val |= SPDIF_CFGR_VDW_24;
163
+ val |= SPDIF_CFGR_ADJ_RIGHT_J;
164
+ break;
165
+ case SNDRV_PCM_FORMAT_S32_LE:
166
+ val |= SPDIF_CFGR_VDW_24;
167
+ val |= SPDIF_CFGR_ADJ_LEFT_J;
131168 break;
132169 default:
133170 return -EINVAL;
134171 }
135172
136
- /* Set clock and calculate divider */
137
- ret = clk_set_rate(spdif->mclk, mclk);
138
- if (ret != 0) {
139
- dev_err(spdif->dev, "Failed to set module clock rate: %d\n",
140
- ret);
141
- return ret;
142
- }
173
+ regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CLR_MASK,
174
+ SPDIF_CFGR_CLR_EN);
143175
176
+ udelay(1);
144177 ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
145178 SPDIF_CFGR_CLK_DIV_MASK |
146179 SPDIF_CFGR_HALFWORD_ENABLE |
147
- SDPIF_CFGR_VDW_MASK, val);
180
+ SDPIF_CFGR_VDW_MASK |
181
+ SPDIF_CFGR_ADJ_MASK, val);
148182
149183 return ret;
150184 }
....@@ -203,7 +237,24 @@
203237 return 0;
204238 }
205239
240
+static int rk_spdif_set_sysclk(struct snd_soc_dai *dai,
241
+ int clk_id, unsigned int freq, int dir)
242
+{
243
+ struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
244
+ int ret = 0;
245
+
246
+ if (!freq)
247
+ return 0;
248
+
249
+ ret = clk_set_rate(spdif->mclk, freq);
250
+ if (ret)
251
+ dev_err(spdif->dev, "Failed to set mclk: %d\n", ret);
252
+
253
+ return ret;
254
+}
255
+
206256 static const struct snd_soc_dai_ops rk_spdif_dai_ops = {
257
+ .set_sysclk = rk_spdif_set_sysclk,
207258 .hw_params = rk_spdif_hw_params,
208259 .trigger = rk_spdif_trigger,
209260 };
....@@ -214,14 +265,11 @@
214265 .stream_name = "Playback",
215266 .channels_min = 2,
216267 .channels_max = 2,
217
- .rates = (SNDRV_PCM_RATE_32000 |
218
- SNDRV_PCM_RATE_44100 |
219
- SNDRV_PCM_RATE_48000 |
220
- SNDRV_PCM_RATE_96000 |
221
- SNDRV_PCM_RATE_192000),
268
+ .rates = SNDRV_PCM_RATE_8000_192000,
222269 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
223270 SNDRV_PCM_FMTBIT_S20_3LE |
224
- SNDRV_PCM_FMTBIT_S24_LE),
271
+ SNDRV_PCM_FMTBIT_S24_LE |
272
+ SNDRV_PCM_FMTBIT_S32_LE),
225273 },
226274 .ops = &rk_spdif_dai_ops,
227275 };
....@@ -238,6 +286,9 @@
238286 case SPDIF_INTCR:
239287 case SPDIF_XFER:
240288 case SPDIF_SMPDR:
289
+ case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11):
290
+ case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11):
291
+ case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11):
241292 return true;
242293 default:
243294 return false;
....@@ -253,6 +304,9 @@
253304 case SPDIF_INTSR:
254305 case SPDIF_XFER:
255306 case SPDIF_SMPDR:
307
+ case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11):
308
+ case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11):
309
+ case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11):
256310 return true;
257311 default:
258312 return false;
....@@ -275,7 +329,7 @@
275329 .reg_bits = 32,
276330 .reg_stride = 4,
277331 .val_bits = 32,
278
- .max_register = SPDIF_SMPDR,
332
+ .max_register = SPDIF_VERSION,
279333 .writeable_reg = rk_spdif_wr_reg,
280334 .readable_reg = rk_spdif_rd_reg,
281335 .volatile_reg = rk_spdif_volatile_reg,
....@@ -320,8 +374,7 @@
320374 if (IS_ERR(spdif->mclk))
321375 return PTR_ERR(spdif->mclk);
322376
323
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
324
- regs = devm_ioremap_resource(&pdev->dev, res);
377
+ regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
325378 if (IS_ERR(regs))
326379 return PTR_ERR(regs);
327380