Lines Matching +full:i2s +full:- +full:regs
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * kirkwood-i2s.c
6 * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
20 #include <linux/platform_data/asoc-kirkwood.h>
52 return -EINVAL; in kirkwood_i2s_set_fmt()
59 value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL); in kirkwood_i2s_set_fmt()
62 writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL); in kirkwood_i2s_set_fmt()
64 value = readl(priv->io+KIRKWOOD_I2S_RECCTL); in kirkwood_i2s_set_fmt()
67 writel(value, priv->io+KIRKWOOD_I2S_RECCTL); in kirkwood_i2s_set_fmt()
104 if (IS_ERR(priv->extclk)) { in kirkwood_set_rate()
107 dev_dbg(dai->dev, "%s: dco set rate = %lu\n", in kirkwood_set_rate()
109 kirkwood_set_dco(priv->io, rate); in kirkwood_set_rate()
115 dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n", in kirkwood_set_rate()
117 clk_set_rate(priv->extclk, 256 * rate); in kirkwood_set_rate()
121 writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL); in kirkwood_set_rate()
142 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in kirkwood_i2s_hw_params()
150 i2s_value = readl(priv->io+i2s_reg); in kirkwood_i2s_hw_params()
154 * Size settings in play/rec i2s control regs and play/rec control in kirkwood_i2s_hw_params()
155 * regs must be the same. in kirkwood_i2s_hw_params()
195 return -EINVAL; in kirkwood_i2s_hw_params()
198 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in kirkwood_i2s_hw_params()
204 priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK | in kirkwood_i2s_hw_params()
207 priv->ctl_play |= ctl_play; in kirkwood_i2s_hw_params()
209 priv->ctl_rec &= ~(KIRKWOOD_RECCTL_ENABLE_MASK | in kirkwood_i2s_hw_params()
211 priv->ctl_rec |= ctl_rec; in kirkwood_i2s_hw_params()
214 writel(i2s_value, priv->io+i2s_reg); in kirkwood_i2s_hw_params()
231 struct snd_pcm_runtime *runtime = substream->runtime; in kirkwood_i2s_play_trigger()
235 ctl = readl(priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
245 ctl = readl(priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
249 } while (timeout--); in kirkwood_i2s_play_trigger()
252 dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", in kirkwood_i2s_play_trigger()
259 ctl = priv->ctl_play; in kirkwood_i2s_play_trigger()
260 if (dai->id == 0) in kirkwood_i2s_play_trigger()
261 ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN; /* i2s */ in kirkwood_i2s_play_trigger()
266 writel(value, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
269 if (!runtime->no_period_wakeup) { in kirkwood_i2s_play_trigger()
270 value = readl(priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_play_trigger()
272 writel(value, priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_play_trigger()
276 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
283 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
285 value = readl(priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_play_trigger()
287 writel(value, priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_play_trigger()
291 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
298 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
306 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_play_trigger()
310 return -EINVAL; in kirkwood_i2s_play_trigger()
322 value = readl(priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
327 ctl = priv->ctl_rec; in kirkwood_i2s_rec_trigger()
328 if (dai->id == 0) in kirkwood_i2s_rec_trigger()
329 ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN; /* i2s */ in kirkwood_i2s_rec_trigger()
334 writel(value, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
337 value = readl(priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_rec_trigger()
339 writel(value, priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_rec_trigger()
342 writel(ctl, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
347 value = readl(priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
349 writel(value, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
351 value = readl(priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_rec_trigger()
353 writel(value, priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_rec_trigger()
356 value = readl(priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
358 writel(value, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
363 value = readl(priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
365 writel(value, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
370 value = readl(priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
372 writel(value, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_rec_trigger()
376 return -EINVAL; in kirkwood_i2s_rec_trigger()
385 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in kirkwood_i2s_trigger()
400 writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE); in kirkwood_i2s_init()
401 writel(0, priv->io + KIRKWOOD_INT_MASK); in kirkwood_i2s_init()
403 reg_data = readl(priv->io + 0x1200); in kirkwood_i2s_init()
406 writel(reg_data, priv->io + 0x1200); in kirkwood_i2s_init()
410 reg_data = readl(priv->io + 0x1200); in kirkwood_i2s_init()
413 writel(reg_data, priv->io + 0x1200); in kirkwood_i2s_init()
416 value = readl(priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_init()
418 writel(value, priv->io + KIRKWOOD_PLAYCTL); in kirkwood_i2s_init()
420 value = readl(priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_init()
422 writel(value, priv->io + KIRKWOOD_RECCTL); in kirkwood_i2s_init()
437 .name = "i2s",
478 .name = "i2s",
523 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; in kirkwood_i2s_dev_probe()
526 struct device_node *np = pdev->dev.of_node; in kirkwood_i2s_dev_probe()
529 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in kirkwood_i2s_dev_probe()
531 return -ENOMEM; in kirkwood_i2s_dev_probe()
533 dev_set_drvdata(&pdev->dev, priv); in kirkwood_i2s_dev_probe()
535 priv->io = devm_platform_ioremap_resource(pdev, 0); in kirkwood_i2s_dev_probe()
536 if (IS_ERR(priv->io)) in kirkwood_i2s_dev_probe()
537 return PTR_ERR(priv->io); in kirkwood_i2s_dev_probe()
539 priv->irq = platform_get_irq(pdev, 0); in kirkwood_i2s_dev_probe()
540 if (priv->irq < 0) in kirkwood_i2s_dev_probe()
541 return priv->irq; in kirkwood_i2s_dev_probe()
544 priv->burst = 128; /* might be 32 or 128 */ in kirkwood_i2s_dev_probe()
546 priv->burst = data->burst; in kirkwood_i2s_dev_probe()
548 dev_err(&pdev->dev, "no DT nor platform data ?!\n"); in kirkwood_i2s_dev_probe()
549 return -EINVAL; in kirkwood_i2s_dev_probe()
552 priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL); in kirkwood_i2s_dev_probe()
553 if (IS_ERR(priv->clk)) { in kirkwood_i2s_dev_probe()
554 dev_err(&pdev->dev, "no clock\n"); in kirkwood_i2s_dev_probe()
555 return PTR_ERR(priv->clk); in kirkwood_i2s_dev_probe()
558 priv->extclk = devm_clk_get(&pdev->dev, "extclk"); in kirkwood_i2s_dev_probe()
559 if (IS_ERR(priv->extclk)) { in kirkwood_i2s_dev_probe()
560 if (PTR_ERR(priv->extclk) == -EPROBE_DEFER) in kirkwood_i2s_dev_probe()
561 return -EPROBE_DEFER; in kirkwood_i2s_dev_probe()
563 if (clk_is_match(priv->extclk, priv->clk)) { in kirkwood_i2s_dev_probe()
564 devm_clk_put(&pdev->dev, priv->extclk); in kirkwood_i2s_dev_probe()
565 priv->extclk = ERR_PTR(-EINVAL); in kirkwood_i2s_dev_probe()
567 dev_info(&pdev->dev, "found external clock\n"); in kirkwood_i2s_dev_probe()
568 clk_prepare_enable(priv->extclk); in kirkwood_i2s_dev_probe()
573 err = clk_prepare_enable(priv->clk); in kirkwood_i2s_dev_probe()
577 /* Some sensible defaults - this reflects the powerup values */ in kirkwood_i2s_dev_probe()
578 priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24; in kirkwood_i2s_dev_probe()
579 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; in kirkwood_i2s_dev_probe()
582 if (priv->burst == 32) { in kirkwood_i2s_dev_probe()
583 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; in kirkwood_i2s_dev_probe()
584 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; in kirkwood_i2s_dev_probe()
586 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; in kirkwood_i2s_dev_probe()
587 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; in kirkwood_i2s_dev_probe()
590 err = snd_soc_register_component(&pdev->dev, &kirkwood_soc_component, in kirkwood_i2s_dev_probe()
593 dev_err(&pdev->dev, "snd_soc_register_component failed\n"); in kirkwood_i2s_dev_probe()
602 if (!IS_ERR(priv->extclk)) in kirkwood_i2s_dev_probe()
603 clk_disable_unprepare(priv->extclk); in kirkwood_i2s_dev_probe()
604 clk_disable_unprepare(priv->clk); in kirkwood_i2s_dev_probe()
611 struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev); in kirkwood_i2s_dev_remove()
613 snd_soc_unregister_component(&pdev->dev); in kirkwood_i2s_dev_remove()
614 if (!IS_ERR(priv->extclk)) in kirkwood_i2s_dev_remove()
615 clk_disable_unprepare(priv->extclk); in kirkwood_i2s_dev_remove()
616 clk_disable_unprepare(priv->clk); in kirkwood_i2s_dev_remove()
623 { .compatible = "marvell,kirkwood-audio" },
624 { .compatible = "marvell,dove-audio" },
625 { .compatible = "marvell,armada370-audio" },
643 MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
644 MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
646 MODULE_ALIAS("platform:mvebu-audio");