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