.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* sound/soc/rockchip/rk_spdif.c |
---|
2 | 3 | * |
---|
3 | 4 | * ALSA SoC Audio Layer - Rockchip I2S Controller driver |
---|
.. | .. |
---|
6 | 7 | * Author: Jianqun <jay.xu@rock-chips.com> |
---|
7 | 8 | * Copyright (c) 2015 Collabora Ltd. |
---|
8 | 9 | * 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. |
---|
13 | 10 | */ |
---|
14 | 11 | |
---|
15 | 12 | #include <linux/module.h> |
---|
.. | .. |
---|
20 | 17 | #include <linux/mfd/syscon.h> |
---|
21 | 18 | #include <linux/regmap.h> |
---|
22 | 19 | #include <sound/pcm_params.h> |
---|
| 20 | +#include <sound/pcm_iec958.h> |
---|
23 | 21 | #include <sound/dmaengine_pcm.h> |
---|
24 | 22 | |
---|
25 | 23 | #include "rockchip_spdif.h" |
---|
.. | .. |
---|
31 | 29 | RK_SPDIF_RK3366, |
---|
32 | 30 | }; |
---|
33 | 31 | |
---|
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 |
---|
35 | 51 | |
---|
36 | 52 | struct rk_spdif_dev { |
---|
37 | 53 | struct device *dev; |
---|
.. | .. |
---|
44 | 60 | struct regmap *regmap; |
---|
45 | 61 | }; |
---|
46 | 62 | |
---|
47 | | -static const struct of_device_id rk_spdif_match[] = { |
---|
| 63 | +static const struct of_device_id rk_spdif_match[] __maybe_unused = { |
---|
48 | 64 | { .compatible = "rockchip,rk3066-spdif", |
---|
49 | 65 | .data = (void *)RK_SPDIF_RK3066 }, |
---|
50 | 66 | { .compatible = "rockchip,rk3188-spdif", |
---|
.. | .. |
---|
62 | 78 | { .compatible = "rockchip,rk3399-spdif", |
---|
63 | 79 | .data = (void *)RK_SPDIF_RK3366 }, |
---|
64 | 80 | { .compatible = "rockchip,rk3568-spdif", |
---|
| 81 | + .data = (void *)RK_SPDIF_RK3366 }, |
---|
| 82 | + { .compatible = "rockchip,rk3588-spdif", |
---|
65 | 83 | .data = (void *)RK_SPDIF_RK3366 }, |
---|
66 | 84 | {}, |
---|
67 | 85 | }; |
---|
.. | .. |
---|
91 | 109 | |
---|
92 | 110 | ret = clk_prepare_enable(spdif->hclk); |
---|
93 | 111 | if (ret) { |
---|
| 112 | + clk_disable_unprepare(spdif->mclk); |
---|
94 | 113 | dev_err(spdif->dev, "hclk clock enable failed %d\n", ret); |
---|
95 | 114 | return ret; |
---|
96 | 115 | } |
---|
.. | .. |
---|
113 | 132 | { |
---|
114 | 133 | struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); |
---|
115 | 134 | unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE; |
---|
116 | | - int srate, mclk; |
---|
117 | | - int ret; |
---|
| 135 | + unsigned int mclk_rate = clk_get_rate(spdif->mclk); |
---|
| 136 | + int bmc, div, ret, i; |
---|
| 137 | + u8 cs[CS_BYTE]; |
---|
| 138 | + u16 *fc = (u16 *)cs; |
---|
118 | 139 | |
---|
119 | | - srate = params_rate(params); |
---|
120 | | - mclk = srate * 128; |
---|
| 140 | + ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, sizeof(cs)); |
---|
| 141 | + if (ret < 0) |
---|
| 142 | + return ret; |
---|
| 143 | + |
---|
| 144 | + for (i = 0; i < CS_BYTE / 2; i++) |
---|
| 145 | + regmap_write(spdif->regmap, SPDIF_CHNSRn(i), CS_FRAME(fc[i])); |
---|
| 146 | + |
---|
| 147 | + regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CSE_MASK, |
---|
| 148 | + SPDIF_CFGR_CSE_EN); |
---|
| 149 | + |
---|
| 150 | + /* bmc = 128fs */ |
---|
| 151 | + bmc = 128 * params_rate(params); |
---|
| 152 | + div = DIV_ROUND_CLOSEST(mclk_rate, bmc); |
---|
| 153 | + val |= SPDIF_CFGR_CLK_DIV(div); |
---|
121 | 154 | |
---|
122 | 155 | switch (params_format(params)) { |
---|
123 | 156 | case SNDRV_PCM_FORMAT_S16_LE: |
---|
.. | .. |
---|
128 | 161 | break; |
---|
129 | 162 | case SNDRV_PCM_FORMAT_S24_LE: |
---|
130 | 163 | val |= SPDIF_CFGR_VDW_24; |
---|
| 164 | + val |= SPDIF_CFGR_ADJ_RIGHT_J; |
---|
| 165 | + break; |
---|
| 166 | + case SNDRV_PCM_FORMAT_S32_LE: |
---|
| 167 | + val |= SPDIF_CFGR_VDW_24; |
---|
| 168 | + val |= SPDIF_CFGR_ADJ_LEFT_J; |
---|
131 | 169 | break; |
---|
132 | 170 | default: |
---|
133 | 171 | return -EINVAL; |
---|
134 | 172 | } |
---|
135 | 173 | |
---|
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 | | - } |
---|
| 174 | + regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CLR_MASK, |
---|
| 175 | + SPDIF_CFGR_CLR_EN); |
---|
143 | 176 | |
---|
| 177 | + udelay(1); |
---|
144 | 178 | ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR, |
---|
145 | 179 | SPDIF_CFGR_CLK_DIV_MASK | |
---|
146 | 180 | SPDIF_CFGR_HALFWORD_ENABLE | |
---|
147 | | - SDPIF_CFGR_VDW_MASK, val); |
---|
| 181 | + SDPIF_CFGR_VDW_MASK | |
---|
| 182 | + SPDIF_CFGR_ADJ_MASK, val); |
---|
148 | 183 | |
---|
149 | 184 | return ret; |
---|
150 | 185 | } |
---|
.. | .. |
---|
203 | 238 | return 0; |
---|
204 | 239 | } |
---|
205 | 240 | |
---|
| 241 | +static int rk_spdif_set_sysclk(struct snd_soc_dai *dai, |
---|
| 242 | + int clk_id, unsigned int freq, int dir) |
---|
| 243 | +{ |
---|
| 244 | + struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai); |
---|
| 245 | + int ret = 0; |
---|
| 246 | + |
---|
| 247 | + if (!freq) |
---|
| 248 | + return 0; |
---|
| 249 | + |
---|
| 250 | + ret = clk_set_rate(spdif->mclk, freq); |
---|
| 251 | + if (ret) |
---|
| 252 | + dev_err(spdif->dev, "Failed to set mclk: %d\n", ret); |
---|
| 253 | + |
---|
| 254 | + return ret; |
---|
| 255 | +} |
---|
| 256 | + |
---|
206 | 257 | static const struct snd_soc_dai_ops rk_spdif_dai_ops = { |
---|
| 258 | + .set_sysclk = rk_spdif_set_sysclk, |
---|
207 | 259 | .hw_params = rk_spdif_hw_params, |
---|
208 | 260 | .trigger = rk_spdif_trigger, |
---|
209 | 261 | }; |
---|
.. | .. |
---|
214 | 266 | .stream_name = "Playback", |
---|
215 | 267 | .channels_min = 2, |
---|
216 | 268 | .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), |
---|
| 269 | + .rates = SNDRV_PCM_RATE_8000_192000, |
---|
222 | 270 | .formats = (SNDRV_PCM_FMTBIT_S16_LE | |
---|
223 | 271 | SNDRV_PCM_FMTBIT_S20_3LE | |
---|
224 | | - SNDRV_PCM_FMTBIT_S24_LE), |
---|
| 272 | + SNDRV_PCM_FMTBIT_S24_LE | |
---|
| 273 | + SNDRV_PCM_FMTBIT_S32_LE), |
---|
225 | 274 | }, |
---|
226 | 275 | .ops = &rk_spdif_dai_ops, |
---|
227 | 276 | }; |
---|
.. | .. |
---|
238 | 287 | case SPDIF_INTCR: |
---|
239 | 288 | case SPDIF_XFER: |
---|
240 | 289 | case SPDIF_SMPDR: |
---|
| 290 | + case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11): |
---|
| 291 | + case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11): |
---|
| 292 | + case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11): |
---|
241 | 293 | return true; |
---|
242 | 294 | default: |
---|
243 | 295 | return false; |
---|
.. | .. |
---|
253 | 305 | case SPDIF_INTSR: |
---|
254 | 306 | case SPDIF_XFER: |
---|
255 | 307 | case SPDIF_SMPDR: |
---|
| 308 | + case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11): |
---|
| 309 | + case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11): |
---|
| 310 | + case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11): |
---|
256 | 311 | return true; |
---|
257 | 312 | default: |
---|
258 | 313 | return false; |
---|
.. | .. |
---|
275 | 330 | .reg_bits = 32, |
---|
276 | 331 | .reg_stride = 4, |
---|
277 | 332 | .val_bits = 32, |
---|
278 | | - .max_register = SPDIF_SMPDR, |
---|
| 333 | + .max_register = SPDIF_VERSION, |
---|
279 | 334 | .writeable_reg = rk_spdif_wr_reg, |
---|
280 | 335 | .readable_reg = rk_spdif_rd_reg, |
---|
281 | 336 | .volatile_reg = rk_spdif_volatile_reg, |
---|
.. | .. |
---|
320 | 375 | if (IS_ERR(spdif->mclk)) |
---|
321 | 376 | return PTR_ERR(spdif->mclk); |
---|
322 | 377 | |
---|
323 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
324 | | - regs = devm_ioremap_resource(&pdev->dev, res); |
---|
| 378 | + regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); |
---|
325 | 379 | if (IS_ERR(regs)) |
---|
326 | 380 | return PTR_ERR(regs); |
---|
327 | 381 | |
---|