e4e6ec7b |
1 | /* |
2 | * STM32 ALSA SoC Digital Audio Interface (I2S) driver. |
3 | * |
4 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved |
5 | * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics. |
6 | * |
7 | * License terms: GPL V2.0. |
8 | * |
9 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License version 2 as published by |
11 | * the Free Software Foundation. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, but |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
16 | * details. |
17 | */ |
18 | |
19 | #include <linux/clk.h> |
20 | #include <linux/delay.h> |
21 | #include <linux/module.h> |
22 | #include <linux/of_irq.h> |
23 | #include <linux/of_platform.h> |
24 | #include <linux/regmap.h> |
25 | #include <linux/reset.h> |
26 | #include <linux/spinlock.h> |
27 | |
28 | #include <sound/dmaengine_pcm.h> |
29 | #include <sound/pcm_params.h> |
30 | |
31 | #define STM32_I2S_CR1_REG 0x0 |
32 | #define STM32_I2S_CFG1_REG 0x08 |
33 | #define STM32_I2S_CFG2_REG 0x0C |
34 | #define STM32_I2S_IER_REG 0x10 |
35 | #define STM32_I2S_SR_REG 0x14 |
36 | #define STM32_I2S_IFCR_REG 0x18 |
37 | #define STM32_I2S_TXDR_REG 0X20 |
38 | #define STM32_I2S_RXDR_REG 0x30 |
39 | #define STM32_I2S_CGFR_REG 0X50 |
40 | |
41 | /* Bit definition for SPI2S_CR1 register */ |
42 | #define I2S_CR1_SPE BIT(0) |
43 | #define I2S_CR1_CSTART BIT(9) |
44 | #define I2S_CR1_CSUSP BIT(10) |
45 | #define I2S_CR1_HDDIR BIT(11) |
46 | #define I2S_CR1_SSI BIT(12) |
47 | #define I2S_CR1_CRC33_17 BIT(13) |
48 | #define I2S_CR1_RCRCI BIT(14) |
49 | #define I2S_CR1_TCRCI BIT(15) |
50 | |
51 | /* Bit definition for SPI_CFG2 register */ |
52 | #define I2S_CFG2_IOSWP_SHIFT 15 |
53 | #define I2S_CFG2_IOSWP BIT(I2S_CFG2_IOSWP_SHIFT) |
54 | #define I2S_CFG2_LSBFRST BIT(23) |
55 | #define I2S_CFG2_AFCNTR BIT(31) |
56 | |
57 | /* Bit definition for SPI_CFG1 register */ |
58 | #define I2S_CFG1_FTHVL_SHIFT 5 |
59 | #define I2S_CFG1_FTHVL_MASK GENMASK(8, I2S_CFG1_FTHVL_SHIFT) |
60 | #define I2S_CFG1_FTHVL_SET(x) ((x) << I2S_CFG1_FTHVL_SHIFT) |
61 | |
62 | #define I2S_CFG1_TXDMAEN BIT(15) |
63 | #define I2S_CFG1_RXDMAEN BIT(14) |
64 | |
65 | /* Bit definition for SPI2S_IER register */ |
66 | #define I2S_IER_RXPIE BIT(0) |
67 | #define I2S_IER_TXPIE BIT(1) |
68 | #define I2S_IER_DPXPIE BIT(2) |
69 | #define I2S_IER_EOTIE BIT(3) |
70 | #define I2S_IER_TXTFIE BIT(4) |
71 | #define I2S_IER_UDRIE BIT(5) |
72 | #define I2S_IER_OVRIE BIT(6) |
73 | #define I2S_IER_CRCEIE BIT(7) |
74 | #define I2S_IER_TIFREIE BIT(8) |
75 | #define I2S_IER_MODFIE BIT(9) |
76 | #define I2S_IER_TSERFIE BIT(10) |
77 | |
78 | /* Bit definition for SPI2S_SR register */ |
79 | #define I2S_SR_RXP BIT(0) |
80 | #define I2S_SR_TXP BIT(1) |
81 | #define I2S_SR_DPXP BIT(2) |
82 | #define I2S_SR_EOT BIT(3) |
83 | #define I2S_SR_TXTF BIT(4) |
84 | #define I2S_SR_UDR BIT(5) |
85 | #define I2S_SR_OVR BIT(6) |
86 | #define I2S_SR_CRCERR BIT(7) |
87 | #define I2S_SR_TIFRE BIT(8) |
88 | #define I2S_SR_MODF BIT(9) |
89 | #define I2S_SR_TSERF BIT(10) |
90 | #define I2S_SR_SUSP BIT(11) |
91 | #define I2S_SR_TXC BIT(12) |
92 | #define I2S_SR_RXPLVL GENMASK(14, 13) |
93 | #define I2S_SR_RXWNE BIT(15) |
94 | |
95 | #define I2S_SR_MASK GENMASK(15, 0) |
96 | |
97 | /* Bit definition for SPI_IFCR register */ |
98 | #define I2S_IFCR_EOTC BIT(3) |
99 | #define I2S_IFCR_TXTFC BIT(4) |
100 | #define I2S_IFCR_UDRC BIT(5) |
101 | #define I2S_IFCR_OVRC BIT(6) |
102 | #define I2S_IFCR_CRCEC BIT(7) |
103 | #define I2S_IFCR_TIFREC BIT(8) |
104 | #define I2S_IFCR_MODFC BIT(9) |
105 | #define I2S_IFCR_TSERFC BIT(10) |
106 | #define I2S_IFCR_SUSPC BIT(11) |
107 | |
108 | #define I2S_IFCR_MASK GENMASK(11, 3) |
109 | |
110 | /* Bit definition for SPI_I2SCGFR register */ |
111 | #define I2S_CGFR_I2SMOD BIT(0) |
112 | |
113 | #define I2S_CGFR_I2SCFG_SHIFT 1 |
114 | #define I2S_CGFR_I2SCFG_MASK GENMASK(3, I2S_CGFR_I2SCFG_SHIFT) |
115 | #define I2S_CGFR_I2SCFG_SET(x) ((x) << I2S_CGFR_I2SCFG_SHIFT) |
116 | |
117 | #define I2S_CGFR_I2SSTD_SHIFT 4 |
118 | #define I2S_CGFR_I2SSTD_MASK GENMASK(5, I2S_CGFR_I2SSTD_SHIFT) |
119 | #define I2S_CGFR_I2SSTD_SET(x) ((x) << I2S_CGFR_I2SSTD_SHIFT) |
120 | |
121 | #define I2S_CGFR_PCMSYNC BIT(7) |
122 | |
123 | #define I2S_CGFR_DATLEN_SHIFT 8 |
124 | #define I2S_CGFR_DATLEN_MASK GENMASK(9, I2S_CGFR_DATLEN_SHIFT) |
125 | #define I2S_CGFR_DATLEN_SET(x) ((x) << I2S_CGFR_DATLEN_SHIFT) |
126 | |
127 | #define I2S_CGFR_CHLEN_SHIFT 10 |
128 | #define I2S_CGFR_CHLEN BIT(I2S_CGFR_CHLEN_SHIFT) |
129 | #define I2S_CGFR_CKPOL BIT(11) |
130 | #define I2S_CGFR_FIXCH BIT(12) |
131 | #define I2S_CGFR_WSINV BIT(13) |
132 | #define I2S_CGFR_DATFMT BIT(14) |
133 | |
134 | #define I2S_CGFR_I2SDIV_SHIFT 16 |
135 | #define I2S_CGFR_I2SDIV_BIT_H 23 |
136 | #define I2S_CGFR_I2SDIV_MASK GENMASK(I2S_CGFR_I2SDIV_BIT_H,\ |
137 | I2S_CGFR_I2SDIV_SHIFT) |
138 | #define I2S_CGFR_I2SDIV_SET(x) ((x) << I2S_CGFR_I2SDIV_SHIFT) |
139 | #define I2S_CGFR_I2SDIV_MAX ((1 << (I2S_CGFR_I2SDIV_BIT_H -\ |
140 | I2S_CGFR_I2SDIV_SHIFT)) - 1) |
141 | |
142 | #define I2S_CGFR_ODD_SHIFT 24 |
143 | #define I2S_CGFR_ODD BIT(I2S_CGFR_ODD_SHIFT) |
144 | #define I2S_CGFR_MCKOE BIT(25) |
145 | |
146 | enum i2s_master_mode { |
147 | I2S_MS_NOT_SET, |
148 | I2S_MS_MASTER, |
149 | I2S_MS_SLAVE, |
150 | }; |
151 | |
152 | enum i2s_mode { |
153 | I2S_I2SMOD_TX_SLAVE, |
154 | I2S_I2SMOD_RX_SLAVE, |
155 | I2S_I2SMOD_TX_MASTER, |
156 | I2S_I2SMOD_RX_MASTER, |
157 | I2S_I2SMOD_FD_SLAVE, |
158 | I2S_I2SMOD_FD_MASTER, |
159 | }; |
160 | |
161 | enum i2s_fifo_th { |
162 | I2S_FIFO_TH_NONE, |
163 | I2S_FIFO_TH_ONE_QUARTER, |
164 | I2S_FIFO_TH_HALF, |
165 | I2S_FIFO_TH_THREE_QUARTER, |
166 | I2S_FIFO_TH_FULL, |
167 | }; |
168 | |
169 | enum i2s_std { |
170 | I2S_STD_I2S, |
171 | I2S_STD_LEFT_J, |
172 | I2S_STD_RIGHT_J, |
173 | I2S_STD_DSP, |
174 | }; |
175 | |
176 | enum i2s_datlen { |
177 | I2S_I2SMOD_DATLEN_16, |
178 | I2S_I2SMOD_DATLEN_24, |
179 | I2S_I2SMOD_DATLEN_32, |
180 | }; |
181 | |
182 | #define STM32_I2S_DAI_NAME_SIZE 20 |
183 | #define STM32_I2S_FIFO_SIZE 16 |
184 | |
185 | #define STM32_I2S_IS_MASTER(x) ((x)->ms_flg == I2S_MS_MASTER) |
186 | #define STM32_I2S_IS_SLAVE(x) ((x)->ms_flg == I2S_MS_SLAVE) |
187 | |
188 | /** |
189 | * @regmap_conf: I2S register map configuration pointer |
190 | * @egmap: I2S register map pointer |
191 | * @pdev: device data pointer |
192 | * @dai_drv: DAI driver pointer |
193 | * @dma_data_tx: dma configuration data for tx channel |
194 | * @dma_data_rx: dma configuration data for tx channel |
195 | * @substream: PCM substream data pointer |
196 | * @i2sclk: kernel clock feeding the I2S clock generator |
197 | * @pclk: peripheral clock driving bus interface |
198 | * @x8kclk: I2S parent clock for sampling frequencies multiple of 8kHz |
199 | * @x11kclk: I2S parent clock for sampling frequencies multiple of 11kHz |
200 | * @base: mmio register base virtual address |
201 | * @phys_addr: I2S registers physical base address |
202 | * @lock_fd: lock to manage race conditions in full duplex mode |
203 | * @dais_name: DAI name |
204 | * @mclk_rate: master clock frequency (Hz) |
205 | * @fmt: DAI protocol |
206 | * @refcount: keep count of opened streams on I2S |
207 | * @ms_flg: master mode flag. |
208 | */ |
209 | struct stm32_i2s_data { |
210 | const struct regmap_config *regmap_conf; |
211 | struct regmap *regmap; |
212 | struct platform_device *pdev; |
213 | struct snd_soc_dai_driver *dai_drv; |
214 | struct snd_dmaengine_dai_dma_data dma_data_tx; |
215 | struct snd_dmaengine_dai_dma_data dma_data_rx; |
216 | struct snd_pcm_substream *substream; |
217 | struct clk *i2sclk; |
218 | struct clk *pclk; |
219 | struct clk *x8kclk; |
220 | struct clk *x11kclk; |
221 | void __iomem *base; |
222 | dma_addr_t phys_addr; |
223 | spinlock_t lock_fd; /* Manage race conditions for full duplex */ |
224 | char dais_name[STM32_I2S_DAI_NAME_SIZE]; |
225 | unsigned int mclk_rate; |
226 | unsigned int fmt; |
227 | int refcount; |
228 | int ms_flg; |
229 | }; |
230 | |
231 | static irqreturn_t stm32_i2s_isr(int irq, void *devid) |
232 | { |
233 | struct stm32_i2s_data *i2s = (struct stm32_i2s_data *)devid; |
234 | struct platform_device *pdev = i2s->pdev; |
235 | u32 sr, ier; |
236 | unsigned long flags; |
237 | int err = 0; |
238 | |
239 | regmap_read(i2s->regmap, STM32_I2S_SR_REG, &sr); |
240 | regmap_read(i2s->regmap, STM32_I2S_IER_REG, &ier); |
241 | |
242 | flags = sr & ier; |
243 | if (!flags) { |
244 | dev_dbg(&pdev->dev, "Spurious IRQ sr=0x%08x, ier=0x%08x\n", |
245 | sr, ier); |
246 | return IRQ_NONE; |
247 | } |
248 | |
249 | regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, |
250 | I2S_IFCR_MASK, flags); |
251 | |
252 | if (flags & I2S_SR_OVR) { |
253 | dev_dbg(&pdev->dev, "Overrun\n"); |
254 | err = 1; |
255 | } |
256 | |
257 | if (flags & I2S_SR_UDR) { |
258 | dev_dbg(&pdev->dev, "Underrun\n"); |
259 | err = 1; |
260 | } |
261 | |
262 | if (flags & I2S_SR_TIFRE) |
263 | dev_dbg(&pdev->dev, "Frame error\n"); |
264 | |
265 | if (err) |
266 | snd_pcm_stop_xrun(i2s->substream); |
267 | |
268 | return IRQ_HANDLED; |
269 | } |
270 | |
271 | static bool stm32_i2s_readable_reg(struct device *dev, unsigned int reg) |
272 | { |
273 | switch (reg) { |
274 | case STM32_I2S_CR1_REG: |
275 | case STM32_I2S_CFG1_REG: |
276 | case STM32_I2S_CFG2_REG: |
277 | case STM32_I2S_IER_REG: |
278 | case STM32_I2S_SR_REG: |
279 | case STM32_I2S_IFCR_REG: |
280 | case STM32_I2S_TXDR_REG: |
281 | case STM32_I2S_RXDR_REG: |
282 | case STM32_I2S_CGFR_REG: |
283 | return true; |
284 | default: |
285 | return false; |
286 | } |
287 | } |
288 | |
289 | static bool stm32_i2s_volatile_reg(struct device *dev, unsigned int reg) |
290 | { |
291 | switch (reg) { |
292 | case STM32_I2S_TXDR_REG: |
293 | case STM32_I2S_RXDR_REG: |
294 | return true; |
295 | default: |
296 | return false; |
297 | } |
298 | } |
299 | |
300 | static bool stm32_i2s_writeable_reg(struct device *dev, unsigned int reg) |
301 | { |
302 | switch (reg) { |
303 | case STM32_I2S_CR1_REG: |
304 | case STM32_I2S_CFG1_REG: |
305 | case STM32_I2S_CFG2_REG: |
306 | case STM32_I2S_IER_REG: |
307 | case STM32_I2S_IFCR_REG: |
308 | case STM32_I2S_TXDR_REG: |
309 | case STM32_I2S_CGFR_REG: |
310 | return true; |
311 | default: |
312 | return false; |
313 | } |
314 | } |
315 | |
316 | static int stm32_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) |
317 | { |
318 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
319 | u32 cgfr; |
320 | u32 cgfr_mask = I2S_CGFR_I2SSTD_MASK | I2S_CGFR_CKPOL | |
321 | I2S_CGFR_WSINV | I2S_CGFR_I2SCFG_MASK; |
322 | |
323 | dev_dbg(cpu_dai->dev, "fmt %x\n", fmt); |
324 | |
325 | /* |
326 | * winv = 0 : default behavior (high/low) for all standards |
327 | * ckpol = 0 for all standards. |
328 | */ |
329 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
330 | case SND_SOC_DAIFMT_I2S: |
331 | cgfr = I2S_CGFR_I2SSTD_SET(I2S_STD_I2S); |
332 | break; |
333 | case SND_SOC_DAIFMT_MSB: |
334 | cgfr = I2S_CGFR_I2SSTD_SET(I2S_STD_LEFT_J); |
335 | break; |
336 | case SND_SOC_DAIFMT_LSB: |
337 | cgfr = I2S_CGFR_I2SSTD_SET(I2S_STD_RIGHT_J); |
338 | break; |
339 | case SND_SOC_DAIFMT_DSP_A: |
340 | cgfr = I2S_CGFR_I2SSTD_SET(I2S_STD_DSP); |
341 | break; |
342 | /* DSP_B not mapped on I2S PCM long format. 1 bit offset does not fit */ |
343 | default: |
344 | dev_err(cpu_dai->dev, "Unsupported protocol %#x\n", |
345 | fmt & SND_SOC_DAIFMT_FORMAT_MASK); |
346 | return -EINVAL; |
347 | } |
348 | |
349 | /* DAI clock strobing */ |
350 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
351 | case SND_SOC_DAIFMT_NB_NF: |
352 | break; |
353 | case SND_SOC_DAIFMT_IB_NF: |
354 | cgfr |= I2S_CGFR_CKPOL; |
355 | break; |
356 | case SND_SOC_DAIFMT_NB_IF: |
357 | cgfr |= I2S_CGFR_WSINV; |
358 | break; |
359 | case SND_SOC_DAIFMT_IB_IF: |
360 | cgfr |= I2S_CGFR_CKPOL; |
361 | cgfr |= I2S_CGFR_WSINV; |
362 | break; |
363 | default: |
364 | dev_err(cpu_dai->dev, "Unsupported strobing %#x\n", |
365 | fmt & SND_SOC_DAIFMT_INV_MASK); |
366 | return -EINVAL; |
367 | } |
368 | |
369 | /* DAI clock master masks */ |
370 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
371 | case SND_SOC_DAIFMT_CBM_CFM: |
372 | i2s->ms_flg = I2S_MS_SLAVE; |
373 | break; |
374 | case SND_SOC_DAIFMT_CBS_CFS: |
375 | i2s->ms_flg = I2S_MS_MASTER; |
376 | break; |
377 | default: |
378 | dev_err(cpu_dai->dev, "Unsupported mode %#x\n", |
379 | fmt & SND_SOC_DAIFMT_MASTER_MASK); |
380 | return -EINVAL; |
381 | } |
382 | |
383 | i2s->fmt = fmt; |
384 | return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
385 | cgfr_mask, cgfr); |
386 | } |
387 | |
388 | static int stm32_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, |
389 | int clk_id, unsigned int freq, int dir) |
390 | { |
391 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
392 | |
393 | dev_dbg(cpu_dai->dev, "I2S MCLK frequency is %uHz\n", freq); |
394 | |
395 | if ((dir == SND_SOC_CLOCK_OUT) && STM32_I2S_IS_MASTER(i2s)) { |
396 | i2s->mclk_rate = freq; |
397 | |
398 | /* Enable master clock if master mode and mclk-fs are set */ |
399 | return regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
400 | I2S_CGFR_MCKOE, I2S_CGFR_MCKOE); |
401 | } |
402 | |
403 | return 0; |
404 | } |
405 | |
406 | static int stm32_i2s_configure_clock(struct snd_soc_dai *cpu_dai, |
407 | struct snd_pcm_hw_params *params) |
408 | { |
409 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
410 | unsigned long i2s_clock_rate; |
411 | unsigned int tmp, div, real_div, nb_bits, frame_len; |
412 | unsigned int rate = params_rate(params); |
413 | int ret; |
414 | u32 cgfr, cgfr_mask; |
415 | bool odd; |
416 | |
417 | if (!(rate % 11025)) |
418 | clk_set_parent(i2s->i2sclk, i2s->x11kclk); |
419 | else |
420 | clk_set_parent(i2s->i2sclk, i2s->x8kclk); |
421 | i2s_clock_rate = clk_get_rate(i2s->i2sclk); |
422 | |
423 | /* |
424 | * mckl = mclk_ratio x ws |
425 | * i2s mode : mclk_ratio = 256 |
426 | * dsp mode : mclk_ratio = 128 |
427 | * |
428 | * mclk on |
429 | * i2s mode : div = i2s_clk / (mclk_ratio * ws) |
430 | * dsp mode : div = i2s_clk / (mclk_ratio * ws) |
431 | * mclk off |
432 | * i2s mode : div = i2s_clk / (nb_bits x ws) |
433 | * dsp mode : div = i2s_clk / (nb_bits x ws) |
434 | */ |
435 | if (i2s->mclk_rate) { |
436 | tmp = DIV_ROUND_CLOSEST(i2s_clock_rate, i2s->mclk_rate); |
437 | } else { |
438 | frame_len = 32; |
439 | if ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) == |
440 | SND_SOC_DAIFMT_DSP_A) |
441 | frame_len = 16; |
442 | |
443 | /* master clock not enabled */ |
444 | ret = regmap_read(i2s->regmap, STM32_I2S_CGFR_REG, &cgfr); |
445 | if (ret < 0) |
446 | return ret; |
447 | |
448 | nb_bits = frame_len * ((cgfr & I2S_CGFR_CHLEN) + 1); |
449 | tmp = DIV_ROUND_CLOSEST(i2s_clock_rate, (nb_bits * rate)); |
450 | } |
451 | |
452 | /* Check the parity of the divider */ |
453 | odd = tmp & 0x1; |
454 | |
455 | /* Compute the div prescaler */ |
456 | div = tmp >> 1; |
457 | |
458 | cgfr = I2S_CGFR_I2SDIV_SET(div) | (odd << I2S_CGFR_ODD_SHIFT); |
459 | cgfr_mask = I2S_CGFR_I2SDIV_MASK | I2S_CGFR_ODD; |
460 | |
461 | real_div = ((2 * div) + odd); |
462 | dev_dbg(cpu_dai->dev, "I2S clk: %ld, SCLK: %d\n", |
463 | i2s_clock_rate, rate); |
464 | dev_dbg(cpu_dai->dev, "Divider: 2*%d(div)+%d(odd) = %d\n", |
465 | div, odd, real_div); |
466 | |
467 | if (((div == 1) && odd) || (div > I2S_CGFR_I2SDIV_MAX)) { |
468 | dev_err(cpu_dai->dev, "Wrong divider setting\n"); |
469 | return -EINVAL; |
470 | } |
471 | |
472 | if (!div && !odd) |
473 | dev_warn(cpu_dai->dev, "real divider forced to 1\n"); |
474 | |
475 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
476 | cgfr_mask, cgfr); |
477 | if (ret < 0) |
478 | return ret; |
479 | |
480 | /* Set bitclock and frameclock to their inactive state */ |
481 | return regmap_update_bits(i2s->regmap, STM32_I2S_CFG2_REG, |
482 | I2S_CFG2_AFCNTR, I2S_CFG2_AFCNTR); |
483 | } |
484 | |
485 | static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai, |
486 | struct snd_pcm_hw_params *params, |
487 | struct snd_pcm_substream *substream) |
488 | { |
489 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
490 | int format = params_width(params); |
491 | u32 cfgr, cfgr_mask, cfg1, cfg1_mask; |
e4e6ec7b |
492 | unsigned int fthlv; |
493 | int ret; |
494 | |
495 | if ((params_channels(params) == 1) && |
496 | ((i2s->fmt & SND_SOC_DAIFMT_FORMAT_MASK) != SND_SOC_DAIFMT_DSP_A)) { |
497 | dev_err(cpu_dai->dev, "Mono mode supported only by DSP_A\n"); |
498 | return -EINVAL; |
499 | } |
500 | |
501 | switch (format) { |
502 | case 16: |
503 | cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_16); |
504 | cfgr_mask = I2S_CGFR_DATLEN_MASK; |
505 | break; |
506 | case 32: |
507 | cfgr = I2S_CGFR_DATLEN_SET(I2S_I2SMOD_DATLEN_32) | |
508 | I2S_CGFR_CHLEN; |
509 | cfgr_mask = I2S_CGFR_DATLEN_MASK | I2S_CGFR_CHLEN; |
510 | break; |
511 | default: |
512 | dev_err(cpu_dai->dev, "Unexpected format %d", format); |
513 | return -EINVAL; |
514 | } |
515 | |
516 | if (STM32_I2S_IS_SLAVE(i2s)) { |
e7cc49b8 |
517 | cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_FD_SLAVE); |
e4e6ec7b |
518 | |
519 | /* As data length is either 16 or 32 bits, fixch always set */ |
520 | cfgr |= I2S_CGFR_FIXCH; |
521 | cfgr_mask |= I2S_CGFR_FIXCH; |
522 | } else { |
e7cc49b8 |
523 | cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_FD_MASTER); |
e4e6ec7b |
524 | } |
525 | cfgr_mask |= I2S_CGFR_I2SCFG_MASK; |
526 | |
527 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
528 | cfgr_mask, cfgr); |
529 | if (ret < 0) |
530 | return ret; |
531 | |
e7cc49b8 |
532 | cfg1 = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; |
e4e6ec7b |
533 | cfg1_mask = cfg1; |
534 | |
535 | fthlv = STM32_I2S_FIFO_SIZE * I2S_FIFO_TH_ONE_QUARTER / 4; |
536 | cfg1 |= I2S_CFG1_FTHVL_SET(fthlv - 1); |
537 | cfg1_mask |= I2S_CFG1_FTHVL_MASK; |
538 | |
539 | return regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, |
540 | cfg1_mask, cfg1); |
541 | } |
542 | |
543 | static int stm32_i2s_startup(struct snd_pcm_substream *substream, |
544 | struct snd_soc_dai *cpu_dai) |
545 | { |
546 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
e4e6ec7b |
547 | |
548 | i2s->substream = substream; |
549 | |
550 | spin_lock(&i2s->lock_fd); |
e7cc49b8 |
551 | i2s->refcount++; |
e4e6ec7b |
552 | spin_unlock(&i2s->lock_fd); |
553 | |
e7cc49b8 |
554 | return regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, |
555 | I2S_IFCR_MASK, I2S_IFCR_MASK); |
e4e6ec7b |
556 | } |
557 | |
558 | static int stm32_i2s_hw_params(struct snd_pcm_substream *substream, |
559 | struct snd_pcm_hw_params *params, |
560 | struct snd_soc_dai *cpu_dai) |
561 | { |
562 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
563 | int ret; |
564 | |
565 | ret = stm32_i2s_configure(cpu_dai, params, substream); |
566 | if (ret < 0) { |
567 | dev_err(cpu_dai->dev, "Configuration returned error %d\n", ret); |
568 | return ret; |
569 | } |
570 | |
571 | if (STM32_I2S_IS_MASTER(i2s)) |
572 | ret = stm32_i2s_configure_clock(cpu_dai, params); |
573 | |
574 | return ret; |
575 | } |
576 | |
577 | static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd, |
578 | struct snd_soc_dai *cpu_dai) |
579 | { |
580 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
581 | bool playback_flg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); |
e7cc49b8 |
582 | u32 cfg1_mask, ier; |
e4e6ec7b |
583 | int ret; |
584 | |
585 | switch (cmd) { |
586 | case SNDRV_PCM_TRIGGER_START: |
587 | case SNDRV_PCM_TRIGGER_RESUME: |
588 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
589 | /* Enable i2s */ |
590 | dev_dbg(cpu_dai->dev, "start I2S\n"); |
591 | |
592 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, |
593 | I2S_CR1_SPE, I2S_CR1_SPE); |
594 | if (ret < 0) { |
595 | dev_err(cpu_dai->dev, "Error %d enabling I2S\n", ret); |
596 | return ret; |
597 | } |
598 | |
599 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, |
600 | I2S_CR1_CSTART, I2S_CR1_CSTART); |
601 | if (ret < 0) { |
602 | dev_err(cpu_dai->dev, "Error %d starting I2S\n", ret); |
603 | return ret; |
604 | } |
e7cc49b8 |
605 | |
606 | regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG, |
607 | I2S_IFCR_MASK, I2S_IFCR_MASK); |
608 | |
609 | if (playback_flg) { |
610 | ier = I2S_IER_UDRIE; |
611 | } else { |
612 | ier = I2S_IER_OVRIE; |
613 | |
614 | spin_lock(&i2s->lock_fd); |
615 | if (i2s->refcount == 1) |
616 | /* dummy write to trigger capture */ |
617 | regmap_write(i2s->regmap, |
618 | STM32_I2S_TXDR_REG, 0); |
619 | spin_unlock(&i2s->lock_fd); |
620 | } |
621 | |
622 | if (STM32_I2S_IS_SLAVE(i2s)) |
623 | ier |= I2S_IER_TIFREIE; |
624 | |
625 | regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, ier, ier); |
e4e6ec7b |
626 | break; |
627 | case SNDRV_PCM_TRIGGER_STOP: |
628 | case SNDRV_PCM_TRIGGER_SUSPEND: |
629 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
e7cc49b8 |
630 | if (playback_flg) |
631 | regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, |
632 | I2S_IER_UDRIE, |
633 | (unsigned int)~I2S_IER_UDRIE); |
634 | else |
635 | regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, |
636 | I2S_IER_OVRIE, |
637 | (unsigned int)~I2S_IER_OVRIE); |
638 | |
639 | spin_lock(&i2s->lock_fd); |
640 | i2s->refcount--; |
641 | if (i2s->refcount) { |
642 | spin_unlock(&i2s->lock_fd); |
643 | break; |
644 | } |
645 | spin_unlock(&i2s->lock_fd); |
646 | |
e4e6ec7b |
647 | dev_dbg(cpu_dai->dev, "stop I2S\n"); |
648 | |
649 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG, |
650 | I2S_CR1_SPE, 0); |
651 | if (ret < 0) { |
652 | dev_err(cpu_dai->dev, "Error %d disabling I2S\n", ret); |
653 | return ret; |
654 | } |
655 | |
e7cc49b8 |
656 | cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN; |
e4e6ec7b |
657 | regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG, |
658 | cfg1_mask, 0); |
659 | break; |
660 | default: |
661 | return -EINVAL; |
662 | } |
663 | |
664 | return 0; |
665 | } |
666 | |
667 | static void stm32_i2s_shutdown(struct snd_pcm_substream *substream, |
668 | struct snd_soc_dai *cpu_dai) |
669 | { |
670 | struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai); |
671 | |
672 | i2s->substream = NULL; |
673 | |
e4e6ec7b |
674 | regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
675 | I2S_CGFR_MCKOE, (unsigned int)~I2S_CGFR_MCKOE); |
676 | } |
677 | |
678 | static int stm32_i2s_dai_probe(struct snd_soc_dai *cpu_dai) |
679 | { |
680 | struct stm32_i2s_data *i2s = dev_get_drvdata(cpu_dai->dev); |
681 | struct snd_dmaengine_dai_dma_data *dma_data_tx = &i2s->dma_data_tx; |
682 | struct snd_dmaengine_dai_dma_data *dma_data_rx = &i2s->dma_data_rx; |
683 | |
684 | /* Buswidth will be set by framework */ |
685 | dma_data_tx->addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED; |
686 | dma_data_tx->addr = (dma_addr_t)(i2s->phys_addr) + STM32_I2S_TXDR_REG; |
687 | dma_data_tx->maxburst = 1; |
688 | dma_data_rx->addr_width = DMA_SLAVE_BUSWIDTH_UNDEFINED; |
689 | dma_data_rx->addr = (dma_addr_t)(i2s->phys_addr) + STM32_I2S_RXDR_REG; |
690 | dma_data_rx->maxburst = 1; |
691 | |
692 | snd_soc_dai_init_dma_data(cpu_dai, dma_data_tx, dma_data_rx); |
693 | |
694 | return 0; |
695 | } |
696 | |
697 | static const struct regmap_config stm32_h7_i2s_regmap_conf = { |
698 | .reg_bits = 32, |
699 | .reg_stride = 4, |
700 | .val_bits = 32, |
701 | .max_register = STM32_I2S_CGFR_REG, |
702 | .readable_reg = stm32_i2s_readable_reg, |
703 | .volatile_reg = stm32_i2s_volatile_reg, |
704 | .writeable_reg = stm32_i2s_writeable_reg, |
705 | .fast_io = true, |
706 | }; |
707 | |
708 | static const struct snd_soc_dai_ops stm32_i2s_pcm_dai_ops = { |
709 | .set_sysclk = stm32_i2s_set_sysclk, |
710 | .set_fmt = stm32_i2s_set_dai_fmt, |
711 | .startup = stm32_i2s_startup, |
712 | .hw_params = stm32_i2s_hw_params, |
713 | .trigger = stm32_i2s_trigger, |
714 | .shutdown = stm32_i2s_shutdown, |
715 | }; |
716 | |
717 | static const struct snd_pcm_hardware stm32_i2s_pcm_hw = { |
718 | .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_MMAP, |
719 | .buffer_bytes_max = 8 * PAGE_SIZE, |
720 | .period_bytes_max = 2048, |
721 | .periods_min = 2, |
722 | .periods_max = 8, |
723 | }; |
724 | |
725 | static const struct snd_dmaengine_pcm_config stm32_i2s_pcm_config = { |
726 | .pcm_hardware = &stm32_i2s_pcm_hw, |
727 | .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, |
728 | .prealloc_buffer_size = PAGE_SIZE * 8, |
729 | }; |
730 | |
731 | static const struct snd_soc_component_driver stm32_i2s_component = { |
732 | .name = "stm32-i2s", |
733 | }; |
734 | |
735 | static void stm32_i2s_dai_init(struct snd_soc_pcm_stream *stream, |
736 | char *stream_name) |
737 | { |
738 | stream->stream_name = stream_name; |
739 | stream->channels_min = 1; |
740 | stream->channels_max = 2; |
741 | stream->rates = SNDRV_PCM_RATE_8000_192000; |
742 | stream->formats = SNDRV_PCM_FMTBIT_S16_LE | |
743 | SNDRV_PCM_FMTBIT_S32_LE; |
744 | } |
745 | |
746 | static int stm32_i2s_dais_init(struct platform_device *pdev, |
747 | struct stm32_i2s_data *i2s) |
748 | { |
749 | struct snd_soc_dai_driver *dai_ptr; |
750 | |
751 | dai_ptr = devm_kzalloc(&pdev->dev, sizeof(struct snd_soc_dai_driver), |
752 | GFP_KERNEL); |
753 | if (!dai_ptr) |
754 | return -ENOMEM; |
755 | |
756 | snprintf(i2s->dais_name, STM32_I2S_DAI_NAME_SIZE, |
757 | "%s", dev_name(&pdev->dev)); |
758 | |
759 | dai_ptr->probe = stm32_i2s_dai_probe; |
760 | dai_ptr->ops = &stm32_i2s_pcm_dai_ops; |
761 | dai_ptr->name = i2s->dais_name; |
762 | dai_ptr->id = 1; |
763 | stm32_i2s_dai_init(&dai_ptr->playback, "playback"); |
764 | stm32_i2s_dai_init(&dai_ptr->capture, "capture"); |
765 | i2s->dai_drv = dai_ptr; |
766 | |
767 | return 0; |
768 | } |
769 | |
770 | static const struct of_device_id stm32_i2s_ids[] = { |
771 | { |
772 | .compatible = "st,stm32h7-i2s", |
773 | .data = &stm32_h7_i2s_regmap_conf |
774 | }, |
775 | {}, |
776 | }; |
777 | |
778 | static int stm32_i2s_parse_dt(struct platform_device *pdev, |
779 | struct stm32_i2s_data *i2s) |
780 | { |
781 | struct device_node *np = pdev->dev.of_node; |
782 | const struct of_device_id *of_id; |
783 | struct reset_control *rst; |
784 | struct resource *res; |
785 | int irq, ret; |
786 | |
787 | if (!np) |
788 | return -ENODEV; |
789 | |
790 | of_id = of_match_device(stm32_i2s_ids, &pdev->dev); |
791 | if (of_id) |
792 | i2s->regmap_conf = (const struct regmap_config *)of_id->data; |
793 | else |
794 | return -EINVAL; |
795 | |
796 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
797 | i2s->base = devm_ioremap_resource(&pdev->dev, res); |
798 | if (IS_ERR(i2s->base)) |
799 | return PTR_ERR(i2s->base); |
800 | |
801 | i2s->phys_addr = res->start; |
802 | |
803 | /* Get clocks */ |
804 | i2s->pclk = devm_clk_get(&pdev->dev, "pclk"); |
805 | if (IS_ERR(i2s->pclk)) { |
806 | dev_err(&pdev->dev, "Could not get pclk\n"); |
807 | return PTR_ERR(i2s->pclk); |
808 | } |
809 | |
810 | i2s->i2sclk = devm_clk_get(&pdev->dev, "i2sclk"); |
811 | if (IS_ERR(i2s->i2sclk)) { |
812 | dev_err(&pdev->dev, "Could not get i2sclk\n"); |
813 | return PTR_ERR(i2s->i2sclk); |
814 | } |
815 | |
816 | i2s->x8kclk = devm_clk_get(&pdev->dev, "x8k"); |
817 | if (IS_ERR(i2s->x8kclk)) { |
818 | dev_err(&pdev->dev, "missing x8k parent clock\n"); |
819 | return PTR_ERR(i2s->x8kclk); |
820 | } |
821 | |
822 | i2s->x11kclk = devm_clk_get(&pdev->dev, "x11k"); |
823 | if (IS_ERR(i2s->x11kclk)) { |
824 | dev_err(&pdev->dev, "missing x11k parent clock\n"); |
825 | return PTR_ERR(i2s->x11kclk); |
826 | } |
827 | |
828 | /* Get irqs */ |
829 | irq = platform_get_irq(pdev, 0); |
830 | if (irq < 0) { |
831 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); |
832 | return -ENOENT; |
833 | } |
834 | |
835 | ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, IRQF_ONESHOT, |
836 | dev_name(&pdev->dev), i2s); |
837 | if (ret) { |
838 | dev_err(&pdev->dev, "irq request returned %d\n", ret); |
839 | return ret; |
840 | } |
841 | |
842 | /* Reset */ |
635eac1e |
843 | rst = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
e4e6ec7b |
844 | if (!IS_ERR(rst)) { |
845 | reset_control_assert(rst); |
846 | udelay(2); |
847 | reset_control_deassert(rst); |
848 | } |
849 | |
850 | return 0; |
851 | } |
852 | |
853 | static int stm32_i2s_probe(struct platform_device *pdev) |
854 | { |
855 | struct stm32_i2s_data *i2s; |
856 | int ret; |
857 | |
858 | i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); |
859 | if (!i2s) |
860 | return -ENOMEM; |
861 | |
862 | ret = stm32_i2s_parse_dt(pdev, i2s); |
863 | if (ret) |
864 | return ret; |
865 | |
866 | i2s->pdev = pdev; |
867 | i2s->ms_flg = I2S_MS_NOT_SET; |
868 | spin_lock_init(&i2s->lock_fd); |
869 | platform_set_drvdata(pdev, i2s); |
870 | |
871 | ret = stm32_i2s_dais_init(pdev, i2s); |
872 | if (ret) |
873 | return ret; |
874 | |
875 | i2s->regmap = devm_regmap_init_mmio(&pdev->dev, i2s->base, |
876 | i2s->regmap_conf); |
877 | if (IS_ERR(i2s->regmap)) { |
878 | dev_err(&pdev->dev, "regmap init failed\n"); |
879 | return PTR_ERR(i2s->regmap); |
880 | } |
881 | |
882 | ret = clk_prepare_enable(i2s->pclk); |
883 | if (ret) { |
884 | dev_err(&pdev->dev, "Enable pclk failed: %d\n", ret); |
885 | return ret; |
886 | } |
887 | |
888 | ret = clk_prepare_enable(i2s->i2sclk); |
889 | if (ret) { |
890 | dev_err(&pdev->dev, "Enable i2sclk failed: %d\n", ret); |
891 | goto err_pclk_disable; |
892 | } |
893 | |
894 | ret = devm_snd_soc_register_component(&pdev->dev, &stm32_i2s_component, |
895 | i2s->dai_drv, 1); |
896 | if (ret) |
897 | goto err_clocks_disable; |
898 | |
899 | ret = devm_snd_dmaengine_pcm_register(&pdev->dev, |
900 | &stm32_i2s_pcm_config, 0); |
901 | if (ret) |
902 | goto err_clocks_disable; |
903 | |
904 | /* Set SPI/I2S in i2s mode */ |
905 | ret = regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG, |
906 | I2S_CGFR_I2SMOD, I2S_CGFR_I2SMOD); |
907 | if (ret) |
908 | goto err_clocks_disable; |
909 | |
910 | return ret; |
911 | |
912 | err_clocks_disable: |
913 | clk_disable_unprepare(i2s->i2sclk); |
914 | err_pclk_disable: |
915 | clk_disable_unprepare(i2s->pclk); |
916 | |
917 | return ret; |
918 | } |
919 | |
920 | static int stm32_i2s_remove(struct platform_device *pdev) |
921 | { |
922 | struct stm32_i2s_data *i2s = platform_get_drvdata(pdev); |
923 | |
924 | clk_disable_unprepare(i2s->i2sclk); |
925 | clk_disable_unprepare(i2s->pclk); |
926 | |
927 | return 0; |
928 | } |
929 | |
930 | MODULE_DEVICE_TABLE(of, stm32_i2s_ids); |
931 | |
932 | static struct platform_driver stm32_i2s_driver = { |
933 | .driver = { |
934 | .name = "st,stm32-i2s", |
935 | .of_match_table = stm32_i2s_ids, |
936 | }, |
937 | .probe = stm32_i2s_probe, |
938 | .remove = stm32_i2s_remove, |
939 | }; |
940 | |
941 | module_platform_driver(stm32_i2s_driver); |
942 | |
943 | MODULE_DESCRIPTION("STM32 Soc i2s Interface"); |
944 | MODULE_AUTHOR("Olivier Moysan, <olivier.moysan@st.com>"); |
945 | MODULE_ALIAS("platform:stm32-i2s"); |
946 | MODULE_LICENSE("GPL v2"); |