2 * STM32 ALSA SoC Digital Audio Interface (SAI) driver.
4 * Copyright (C) 2016, STMicroelectronics - All Rights Reserved
5 * Author(s): Olivier Moysan <olivier.moysan@st.com> for STMicroelectronics.
7 * License terms: GPL V2.0.
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.
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
19 #include <linux/clk.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/of_irq.h>
23 #include <linux/of_platform.h>
24 #include <linux/regmap.h>
26 #include <sound/core.h>
27 #include <sound/dmaengine_pcm.h>
28 #include <sound/pcm_params.h>
30 #include "stm32_sai.h"
32 #define SAI_FREE_PROTOCOL 0x0
34 #define SAI_SLOT_SIZE_AUTO 0x0
35 #define SAI_SLOT_SIZE_16 0x1
36 #define SAI_SLOT_SIZE_32 0x2
38 #define SAI_DATASIZE_8 0x2
39 #define SAI_DATASIZE_10 0x3
40 #define SAI_DATASIZE_16 0x4
41 #define SAI_DATASIZE_20 0x5
42 #define SAI_DATASIZE_24 0x6
43 #define SAI_DATASIZE_32 0x7
45 #define STM_SAI_FIFO_SIZE 8
46 #define STM_SAI_DAI_NAME_SIZE 15
48 #define STM_SAI_IS_PLAYBACK(ip) ((ip)->dir == SNDRV_PCM_STREAM_PLAYBACK)
49 #define STM_SAI_IS_CAPTURE(ip) ((ip)->dir == SNDRV_PCM_STREAM_CAPTURE)
51 #define STM_SAI_A_ID 0x0
52 #define STM_SAI_B_ID 0x1
54 #define STM_SAI_IS_SUB_A(x) ((x)->id == STM_SAI_A_ID)
55 #define STM_SAI_IS_SUB_B(x) ((x)->id == STM_SAI_B_ID)
56 #define STM_SAI_BLOCK_NAME(x) (((x)->id == STM_SAI_A_ID) ? "A" : "B")
58 #define SAI_SYNC_NONE 0x0
59 #define SAI_SYNC_INTERNAL 0x1
60 #define SAI_SYNC_EXTERNAL 0x2
62 #define STM_SAI_HAS_EXT_SYNC(x) (!STM_SAI_IS_F4(sai->pdata))
65 * struct stm32_sai_sub_data - private data of SAI sub block (block A or B)
66 * @pdev: device data pointer
67 * @regmap: SAI register map pointer
68 * @regmap_config: SAI sub block register map configuration pointer
69 * @dma_params: dma configuration data for rx or tx channel
70 * @cpu_dai_drv: DAI driver data pointer
71 * @cpu_dai: DAI runtime data pointer
72 * @substream: PCM substream data pointer
73 * @pdata: SAI block parent data pointer
74 * @np_sync_provider: synchronization provider node
75 * @sai_ck: kernel clock feeding the SAI clock generator
76 * @phys_addr: SAI registers physical base address
77 * @mclk_rate: SAI block master clock frequency (Hz). set at init
78 * @id: SAI sub block id corresponding to sub-block A or B
79 * @dir: SAI block direction (playback or capture). set at init
80 * @master: SAI block mode flag. (true=master, false=slave) set at init
81 * @fmt: SAI block format. relevant only for custom protocols. set at init
82 * @sync: SAI block synchronization mode. (none, internal or external)
83 * @synco: SAI block ext sync source (provider setting). (none, sub-block A/B)
84 * @synci: SAI block ext sync source (client setting). (SAI sync provider index)
85 * @fs_length: frame synchronization length. depends on protocol settings
86 * @slots: rx or tx slot number
87 * @slot_width: rx or tx slot width in bits
88 * @slot_mask: rx or tx active slots mask. set at init or at runtime
89 * @data_size: PCM data width. corresponds to PCM substream width.
91 struct stm32_sai_sub_data
{
92 struct platform_device
*pdev
;
93 struct regmap
*regmap
;
94 const struct regmap_config
*regmap_config
;
95 struct snd_dmaengine_dai_dma_data dma_params
;
96 struct snd_soc_dai_driver
*cpu_dai_drv
;
97 struct snd_soc_dai
*cpu_dai
;
98 struct snd_pcm_substream
*substream
;
99 struct stm32_sai_data
*pdata
;
100 struct device_node
*np_sync_provider
;
102 dma_addr_t phys_addr
;
103 unsigned int mclk_rate
;
118 enum stm32_sai_fifo_th
{
119 STM_SAI_FIFO_TH_EMPTY
,
120 STM_SAI_FIFO_TH_QUARTER
,
121 STM_SAI_FIFO_TH_HALF
,
122 STM_SAI_FIFO_TH_3_QUARTER
,
123 STM_SAI_FIFO_TH_FULL
,
126 static bool stm32_sai_sub_readable_reg(struct device
*dev
, unsigned int reg
)
129 case STM_SAI_CR1_REGX
:
130 case STM_SAI_CR2_REGX
:
131 case STM_SAI_FRCR_REGX
:
132 case STM_SAI_SLOTR_REGX
:
133 case STM_SAI_IMR_REGX
:
134 case STM_SAI_SR_REGX
:
135 case STM_SAI_CLRFR_REGX
:
136 case STM_SAI_DR_REGX
:
137 case STM_SAI_PDMCR_REGX
:
138 case STM_SAI_PDMLY_REGX
:
145 static bool stm32_sai_sub_volatile_reg(struct device
*dev
, unsigned int reg
)
148 case STM_SAI_DR_REGX
:
155 static bool stm32_sai_sub_writeable_reg(struct device
*dev
, unsigned int reg
)
158 case STM_SAI_CR1_REGX
:
159 case STM_SAI_CR2_REGX
:
160 case STM_SAI_FRCR_REGX
:
161 case STM_SAI_SLOTR_REGX
:
162 case STM_SAI_IMR_REGX
:
163 case STM_SAI_SR_REGX
:
164 case STM_SAI_CLRFR_REGX
:
165 case STM_SAI_DR_REGX
:
166 case STM_SAI_PDMCR_REGX
:
167 case STM_SAI_PDMLY_REGX
:
174 static const struct regmap_config stm32_sai_sub_regmap_config_f4
= {
178 .max_register
= STM_SAI_DR_REGX
,
179 .readable_reg
= stm32_sai_sub_readable_reg
,
180 .volatile_reg
= stm32_sai_sub_volatile_reg
,
181 .writeable_reg
= stm32_sai_sub_writeable_reg
,
185 static const struct regmap_config stm32_sai_sub_regmap_config_h7
= {
189 .max_register
= STM_SAI_PDMLY_REGX
,
190 .readable_reg
= stm32_sai_sub_readable_reg
,
191 .volatile_reg
= stm32_sai_sub_volatile_reg
,
192 .writeable_reg
= stm32_sai_sub_writeable_reg
,
196 static irqreturn_t
stm32_sai_isr(int irq
, void *devid
)
198 struct stm32_sai_sub_data
*sai
= (struct stm32_sai_sub_data
*)devid
;
199 struct platform_device
*pdev
= sai
->pdev
;
200 unsigned int sr
, imr
, flags
;
201 snd_pcm_state_t status
= SNDRV_PCM_STATE_RUNNING
;
203 regmap_read(sai
->regmap
, STM_SAI_IMR_REGX
, &imr
);
204 regmap_read(sai
->regmap
, STM_SAI_SR_REGX
, &sr
);
210 regmap_update_bits(sai
->regmap
, STM_SAI_CLRFR_REGX
, SAI_XCLRFR_MASK
,
213 if (!sai
->substream
) {
214 dev_err(&pdev
->dev
, "Device stopped. Spurious IRQ 0x%x\n", sr
);
218 if (flags
& SAI_XIMR_OVRUDRIE
) {
219 dev_err(&pdev
->dev
, "IRQ %s\n",
220 STM_SAI_IS_PLAYBACK(sai
) ? "underrun" : "overrun");
221 status
= SNDRV_PCM_STATE_XRUN
;
224 if (flags
& SAI_XIMR_MUTEDETIE
)
225 dev_dbg(&pdev
->dev
, "IRQ mute detected\n");
227 if (flags
& SAI_XIMR_WCKCFGIE
) {
228 dev_err(&pdev
->dev
, "IRQ wrong clock configuration\n");
229 status
= SNDRV_PCM_STATE_DISCONNECTED
;
232 if (flags
& SAI_XIMR_CNRDYIE
)
233 dev_err(&pdev
->dev
, "IRQ Codec not ready\n");
235 if (flags
& SAI_XIMR_AFSDETIE
) {
236 dev_err(&pdev
->dev
, "IRQ Anticipated frame synchro\n");
237 status
= SNDRV_PCM_STATE_XRUN
;
240 if (flags
& SAI_XIMR_LFSDETIE
) {
241 dev_err(&pdev
->dev
, "IRQ Late frame synchro\n");
242 status
= SNDRV_PCM_STATE_XRUN
;
245 if (status
!= SNDRV_PCM_STATE_RUNNING
) {
246 snd_pcm_stream_lock(sai
->substream
);
247 snd_pcm_stop(sai
->substream
, SNDRV_PCM_STATE_XRUN
);
248 snd_pcm_stream_unlock(sai
->substream
);
254 static int stm32_sai_set_sysclk(struct snd_soc_dai
*cpu_dai
,
255 int clk_id
, unsigned int freq
, int dir
)
257 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
260 if ((dir
== SND_SOC_CLOCK_OUT
) && sai
->master
) {
261 ret
= regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
,
263 (unsigned int)~SAI_XCR1_NODIV
);
267 sai
->mclk_rate
= freq
;
268 dev_dbg(cpu_dai
->dev
, "SAI MCLK frequency is %uHz\n", freq
);
274 static int stm32_sai_set_dai_tdm_slot(struct snd_soc_dai
*cpu_dai
, u32 tx_mask
,
275 u32 rx_mask
, int slots
, int slot_width
)
277 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
278 int slotr
, slotr_mask
, slot_size
;
280 dev_dbg(cpu_dai
->dev
, "Masks tx/rx:%#x/%#x, slots:%d, width:%d\n",
281 tx_mask
, rx_mask
, slots
, slot_width
);
283 switch (slot_width
) {
285 slot_size
= SAI_SLOT_SIZE_16
;
288 slot_size
= SAI_SLOT_SIZE_32
;
291 slot_size
= SAI_SLOT_SIZE_AUTO
;
295 slotr
= SAI_XSLOTR_SLOTSZ_SET(slot_size
) |
296 SAI_XSLOTR_NBSLOT_SET(slots
- 1);
297 slotr_mask
= SAI_XSLOTR_SLOTSZ_MASK
| SAI_XSLOTR_NBSLOT_MASK
;
299 /* tx/rx mask set in machine init, if slot number defined in DT */
300 if (STM_SAI_IS_PLAYBACK(sai
)) {
301 sai
->slot_mask
= tx_mask
;
302 slotr
|= SAI_XSLOTR_SLOTEN_SET(tx_mask
);
305 if (STM_SAI_IS_CAPTURE(sai
)) {
306 sai
->slot_mask
= rx_mask
;
307 slotr
|= SAI_XSLOTR_SLOTEN_SET(rx_mask
);
310 slotr_mask
|= SAI_XSLOTR_SLOTEN_MASK
;
312 regmap_update_bits(sai
->regmap
, STM_SAI_SLOTR_REGX
, slotr_mask
, slotr
);
314 sai
->slot_width
= slot_width
;
320 static int stm32_sai_set_dai_fmt(struct snd_soc_dai
*cpu_dai
, unsigned int fmt
)
322 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
324 int cr1_mask
, frcr_mask
= 0;
327 dev_dbg(cpu_dai
->dev
, "fmt %x\n", fmt
);
329 cr1_mask
= SAI_XCR1_PRTCFG_MASK
;
330 cr1
= SAI_XCR1_PRTCFG_SET(SAI_FREE_PROTOCOL
);
332 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
333 /* SCK active high for all protocols */
334 case SND_SOC_DAIFMT_I2S
:
335 cr1
|= SAI_XCR1_CKSTR
;
336 frcr
|= SAI_XFRCR_FSOFF
| SAI_XFRCR_FSDEF
;
339 case SND_SOC_DAIFMT_MSB
:
340 frcr
|= SAI_XFRCR_FSPOL
| SAI_XFRCR_FSDEF
;
342 /* Right justified */
343 case SND_SOC_DAIFMT_LSB
:
344 frcr
|= SAI_XFRCR_FSPOL
| SAI_XFRCR_FSDEF
;
346 case SND_SOC_DAIFMT_DSP_A
:
347 frcr
|= SAI_XFRCR_FSPOL
| SAI_XFRCR_FSOFF
;
349 case SND_SOC_DAIFMT_DSP_B
:
350 frcr
|= SAI_XFRCR_FSPOL
;
353 dev_err(cpu_dai
->dev
, "Unsupported protocol %#x\n",
354 fmt
& SND_SOC_DAIFMT_FORMAT_MASK
);
358 cr1_mask
|= SAI_XCR1_CKSTR
;
359 frcr_mask
|= SAI_XFRCR_FSPOL
| SAI_XFRCR_FSOFF
|
362 /* DAI clock strobing. Invert setting previously set */
363 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
364 case SND_SOC_DAIFMT_NB_NF
:
366 case SND_SOC_DAIFMT_IB_NF
:
367 cr1
^= SAI_XCR1_CKSTR
;
369 case SND_SOC_DAIFMT_NB_IF
:
370 frcr
^= SAI_XFRCR_FSPOL
;
372 case SND_SOC_DAIFMT_IB_IF
:
373 /* Invert fs & sck */
374 cr1
^= SAI_XCR1_CKSTR
;
375 frcr
^= SAI_XFRCR_FSPOL
;
378 dev_err(cpu_dai
->dev
, "Unsupported strobing %#x\n",
379 fmt
& SND_SOC_DAIFMT_INV_MASK
);
382 cr1_mask
|= SAI_XCR1_CKSTR
;
383 frcr_mask
|= SAI_XFRCR_FSPOL
;
385 regmap_update_bits(sai
->regmap
, STM_SAI_FRCR_REGX
, frcr_mask
, frcr
);
387 /* DAI clock master masks */
388 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
389 case SND_SOC_DAIFMT_CBM_CFM
:
390 /* codec is master */
391 cr1
|= SAI_XCR1_SLAVE
;
394 case SND_SOC_DAIFMT_CBS_CFS
:
398 dev_err(cpu_dai
->dev
, "Unsupported mode %#x\n",
399 fmt
& SND_SOC_DAIFMT_MASTER_MASK
);
403 /* Set slave mode if sub-block is synchronized with another SAI */
405 dev_dbg(cpu_dai
->dev
, "Synchronized SAI configured as slave\n");
406 cr1
|= SAI_XCR1_SLAVE
;
410 cr1_mask
|= SAI_XCR1_SLAVE
;
412 /* do not generate master by default */
413 cr1
|= SAI_XCR1_NODIV
;
414 cr1_mask
|= SAI_XCR1_NODIV
;
416 ret
= regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
, cr1_mask
, cr1
);
418 dev_err(cpu_dai
->dev
, "Failed to update CR1 register\n");
427 static int stm32_sai_startup(struct snd_pcm_substream
*substream
,
428 struct snd_soc_dai
*cpu_dai
)
430 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
433 sai
->substream
= substream
;
435 ret
= clk_prepare_enable(sai
->sai_ck
);
437 dev_err(cpu_dai
->dev
, "Failed to enable clock: %d\n", ret
);
443 regmap_update_bits(sai
->regmap
, STM_SAI_CLRFR_REGX
,
444 SAI_XCLRFR_MASK
, SAI_XCLRFR_MASK
);
446 imr
= SAI_XIMR_OVRUDRIE
;
447 if (STM_SAI_IS_CAPTURE(sai
)) {
448 regmap_read(sai
->regmap
, STM_SAI_CR2_REGX
, &cr2
);
449 if (cr2
& SAI_XCR2_MUTECNT_MASK
)
450 imr
|= SAI_XIMR_MUTEDETIE
;
454 imr
|= SAI_XIMR_WCKCFGIE
;
456 imr
|= SAI_XIMR_AFSDETIE
| SAI_XIMR_LFSDETIE
;
458 regmap_update_bits(sai
->regmap
, STM_SAI_IMR_REGX
,
464 static int stm32_sai_set_config(struct snd_soc_dai
*cpu_dai
,
465 struct snd_pcm_substream
*substream
,
466 struct snd_pcm_hw_params
*params
)
468 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
469 int cr1
, cr1_mask
, ret
;
472 * DMA bursts increment is set to 4 words.
473 * SAI fifo threshold is set to half fifo, to keep enough space
474 * for DMA incoming bursts.
476 regmap_update_bits(sai
->regmap
, STM_SAI_CR2_REGX
,
477 SAI_XCR2_FFLUSH
| SAI_XCR2_FTH_MASK
,
479 SAI_XCR2_FTH_SET(STM_SAI_FIFO_TH_HALF
));
481 /* Mode, data format and channel config */
482 cr1_mask
= SAI_XCR1_DS_MASK
;
483 switch (params_format(params
)) {
484 case SNDRV_PCM_FORMAT_S8
:
485 cr1
= SAI_XCR1_DS_SET(SAI_DATASIZE_8
);
487 case SNDRV_PCM_FORMAT_S16_LE
:
488 cr1
= SAI_XCR1_DS_SET(SAI_DATASIZE_16
);
490 case SNDRV_PCM_FORMAT_S32_LE
:
491 cr1
= SAI_XCR1_DS_SET(SAI_DATASIZE_32
);
494 dev_err(cpu_dai
->dev
, "Data format not supported");
498 cr1_mask
|= SAI_XCR1_MONO
;
499 if ((sai
->slots
== 2) && (params_channels(params
) == 1))
500 cr1
|= SAI_XCR1_MONO
;
502 ret
= regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
, cr1_mask
, cr1
);
504 dev_err(cpu_dai
->dev
, "Failed to update CR1 register\n");
511 static int stm32_sai_set_slots(struct snd_soc_dai
*cpu_dai
)
513 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
516 regmap_read(sai
->regmap
, STM_SAI_SLOTR_REGX
, &slotr
);
519 * If SLOTSZ is set to auto in SLOTR, align slot width on data size
520 * By default slot width = data size, if not forced from DT
522 slot_sz
= slotr
& SAI_XSLOTR_SLOTSZ_MASK
;
523 if (slot_sz
== SAI_XSLOTR_SLOTSZ_SET(SAI_SLOT_SIZE_AUTO
))
524 sai
->slot_width
= sai
->data_size
;
526 if (sai
->slot_width
< sai
->data_size
) {
527 dev_err(cpu_dai
->dev
,
528 "Data size %d larger than slot width\n",
533 /* Slot number is set to 2, if not specified in DT */
537 /* The number of slots in the audio frame is equal to NBSLOT[3:0] + 1*/
538 regmap_update_bits(sai
->regmap
, STM_SAI_SLOTR_REGX
,
539 SAI_XSLOTR_NBSLOT_MASK
,
540 SAI_XSLOTR_NBSLOT_SET((sai
->slots
- 1)));
542 /* Set default slots mask if not already set from DT */
543 if (!(slotr
& SAI_XSLOTR_SLOTEN_MASK
)) {
544 sai
->slot_mask
= (1 << sai
->slots
) - 1;
545 regmap_update_bits(sai
->regmap
,
546 STM_SAI_SLOTR_REGX
, SAI_XSLOTR_SLOTEN_MASK
,
547 SAI_XSLOTR_SLOTEN_SET(sai
->slot_mask
));
550 dev_dbg(cpu_dai
->dev
, "Slots %d, slot width %d\n",
551 sai
->slots
, sai
->slot_width
);
556 static void stm32_sai_set_frame(struct snd_soc_dai
*cpu_dai
)
558 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
559 int fs_active
, offset
, format
;
562 format
= sai
->fmt
& SND_SOC_DAIFMT_FORMAT_MASK
;
563 sai
->fs_length
= sai
->slot_width
* sai
->slots
;
565 fs_active
= sai
->fs_length
/ 2;
566 if ((format
== SND_SOC_DAIFMT_DSP_A
) ||
567 (format
== SND_SOC_DAIFMT_DSP_B
))
570 frcr
= SAI_XFRCR_FRL_SET((sai
->fs_length
- 1));
571 frcr
|= SAI_XFRCR_FSALL_SET((fs_active
- 1));
572 frcr_mask
= SAI_XFRCR_FRL_MASK
| SAI_XFRCR_FSALL_MASK
;
574 dev_dbg(cpu_dai
->dev
, "Frame length %d, frame active %d\n",
575 sai
->fs_length
, fs_active
);
577 regmap_update_bits(sai
->regmap
, STM_SAI_FRCR_REGX
, frcr_mask
, frcr
);
579 if ((sai
->fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) == SND_SOC_DAIFMT_LSB
) {
580 offset
= sai
->slot_width
- sai
->data_size
;
582 regmap_update_bits(sai
->regmap
, STM_SAI_SLOTR_REGX
,
583 SAI_XSLOTR_FBOFF_MASK
,
584 SAI_XSLOTR_FBOFF_SET(offset
));
588 static int stm32_sai_configure_clock(struct snd_soc_dai
*cpu_dai
,
589 struct snd_pcm_hw_params
*params
)
591 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
592 int cr1
, mask
, div
= 0;
593 int sai_clk_rate
, mclk_ratio
, den
, ret
;
594 int version
= sai
->pdata
->conf
->version
;
596 if (!sai
->mclk_rate
) {
597 dev_err(cpu_dai
->dev
, "Mclk rate is null\n");
601 if (!(params_rate(params
) % 11025))
602 clk_set_parent(sai
->sai_ck
, sai
->pdata
->clk_x11k
);
604 clk_set_parent(sai
->sai_ck
, sai
->pdata
->clk_x8k
);
605 sai_clk_rate
= clk_get_rate(sai
->sai_ck
);
607 if (STM_SAI_IS_F4(sai
->pdata
)) {
609 * mclk_rate = 256 * fs
610 * MCKDIV = 0 if sai_ck < 3/2 * mclk_rate
611 * MCKDIV = sai_ck / (2 * mclk_rate) otherwise
613 if (2 * sai_clk_rate
>= 3 * sai
->mclk_rate
)
614 div
= DIV_ROUND_CLOSEST(sai_clk_rate
,
620 * MCKDIV = sai_ck / (ws x 256) (NOMCK=0. OSR=0)
621 * MCKDIV = sai_ck / (ws x 512) (NOMCK=0. OSR=1)
623 * MCKDIV = sai_ck / (frl x ws) (NOMCK=1)
624 * Note: NOMCK/NODIV correspond to same bit.
626 if (sai
->mclk_rate
) {
627 mclk_ratio
= sai
->mclk_rate
/ params_rate(params
);
628 if (mclk_ratio
!= 256) {
629 if (mclk_ratio
== 512) {
633 dev_err(cpu_dai
->dev
,
634 "Wrong mclk ratio %d\n",
639 div
= DIV_ROUND_CLOSEST(sai_clk_rate
, sai
->mclk_rate
);
641 /* mclk-fs not set, master clock not active. NOMCK=1 */
642 den
= sai
->fs_length
* params_rate(params
);
643 div
= DIV_ROUND_CLOSEST(sai_clk_rate
, den
);
647 if (div
> SAI_XCR1_MCKDIV_MAX(version
)) {
648 dev_err(cpu_dai
->dev
, "Divider %d out of range\n", div
);
651 dev_dbg(cpu_dai
->dev
, "SAI clock %d, divider %d\n", sai_clk_rate
, div
);
653 mask
= SAI_XCR1_MCKDIV_MASK(SAI_XCR1_MCKDIV_WIDTH(version
));
654 cr1
= SAI_XCR1_MCKDIV_SET(div
);
655 ret
= regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
, mask
, cr1
);
657 dev_err(cpu_dai
->dev
, "Failed to update CR1 register\n");
664 static int stm32_sai_hw_params(struct snd_pcm_substream
*substream
,
665 struct snd_pcm_hw_params
*params
,
666 struct snd_soc_dai
*cpu_dai
)
668 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
671 sai
->data_size
= params_width(params
);
673 ret
= stm32_sai_set_slots(cpu_dai
);
676 stm32_sai_set_frame(cpu_dai
);
678 ret
= stm32_sai_set_config(cpu_dai
, substream
, params
);
683 ret
= stm32_sai_configure_clock(cpu_dai
, params
);
688 static int stm32_sai_trigger(struct snd_pcm_substream
*substream
, int cmd
,
689 struct snd_soc_dai
*cpu_dai
)
691 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
695 case SNDRV_PCM_TRIGGER_START
:
696 case SNDRV_PCM_TRIGGER_RESUME
:
697 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
698 dev_dbg(cpu_dai
->dev
, "Enable DMA and SAI\n");
700 regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
,
701 SAI_XCR1_DMAEN
, SAI_XCR1_DMAEN
);
704 ret
= regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
,
705 SAI_XCR1_SAIEN
, SAI_XCR1_SAIEN
);
707 dev_err(cpu_dai
->dev
, "Failed to update CR1 register\n");
709 case SNDRV_PCM_TRIGGER_SUSPEND
:
710 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
711 case SNDRV_PCM_TRIGGER_STOP
:
712 dev_dbg(cpu_dai
->dev
, "Disable DMA and SAI\n");
714 regmap_update_bits(sai
->regmap
, STM_SAI_IMR_REGX
,
717 regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
,
719 (unsigned int)~SAI_XCR1_SAIEN
);
721 ret
= regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
,
723 (unsigned int)~SAI_XCR1_DMAEN
);
725 dev_err(cpu_dai
->dev
, "Failed to update CR1 register\n");
734 static void stm32_sai_shutdown(struct snd_pcm_substream
*substream
,
735 struct snd_soc_dai
*cpu_dai
)
737 struct stm32_sai_sub_data
*sai
= snd_soc_dai_get_drvdata(cpu_dai
);
739 regmap_update_bits(sai
->regmap
, STM_SAI_IMR_REGX
, SAI_XIMR_MASK
, 0);
741 regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
, SAI_XCR1_NODIV
,
744 clk_disable_unprepare(sai
->sai_ck
);
745 sai
->substream
= NULL
;
748 static int stm32_sai_dai_probe(struct snd_soc_dai
*cpu_dai
)
750 struct stm32_sai_sub_data
*sai
= dev_get_drvdata(cpu_dai
->dev
);
751 int cr1
= 0, cr1_mask
;
753 sai
->dma_params
.addr
= (dma_addr_t
)(sai
->phys_addr
+ STM_SAI_DR_REGX
);
755 * DMA supports 4, 8 or 16 burst sizes. Burst size 4 is the best choice,
756 * as it allows bytes, half-word and words transfers. (See DMA fifos
759 sai
->dma_params
.maxburst
= 4;
760 /* Buswidth will be set by framework at runtime */
761 sai
->dma_params
.addr_width
= DMA_SLAVE_BUSWIDTH_UNDEFINED
;
763 if (STM_SAI_IS_PLAYBACK(sai
))
764 snd_soc_dai_init_dma_data(cpu_dai
, &sai
->dma_params
, NULL
);
766 snd_soc_dai_init_dma_data(cpu_dai
, NULL
, &sai
->dma_params
);
768 cr1_mask
= SAI_XCR1_RX_TX
;
769 if (STM_SAI_IS_CAPTURE(sai
))
770 cr1
|= SAI_XCR1_RX_TX
;
772 /* Configure synchronization */
773 if (sai
->sync
== SAI_SYNC_EXTERNAL
) {
774 /* Configure synchro client and provider */
775 sai
->pdata
->set_sync(sai
->pdata
, sai
->np_sync_provider
,
776 sai
->synco
, sai
->synci
);
779 cr1_mask
|= SAI_XCR1_SYNCEN_MASK
;
780 cr1
|= SAI_XCR1_SYNCEN_SET(sai
->sync
);
782 return regmap_update_bits(sai
->regmap
, STM_SAI_CR1_REGX
, cr1_mask
, cr1
);
785 static const struct snd_soc_dai_ops stm32_sai_pcm_dai_ops
= {
786 .set_sysclk
= stm32_sai_set_sysclk
,
787 .set_fmt
= stm32_sai_set_dai_fmt
,
788 .set_tdm_slot
= stm32_sai_set_dai_tdm_slot
,
789 .startup
= stm32_sai_startup
,
790 .hw_params
= stm32_sai_hw_params
,
791 .trigger
= stm32_sai_trigger
,
792 .shutdown
= stm32_sai_shutdown
,
795 static const struct snd_pcm_hardware stm32_sai_pcm_hw
= {
796 .info
= SNDRV_PCM_INFO_INTERLEAVED
| SNDRV_PCM_INFO_MMAP
,
797 .buffer_bytes_max
= 8 * PAGE_SIZE
,
798 .period_bytes_min
= 1024, /* 5ms at 48kHz */
799 .period_bytes_max
= PAGE_SIZE
,
804 static struct snd_soc_dai_driver stm32_sai_playback_dai
[] = {
806 .probe
= stm32_sai_dai_probe
,
807 .id
= 1, /* avoid call to fmt_single_name() */
813 .rates
= SNDRV_PCM_RATE_CONTINUOUS
,
814 /* DMA does not support 24 bits transfers */
816 SNDRV_PCM_FMTBIT_S8
|
817 SNDRV_PCM_FMTBIT_S16_LE
|
818 SNDRV_PCM_FMTBIT_S32_LE
,
820 .ops
= &stm32_sai_pcm_dai_ops
,
824 static struct snd_soc_dai_driver stm32_sai_capture_dai
[] = {
826 .probe
= stm32_sai_dai_probe
,
827 .id
= 1, /* avoid call to fmt_single_name() */
833 .rates
= SNDRV_PCM_RATE_CONTINUOUS
,
834 /* DMA does not support 24 bits transfers */
836 SNDRV_PCM_FMTBIT_S8
|
837 SNDRV_PCM_FMTBIT_S16_LE
|
838 SNDRV_PCM_FMTBIT_S32_LE
,
840 .ops
= &stm32_sai_pcm_dai_ops
,
844 static const struct snd_dmaengine_pcm_config stm32_sai_pcm_config
= {
845 .pcm_hardware
= &stm32_sai_pcm_hw
,
846 .prepare_slave_config
= snd_dmaengine_pcm_prepare_slave_config
,
849 static const struct snd_soc_component_driver stm32_component
= {
853 static const struct of_device_id stm32_sai_sub_ids
[] = {
854 { .compatible
= "st,stm32-sai-sub-a",
855 .data
= (void *)STM_SAI_A_ID
},
856 { .compatible
= "st,stm32-sai-sub-b",
857 .data
= (void *)STM_SAI_B_ID
},
860 MODULE_DEVICE_TABLE(of
, stm32_sai_sub_ids
);
862 static int stm32_sai_sub_parse_of(struct platform_device
*pdev
,
863 struct stm32_sai_sub_data
*sai
)
865 struct device_node
*np
= pdev
->dev
.of_node
;
866 struct resource
*res
;
868 struct of_phandle_args args
;
874 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
875 base
= devm_ioremap_resource(&pdev
->dev
, res
);
877 return PTR_ERR(base
);
879 sai
->phys_addr
= res
->start
;
881 sai
->regmap_config
= &stm32_sai_sub_regmap_config_f4
;
882 /* Note: PDM registers not available for H7 sub-block B */
883 if (STM_SAI_IS_H7(sai
->pdata
) && STM_SAI_IS_SUB_A(sai
))
884 sai
->regmap_config
= &stm32_sai_sub_regmap_config_h7
;
886 sai
->regmap
= devm_regmap_init_mmio_clk(&pdev
->dev
, "sai_ck",
887 base
, sai
->regmap_config
);
888 if (IS_ERR(sai
->regmap
)) {
889 dev_err(&pdev
->dev
, "Failed to initialize MMIO\n");
890 return PTR_ERR(sai
->regmap
);
893 /* Get direction property */
894 if (of_property_match_string(np
, "dma-names", "tx") >= 0) {
895 sai
->dir
= SNDRV_PCM_STREAM_PLAYBACK
;
896 } else if (of_property_match_string(np
, "dma-names", "rx") >= 0) {
897 sai
->dir
= SNDRV_PCM_STREAM_CAPTURE
;
899 dev_err(&pdev
->dev
, "Unsupported direction\n");
903 /* Get synchronization property */
905 ret
= of_parse_phandle_with_fixed_args(np
, "st,sync", 1, 0, &args
);
906 if (ret
< 0 && ret
!= -ENOENT
) {
907 dev_err(&pdev
->dev
, "Failed to get st,sync property\n");
911 sai
->sync
= SAI_SYNC_NONE
;
914 dev_err(&pdev
->dev
, "%s sync own reference\n",
916 of_node_put(args
.np
);
920 sai
->np_sync_provider
= of_get_parent(args
.np
);
921 if (!sai
->np_sync_provider
) {
922 dev_err(&pdev
->dev
, "%s parent node not found\n",
924 of_node_put(args
.np
);
928 sai
->sync
= SAI_SYNC_INTERNAL
;
929 if (sai
->np_sync_provider
!= sai
->pdata
->pdev
->dev
.of_node
) {
930 if (!STM_SAI_HAS_EXT_SYNC(sai
)) {
932 "External synchro not supported\n");
933 of_node_put(args
.np
);
936 sai
->sync
= SAI_SYNC_EXTERNAL
;
938 sai
->synci
= args
.args
[0];
939 if (sai
->synci
< 1 ||
940 (sai
->synci
> (SAI_GCR_SYNCIN_MAX
+ 1))) {
941 dev_err(&pdev
->dev
, "Wrong SAI index\n");
942 of_node_put(args
.np
);
946 if (of_property_match_string(args
.np
, "compatible",
947 "st,stm32-sai-sub-a") >= 0)
948 sai
->synco
= STM_SAI_SYNC_OUT_A
;
950 if (of_property_match_string(args
.np
, "compatible",
951 "st,stm32-sai-sub-b") >= 0)
952 sai
->synco
= STM_SAI_SYNC_OUT_B
;
955 dev_err(&pdev
->dev
, "Unknown SAI sub-block\n");
956 of_node_put(args
.np
);
961 dev_dbg(&pdev
->dev
, "%s synchronized with %s\n",
962 pdev
->name
, args
.np
->full_name
);
965 of_node_put(args
.np
);
966 sai
->sai_ck
= devm_clk_get(&pdev
->dev
, "sai_ck");
967 if (IS_ERR(sai
->sai_ck
)) {
968 dev_err(&pdev
->dev
, "Missing kernel clock sai_ck\n");
969 return PTR_ERR(sai
->sai_ck
);
975 static int stm32_sai_sub_dais_init(struct platform_device
*pdev
,
976 struct stm32_sai_sub_data
*sai
)
978 sai
->cpu_dai_drv
= devm_kzalloc(&pdev
->dev
,
979 sizeof(struct snd_soc_dai_driver
),
981 if (!sai
->cpu_dai_drv
)
984 sai
->cpu_dai_drv
->name
= dev_name(&pdev
->dev
);
985 if (STM_SAI_IS_PLAYBACK(sai
)) {
986 memcpy(sai
->cpu_dai_drv
, &stm32_sai_playback_dai
,
987 sizeof(stm32_sai_playback_dai
));
988 sai
->cpu_dai_drv
->playback
.stream_name
= sai
->cpu_dai_drv
->name
;
990 memcpy(sai
->cpu_dai_drv
, &stm32_sai_capture_dai
,
991 sizeof(stm32_sai_capture_dai
));
992 sai
->cpu_dai_drv
->capture
.stream_name
= sai
->cpu_dai_drv
->name
;
998 static int stm32_sai_sub_probe(struct platform_device
*pdev
)
1000 struct stm32_sai_sub_data
*sai
;
1001 const struct of_device_id
*of_id
;
1004 sai
= devm_kzalloc(&pdev
->dev
, sizeof(*sai
), GFP_KERNEL
);
1008 of_id
= of_match_device(stm32_sai_sub_ids
, &pdev
->dev
);
1011 sai
->id
= (uintptr_t)of_id
->data
;
1014 platform_set_drvdata(pdev
, sai
);
1016 sai
->pdata
= dev_get_drvdata(pdev
->dev
.parent
);
1018 dev_err(&pdev
->dev
, "Parent device data not available\n");
1022 ret
= stm32_sai_sub_parse_of(pdev
, sai
);
1026 ret
= stm32_sai_sub_dais_init(pdev
, sai
);
1030 ret
= devm_request_irq(&pdev
->dev
, sai
->pdata
->irq
, stm32_sai_isr
,
1031 IRQF_SHARED
, dev_name(&pdev
->dev
), sai
);
1033 dev_err(&pdev
->dev
, "IRQ request returned %d\n", ret
);
1037 ret
= devm_snd_soc_register_component(&pdev
->dev
, &stm32_component
,
1038 sai
->cpu_dai_drv
, 1);
1042 ret
= devm_snd_dmaengine_pcm_register(&pdev
->dev
,
1043 &stm32_sai_pcm_config
, 0);
1045 dev_err(&pdev
->dev
, "Could not register pcm dma\n");
1052 static struct platform_driver stm32_sai_sub_driver
= {
1054 .name
= "st,stm32-sai-sub",
1055 .of_match_table
= stm32_sai_sub_ids
,
1057 .probe
= stm32_sai_sub_probe
,
1060 module_platform_driver(stm32_sai_sub_driver
);
1062 MODULE_DESCRIPTION("STM32 Soc SAI sub-block Interface");
1063 MODULE_AUTHOR("Olivier Moysan <olivier.moysan@st.com>");
1064 MODULE_ALIAS("platform:st,stm32-sai-sub");
1065 MODULE_LICENSE("GPL v2");