520 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * linux/sound/soc/ep93xx-i2s.c4 * EP93xx I2S driver5 *6 * Copyright (C) 2010 Ryan Mallon7 *8 * Based on the original driver by:9 * Copyright (C) 2007 Chase Douglas <chasedouglas@gmail>10 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>11 */12 13#include <linux/module.h>14#include <linux/init.h>15#include <linux/slab.h>16#include <linux/clk.h>17#include <linux/io.h>18#include <linux/of.h>19 20#include <sound/core.h>21#include <sound/dmaengine_pcm.h>22#include <sound/pcm.h>23#include <sound/pcm_params.h>24#include <sound/initval.h>25#include <sound/soc.h>26 27#include <linux/soc/cirrus/ep93xx.h>28 29#include "ep93xx-pcm.h"30 31#define EP93XX_I2S_TXCLKCFG 0x0032#define EP93XX_I2S_RXCLKCFG 0x0433#define EP93XX_I2S_GLSTS 0x0834#define EP93XX_I2S_GLCTRL 0x0C35 36#define EP93XX_I2S_I2STX0LFT 0x1037#define EP93XX_I2S_I2STX0RT 0x1438 39#define EP93XX_I2S_TXLINCTRLDATA 0x2840#define EP93XX_I2S_TXCTRL 0x2C41#define EP93XX_I2S_TXWRDLEN 0x3042#define EP93XX_I2S_TX0EN 0x3443 44#define EP93XX_I2S_RXLINCTRLDATA 0x5845#define EP93XX_I2S_RXCTRL 0x5C46#define EP93XX_I2S_RXWRDLEN 0x6047#define EP93XX_I2S_RX0EN 0x6448 49#define EP93XX_I2S_WRDLEN_16 (0 << 0)50#define EP93XX_I2S_WRDLEN_24 (1 << 0)51#define EP93XX_I2S_WRDLEN_32 (2 << 0)52 53#define EP93XX_I2S_RXLINCTRLDATA_R_JUST BIT(1) /* Right justify */54 55#define EP93XX_I2S_TXLINCTRLDATA_R_JUST BIT(2) /* Right justify */56 57/*58 * Transmit empty interrupt level select:59 * 0 - Generate interrupt when FIFO is half empty60 * 1 - Generate interrupt when FIFO is empty61 */62#define EP93XX_I2S_TXCTRL_TXEMPTY_LVL BIT(0)63#define EP93XX_I2S_TXCTRL_TXUFIE BIT(1) /* Transmit interrupt enable */64 65#define EP93XX_I2S_CLKCFG_LRS (1 << 0) /* lrclk polarity */66#define EP93XX_I2S_CLKCFG_CKP (1 << 1) /* Bit clock polarity */67#define EP93XX_I2S_CLKCFG_REL (1 << 2) /* First bit transition */68#define EP93XX_I2S_CLKCFG_MASTER (1 << 3) /* Master mode */69#define EP93XX_I2S_CLKCFG_NBCG (1 << 4) /* Not bit clock gating */70 71#define EP93XX_I2S_GLSTS_TX0_FIFO_FULL BIT(12)72 73struct ep93xx_i2s_info {74 struct clk *mclk;75 struct clk *sclk;76 struct clk *lrclk;77 void __iomem *regs;78 struct snd_dmaengine_dai_dma_data dma_params_rx;79 struct snd_dmaengine_dai_dma_data dma_params_tx;80};81 82static inline void ep93xx_i2s_write_reg(struct ep93xx_i2s_info *info,83 unsigned reg, unsigned val)84{85 __raw_writel(val, info->regs + reg);86}87 88static inline unsigned ep93xx_i2s_read_reg(struct ep93xx_i2s_info *info,89 unsigned reg)90{91 return __raw_readl(info->regs + reg);92}93 94static void ep93xx_i2s_enable(struct ep93xx_i2s_info *info, int stream)95{96 unsigned base_reg;97 98 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&99 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {100 /* Enable clocks */101 clk_prepare_enable(info->mclk);102 clk_prepare_enable(info->sclk);103 clk_prepare_enable(info->lrclk);104 105 /* Enable i2s */106 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 1);107 }108 109 /* Enable fifo */110 if (stream == SNDRV_PCM_STREAM_PLAYBACK)111 base_reg = EP93XX_I2S_TX0EN;112 else113 base_reg = EP93XX_I2S_RX0EN;114 ep93xx_i2s_write_reg(info, base_reg, 1);115 116 /* Enable TX IRQs (FIFO empty or underflow) */117 if (IS_ENABLED(CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG) &&118 stream == SNDRV_PCM_STREAM_PLAYBACK)119 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCTRL,120 EP93XX_I2S_TXCTRL_TXEMPTY_LVL |121 EP93XX_I2S_TXCTRL_TXUFIE);122}123 124static void ep93xx_i2s_disable(struct ep93xx_i2s_info *info, int stream)125{126 unsigned base_reg;127 128 /* Disable IRQs */129 if (IS_ENABLED(CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG) &&130 stream == SNDRV_PCM_STREAM_PLAYBACK)131 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCTRL, 0);132 133 /* Disable fifo */134 if (stream == SNDRV_PCM_STREAM_PLAYBACK)135 base_reg = EP93XX_I2S_TX0EN;136 else137 base_reg = EP93XX_I2S_RX0EN;138 ep93xx_i2s_write_reg(info, base_reg, 0);139 140 if ((ep93xx_i2s_read_reg(info, EP93XX_I2S_TX0EN) & 0x1) == 0 &&141 (ep93xx_i2s_read_reg(info, EP93XX_I2S_RX0EN) & 0x1) == 0) {142 /* Disable i2s */143 ep93xx_i2s_write_reg(info, EP93XX_I2S_GLCTRL, 0);144 145 /* Disable clocks */146 clk_disable_unprepare(info->lrclk);147 clk_disable_unprepare(info->sclk);148 clk_disable_unprepare(info->mclk);149 }150}151 152/*153 * According to documentation I2S controller can handle underflow conditions154 * just fine, but in reality the state machine is sometimes confused so that155 * the whole stream is shifted by one byte. The watchdog below disables the TX156 * FIFO, fills the buffer with zeroes and re-enables the FIFO. State machine157 * is being reset and by filling the buffer we get some time before next158 * underflow happens.159 */160static irqreturn_t ep93xx_i2s_interrupt(int irq, void *dev_id)161{162 struct ep93xx_i2s_info *info = dev_id;163 164 /* Disable FIFO */165 ep93xx_i2s_write_reg(info, EP93XX_I2S_TX0EN, 0);166 /*167 * Fill TX FIFO with zeroes, this way we can defer next IRQs as much as168 * possible and get more time for DMA to catch up. Actually there are169 * only 8 samples in this FIFO, so even on 8kHz maximum deferral here is170 * 1ms.171 */172 while (!(ep93xx_i2s_read_reg(info, EP93XX_I2S_GLSTS) &173 EP93XX_I2S_GLSTS_TX0_FIFO_FULL)) {174 ep93xx_i2s_write_reg(info, EP93XX_I2S_I2STX0LFT, 0);175 ep93xx_i2s_write_reg(info, EP93XX_I2S_I2STX0RT, 0);176 }177 /* Re-enable FIFO */178 ep93xx_i2s_write_reg(info, EP93XX_I2S_TX0EN, 1);179 180 return IRQ_HANDLED;181}182 183static int ep93xx_i2s_dai_probe(struct snd_soc_dai *dai)184{185 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);186 187 snd_soc_dai_init_dma_data(dai, &info->dma_params_tx,188 &info->dma_params_rx);189 190 return 0;191}192 193static int ep93xx_i2s_startup(struct snd_pcm_substream *substream,194 struct snd_soc_dai *dai)195{196 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);197 198 ep93xx_i2s_enable(info, substream->stream);199 200 return 0;201}202 203static void ep93xx_i2s_shutdown(struct snd_pcm_substream *substream,204 struct snd_soc_dai *dai)205{206 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);207 208 ep93xx_i2s_disable(info, substream->stream);209}210 211static int ep93xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,212 unsigned int fmt)213{214 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);215 unsigned int clk_cfg;216 unsigned int txlin_ctrl = 0;217 unsigned int rxlin_ctrl = 0;218 219 clk_cfg = ep93xx_i2s_read_reg(info, EP93XX_I2S_RXCLKCFG);220 221 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {222 case SND_SOC_DAIFMT_I2S:223 clk_cfg |= EP93XX_I2S_CLKCFG_REL;224 break;225 226 case SND_SOC_DAIFMT_LEFT_J:227 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;228 break;229 230 case SND_SOC_DAIFMT_RIGHT_J:231 clk_cfg &= ~EP93XX_I2S_CLKCFG_REL;232 rxlin_ctrl |= EP93XX_I2S_RXLINCTRLDATA_R_JUST;233 txlin_ctrl |= EP93XX_I2S_TXLINCTRLDATA_R_JUST;234 break;235 236 default:237 return -EINVAL;238 }239 240 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {241 case SND_SOC_DAIFMT_BP_FP:242 /* CPU is provider */243 clk_cfg |= EP93XX_I2S_CLKCFG_MASTER;244 break;245 246 case SND_SOC_DAIFMT_BC_FC:247 /* Codec is provider */248 clk_cfg &= ~EP93XX_I2S_CLKCFG_MASTER;249 break;250 251 default:252 return -EINVAL;253 }254 255 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {256 case SND_SOC_DAIFMT_NB_NF:257 /* Negative bit clock, lrclk low on left word */258 clk_cfg &= ~(EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS);259 break;260 261 case SND_SOC_DAIFMT_NB_IF:262 /* Negative bit clock, lrclk low on right word */263 clk_cfg &= ~EP93XX_I2S_CLKCFG_CKP;264 clk_cfg |= EP93XX_I2S_CLKCFG_LRS;265 break;266 267 case SND_SOC_DAIFMT_IB_NF:268 /* Positive bit clock, lrclk low on left word */269 clk_cfg |= EP93XX_I2S_CLKCFG_CKP;270 clk_cfg &= ~EP93XX_I2S_CLKCFG_LRS;271 break;272 273 case SND_SOC_DAIFMT_IB_IF:274 /* Positive bit clock, lrclk low on right word */275 clk_cfg |= EP93XX_I2S_CLKCFG_CKP | EP93XX_I2S_CLKCFG_LRS;276 break;277 }278 279 /* Write new register values */280 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXCLKCFG, clk_cfg);281 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXCLKCFG, clk_cfg);282 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXLINCTRLDATA, rxlin_ctrl);283 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXLINCTRLDATA, txlin_ctrl);284 return 0;285}286 287static int ep93xx_i2s_hw_params(struct snd_pcm_substream *substream,288 struct snd_pcm_hw_params *params,289 struct snd_soc_dai *dai)290{291 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(dai);292 unsigned word_len, div, sdiv, lrdiv;293 int err;294 295 switch (params_format(params)) {296 case SNDRV_PCM_FORMAT_S16_LE:297 word_len = EP93XX_I2S_WRDLEN_16;298 break;299 300 case SNDRV_PCM_FORMAT_S24_LE:301 word_len = EP93XX_I2S_WRDLEN_24;302 break;303 304 case SNDRV_PCM_FORMAT_S32_LE:305 word_len = EP93XX_I2S_WRDLEN_32;306 break;307 308 default:309 return -EINVAL;310 }311 312 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)313 ep93xx_i2s_write_reg(info, EP93XX_I2S_TXWRDLEN, word_len);314 else315 ep93xx_i2s_write_reg(info, EP93XX_I2S_RXWRDLEN, word_len);316 317 /*318 * EP93xx I2S module can be setup so SCLK / LRCLK value can be319 * 32, 64, 128. MCLK / SCLK value can be 2 and 4.320 * We set LRCLK equal to `rate' and minimum SCLK / LRCLK 321 * value is 64, because our sample size is 32 bit * 2 channels.322 * I2S standard permits us to transmit more bits than323 * the codec uses.324 */325 div = clk_get_rate(info->mclk) / params_rate(params);326 sdiv = 4;327 if (div > (256 + 512) / 2) {328 lrdiv = 128;329 } else {330 lrdiv = 64;331 if (div < (128 + 256) / 2)332 sdiv = 2;333 }334 335 err = clk_set_rate(info->sclk, clk_get_rate(info->mclk) / sdiv);336 if (err)337 return err;338 339 err = clk_set_rate(info->lrclk, clk_get_rate(info->sclk) / lrdiv);340 if (err)341 return err;342 343 return 0;344}345 346static int ep93xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id,347 unsigned int freq, int dir)348{349 struct ep93xx_i2s_info *info = snd_soc_dai_get_drvdata(cpu_dai);350 351 if (dir == SND_SOC_CLOCK_IN || clk_id != 0)352 return -EINVAL;353 if (!freq)354 return 0;355 356 return clk_set_rate(info->mclk, freq);357}358 359#ifdef CONFIG_PM360static int ep93xx_i2s_suspend(struct snd_soc_component *component)361{362 struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);363 364 if (!snd_soc_component_active(component))365 return 0;366 367 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_PLAYBACK);368 ep93xx_i2s_disable(info, SNDRV_PCM_STREAM_CAPTURE);369 370 return 0;371}372 373static int ep93xx_i2s_resume(struct snd_soc_component *component)374{375 struct ep93xx_i2s_info *info = snd_soc_component_get_drvdata(component);376 377 if (!snd_soc_component_active(component))378 return 0;379 380 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_PLAYBACK);381 ep93xx_i2s_enable(info, SNDRV_PCM_STREAM_CAPTURE);382 383 return 0;384}385#else386#define ep93xx_i2s_suspend NULL387#define ep93xx_i2s_resume NULL388#endif389 390static const struct snd_soc_dai_ops ep93xx_i2s_dai_ops = {391 .probe = ep93xx_i2s_dai_probe,392 .startup = ep93xx_i2s_startup,393 .shutdown = ep93xx_i2s_shutdown,394 .hw_params = ep93xx_i2s_hw_params,395 .set_sysclk = ep93xx_i2s_set_sysclk,396 .set_fmt = ep93xx_i2s_set_dai_fmt,397};398 399#define EP93XX_I2S_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)400 401static struct snd_soc_dai_driver ep93xx_i2s_dai = {402 .symmetric_rate = 1,403 .playback = {404 .channels_min = 2,405 .channels_max = 2,406 .rates = SNDRV_PCM_RATE_8000_192000,407 .formats = EP93XX_I2S_FORMATS,408 },409 .capture = {410 .channels_min = 2,411 .channels_max = 2,412 .rates = SNDRV_PCM_RATE_8000_192000,413 .formats = EP93XX_I2S_FORMATS,414 },415 .ops = &ep93xx_i2s_dai_ops,416};417 418static const struct snd_soc_component_driver ep93xx_i2s_component = {419 .name = "ep93xx-i2s",420 .suspend = ep93xx_i2s_suspend,421 .resume = ep93xx_i2s_resume,422 .legacy_dai_naming = 1,423};424 425static int ep93xx_i2s_probe(struct platform_device *pdev)426{427 struct ep93xx_i2s_info *info;428 int err;429 430 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);431 if (!info)432 return -ENOMEM;433 434 info->regs = devm_platform_ioremap_resource(pdev, 0);435 if (IS_ERR(info->regs))436 return PTR_ERR(info->regs);437 438 if (IS_ENABLED(CONFIG_SND_EP93XX_SOC_I2S_WATCHDOG)) {439 int irq = platform_get_irq(pdev, 0);440 if (irq <= 0)441 return irq < 0 ? irq : -ENODEV;442 443 err = devm_request_irq(&pdev->dev, irq, ep93xx_i2s_interrupt, 0,444 pdev->name, info);445 if (err)446 return err;447 }448 449 info->mclk = clk_get(&pdev->dev, "mclk");450 if (IS_ERR(info->mclk)) {451 err = PTR_ERR(info->mclk);452 goto fail;453 }454 455 info->sclk = clk_get(&pdev->dev, "sclk");456 if (IS_ERR(info->sclk)) {457 err = PTR_ERR(info->sclk);458 goto fail_put_mclk;459 }460 461 info->lrclk = clk_get(&pdev->dev, "lrclk");462 if (IS_ERR(info->lrclk)) {463 err = PTR_ERR(info->lrclk);464 goto fail_put_sclk;465 }466 467 dev_set_drvdata(&pdev->dev, info);468 469 err = devm_snd_soc_register_component(&pdev->dev, &ep93xx_i2s_component,470 &ep93xx_i2s_dai, 1);471 if (err)472 goto fail_put_lrclk;473 474 err = devm_ep93xx_pcm_platform_register(&pdev->dev);475 if (err)476 goto fail_put_lrclk;477 478 return 0;479 480fail_put_lrclk:481 clk_put(info->lrclk);482fail_put_sclk:483 clk_put(info->sclk);484fail_put_mclk:485 clk_put(info->mclk);486fail:487 return err;488}489 490static void ep93xx_i2s_remove(struct platform_device *pdev)491{492 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);493 494 clk_put(info->lrclk);495 clk_put(info->sclk);496 clk_put(info->mclk);497}498 499static const struct of_device_id ep93xx_i2s_of_ids[] = {500 { .compatible = "cirrus,ep9301-i2s" },501 {}502};503MODULE_DEVICE_TABLE(of, ep93xx_i2s_of_ids);504 505static struct platform_driver ep93xx_i2s_driver = {506 .probe = ep93xx_i2s_probe,507 .remove = ep93xx_i2s_remove,508 .driver = {509 .name = "ep93xx-i2s",510 .of_match_table = ep93xx_i2s_of_ids,511 },512};513 514module_platform_driver(ep93xx_i2s_driver);515 516MODULE_ALIAS("platform:ep93xx-i2s");517MODULE_AUTHOR("Ryan Mallon");518MODULE_DESCRIPTION("EP93XX I2S driver");519MODULE_LICENSE("GPL");520