Lines Matching +full:ep9301 +full:- +full:i2s
1 // SPDX-License-Identifier: GPL-2.0-only
3 * linux/sound/soc/ep93xx-i2s.c
4 * EP93xx I2S driver
29 #include "ep93xx-pcm.h"
59 * 0 - Generate interrupt when FIFO is half empty
60 * 1 - Generate interrupt when FIFO is empty
85 __raw_writel(val, info->regs + reg); in ep93xx_i2s_write_reg()
91 return __raw_readl(info->regs + reg); in ep93xx_i2s_read_reg()
101 clk_prepare_enable(info->mclk); in ep93xx_i2s_enable()
102 clk_prepare_enable(info->sclk); in ep93xx_i2s_enable()
103 clk_prepare_enable(info->lrclk); in ep93xx_i2s_enable()
105 /* Enable i2s */ in ep93xx_i2s_enable()
142 /* Disable i2s */ in ep93xx_i2s_disable()
146 clk_disable_unprepare(info->lrclk); in ep93xx_i2s_disable()
147 clk_disable_unprepare(info->sclk); in ep93xx_i2s_disable()
148 clk_disable_unprepare(info->mclk); in ep93xx_i2s_disable()
153 * According to documentation I2S controller can handle underflow conditions
156 * FIFO, fills the buffer with zeroes and re-enables the FIFO. State machine
177 /* Re-enable FIFO */ in ep93xx_i2s_interrupt()
187 snd_soc_dai_init_dma_data(dai, &info->dma_params_tx, in ep93xx_i2s_dai_probe()
188 &info->dma_params_rx); in ep93xx_i2s_dai_probe()
198 ep93xx_i2s_enable(info, substream->stream); in ep93xx_i2s_startup()
208 ep93xx_i2s_disable(info, substream->stream); in ep93xx_i2s_shutdown()
237 return -EINVAL; in ep93xx_i2s_set_dai_fmt()
252 return -EINVAL; in ep93xx_i2s_set_dai_fmt()
309 return -EINVAL; in ep93xx_i2s_hw_params()
312 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in ep93xx_i2s_hw_params()
318 * EP93xx I2S module can be setup so SCLK / LRCLK value can be in ep93xx_i2s_hw_params()
322 * I2S standard permits us to transmit more bits than in ep93xx_i2s_hw_params()
325 div = clk_get_rate(info->mclk) / params_rate(params); in ep93xx_i2s_hw_params()
335 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv); in ep93xx_i2s_hw_params()
339 err = clk_set_rate(info->lrclk, clk_get_rate(info->sclk) / lrdiv); in ep93xx_i2s_hw_params()
352 return -EINVAL; in ep93xx_i2s_set_sysclk()
356 return clk_set_rate(info->mclk, freq); in ep93xx_i2s_set_sysclk()
419 .name = "ep93xx-i2s",
430 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); in ep93xx_i2s_probe()
432 return -ENOMEM; in ep93xx_i2s_probe()
434 info->regs = devm_platform_ioremap_resource(pdev, 0); in ep93xx_i2s_probe()
435 if (IS_ERR(info->regs)) in ep93xx_i2s_probe()
436 return PTR_ERR(info->regs); in ep93xx_i2s_probe()
441 return irq < 0 ? irq : -ENODEV; in ep93xx_i2s_probe()
443 err = devm_request_irq(&pdev->dev, irq, ep93xx_i2s_interrupt, 0, in ep93xx_i2s_probe()
444 pdev->name, info); in ep93xx_i2s_probe()
449 info->mclk = clk_get(&pdev->dev, "mclk"); in ep93xx_i2s_probe()
450 if (IS_ERR(info->mclk)) { in ep93xx_i2s_probe()
451 err = PTR_ERR(info->mclk); in ep93xx_i2s_probe()
455 info->sclk = clk_get(&pdev->dev, "sclk"); in ep93xx_i2s_probe()
456 if (IS_ERR(info->sclk)) { in ep93xx_i2s_probe()
457 err = PTR_ERR(info->sclk); in ep93xx_i2s_probe()
461 info->lrclk = clk_get(&pdev->dev, "lrclk"); in ep93xx_i2s_probe()
462 if (IS_ERR(info->lrclk)) { in ep93xx_i2s_probe()
463 err = PTR_ERR(info->lrclk); in ep93xx_i2s_probe()
467 dev_set_drvdata(&pdev->dev, info); in ep93xx_i2s_probe()
469 err = devm_snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component, in ep93xx_i2s_probe()
474 err = devm_ep93xx_pcm_platform_register(&pdev->dev); in ep93xx_i2s_probe()
481 clk_put(info->lrclk); in ep93xx_i2s_probe()
483 clk_put(info->sclk); in ep93xx_i2s_probe()
485 clk_put(info->mclk); in ep93xx_i2s_probe()
492 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); in ep93xx_i2s_remove()
494 clk_put(info->lrclk); in ep93xx_i2s_remove()
495 clk_put(info->sclk); in ep93xx_i2s_remove()
496 clk_put(info->mclk); in ep93xx_i2s_remove()
500 { .compatible = "cirrus,ep9301-i2s" },
509 .name = "ep93xx-i2s",
516 MODULE_ALIAS("platform:ep93xx-i2s");
518 MODULE_DESCRIPTION("EP93XX I2S driver");