1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2021 Advanced Micro Devices, Inc.
8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
12 * Generic Hardware interface for ACP Audio I2S controller
15 #include <linux/platform_device.h>
16 #include <linux/module.h>
17 #include <linux/err.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/soc-dai.h>
22 #include <linux/dma-mapping.h>
23 #include <linux/bitfield.h>
27 #define DRV_NAME "acp_i2s_playcap"
28 #define I2S_MASTER_MODE_ENABLE 1
29 #define LRCLK_DIV_FIELD GENMASK(10, 2)
30 #define BCLK_DIV_FIELD GENMASK(23, 11)
31 #define ACP63_LRCLK_DIV_FIELD GENMASK(12, 2)
32 #define ACP63_BCLK_DIV_FIELD GENMASK(23, 13)
34 static inline void acp_set_i2s_clk(struct acp_dev_data
*adata
, int dai_id
)
37 struct acp_chip_info
*chip
;
41 chip
= dev_get_platdata(dev
);
44 i2s_clk_reg
= ACP_I2STDM0_MSTRCLKGEN
;
47 i2s_clk_reg
= ACP_I2STDM1_MSTRCLKGEN
;
50 i2s_clk_reg
= ACP_I2STDM2_MSTRCLKGEN
;
53 i2s_clk_reg
= ACP_I2STDM0_MSTRCLKGEN
;
57 val
= I2S_MASTER_MODE_ENABLE
;
61 switch (chip
->acp_rev
) {
65 val
|= FIELD_PREP(ACP63_LRCLK_DIV_FIELD
, adata
->lrclk_div
);
66 val
|= FIELD_PREP(ACP63_BCLK_DIV_FIELD
, adata
->bclk_div
);
69 val
|= FIELD_PREP(LRCLK_DIV_FIELD
, adata
->lrclk_div
);
70 val
|= FIELD_PREP(BCLK_DIV_FIELD
, adata
->bclk_div
);
72 writel(val
, adata
->acp_base
+ i2s_clk_reg
);
75 static int acp_i2s_set_fmt(struct snd_soc_dai
*cpu_dai
,
78 struct acp_dev_data
*adata
= snd_soc_dai_get_drvdata(cpu_dai
);
81 mode
= fmt
& SND_SOC_DAIFMT_FORMAT_MASK
;
83 case SND_SOC_DAIFMT_I2S
:
84 adata
->tdm_mode
= TDM_DISABLE
;
86 case SND_SOC_DAIFMT_DSP_A
:
87 adata
->tdm_mode
= TDM_ENABLE
;
95 static int acp_i2s_set_tdm_slot(struct snd_soc_dai
*dai
, u32 tx_mask
, u32 rx_mask
,
96 int slots
, int slot_width
)
98 struct device
*dev
= dai
->component
->dev
;
99 struct acp_dev_data
*adata
= snd_soc_dai_get_drvdata(dai
);
100 struct acp_chip_info
*chip
;
101 struct acp_stream
*stream
;
102 int slot_len
, no_of_slots
;
104 chip
= dev_get_platdata(dev
);
105 switch (slot_width
) {
119 dev_err(dev
, "Unsupported bitdepth %d\n", slot_width
);
123 switch (chip
->acp_rev
) {
134 dev_err(dev
, "Unsupported slots %d\n", slots
);
149 dev_err(dev
, "Unsupported slots %d\n", slots
);
154 dev_err(dev
, "Unknown chip revision %d\n", chip
->acp_rev
);
160 spin_lock_irq(&adata
->acp_lock
);
161 list_for_each_entry(stream
, &adata
->stream_list
, list
) {
162 switch (chip
->acp_rev
) {
165 if (tx_mask
&& stream
->dir
== SNDRV_PCM_STREAM_PLAYBACK
)
166 adata
->tdm_tx_fmt
[stream
->dai_id
- 1] =
167 FRM_LEN
| (slots
<< 15) | (slot_len
<< 18);
168 else if (rx_mask
&& stream
->dir
== SNDRV_PCM_STREAM_CAPTURE
)
169 adata
->tdm_rx_fmt
[stream
->dai_id
- 1] =
170 FRM_LEN
| (slots
<< 15) | (slot_len
<< 18);
175 if (tx_mask
&& stream
->dir
== SNDRV_PCM_STREAM_PLAYBACK
)
176 adata
->tdm_tx_fmt
[stream
->dai_id
- 1] =
177 FRM_LEN
| (slots
<< 13) | (slot_len
<< 18);
178 else if (rx_mask
&& stream
->dir
== SNDRV_PCM_STREAM_CAPTURE
)
179 adata
->tdm_rx_fmt
[stream
->dai_id
- 1] =
180 FRM_LEN
| (slots
<< 13) | (slot_len
<< 18);
183 dev_err(dev
, "Unknown chip revision %d\n", chip
->acp_rev
);
187 spin_unlock_irq(&adata
->acp_lock
);
191 static int acp_i2s_hwparams(struct snd_pcm_substream
*substream
, struct snd_pcm_hw_params
*params
,
192 struct snd_soc_dai
*dai
)
194 struct device
*dev
= dai
->component
->dev
;
195 struct acp_dev_data
*adata
;
196 struct acp_resource
*rsrc
;
199 u32 reg_val
, fmt_reg
, tdm_fmt
;
200 u32 lrclk_div_val
, bclk_div_val
;
202 adata
= snd_soc_dai_get_drvdata(dai
);
205 /* These values are as per Hardware Spec */
206 switch (params_format(params
)) {
207 case SNDRV_PCM_FORMAT_U8
:
208 case SNDRV_PCM_FORMAT_S8
:
209 xfer_resolution
= 0x0;
211 case SNDRV_PCM_FORMAT_S16_LE
:
212 xfer_resolution
= 0x02;
214 case SNDRV_PCM_FORMAT_S24_LE
:
215 xfer_resolution
= 0x04;
217 case SNDRV_PCM_FORMAT_S32_LE
:
218 xfer_resolution
= 0x05;
224 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
225 switch (dai
->driver
->id
) {
226 case I2S_BT_INSTANCE
:
227 reg_val
= ACP_BTTDM_ITER
;
228 fmt_reg
= ACP_BTTDM_TXFRMT
;
230 case I2S_SP_INSTANCE
:
231 reg_val
= ACP_I2STDM_ITER
;
232 fmt_reg
= ACP_I2STDM_TXFRMT
;
234 case I2S_HS_INSTANCE
:
235 reg_val
= ACP_HSTDM_ITER
;
236 fmt_reg
= ACP_HSTDM_TXFRMT
;
239 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
242 adata
->xfer_tx_resolution
[dai
->driver
->id
- 1] = xfer_resolution
;
244 switch (dai
->driver
->id
) {
245 case I2S_BT_INSTANCE
:
246 reg_val
= ACP_BTTDM_IRER
;
247 fmt_reg
= ACP_BTTDM_RXFRMT
;
249 case I2S_SP_INSTANCE
:
250 reg_val
= ACP_I2STDM_IRER
;
251 fmt_reg
= ACP_I2STDM_RXFRMT
;
253 case I2S_HS_INSTANCE
:
254 reg_val
= ACP_HSTDM_IRER
;
255 fmt_reg
= ACP_HSTDM_RXFRMT
;
258 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
261 adata
->xfer_rx_resolution
[dai
->driver
->id
- 1] = xfer_resolution
;
264 val
= readl(adata
->acp_base
+ reg_val
);
265 val
&= ~ACP3x_ITER_IRER_SAMP_LEN_MASK
;
266 val
= val
| (xfer_resolution
<< 3);
267 writel(val
, adata
->acp_base
+ reg_val
);
269 if (adata
->tdm_mode
) {
270 val
= readl(adata
->acp_base
+ reg_val
);
271 writel(val
| BIT(1), adata
->acp_base
+ reg_val
);
272 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
)
273 tdm_fmt
= adata
->tdm_tx_fmt
[dai
->driver
->id
- 1];
275 tdm_fmt
= adata
->tdm_rx_fmt
[dai
->driver
->id
- 1];
276 writel(tdm_fmt
, adata
->acp_base
+ fmt_reg
);
279 if (rsrc
->soc_mclk
) {
280 switch (params_format(params
)) {
281 case SNDRV_PCM_FORMAT_S16_LE
:
282 switch (params_rate(params
)) {
311 case SNDRV_PCM_FORMAT_S32_LE
:
312 switch (params_rate(params
)) {
345 switch (params_rate(params
)) {
352 switch (params_channels(params
)) {
356 bclk_div_val
= bclk_div_val
>> 1;
357 lrclk_div_val
= lrclk_div_val
<< 1;
360 bclk_div_val
= bclk_div_val
>> 2;
361 lrclk_div_val
= lrclk_div_val
<< 2;
364 bclk_div_val
= bclk_div_val
>> 3;
365 lrclk_div_val
= lrclk_div_val
<< 3;
368 bclk_div_val
= bclk_div_val
>> 4;
369 lrclk_div_val
= lrclk_div_val
<< 4;
372 dev_err(dev
, "Unsupported channels %#x\n",
373 params_channels(params
));
379 adata
->lrclk_div
= lrclk_div_val
;
380 adata
->bclk_div
= bclk_div_val
;
385 static int acp_i2s_trigger(struct snd_pcm_substream
*substream
, int cmd
, struct snd_soc_dai
*dai
)
387 struct acp_stream
*stream
= substream
->runtime
->private_data
;
388 struct device
*dev
= dai
->component
->dev
;
389 struct acp_dev_data
*adata
= dev_get_drvdata(dev
);
390 struct acp_resource
*rsrc
= adata
->rsrc
;
391 u32 val
, period_bytes
, reg_val
, ier_val
, water_val
, buf_size
, buf_reg
;
393 period_bytes
= frames_to_bytes(substream
->runtime
, substream
->runtime
->period_size
);
394 buf_size
= frames_to_bytes(substream
->runtime
, substream
->runtime
->buffer_size
);
397 case SNDRV_PCM_TRIGGER_START
:
398 case SNDRV_PCM_TRIGGER_RESUME
:
399 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
400 stream
->bytescount
= acp_get_byte_count(adata
, stream
->dai_id
, substream
->stream
);
401 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
402 switch (dai
->driver
->id
) {
403 case I2S_BT_INSTANCE
:
404 water_val
= ACP_BT_TX_INTR_WATERMARK_SIZE(adata
);
405 reg_val
= ACP_BTTDM_ITER
;
406 ier_val
= ACP_BTTDM_IER
;
407 buf_reg
= ACP_BT_TX_RINGBUFSIZE(adata
);
409 case I2S_SP_INSTANCE
:
410 water_val
= ACP_I2S_TX_INTR_WATERMARK_SIZE(adata
);
411 reg_val
= ACP_I2STDM_ITER
;
412 ier_val
= ACP_I2STDM_IER
;
413 buf_reg
= ACP_I2S_TX_RINGBUFSIZE(adata
);
415 case I2S_HS_INSTANCE
:
416 water_val
= ACP_HS_TX_INTR_WATERMARK_SIZE
;
417 reg_val
= ACP_HSTDM_ITER
;
418 ier_val
= ACP_HSTDM_IER
;
419 buf_reg
= ACP_HS_TX_RINGBUFSIZE
;
422 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
426 switch (dai
->driver
->id
) {
427 case I2S_BT_INSTANCE
:
428 water_val
= ACP_BT_RX_INTR_WATERMARK_SIZE(adata
);
429 reg_val
= ACP_BTTDM_IRER
;
430 ier_val
= ACP_BTTDM_IER
;
431 buf_reg
= ACP_BT_RX_RINGBUFSIZE(adata
);
433 case I2S_SP_INSTANCE
:
434 water_val
= ACP_I2S_RX_INTR_WATERMARK_SIZE(adata
);
435 reg_val
= ACP_I2STDM_IRER
;
436 ier_val
= ACP_I2STDM_IER
;
437 buf_reg
= ACP_I2S_RX_RINGBUFSIZE(adata
);
439 case I2S_HS_INSTANCE
:
440 water_val
= ACP_HS_RX_INTR_WATERMARK_SIZE
;
441 reg_val
= ACP_HSTDM_IRER
;
442 ier_val
= ACP_HSTDM_IER
;
443 buf_reg
= ACP_HS_RX_RINGBUFSIZE
;
446 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
451 writel(period_bytes
, adata
->acp_base
+ water_val
);
452 writel(buf_size
, adata
->acp_base
+ buf_reg
);
454 acp_set_i2s_clk(adata
, dai
->driver
->id
);
455 val
= readl(adata
->acp_base
+ reg_val
);
457 writel(val
, adata
->acp_base
+ reg_val
);
458 writel(1, adata
->acp_base
+ ier_val
);
460 case SNDRV_PCM_TRIGGER_STOP
:
461 case SNDRV_PCM_TRIGGER_SUSPEND
:
462 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
463 if (substream
->stream
== SNDRV_PCM_STREAM_PLAYBACK
) {
464 switch (dai
->driver
->id
) {
465 case I2S_BT_INSTANCE
:
466 reg_val
= ACP_BTTDM_ITER
;
468 case I2S_SP_INSTANCE
:
469 reg_val
= ACP_I2STDM_ITER
;
471 case I2S_HS_INSTANCE
:
472 reg_val
= ACP_HSTDM_ITER
;
475 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
480 switch (dai
->driver
->id
) {
481 case I2S_BT_INSTANCE
:
482 reg_val
= ACP_BTTDM_IRER
;
484 case I2S_SP_INSTANCE
:
485 reg_val
= ACP_I2STDM_IRER
;
487 case I2S_HS_INSTANCE
:
488 reg_val
= ACP_HSTDM_IRER
;
491 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
495 val
= readl(adata
->acp_base
+ reg_val
);
497 writel(val
, adata
->acp_base
+ reg_val
);
499 if (!(readl(adata
->acp_base
+ ACP_BTTDM_ITER
) & BIT(0)) &&
500 !(readl(adata
->acp_base
+ ACP_BTTDM_IRER
) & BIT(0)))
501 writel(0, adata
->acp_base
+ ACP_BTTDM_IER
);
502 if (!(readl(adata
->acp_base
+ ACP_I2STDM_ITER
) & BIT(0)) &&
503 !(readl(adata
->acp_base
+ ACP_I2STDM_IRER
) & BIT(0)))
504 writel(0, adata
->acp_base
+ ACP_I2STDM_IER
);
505 if (!(readl(adata
->acp_base
+ ACP_HSTDM_ITER
) & BIT(0)) &&
506 !(readl(adata
->acp_base
+ ACP_HSTDM_IRER
) & BIT(0)))
507 writel(0, adata
->acp_base
+ ACP_HSTDM_IER
);
516 static int acp_i2s_prepare(struct snd_pcm_substream
*substream
, struct snd_soc_dai
*dai
)
518 struct device
*dev
= dai
->component
->dev
;
519 struct acp_dev_data
*adata
= dev_get_drvdata(dev
);
520 struct acp_chip_info
*chip
;
521 struct acp_resource
*rsrc
= adata
->rsrc
;
522 struct acp_stream
*stream
= substream
->runtime
->private_data
;
523 u32 reg_dma_size
= 0, reg_fifo_size
= 0, reg_fifo_addr
= 0;
524 u32 phy_addr
= 0, acp_fifo_addr
= 0, ext_int_ctrl
;
525 unsigned int dir
= substream
->stream
;
527 chip
= dev_get_platdata(dev
);
528 switch (dai
->driver
->id
) {
529 case I2S_SP_INSTANCE
:
530 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
) {
531 reg_dma_size
= ACP_I2S_TX_DMA_SIZE(adata
);
532 acp_fifo_addr
= rsrc
->sram_pte_offset
+
533 SP_PB_FIFO_ADDR_OFFSET
;
534 reg_fifo_addr
= ACP_I2S_TX_FIFOADDR(adata
);
535 reg_fifo_size
= ACP_I2S_TX_FIFOSIZE(adata
);
537 if (chip
->acp_rev
>= ACP70_PCI_ID
)
538 phy_addr
= ACP7x_I2S_SP_TX_MEM_WINDOW_START
;
540 phy_addr
= I2S_SP_TX_MEM_WINDOW_START
+ stream
->reg_offset
;
541 writel(phy_addr
, adata
->acp_base
+ ACP_I2S_TX_RINGBUFADDR(adata
));
543 reg_dma_size
= ACP_I2S_RX_DMA_SIZE(adata
);
544 acp_fifo_addr
= rsrc
->sram_pte_offset
+
545 SP_CAPT_FIFO_ADDR_OFFSET
;
546 reg_fifo_addr
= ACP_I2S_RX_FIFOADDR(adata
);
547 reg_fifo_size
= ACP_I2S_RX_FIFOSIZE(adata
);
549 if (chip
->acp_rev
>= ACP70_PCI_ID
)
550 phy_addr
= ACP7x_I2S_SP_RX_MEM_WINDOW_START
;
552 phy_addr
= I2S_SP_RX_MEM_WINDOW_START
+ stream
->reg_offset
;
553 writel(phy_addr
, adata
->acp_base
+ ACP_I2S_RX_RINGBUFADDR(adata
));
556 case I2S_BT_INSTANCE
:
557 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
) {
558 reg_dma_size
= ACP_BT_TX_DMA_SIZE(adata
);
559 acp_fifo_addr
= rsrc
->sram_pte_offset
+
560 BT_PB_FIFO_ADDR_OFFSET
;
561 reg_fifo_addr
= ACP_BT_TX_FIFOADDR(adata
);
562 reg_fifo_size
= ACP_BT_TX_FIFOSIZE(adata
);
564 if (chip
->acp_rev
>= ACP70_PCI_ID
)
565 phy_addr
= ACP7x_I2S_BT_TX_MEM_WINDOW_START
;
567 phy_addr
= I2S_BT_TX_MEM_WINDOW_START
+ stream
->reg_offset
;
568 writel(phy_addr
, adata
->acp_base
+ ACP_BT_TX_RINGBUFADDR(adata
));
570 reg_dma_size
= ACP_BT_RX_DMA_SIZE(adata
);
571 acp_fifo_addr
= rsrc
->sram_pte_offset
+
572 BT_CAPT_FIFO_ADDR_OFFSET
;
573 reg_fifo_addr
= ACP_BT_RX_FIFOADDR(adata
);
574 reg_fifo_size
= ACP_BT_RX_FIFOSIZE(adata
);
576 if (chip
->acp_rev
>= ACP70_PCI_ID
)
577 phy_addr
= ACP7x_I2S_BT_RX_MEM_WINDOW_START
;
579 phy_addr
= I2S_BT_TX_MEM_WINDOW_START
+ stream
->reg_offset
;
580 writel(phy_addr
, adata
->acp_base
+ ACP_BT_RX_RINGBUFADDR(adata
));
583 case I2S_HS_INSTANCE
:
584 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
) {
585 reg_dma_size
= ACP_HS_TX_DMA_SIZE
;
586 acp_fifo_addr
= rsrc
->sram_pte_offset
+
587 HS_PB_FIFO_ADDR_OFFSET
;
588 reg_fifo_addr
= ACP_HS_TX_FIFOADDR
;
589 reg_fifo_size
= ACP_HS_TX_FIFOSIZE
;
591 if (chip
->acp_rev
>= ACP70_PCI_ID
)
592 phy_addr
= ACP7x_I2S_HS_TX_MEM_WINDOW_START
;
594 phy_addr
= I2S_HS_TX_MEM_WINDOW_START
+ stream
->reg_offset
;
595 writel(phy_addr
, adata
->acp_base
+ ACP_HS_TX_RINGBUFADDR
);
597 reg_dma_size
= ACP_HS_RX_DMA_SIZE
;
598 acp_fifo_addr
= rsrc
->sram_pte_offset
+
599 HS_CAPT_FIFO_ADDR_OFFSET
;
600 reg_fifo_addr
= ACP_HS_RX_FIFOADDR
;
601 reg_fifo_size
= ACP_HS_RX_FIFOSIZE
;
603 if (chip
->acp_rev
>= ACP70_PCI_ID
)
604 phy_addr
= ACP7x_I2S_HS_RX_MEM_WINDOW_START
;
606 phy_addr
= I2S_HS_RX_MEM_WINDOW_START
+ stream
->reg_offset
;
607 writel(phy_addr
, adata
->acp_base
+ ACP_HS_RX_RINGBUFADDR
);
611 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
615 writel(DMA_SIZE
, adata
->acp_base
+ reg_dma_size
);
616 writel(acp_fifo_addr
, adata
->acp_base
+ reg_fifo_addr
);
617 writel(FIFO_SIZE
, adata
->acp_base
+ reg_fifo_size
);
619 ext_int_ctrl
= readl(ACP_EXTERNAL_INTR_CNTL(adata
, rsrc
->irqp_used
));
620 ext_int_ctrl
|= BIT(I2S_RX_THRESHOLD(rsrc
->offset
)) |
621 BIT(BT_RX_THRESHOLD(rsrc
->offset
)) |
622 BIT(I2S_TX_THRESHOLD(rsrc
->offset
)) |
623 BIT(BT_TX_THRESHOLD(rsrc
->offset
)) |
624 BIT(HS_RX_THRESHOLD(rsrc
->offset
)) |
625 BIT(HS_TX_THRESHOLD(rsrc
->offset
));
627 writel(ext_int_ctrl
, ACP_EXTERNAL_INTR_CNTL(adata
, rsrc
->irqp_used
));
632 static int acp_i2s_startup(struct snd_pcm_substream
*substream
, struct snd_soc_dai
*dai
)
634 struct acp_stream
*stream
= substream
->runtime
->private_data
;
635 struct device
*dev
= dai
->component
->dev
;
636 struct acp_dev_data
*adata
= dev_get_drvdata(dev
);
637 struct acp_resource
*rsrc
= adata
->rsrc
;
638 unsigned int dir
= substream
->stream
;
639 unsigned int irq_bit
= 0;
641 switch (dai
->driver
->id
) {
642 case I2S_SP_INSTANCE
:
643 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
) {
644 irq_bit
= BIT(I2S_TX_THRESHOLD(rsrc
->offset
));
645 stream
->pte_offset
= ACP_SRAM_SP_PB_PTE_OFFSET
;
646 stream
->fifo_offset
= SP_PB_FIFO_ADDR_OFFSET
;
648 irq_bit
= BIT(I2S_RX_THRESHOLD(rsrc
->offset
));
649 stream
->pte_offset
= ACP_SRAM_SP_CP_PTE_OFFSET
;
650 stream
->fifo_offset
= SP_CAPT_FIFO_ADDR_OFFSET
;
653 case I2S_BT_INSTANCE
:
654 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
) {
655 irq_bit
= BIT(BT_TX_THRESHOLD(rsrc
->offset
));
656 stream
->pte_offset
= ACP_SRAM_BT_PB_PTE_OFFSET
;
657 stream
->fifo_offset
= BT_PB_FIFO_ADDR_OFFSET
;
659 irq_bit
= BIT(BT_RX_THRESHOLD(rsrc
->offset
));
660 stream
->pte_offset
= ACP_SRAM_BT_CP_PTE_OFFSET
;
661 stream
->fifo_offset
= BT_CAPT_FIFO_ADDR_OFFSET
;
664 case I2S_HS_INSTANCE
:
665 if (dir
== SNDRV_PCM_STREAM_PLAYBACK
) {
666 irq_bit
= BIT(HS_TX_THRESHOLD(rsrc
->offset
));
667 stream
->pte_offset
= ACP_SRAM_HS_PB_PTE_OFFSET
;
668 stream
->fifo_offset
= HS_PB_FIFO_ADDR_OFFSET
;
670 irq_bit
= BIT(HS_RX_THRESHOLD(rsrc
->offset
));
671 stream
->pte_offset
= ACP_SRAM_HS_CP_PTE_OFFSET
;
672 stream
->fifo_offset
= HS_CAPT_FIFO_ADDR_OFFSET
;
676 dev_err(dev
, "Invalid dai id %x\n", dai
->driver
->id
);
680 /* Save runtime dai configuration in stream */
681 stream
->id
= dai
->driver
->id
+ dir
;
682 stream
->dai_id
= dai
->driver
->id
;
683 stream
->irq_bit
= irq_bit
;
684 stream
->dir
= substream
->stream
;
689 const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops
= {
690 .startup
= acp_i2s_startup
,
691 .hw_params
= acp_i2s_hwparams
,
692 .prepare
= acp_i2s_prepare
,
693 .trigger
= acp_i2s_trigger
,
694 .set_fmt
= acp_i2s_set_fmt
,
695 .set_tdm_slot
= acp_i2s_set_tdm_slot
,
697 EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops
, "SND_SOC_ACP_COMMON");
699 MODULE_DESCRIPTION("AMD ACP Audio I2S controller");
700 MODULE_LICENSE("Dual BSD/GPL");
701 MODULE_ALIAS(DRV_NAME
);