^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/core.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/soc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <sound/dmaengine_pcm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "jz4740-i2s.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define JZ4740_DMA_TYPE_AIC_TRANSMIT 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define JZ4740_DMA_TYPE_AIC_RECEIVE 25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define JZ_REG_AIC_CONF 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define JZ_REG_AIC_CTRL 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define JZ_REG_AIC_I2S_FMT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define JZ_REG_AIC_FIFO_STATUS 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define JZ_REG_AIC_I2S_STATUS 0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define JZ_REG_AIC_CLK_DIV 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define JZ_REG_AIC_FIFO 0x34
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_MASK (0xf << 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_MASK (0xf << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define JZ_AIC_CONF_OVERFLOW_PLAY_LAST BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define JZ_AIC_CONF_INTERNAL_CODEC BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define JZ_AIC_CONF_I2S BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define JZ_AIC_CONF_RESET BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define JZ_AIC_CONF_BIT_CLK_MASTER BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define JZ_AIC_CONF_SYNC_CLK_MASTER BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define JZ_AIC_CONF_ENABLE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK (0x7 << 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK (0x7 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define JZ_AIC_CTRL_ENABLE_RX_DMA BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define JZ_AIC_CTRL_ENABLE_TX_DMA BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define JZ_AIC_CTRL_FLUSH BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define JZ_AIC_CTRL_ENABLE_TFS_INT BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define JZ_AIC_CTRL_ENABLE_LOOPBACK BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define JZ_AIC_CTRL_ENABLE_PLAYBACK BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define JZ_AIC_CTRL_ENABLE_CAPTURE BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET 19
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define JZ_AIC_I2S_FMT_DISABLE_BIT_CLK BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define JZ_AIC_I2S_FMT_DISABLE_BIT_ICLK BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define JZ_AIC_I2S_FMT_ENABLE_SYS_CLK BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define JZ_AIC_I2S_FMT_MSB BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define JZ_AIC_I2S_STATUS_BUSY BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define JZ_AIC_CLK_DIV_MASK 0xf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define I2SDIV_DV_SHIFT 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define I2SDIV_DV_MASK (0xf << I2SDIV_DV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define I2SDIV_IDV_SHIFT 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define I2SDIV_IDV_MASK (0xf << I2SDIV_IDV_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) enum jz47xx_i2s_version {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) JZ_I2S_JZ4740,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) JZ_I2S_JZ4760,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) JZ_I2S_JZ4770,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) JZ_I2S_JZ4780,
^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) struct i2s_soc_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) enum jz47xx_i2s_version version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct snd_soc_dai_driver *dai;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct jz4740_i2s {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct resource *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dma_addr_t phys_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct clk *clk_aic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct clk *clk_i2s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct snd_dmaengine_dai_dma_data playback_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct snd_dmaengine_dai_dma_data capture_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) const struct i2s_soc_info *soc_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static inline uint32_t jz4740_i2s_read(const struct jz4740_i2s *i2s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return readl(i2s->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static inline void jz4740_i2s_write(const struct jz4740_i2s *i2s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) unsigned int reg, uint32_t value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) writel(value, i2s->base + reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) uint32_t conf, ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (snd_soc_dai_active(dai))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) ctrl |= JZ_AIC_CTRL_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ret = clk_prepare_enable(i2s->clk_i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) conf |= JZ_AIC_CONF_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static void jz4740_i2s_shutdown(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) uint32_t conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (snd_soc_dai_active(dai))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) conf &= ~JZ_AIC_CONF_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) clk_disable_unprepare(i2s->clk_i2s);
^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) static int jz4740_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) uint32_t ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) uint32_t mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) mask = JZ_AIC_CTRL_ENABLE_PLAYBACK | JZ_AIC_CTRL_ENABLE_TX_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mask = JZ_AIC_CTRL_ENABLE_CAPTURE | JZ_AIC_CTRL_ENABLE_RX_DMA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ctrl |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ctrl &= ~mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return -EINVAL;
^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) jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static int jz4740_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) uint32_t format = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) uint32_t conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) conf &= ~(JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case SND_SOC_DAIFMT_CBS_CFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) conf |= JZ_AIC_CONF_BIT_CLK_MASTER | JZ_AIC_CONF_SYNC_CLK_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) format |= JZ_AIC_I2S_FMT_ENABLE_SYS_CLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) case SND_SOC_DAIFMT_CBM_CFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) conf |= JZ_AIC_CONF_SYNC_CLK_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case SND_SOC_DAIFMT_CBS_CFM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) conf |= JZ_AIC_CONF_BIT_CLK_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case SND_SOC_DAIFMT_CBM_CFM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) }
^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_MSB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) format |= JZ_AIC_I2S_FMT_MSB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case SND_SOC_DAIFMT_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) case SND_SOC_DAIFMT_NB_NF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) jz4740_i2s_write(i2s, JZ_REG_AIC_I2S_FMT, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static int jz4740_i2s_hw_params(struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned int sample_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) uint32_t ctrl, div_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) int div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) div_reg = jz4740_i2s_read(i2s, JZ_REG_AIC_CLK_DIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) div = clk_get_rate(i2s->clk_i2s) / (64 * params_rate(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) switch (params_format(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) case SNDRV_PCM_FORMAT_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) sample_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) case SNDRV_PCM_FORMAT_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) sample_size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ctrl &= ~JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ctrl |= sample_size << JZ_AIC_CTRL_OUTPUT_SAMPLE_SIZE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (params_channels(params) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) ctrl |= JZ_AIC_CTRL_MONO_TO_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) ctrl &= ~JZ_AIC_CTRL_MONO_TO_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) div_reg &= ~I2SDIV_DV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ctrl &= ~JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) ctrl |= sample_size << JZ_AIC_CTRL_INPUT_SAMPLE_SIZE_OFFSET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (i2s->soc_info->version >= JZ_I2S_JZ4770) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) div_reg &= ~I2SDIV_IDV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) div_reg |= (div - 1) << I2SDIV_IDV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) div_reg &= ~I2SDIV_DV_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) div_reg |= (div - 1) << I2SDIV_DV_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) jz4740_i2s_write(i2s, JZ_REG_AIC_CLK_DIV, div_reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) static int jz4740_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned int freq, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct clk *parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) switch (clk_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) case JZ4740_I2S_CLKSRC_EXT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) parent = clk_get(NULL, "ext");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (IS_ERR(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return PTR_ERR(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) clk_set_parent(i2s->clk_i2s, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) case JZ4740_I2S_CLKSRC_PLL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) parent = clk_get(NULL, "pll half");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (IS_ERR(parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return PTR_ERR(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) clk_set_parent(i2s->clk_i2s, parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) ret = clk_set_rate(i2s->clk_i2s, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) clk_put(parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) static int jz4740_i2s_suspend(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) uint32_t conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (snd_soc_component_active(component)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) conf &= ~JZ_AIC_CONF_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) clk_disable_unprepare(i2s->clk_i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) clk_disable_unprepare(i2s->clk_aic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static int jz4740_i2s_resume(struct snd_soc_component *component)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct jz4740_i2s *i2s = snd_soc_component_get_drvdata(component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) uint32_t conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) ret = clk_prepare_enable(i2s->clk_aic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (snd_soc_component_active(component)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = clk_prepare_enable(i2s->clk_i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) clk_disable_unprepare(i2s->clk_aic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) conf = jz4740_i2s_read(i2s, JZ_REG_AIC_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) conf |= JZ_AIC_CONF_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static void jz4740_i2c_init_pcm_config(struct jz4740_i2s *i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) struct snd_dmaengine_dai_dma_data *dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* Playback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) dma_data = &i2s->playback_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) dma_data->maxburst = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) dma_data->slave_id = JZ4740_DMA_TYPE_AIC_TRANSMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) dma_data = &i2s->capture_dma_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) dma_data->maxburst = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) dma_data->slave_id = JZ4740_DMA_TYPE_AIC_RECEIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) dma_data->addr = i2s->phys_base + JZ_REG_AIC_FIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) static int jz4740_i2s_dai_probe(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) uint32_t conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) ret = clk_prepare_enable(i2s->clk_aic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) jz4740_i2c_init_pcm_config(i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) snd_soc_dai_init_dma_data(dai, &i2s->playback_dma_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) &i2s->capture_dma_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (i2s->soc_info->version >= JZ_I2S_JZ4760) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) conf = (7 << JZ4760_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) (8 << JZ4760_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) JZ_AIC_CONF_I2S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) JZ_AIC_CONF_INTERNAL_CODEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) conf = (7 << JZ_AIC_CONF_FIFO_RX_THRESHOLD_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) (8 << JZ_AIC_CONF_FIFO_TX_THRESHOLD_OFFSET) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) JZ_AIC_CONF_OVERFLOW_PLAY_LAST |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) JZ_AIC_CONF_I2S |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) JZ_AIC_CONF_INTERNAL_CODEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, JZ_AIC_CONF_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) jz4740_i2s_write(i2s, JZ_REG_AIC_CONF, conf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) static int jz4740_i2s_dai_remove(struct snd_soc_dai *dai)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) clk_disable_unprepare(i2s->clk_aic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static const struct snd_soc_dai_ops jz4740_i2s_dai_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) .startup = jz4740_i2s_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) .shutdown = jz4740_i2s_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .trigger = jz4740_i2s_trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .hw_params = jz4740_i2s_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .set_fmt = jz4740_i2s_set_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) .set_sysclk = jz4740_i2s_set_sysclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) #define JZ4740_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) SNDRV_PCM_FMTBIT_S16_LE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) static struct snd_soc_dai_driver jz4740_i2s_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .probe = jz4740_i2s_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) .remove = jz4740_i2s_dai_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) .rates = SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .formats = JZ4740_I2S_FMTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) .rates = SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .formats = JZ4740_I2S_FMTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) .symmetric_rates = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) .ops = &jz4740_i2s_dai_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static const struct i2s_soc_info jz4740_i2s_soc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) .version = JZ_I2S_JZ4740,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) .dai = &jz4740_i2s_dai,
^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) static const struct i2s_soc_info jz4760_i2s_soc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) .version = JZ_I2S_JZ4760,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .dai = &jz4740_i2s_dai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) static struct snd_soc_dai_driver jz4770_i2s_dai = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) .probe = jz4740_i2s_dai_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) .remove = jz4740_i2s_dai_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) .playback = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) .channels_min = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) .rates = SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .formats = JZ4740_I2S_FMTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .capture = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) .channels_min = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .channels_max = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .rates = SNDRV_PCM_RATE_8000_48000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .formats = JZ4740_I2S_FMTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .ops = &jz4740_i2s_dai_ops,
^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 const struct i2s_soc_info jz4770_i2s_soc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .version = JZ_I2S_JZ4770,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .dai = &jz4770_i2s_dai,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static const struct i2s_soc_info jz4780_i2s_soc_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .version = JZ_I2S_JZ4780,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) .dai = &jz4770_i2s_dai,
^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 const struct snd_soc_component_driver jz4740_i2s_component = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) .name = "jz4740-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) .suspend = jz4740_i2s_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) .resume = jz4740_i2s_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static const struct of_device_id jz4740_of_matches[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) { .compatible = "ingenic,jz4740-i2s", .data = &jz4740_i2s_soc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) { .compatible = "ingenic,jz4760-i2s", .data = &jz4760_i2s_soc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) { .compatible = "ingenic,jz4770-i2s", .data = &jz4770_i2s_soc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) { .compatible = "ingenic,jz4780-i2s", .data = &jz4780_i2s_soc_info },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) { /* sentinel */ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) MODULE_DEVICE_TABLE(of, jz4740_of_matches);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static int jz4740_i2s_dev_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct jz4740_i2s *i2s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct resource *mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!i2s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) i2s->soc_info = device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) i2s->base = devm_ioremap_resource(dev, mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (IS_ERR(i2s->base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return PTR_ERR(i2s->base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) i2s->phys_base = mem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) i2s->clk_aic = devm_clk_get(dev, "aic");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (IS_ERR(i2s->clk_aic))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return PTR_ERR(i2s->clk_aic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) i2s->clk_i2s = devm_clk_get(dev, "i2s");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (IS_ERR(i2s->clk_i2s))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return PTR_ERR(i2s->clk_i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) platform_set_drvdata(pdev, i2s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = devm_snd_soc_register_component(dev, &jz4740_i2s_component,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) i2s->soc_info->dai, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return devm_snd_dmaengine_pcm_register(dev, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) SND_DMAENGINE_PCM_FLAG_COMPAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) static struct platform_driver jz4740_i2s_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) .probe = jz4740_i2s_dev_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) .name = "jz4740-i2s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) .of_match_table = jz4740_of_matches,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) module_platform_driver(jz4740_i2s_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) MODULE_AUTHOR("Lars-Peter Clausen, <lars@metafoo.de>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) MODULE_DESCRIPTION("Ingenic JZ4740 SoC I2S driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) MODULE_ALIAS("platform:jz4740-i2s");