Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");