1 // SPDX-License-Identifier: GPL-2.0
3 // Xilinx ASoC audio formatter support
5 // Copyright (C) 2018 Xilinx, Inc.
7 // Author: Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>
11 #include <linux/module.h>
12 #include <linux/of_address.h>
13 #include <linux/of_irq.h>
14 #include <linux/sizes.h>
16 #include <sound/asoundef.h>
17 #include <sound/soc.h>
18 #include <sound/pcm_params.h>
20 #define DRV_NAME "xlnx_formatter_pcm"
22 #define XLNX_S2MM_OFFSET 0
23 #define XLNX_MM2S_OFFSET 0x100
25 #define XLNX_AUD_CORE_CONFIG 0x4
26 #define XLNX_AUD_CTRL 0x10
27 #define XLNX_AUD_STS 0x14
29 #define AUD_CTRL_RESET_MASK BIT(1)
30 #define AUD_CFG_MM2S_MASK BIT(15)
31 #define AUD_CFG_S2MM_MASK BIT(31)
33 #define XLNX_AUD_FS_MULTIPLIER 0x18
34 #define XLNX_AUD_PERIOD_CONFIG 0x1C
35 #define XLNX_AUD_BUFF_ADDR_LSB 0x20
36 #define XLNX_AUD_BUFF_ADDR_MSB 0x24
37 #define XLNX_AUD_XFER_COUNT 0x28
38 #define XLNX_AUD_CH_STS_START 0x2C
39 #define XLNX_BYTES_PER_CH 0x44
41 #define AUD_STS_IOC_IRQ_MASK BIT(31)
42 #define AUD_STS_CH_STS_MASK BIT(29)
43 #define AUD_CTRL_IOC_IRQ_MASK BIT(13)
44 #define AUD_CTRL_TOUT_IRQ_MASK BIT(14)
45 #define AUD_CTRL_DMA_EN_MASK BIT(0)
47 #define CFG_MM2S_CH_MASK GENMASK(11, 8)
48 #define CFG_MM2S_CH_SHIFT 8
49 #define CFG_MM2S_XFER_MASK GENMASK(14, 13)
50 #define CFG_MM2S_XFER_SHIFT 13
51 #define CFG_MM2S_PKG_MASK BIT(12)
53 #define CFG_S2MM_CH_MASK GENMASK(27, 24)
54 #define CFG_S2MM_CH_SHIFT 24
55 #define CFG_S2MM_XFER_MASK GENMASK(30, 29)
56 #define CFG_S2MM_XFER_SHIFT 29
57 #define CFG_S2MM_PKG_MASK BIT(28)
59 #define AUD_CTRL_DATA_WIDTH_SHIFT 16
60 #define AUD_CTRL_ACTIVE_CH_SHIFT 19
61 #define PERIOD_CFG_PERIODS_SHIFT 16
65 #define PERIOD_BYTES_MIN 192
66 #define PERIOD_BYTES_MAX (50 * 1024)
67 #define XLNX_PARAM_UNKNOWN 0
77 struct xlnx_pcm_drv_data
{
83 struct snd_pcm_substream
*play_stream
;
84 struct snd_pcm_substream
*capture_stream
;
89 * struct xlnx_pcm_stream_param - stream configuration
90 * @mmio: base address offset
91 * @interleaved: audio channels arrangement in buffer
92 * @xfer_mode: data formatting mode during transfer
93 * @ch_limit: Maximum channels supported
94 * @buffer_size: stream ring buffer size
96 struct xlnx_pcm_stream_param
{
104 static const struct snd_pcm_hardware xlnx_pcm_hardware
= {
105 .info
= SNDRV_PCM_INFO_INTERLEAVED
| SNDRV_PCM_INFO_BLOCK_TRANSFER
|
106 SNDRV_PCM_INFO_BATCH
| SNDRV_PCM_INFO_PAUSE
|
107 SNDRV_PCM_INFO_RESUME
,
108 .formats
= SNDRV_PCM_FMTBIT_S8
| SNDRV_PCM_FMTBIT_S16_LE
|
109 SNDRV_PCM_FMTBIT_S24_LE
,
112 .rates
= SNDRV_PCM_RATE_8000_192000
,
115 .buffer_bytes_max
= PERIODS_MAX
* PERIOD_BYTES_MAX
,
116 .period_bytes_min
= PERIOD_BYTES_MIN
,
117 .period_bytes_max
= PERIOD_BYTES_MAX
,
118 .periods_min
= PERIODS_MIN
,
119 .periods_max
= PERIODS_MAX
,
129 static void xlnx_parse_aes_params(u32 chsts_reg1_val
, u32 chsts_reg2_val
,
132 u32 padded
, srate
, bit_depth
, status
[2];
134 if (chsts_reg1_val
& IEC958_AES0_PROFESSIONAL
) {
135 status
[0] = chsts_reg1_val
& 0xff;
136 status
[1] = (chsts_reg1_val
>> 16) & 0xff;
138 switch (status
[0] & IEC958_AES0_PRO_FS
) {
139 case IEC958_AES0_PRO_FS_44100
:
142 case IEC958_AES0_PRO_FS_48000
:
145 case IEC958_AES0_PRO_FS_32000
:
148 case IEC958_AES0_PRO_FS_NOTID
:
150 srate
= XLNX_PARAM_UNKNOWN
;
154 switch (status
[1] & IEC958_AES2_PRO_SBITS
) {
155 case IEC958_AES2_PRO_WORDLEN_NOTID
:
156 case IEC958_AES2_PRO_SBITS_20
:
159 case IEC958_AES2_PRO_SBITS_24
:
163 bit_depth
= XLNX_PARAM_UNKNOWN
;
167 switch (status
[1] & IEC958_AES2_PRO_WORDLEN
) {
168 case IEC958_AES2_PRO_WORDLEN_20_16
:
169 bit_depth
= 16 + padded
;
171 case IEC958_AES2_PRO_WORDLEN_22_18
:
172 bit_depth
= 18 + padded
;
174 case IEC958_AES2_PRO_WORDLEN_23_19
:
175 bit_depth
= 19 + padded
;
177 case IEC958_AES2_PRO_WORDLEN_24_20
:
178 bit_depth
= 20 + padded
;
180 case IEC958_AES2_PRO_WORDLEN_NOTID
:
182 bit_depth
= XLNX_PARAM_UNKNOWN
;
187 status
[0] = (chsts_reg1_val
>> 24) & 0xff;
188 status
[1] = chsts_reg2_val
& 0xff;
190 switch (status
[0] & IEC958_AES3_CON_FS
) {
191 case IEC958_AES3_CON_FS_44100
:
194 case IEC958_AES3_CON_FS_48000
:
197 case IEC958_AES3_CON_FS_32000
:
201 srate
= XLNX_PARAM_UNKNOWN
;
205 if (status
[1] & IEC958_AES4_CON_MAX_WORDLEN_24
)
210 switch (status
[1] & IEC958_AES4_CON_WORDLEN
) {
211 case IEC958_AES4_CON_WORDLEN_20_16
:
212 bit_depth
= 16 + padded
;
214 case IEC958_AES4_CON_WORDLEN_22_18
:
215 bit_depth
= 18 + padded
;
217 case IEC958_AES4_CON_WORDLEN_23_19
:
218 bit_depth
= 19 + padded
;
220 case IEC958_AES4_CON_WORDLEN_24_20
:
221 bit_depth
= 20 + padded
;
223 case IEC958_AES4_CON_WORDLEN_21_17
:
224 bit_depth
= 17 + padded
;
226 case IEC958_AES4_CON_WORDLEN_NOTID
:
228 bit_depth
= XLNX_PARAM_UNKNOWN
;
234 if (srate
!= XLNX_PARAM_UNKNOWN
)
235 dev_info(dev
, "sample rate = %d\n", srate
);
237 dev_info(dev
, "sample rate = unknown\n");
239 if (bit_depth
!= XLNX_PARAM_UNKNOWN
)
240 dev_info(dev
, "bit_depth = %d\n", bit_depth
);
242 dev_info(dev
, "bit_depth = unknown\n");
245 static int xlnx_formatter_pcm_reset(void __iomem
*mmio_base
)
247 u32 val
, retries
= 0;
249 val
= readl(mmio_base
+ XLNX_AUD_CTRL
);
250 val
|= AUD_CTRL_RESET_MASK
;
251 writel(val
, mmio_base
+ XLNX_AUD_CTRL
);
253 val
= readl(mmio_base
+ XLNX_AUD_CTRL
);
254 /* Poll for maximum timeout of approximately 100ms (1 * 100)*/
255 while ((val
& AUD_CTRL_RESET_MASK
) && (retries
< 100)) {
258 val
= readl(mmio_base
+ XLNX_AUD_CTRL
);
260 if (val
& AUD_CTRL_RESET_MASK
)
266 static void xlnx_formatter_disable_irqs(void __iomem
*mmio_base
, int stream
)
270 val
= readl(mmio_base
+ XLNX_AUD_CTRL
);
271 val
&= ~AUD_CTRL_IOC_IRQ_MASK
;
272 if (stream
== SNDRV_PCM_STREAM_CAPTURE
)
273 val
&= ~AUD_CTRL_TOUT_IRQ_MASK
;
275 writel(val
, mmio_base
+ XLNX_AUD_CTRL
);
278 static irqreturn_t
xlnx_mm2s_irq_handler(int irq
, void *arg
)
282 struct device
*dev
= arg
;
283 struct xlnx_pcm_drv_data
*adata
= dev_get_drvdata(dev
);
285 reg
= adata
->mmio
+ XLNX_MM2S_OFFSET
+ XLNX_AUD_STS
;
287 if (val
& AUD_STS_IOC_IRQ_MASK
) {
288 writel(val
& AUD_STS_IOC_IRQ_MASK
, reg
);
289 if (adata
->play_stream
)
290 snd_pcm_period_elapsed(adata
->play_stream
);
297 static irqreturn_t
xlnx_s2mm_irq_handler(int irq
, void *arg
)
301 struct device
*dev
= arg
;
302 struct xlnx_pcm_drv_data
*adata
= dev_get_drvdata(dev
);
304 reg
= adata
->mmio
+ XLNX_S2MM_OFFSET
+ XLNX_AUD_STS
;
306 if (val
& AUD_STS_IOC_IRQ_MASK
) {
307 writel(val
& AUD_STS_IOC_IRQ_MASK
, reg
);
308 if (adata
->capture_stream
)
309 snd_pcm_period_elapsed(adata
->capture_stream
);
316 static int xlnx_formatter_pcm_open(struct snd_soc_component
*component
,
317 struct snd_pcm_substream
*substream
)
320 u32 val
, data_format_mode
;
321 u32 ch_count_mask
, ch_count_shift
, data_xfer_mode
, data_xfer_shift
;
322 struct xlnx_pcm_stream_param
*stream_data
;
323 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
324 struct xlnx_pcm_drv_data
*adata
= dev_get_drvdata(component
->dev
);
326 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
&&
327 !adata
->mm2s_presence
)
329 else if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
&&
330 !adata
->s2mm_presence
)
333 stream_data
= kzalloc(sizeof(*stream_data
), GFP_KERNEL
);
337 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
338 ch_count_mask
= CFG_MM2S_CH_MASK
;
339 ch_count_shift
= CFG_MM2S_CH_SHIFT
;
340 data_xfer_mode
= CFG_MM2S_XFER_MASK
;
341 data_xfer_shift
= CFG_MM2S_XFER_SHIFT
;
342 data_format_mode
= CFG_MM2S_PKG_MASK
;
343 stream_data
->mmio
= adata
->mmio
+ XLNX_MM2S_OFFSET
;
344 adata
->play_stream
= substream
;
347 ch_count_mask
= CFG_S2MM_CH_MASK
;
348 ch_count_shift
= CFG_S2MM_CH_SHIFT
;
349 data_xfer_mode
= CFG_S2MM_XFER_MASK
;
350 data_xfer_shift
= CFG_S2MM_XFER_SHIFT
;
351 data_format_mode
= CFG_S2MM_PKG_MASK
;
352 stream_data
->mmio
= adata
->mmio
+ XLNX_S2MM_OFFSET
;
353 adata
->capture_stream
= substream
;
356 val
= readl(adata
->mmio
+ XLNX_AUD_CORE_CONFIG
);
358 if (!(val
& data_format_mode
))
359 stream_data
->interleaved
= true;
361 stream_data
->xfer_mode
= (val
& data_xfer_mode
) >> data_xfer_shift
;
362 stream_data
->ch_limit
= (val
& ch_count_mask
) >> ch_count_shift
;
363 dev_info(component
->dev
,
364 "stream %d : format = %d mode = %d ch_limit = %d\n",
365 substream
->stream
, stream_data
->interleaved
,
366 stream_data
->xfer_mode
, stream_data
->ch_limit
);
368 snd_soc_set_runtime_hwparams(substream
, &xlnx_pcm_hardware
);
369 runtime
->private_data
= stream_data
;
371 /* Resize the period size divisible by 64 */
372 err
= snd_pcm_hw_constraint_step(runtime
, 0,
373 SNDRV_PCM_HW_PARAM_PERIOD_BYTES
, 64);
375 dev_err(component
->dev
,
376 "unable to set constraint on period bytes\n");
380 /* enable DMA IOC irq */
381 val
= readl(stream_data
->mmio
+ XLNX_AUD_CTRL
);
382 val
|= AUD_CTRL_IOC_IRQ_MASK
;
383 writel(val
, stream_data
->mmio
+ XLNX_AUD_CTRL
);
388 static int xlnx_formatter_pcm_close(struct snd_soc_component
*component
,
389 struct snd_pcm_substream
*substream
)
392 struct xlnx_pcm_stream_param
*stream_data
=
393 substream
->runtime
->private_data
;
395 ret
= xlnx_formatter_pcm_reset(stream_data
->mmio
);
397 dev_err(component
->dev
, "audio formatter reset failed\n");
400 xlnx_formatter_disable_irqs(stream_data
->mmio
, substream
->stream
);
407 static snd_pcm_uframes_t
408 xlnx_formatter_pcm_pointer(struct snd_soc_component
*component
,
409 struct snd_pcm_substream
*substream
)
412 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
413 struct xlnx_pcm_stream_param
*stream_data
= runtime
->private_data
;
415 pos
= readl(stream_data
->mmio
+ XLNX_AUD_XFER_COUNT
);
417 if (pos
>= stream_data
->buffer_size
)
420 return bytes_to_frames(runtime
, pos
);
423 static int xlnx_formatter_pcm_hw_params(struct snd_soc_component
*component
,
424 struct snd_pcm_substream
*substream
,
425 struct snd_pcm_hw_params
*params
)
427 u32 low
, high
, active_ch
, val
, bytes_per_ch
, bits_per_sample
;
428 u32 aes_reg1_val
, aes_reg2_val
;
430 struct snd_pcm_runtime
*runtime
= substream
->runtime
;
431 struct xlnx_pcm_stream_param
*stream_data
= runtime
->private_data
;
433 active_ch
= params_channels(params
);
434 if (active_ch
> stream_data
->ch_limit
)
437 if (substream
->stream
== SNDRV_PCM_STREAM_CAPTURE
&&
438 stream_data
->xfer_mode
== AES_TO_PCM
) {
439 val
= readl(stream_data
->mmio
+ XLNX_AUD_STS
);
440 if (val
& AUD_STS_CH_STS_MASK
) {
441 aes_reg1_val
= readl(stream_data
->mmio
+
442 XLNX_AUD_CH_STS_START
);
443 aes_reg2_val
= readl(stream_data
->mmio
+
444 XLNX_AUD_CH_STS_START
+ 0x4);
446 xlnx_parse_aes_params(aes_reg1_val
, aes_reg2_val
,
451 size
= params_buffer_bytes(params
);
453 stream_data
->buffer_size
= size
;
455 low
= lower_32_bits(substream
->dma_buffer
.addr
);
456 high
= upper_32_bits(substream
->dma_buffer
.addr
);
457 writel(low
, stream_data
->mmio
+ XLNX_AUD_BUFF_ADDR_LSB
);
458 writel(high
, stream_data
->mmio
+ XLNX_AUD_BUFF_ADDR_MSB
);
460 val
= readl(stream_data
->mmio
+ XLNX_AUD_CTRL
);
461 bits_per_sample
= params_width(params
);
462 switch (bits_per_sample
) {
464 val
|= (BIT_DEPTH_8
<< AUD_CTRL_DATA_WIDTH_SHIFT
);
467 val
|= (BIT_DEPTH_16
<< AUD_CTRL_DATA_WIDTH_SHIFT
);
470 val
|= (BIT_DEPTH_20
<< AUD_CTRL_DATA_WIDTH_SHIFT
);
473 val
|= (BIT_DEPTH_24
<< AUD_CTRL_DATA_WIDTH_SHIFT
);
476 val
|= (BIT_DEPTH_32
<< AUD_CTRL_DATA_WIDTH_SHIFT
);
482 val
|= active_ch
<< AUD_CTRL_ACTIVE_CH_SHIFT
;
483 writel(val
, stream_data
->mmio
+ XLNX_AUD_CTRL
);
485 val
= (params_periods(params
) << PERIOD_CFG_PERIODS_SHIFT
)
486 | params_period_bytes(params
);
487 writel(val
, stream_data
->mmio
+ XLNX_AUD_PERIOD_CONFIG
);
488 bytes_per_ch
= DIV_ROUND_UP(params_period_bytes(params
), active_ch
);
489 writel(bytes_per_ch
, stream_data
->mmio
+ XLNX_BYTES_PER_CH
);
494 static int xlnx_formatter_pcm_trigger(struct snd_soc_component
*component
,
495 struct snd_pcm_substream
*substream
,
499 struct xlnx_pcm_stream_param
*stream_data
=
500 substream
->runtime
->private_data
;
503 case SNDRV_PCM_TRIGGER_START
:
504 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
505 case SNDRV_PCM_TRIGGER_RESUME
:
506 val
= readl(stream_data
->mmio
+ XLNX_AUD_CTRL
);
507 val
|= AUD_CTRL_DMA_EN_MASK
;
508 writel(val
, stream_data
->mmio
+ XLNX_AUD_CTRL
);
510 case SNDRV_PCM_TRIGGER_STOP
:
511 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
512 case SNDRV_PCM_TRIGGER_SUSPEND
:
513 val
= readl(stream_data
->mmio
+ XLNX_AUD_CTRL
);
514 val
&= ~AUD_CTRL_DMA_EN_MASK
;
515 writel(val
, stream_data
->mmio
+ XLNX_AUD_CTRL
);
522 static int xlnx_formatter_pcm_new(struct snd_soc_component
*component
,
523 struct snd_soc_pcm_runtime
*rtd
)
525 snd_pcm_set_managed_buffer_all(rtd
->pcm
,
526 SNDRV_DMA_TYPE_DEV
, component
->dev
,
527 xlnx_pcm_hardware
.buffer_bytes_max
,
528 xlnx_pcm_hardware
.buffer_bytes_max
);
532 static const struct snd_soc_component_driver xlnx_asoc_component
= {
534 .open
= xlnx_formatter_pcm_open
,
535 .close
= xlnx_formatter_pcm_close
,
536 .hw_params
= xlnx_formatter_pcm_hw_params
,
537 .trigger
= xlnx_formatter_pcm_trigger
,
538 .pointer
= xlnx_formatter_pcm_pointer
,
539 .pcm_construct
= xlnx_formatter_pcm_new
,
542 static int xlnx_formatter_pcm_probe(struct platform_device
*pdev
)
546 struct xlnx_pcm_drv_data
*aud_drv_data
;
547 struct device
*dev
= &pdev
->dev
;
549 aud_drv_data
= devm_kzalloc(dev
, sizeof(*aud_drv_data
), GFP_KERNEL
);
553 aud_drv_data
->axi_clk
= devm_clk_get(dev
, "s_axi_lite_aclk");
554 if (IS_ERR(aud_drv_data
->axi_clk
)) {
555 ret
= PTR_ERR(aud_drv_data
->axi_clk
);
556 dev_err(dev
, "failed to get s_axi_lite_aclk(%d)\n", ret
);
559 ret
= clk_prepare_enable(aud_drv_data
->axi_clk
);
562 "failed to enable s_axi_lite_aclk(%d)\n", ret
);
566 aud_drv_data
->mmio
= devm_platform_ioremap_resource(pdev
, 0);
567 if (IS_ERR(aud_drv_data
->mmio
)) {
568 dev_err(dev
, "audio formatter ioremap failed\n");
569 ret
= PTR_ERR(aud_drv_data
->mmio
);
573 val
= readl(aud_drv_data
->mmio
+ XLNX_AUD_CORE_CONFIG
);
574 if (val
& AUD_CFG_MM2S_MASK
) {
575 aud_drv_data
->mm2s_presence
= true;
576 ret
= xlnx_formatter_pcm_reset(aud_drv_data
->mmio
+
579 dev_err(dev
, "audio formatter reset failed\n");
582 xlnx_formatter_disable_irqs(aud_drv_data
->mmio
+
584 SNDRV_PCM_STREAM_PLAYBACK
);
586 aud_drv_data
->mm2s_irq
= platform_get_irq_byname(pdev
,
588 if (aud_drv_data
->mm2s_irq
< 0) {
589 ret
= aud_drv_data
->mm2s_irq
;
592 ret
= devm_request_irq(dev
, aud_drv_data
->mm2s_irq
,
593 xlnx_mm2s_irq_handler
, 0,
594 "xlnx_formatter_pcm_mm2s_irq", dev
);
596 dev_err(dev
, "xlnx audio mm2s irq request failed\n");
600 if (val
& AUD_CFG_S2MM_MASK
) {
601 aud_drv_data
->s2mm_presence
= true;
602 ret
= xlnx_formatter_pcm_reset(aud_drv_data
->mmio
+
605 dev_err(dev
, "audio formatter reset failed\n");
608 xlnx_formatter_disable_irqs(aud_drv_data
->mmio
+
610 SNDRV_PCM_STREAM_CAPTURE
);
612 aud_drv_data
->s2mm_irq
= platform_get_irq_byname(pdev
,
614 if (aud_drv_data
->s2mm_irq
< 0) {
615 ret
= aud_drv_data
->s2mm_irq
;
618 ret
= devm_request_irq(dev
, aud_drv_data
->s2mm_irq
,
619 xlnx_s2mm_irq_handler
, 0,
620 "xlnx_formatter_pcm_s2mm_irq",
623 dev_err(dev
, "xlnx audio s2mm irq request failed\n");
628 dev_set_drvdata(dev
, aud_drv_data
);
630 ret
= devm_snd_soc_register_component(dev
, &xlnx_asoc_component
,
633 dev_err(dev
, "pcm platform device register failed\n");
640 clk_disable_unprepare(aud_drv_data
->axi_clk
);
644 static int xlnx_formatter_pcm_remove(struct platform_device
*pdev
)
647 struct xlnx_pcm_drv_data
*adata
= dev_get_drvdata(&pdev
->dev
);
649 if (adata
->s2mm_presence
)
650 ret
= xlnx_formatter_pcm_reset(adata
->mmio
+ XLNX_S2MM_OFFSET
);
652 /* Try MM2S reset, even if S2MM reset fails */
653 if (adata
->mm2s_presence
)
654 ret
= xlnx_formatter_pcm_reset(adata
->mmio
+ XLNX_MM2S_OFFSET
);
657 dev_err(&pdev
->dev
, "audio formatter reset failed\n");
659 clk_disable_unprepare(adata
->axi_clk
);
663 static const struct of_device_id xlnx_formatter_pcm_of_match
[] = {
664 { .compatible
= "xlnx,audio-formatter-1.0"},
667 MODULE_DEVICE_TABLE(of
, xlnx_formatter_pcm_of_match
);
669 static struct platform_driver xlnx_formatter_pcm_driver
= {
670 .probe
= xlnx_formatter_pcm_probe
,
671 .remove
= xlnx_formatter_pcm_remove
,
674 .of_match_table
= xlnx_formatter_pcm_of_match
,
678 module_platform_driver(xlnx_formatter_pcm_driver
);
679 MODULE_AUTHOR("Maruthi Srinivas Bayyavarapu <maruthis@xilinx.com>");
680 MODULE_LICENSE("GPL v2");