• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 HiHope Open Source Organization .
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #ifndef RK3588_DAI_LINUX_H
10 #define RK3588_DAI_LINUX_H
11 
12 #include <sound/dmaengine_pcm.h>
13 
14 #ifdef __cplusplus
15 #if __cplusplus
16 extern "C" {
17 #endif
18 #endif /* __cplusplus */
19 /*
20  * CKR
21  * clock generation register
22  */
23 #define I2S_CKR_TRCM_SHIFT	28
24 #define I2S_CKR_TRCM(x)	((x) << I2S_CKR_TRCM_SHIFT)
25 #define I2S_CKR_TRCM_TXRX	(0 << I2S_CKR_TRCM_SHIFT)
26 #define I2S_CKR_TRCM_TXONLY	(1 << I2S_CKR_TRCM_SHIFT)
27 #define I2S_CKR_TRCM_RXONLY	(2 << I2S_CKR_TRCM_SHIFT)
28 #define I2S_CKR_TRCM_MASK	(3 << I2S_CKR_TRCM_SHIFT)
29 #define I2S_CKR_RSD_SHIFT	8
30 #define I2S_CKR_RSD(x)		(((x) - 1) << I2S_CKR_RSD_SHIFT)
31 #define I2S_CKR_RSD_MASK	(0xff << I2S_CKR_RSD_SHIFT)
32 #define I2S_CKR_TSD_SHIFT	0
33 #define I2S_CKR_TSD(x)		(((x) - 1) << I2S_CKR_TSD_SHIFT)
34 #define I2S_CKR_TSD_MASK	(0xff << I2S_CKR_TSD_SHIFT)
35 
36 #define I2S_TXCR_TFS_SHIFT	5
37 #define I2S_TXCR_TFS_I2S	(0 << I2S_TXCR_TFS_SHIFT)
38 #define I2S_TXCR_TFS_PCM	(1 << I2S_TXCR_TFS_SHIFT)
39 #define I2S_TXCR_TFS_TDM_PCM	(2 << I2S_TXCR_TFS_SHIFT)
40 #define I2S_TXCR_TFS_TDM_I2S	(3 << I2S_TXCR_TFS_SHIFT)
41 #define I2S_TXCR_TFS_MASK	(3 << I2S_TXCR_TFS_SHIFT)
42 #define I2S_TXCR_CSR_SHIFT	15
43 #define I2S_TXCR_CSR(x)		((x) << I2S_TXCR_CSR_SHIFT)
44 #define I2S_TXCR_CSR_MASK	(3 << I2S_TXCR_CSR_SHIFT)
45 #define I2S_TXCR_VDW_SHIFT	0
46 #define I2S_TXCR_VDW(x)		(((x) - 1) << I2S_TXCR_VDW_SHIFT)
47 #define I2S_TXCR_VDW_MASK	(0x1f << I2S_TXCR_VDW_SHIFT)
48 
49 #define I2S_RXCR_CSR_SHIFT	15
50 #define I2S_RXCR_CSR(x)		((x) << I2S_RXCR_CSR_SHIFT)
51 #define I2S_RXCR_CSR_MASK	(3 << I2S_RXCR_CSR_SHIFT)
52 #define I2S_RXCR_VDW_SHIFT	0
53 #define I2S_RXCR_VDW(x)		(((x) - 1) << I2S_RXCR_VDW_SHIFT)
54 #define I2S_RXCR_VDW_MASK	(0x1f << I2S_RXCR_VDW_SHIFT)
55 
56 /*
57  * DMACR
58  * DMA control register
59  */
60 #define I2S_DMACR_RDE_SHIFT	24
61 #define I2S_DMACR_RDE_DISABLE	(0 << I2S_DMACR_RDE_SHIFT)
62 #define I2S_DMACR_RDE_ENABLE	(1 << I2S_DMACR_RDE_SHIFT)
63 #define I2S_DMACR_RDL_SHIFT	16
64 #define I2S_DMACR_RDL(x)	(((x) - 1) << I2S_DMACR_RDL_SHIFT)
65 #define I2S_DMACR_RDL_MASK	(0x1f << I2S_DMACR_RDL_SHIFT)
66 #define I2S_DMACR_TDE_SHIFT	8
67 #define I2S_DMACR_TDE_DISABLE	(0 << I2S_DMACR_TDE_SHIFT)
68 #define I2S_DMACR_TDE_ENABLE	(1 << I2S_DMACR_TDE_SHIFT)
69 #define I2S_DMACR_TDL_SHIFT	0
70 #define I2S_DMACR_TDL(x)	((x) << I2S_DMACR_TDL_SHIFT)
71 #define I2S_DMACR_TDL_MASK	(0x1f << I2S_DMACR_TDL_SHIFT)
72 
73 /*
74  * CLR
75  * clear SCLK domain logic register
76  */
77 #define I2S_CLR_RXC	BIT(1)
78 #define I2S_CLR_TXC	BIT(0)
79 
80 
81 /*
82  * XFER
83  * Transfer start register
84  */
85 #define I2S_XFER_RXS_SHIFT	1
86 #define I2S_XFER_RXS_STOP	(0 << I2S_XFER_RXS_SHIFT)
87 #define I2S_XFER_RXS_START	(1 << I2S_XFER_RXS_SHIFT)
88 #define I2S_XFER_TXS_SHIFT	0
89 #define I2S_XFER_TXS_STOP	(0 << I2S_XFER_TXS_SHIFT)
90 #define I2S_XFER_TXS_START	(1 << I2S_XFER_TXS_SHIFT)
91 
92 /*
93  * CLKDIV
94  * Mclk div register
95  */
96 #define I2S_CLKDIV_TXM_SHIFT	0
97 #define I2S_CLKDIV_TXM(x)		(((x) - 1) << I2S_CLKDIV_TXM_SHIFT)
98 #define I2S_CLKDIV_TXM_MASK	(0xff << I2S_CLKDIV_TXM_SHIFT)
99 #define I2S_CLKDIV_RXM_SHIFT	8
100 #define I2S_CLKDIV_RXM(x)		(((x) - 1) << I2S_CLKDIV_RXM_SHIFT)
101 #define I2S_CLKDIV_RXM_MASK	(0xff << I2S_CLKDIV_RXM_SHIFT)
102 
103 
104 
105 /* channel select */
106 #define I2S_CSR_SHIFT	15
107 #define I2S_CHN_2	(0 << I2S_CSR_SHIFT)
108 #define I2S_CHN_4	(1 << I2S_CSR_SHIFT)
109 #define I2S_CHN_6	(2 << I2S_CSR_SHIFT)
110 #define I2S_CHN_8	(3 << I2S_CSR_SHIFT)
111 
112 
113 /* I2S REGS */
114 #define I2S_TXCR	(0x0000)
115 #define I2S_RXCR	(0x0004)
116 #define I2S_CKR		(0x0008)
117 #define I2S_TXFIFOLR	(0x000c)
118 #define I2S_DMACR	(0x0010)
119 #define I2S_INTCR	(0x0014)
120 #define I2S_INTSR	(0x0018)
121 #define I2S_XFER	(0x001c)
122 #define I2S_CLR		(0x0020)
123 #define I2S_TXDR	(0x0024)
124 #define I2S_RXDR	(0x0028)
125 #define I2S_RXFIFOLR	(0x002c)
126 #define I2S_TDM_TXCR	(0x0030)
127 #define I2S_TDM_RXCR	(0x0034)
128 #define I2S_CLKDIV	(0x0038)
129 
130 #define DEFAULT_MCLK_FS				256
131 #define CH_GRP_MAX				4  /* The max channel 8 / 2 */
132 #define MULTIPLEX_CH_MAX			10
133 #define CLK_PPM_MIN				(-1000)
134 #define CLK_PPM_MAX				(1000)
135 struct txrx_config {
136 	u32 addr;
137 	u32 reg;
138 	u32 txonly;
139 	u32 rxonly;
140 };
141 
142 struct rk_i2s_soc_data {
143 	u32 softrst_offset;
144 	u32 grf_reg_offset;
145 	u32 grf_shift;
146 	int config_count;
147 	const struct txrx_config *configs;
148 	int (*init)(struct device *dev, u32 addr);
149 };
150 
151 struct rk3588_i2s_tdm_dev {
152 	struct device *dev;
153 	struct clk *hclk;
154 	struct clk *mclk_tx;
155 	struct clk *mclk_rx;
156 	/* The mclk_tx_src is parent of mclk_tx */
157 	struct clk *mclk_tx_src;
158 	/* The mclk_rx_src is parent of mclk_rx */
159 	struct clk *mclk_rx_src;
160 	/*
161 	 * The mclk_root0 and mclk_root1 are root parent and supplies for
162 	 * the different FS.
163 	 *
164 	 * e.g:
165 	 * mclk_root0 is VPLL0, used for FS=48000Hz
166 	 * mclk_root0 is VPLL1, used for FS=44100Hz
167 	 */
168 	struct clk *mclk_root0;
169 	struct clk *mclk_root1;
170 	struct regmap *regmap;
171 	struct regmap *grf;
172 	struct snd_dmaengine_dai_dma_data capture_dma_data;
173 	struct snd_dmaengine_dai_dma_data playback_dma_data;
174 	struct reset_control *tx_reset;
175 	struct reset_control *rx_reset;
176 	const struct rk_i2s_soc_data *soc_data;
177 	void __iomem *cru_base;
178 	bool is_master_mode;
179 	bool io_multiplex;
180 	bool mclk_calibrate;
181 	bool tdm_mode;
182 	bool tdm_fsync_half_frame;
183 	unsigned int mclk_rx_freq;
184 	unsigned int mclk_tx_freq;
185 	unsigned int mclk_root0_freq;
186 	unsigned int mclk_root1_freq;
187 	unsigned int mclk_root0_initial_freq;
188 	unsigned int mclk_root1_initial_freq;
189 	unsigned int bclk_fs;
190 	unsigned int clk_trcm;
191 	unsigned int i2s_sdis[CH_GRP_MAX];
192 	unsigned int i2s_sdos[CH_GRP_MAX];
193 	int clk_ppm;
194 	int tx_reset_id;
195 	int rx_reset_id;
196 	atomic_t refcount;
197 	spinlock_t lock; /* xfer lock */
198 	bool txStart;
199     bool rxStart;
200 };
201 #ifdef __cplusplus
202 #if __cplusplus
203         }
204 #endif
205 #endif /* __cplusplus */
206 
207 #endif /* RK3588_DAI_LINUX_H */
208