1 // SPDX-License-Identifier: GPL-2.0
3 * SPDIF driver for the StarFive JH7110 SoC
5 * Copyright (C) 2022 StarFive Technology Co., Ltd.
8 #include <linux/init.h>
9 #include <linux/kernel.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/slab.h>
14 #include <linux/clk.h>
15 #include <linux/regmap.h>
16 #include <linux/reset.h>
18 #include <sound/core.h>
19 #include <sound/pcm.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/initval.h>
23 #include <sound/dmaengine_pcm.h>
24 #include "starfive_spdif.h"
26 static irqreturn_t spdif_irq_handler(int irq, void *dev_id)
28 struct sf_spdif_dev *dev = dev_id;
29 bool irq_valid = false;
33 regmap_read(dev->regmap, SPDIF_INT_REG, &intr);
34 regmap_read(dev->regmap, SPDIF_STAT_REG, &stat);
35 regmap_update_bits(dev->regmap, SPDIF_CTRL,
36 SPDIF_MASK_ENABLE, 0);
37 regmap_update_bits(dev->regmap, SPDIF_INT_REG,
38 SPDIF_INT_REG_BIT, 0);
40 if ((stat & SPDIF_EMPTY_FLAG) || (stat & SPDIF_AEMPTY_FLAG)) {
41 sf_spdif_pcm_push_tx(dev);
45 if ((stat & SPDIF_FULL_FLAG) || (stat & SPDIF_AFULL_FLAG)) {
46 sf_spdif_pcm_pop_rx(dev);
50 if (stat & SPDIF_PARITY_FLAG)
53 if (stat & SPDIF_UNDERR_FLAG)
56 if (stat & SPDIF_OVRERR_FLAG)
59 if (stat & SPDIF_SYNCERR_FLAG)
62 if (stat & SPDIF_LOCK_FLAG)
65 if (stat & SPDIF_BEGIN_FLAG)
68 if (stat & SPDIF_RIGHT_LEFT)
71 regmap_update_bits(dev->regmap, SPDIF_CTRL,
72 SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
80 static int sf_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
81 struct snd_soc_dai *dai)
83 struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
86 tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
89 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
90 SPDIF_TR_MODE, SPDIF_TR_MODE);
92 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
93 SPDIF_MASK_FIFO, SPDIF_EMPTY_MASK | SPDIF_AEMPTY_MASK);
96 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
99 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
100 SPDIF_MASK_FIFO, SPDIF_FULL_MASK | SPDIF_AFULL_MASK);
104 case SNDRV_PCM_TRIGGER_START:
105 case SNDRV_PCM_TRIGGER_RESUME:
106 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
107 /* clock recovery form the SPDIF data stream 0:clk_enable */
108 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
109 SPDIF_CLK_ENABLE, 0);
111 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
112 SPDIF_ENABLE, SPDIF_ENABLE);
114 case SNDRV_PCM_TRIGGER_STOP:
115 case SNDRV_PCM_TRIGGER_SUSPEND:
116 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
117 /* clock recovery form the SPDIF data stream 1:power save mode */
118 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
119 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
121 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
125 dev_err(dai->dev, "%s L.%d cmd:%d\n", __func__, __LINE__, cmd);
132 static int sf_spdif_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
135 struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
136 unsigned int channels;
139 unsigned int tsamplerate;
141 unsigned int audio_root;
144 channels = params_channels(params);
145 rate = params_rate(params);
146 format = params_format(params);
150 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
151 SPDIF_CHANNEL_MODE, SPDIF_CHANNEL_MODE);
152 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
153 SPDIF_DUPLICATE, SPDIF_DUPLICATE);
154 spdif->channels = false;
157 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
158 SPDIF_CHANNEL_MODE, 0);
159 spdif->channels = true;
162 dev_err(dai->dev, "invalid channels number\n");
167 case SNDRV_PCM_FORMAT_S16_LE:
168 case SNDRV_PCM_FORMAT_S24_LE:
169 case SNDRV_PCM_FORMAT_S24_3LE:
170 case SNDRV_PCM_FORMAT_S32_LE:
173 dev_err(dai->dev, "invalid format\n");
177 audio_root = 204800000;
189 audio_root = 153600000;
193 dev_err(dai->dev, "channel:%d sample rate:%d\n", channels, rate);
197 ret = clk_set_rate(spdif->audio_root, audio_root);
199 dev_err(dai->dev, "failed to set audio_root rate :%d\n", ret);
202 dev_dbg(dai->dev, "audio_root get rate:%ld\n",
203 clk_get_rate(spdif->audio_root));
205 ret = clk_set_rate(spdif->mclk_inner, mclk);
207 dev_err(dai->dev, "failed to set mclk_inner rate :%d\n", ret);
211 mclk = clk_get_rate(spdif->mclk_inner);
212 dev_dbg(dai->dev, "mclk_inner get rate:%d\n", mclk);
213 /* (FCLK)4096000/128=32000 */
214 tsamplerate = (mclk / 128 + rate / 2) / rate - 1;
218 /* transmission sample rate */
219 regmap_update_bits(spdif->regmap, SPDIF_CTRL, 0xFF, tsamplerate);
224 static int sf_spdif_clks_get(struct platform_device *pdev,
225 struct sf_spdif_dev *spdif)
227 static struct clk_bulk_data clks[] = {
228 { .id = "spdif-apb" }, /* clock-names in dts file */
229 { .id = "spdif-core" },
231 { .id = "mclk_inner"},
233 int ret = devm_clk_bulk_get(&pdev->dev, ARRAY_SIZE(clks), clks);
235 spdif->spdif_apb = clks[0].clk;
236 spdif->spdif_core = clks[1].clk;
237 spdif->audio_root = clks[2].clk;
238 spdif->mclk_inner = clks[3].clk;
242 static int sf_spdif_resets_get(struct platform_device *pdev,
243 struct sf_spdif_dev *spdif)
245 struct reset_control_bulk_data resets[] = {
248 int ret = devm_reset_control_bulk_get_exclusive(&pdev->dev, ARRAY_SIZE(resets), resets);
253 spdif->rst_apb = resets[0].rstc;
258 static int sf_spdif_clk_init(struct platform_device *pdev,
259 struct sf_spdif_dev *spdif)
263 ret = clk_prepare_enable(spdif->spdif_apb);
265 dev_err(&pdev->dev, "failed to prepare enable spdif_apb\n");
266 goto disable_apb_clk;
269 ret = clk_prepare_enable(spdif->spdif_core);
271 dev_err(&pdev->dev, "failed to prepare enable spdif_core\n");
272 goto disable_core_clk;
275 ret = clk_set_rate(spdif->audio_root, 204800000);
277 dev_err(&pdev->dev, "failed to set rate for spdif audroot ret=%d\n", ret);
278 goto disable_core_clk;
281 ret = clk_set_rate(spdif->mclk_inner, 8192000);
283 dev_err(&pdev->dev, "failed to set rate for spdif mclk_inner ret=%d\n", ret);
284 goto disable_core_clk;
287 dev_dbg(&pdev->dev, "spdif->spdif_apb = %lu\n", clk_get_rate(spdif->spdif_apb));
288 dev_dbg(&pdev->dev, "spdif->spdif_core = %lu\n", clk_get_rate(spdif->spdif_core));
290 ret = reset_control_deassert(spdif->rst_apb);
292 dev_err(&pdev->dev, "failed to deassert apb\n");
293 goto disable_core_clk;
299 clk_disable_unprepare(spdif->spdif_core);
301 clk_disable_unprepare(spdif->spdif_apb);
306 static int sf_spdif_dai_probe(struct snd_soc_dai *dai)
308 struct sf_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
311 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
312 SPDIF_ENABLE | SPDIF_SFR_ENABLE | SPDIF_FIFO_ENABLE, 0);
315 regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
316 SPDIF_INT_REG_BIT, 0);
318 /* power save mode */
319 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
320 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
322 /* power save mode */
323 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
324 SPDIF_CLK_ENABLE, SPDIF_CLK_ENABLE);
326 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
327 SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE,
328 SPDIF_PARITCHECK|SPDIF_VALIDITYCHECK|SPDIF_DUPLICATE);
330 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
331 SPDIF_SETPREAMBB, SPDIF_SETPREAMBB);
333 regmap_update_bits(spdif->regmap, SPDIF_INT_REG,
334 BIT8TO20MASK<<SPDIF_PREAMBLEDEL, 0x3<<SPDIF_PREAMBLEDEL);
336 regmap_update_bits(spdif->regmap, SPDIF_FIFO_CTRL,
337 ALLBITMASK, 0x20|(0x20<<SPDIF_AFULL_THRESHOLD));
339 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
340 SPDIF_PARITYGEN, SPDIF_PARITYGEN);
342 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
343 SPDIF_MASK_ENABLE, SPDIF_MASK_ENABLE);
345 /* APB access to FIFO enable, disable if use DMA/FIFO */
346 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
347 SPDIF_USE_FIFO_IF, 0);
350 regmap_update_bits(spdif->regmap, SPDIF_CTRL,
351 SPDIF_CHANNEL_MODE, 0);
356 static const struct snd_soc_dai_ops sf_spdif_dai_ops = {
357 .trigger = sf_spdif_trigger,
358 .hw_params = sf_spdif_hw_params,
361 #define SF_PCM_RATE_44100_192000 (SNDRV_PCM_RATE_44100 | \
362 SNDRV_PCM_RATE_48000 | \
363 SNDRV_PCM_RATE_96000 | \
364 SNDRV_PCM_RATE_192000)
366 #define SF_PCM_RATE_8000_22050 (SNDRV_PCM_RATE_8000 | \
367 SNDRV_PCM_RATE_11025 | \
368 SNDRV_PCM_RATE_16000 | \
369 SNDRV_PCM_RATE_22050)
371 static struct snd_soc_dai_driver sf_spdif_dai = {
374 .probe = sf_spdif_dai_probe,
376 .stream_name = "Playback",
379 .rates = SF_PCM_RATE_8000_22050,
380 .formats = SNDRV_PCM_FMTBIT_S16_LE |
381 SNDRV_PCM_FMTBIT_S24_LE |
382 SNDRV_PCM_FMTBIT_S24_3LE |
383 SNDRV_PCM_FMTBIT_S32_LE,
385 .ops = &sf_spdif_dai_ops,
389 static const struct snd_soc_component_driver sf_spdif_component = {
390 .name = "starfive-spdif",
393 static const struct regmap_config sf_spdif_regmap_config = {
397 .max_register = 0x200,
400 static int sf_spdif_probe(struct platform_device *pdev)
402 struct sf_spdif_dev *spdif;
403 struct resource *res;
408 spdif = devm_kzalloc(&pdev->dev, sizeof(*spdif), GFP_KERNEL);
412 platform_set_drvdata(pdev, spdif);
414 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
415 base = devm_ioremap_resource(&pdev->dev, res);
417 return PTR_ERR(base);
419 spdif->spdif_base = base;
420 spdif->regmap = devm_regmap_init_mmio(&pdev->dev, spdif->spdif_base,
421 &sf_spdif_regmap_config);
422 if (IS_ERR(spdif->regmap))
423 return PTR_ERR(spdif->regmap);
425 ret = sf_spdif_clks_get(pdev, spdif);
427 dev_err(&pdev->dev, "failed to get audio clock\n");
431 ret = sf_spdif_resets_get(pdev, spdif);
433 dev_err(&pdev->dev, "failed to get audio reset controls\n");
437 ret = sf_spdif_clk_init(pdev, spdif);
439 dev_err(&pdev->dev, "failed to enable audio clock\n");
443 spdif->dev = &pdev->dev;
446 irq = platform_get_irq(pdev, 0);
448 ret = devm_request_irq(&pdev->dev, irq, spdif_irq_handler, 0,
451 dev_err(&pdev->dev, "failed to request irq\n");
456 ret = devm_snd_soc_register_component(&pdev->dev, &sf_spdif_component,
459 goto err_clk_disable;
462 ret = sf_spdif_pcm_register(pdev);
463 spdif->use_pio = true;
465 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
467 spdif->use_pio = false;
471 goto err_clk_disable;
479 static const struct of_device_id sf_spdif_of_match[] = {
480 { .compatible = "starfive,jh7110-spdif", },
483 MODULE_DEVICE_TABLE(of, sf_spdif_of_match);
485 static struct platform_driver sf_spdif_driver = {
487 .name = "starfive-spdif",
488 .of_match_table = sf_spdif_of_match,
490 .probe = sf_spdif_probe,
492 module_platform_driver(sf_spdif_driver);
494 MODULE_AUTHOR("curry.zhang <curry.zhang@starfive.com>");
495 MODULE_DESCRIPTION("starfive SPDIF driver");
496 MODULE_LICENSE("GPL v2");