1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 // 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. 5 // 6 // Copyright(c) 2021 Advanced Micro Devices, Inc. 7 // 8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com> 9 // 10 11 /* 12 * Generic Hardware interface for ACP Audio I2S controller 13 */ 14 15 #include <linux/platform_device.h> 16 #include <linux/module.h> 17 #include <linux/err.h> 18 #include <linux/io.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> 24 25 #include "amd.h" 26 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) 33 34 static inline void acp_set_i2s_clk(struct acp_chip_info *chip, int dai_id) 35 { 36 u32 i2s_clk_reg, val; 37 38 switch (dai_id) { 39 case I2S_SP_INSTANCE: 40 i2s_clk_reg = ACP_I2STDM0_MSTRCLKGEN; 41 break; 42 case I2S_BT_INSTANCE: 43 i2s_clk_reg = ACP_I2STDM1_MSTRCLKGEN; 44 break; 45 case I2S_HS_INSTANCE: 46 i2s_clk_reg = ACP_I2STDM2_MSTRCLKGEN; 47 break; 48 default: 49 i2s_clk_reg = ACP_I2STDM0_MSTRCLKGEN; 50 break; 51 } 52 53 val = I2S_MASTER_MODE_ENABLE; 54 if (chip->tdm_mode) 55 val |= BIT(1); 56 57 switch (chip->acp_rev) { 58 case ACP63_PCI_ID: 59 case ACP70_PCI_ID: 60 case ACP71_PCI_ID: 61 val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, chip->lrclk_div); 62 val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, chip->bclk_div); 63 break; 64 default: 65 val |= FIELD_PREP(LRCLK_DIV_FIELD, chip->lrclk_div); 66 val |= FIELD_PREP(BCLK_DIV_FIELD, chip->bclk_div); 67 } 68 writel(val, chip->base + i2s_clk_reg); 69 } 70 71 static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai, 72 unsigned int fmt) 73 { 74 struct device *dev = cpu_dai->component->dev; 75 struct acp_chip_info *chip = dev_get_platdata(dev); 76 int mode; 77 78 mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK; 79 switch (mode) { 80 case SND_SOC_DAIFMT_I2S: 81 chip->tdm_mode = TDM_DISABLE; 82 break; 83 case SND_SOC_DAIFMT_DSP_A: 84 chip->tdm_mode = TDM_ENABLE; 85 break; 86 default: 87 return -EINVAL; 88 } 89 return 0; 90 } 91 92 static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mask, 93 int slots, int slot_width) 94 { 95 struct device *dev = dai->component->dev; 96 struct acp_chip_info *chip; 97 struct acp_stream *stream; 98 int slot_len, no_of_slots; 99 100 chip = dev_get_drvdata(dev->parent); 101 switch (slot_width) { 102 case SLOT_WIDTH_8: 103 slot_len = 8; 104 break; 105 case SLOT_WIDTH_16: 106 slot_len = 16; 107 break; 108 case SLOT_WIDTH_24: 109 slot_len = 24; 110 break; 111 case SLOT_WIDTH_32: 112 slot_len = 0; 113 break; 114 default: 115 dev_err(dev, "Unsupported bitdepth %d\n", slot_width); 116 return -EINVAL; 117 } 118 119 switch (chip->acp_rev) { 120 case ACP_RN_PCI_ID: 121 case ACP_RMB_PCI_ID: 122 switch (slots) { 123 case 1 ... 7: 124 no_of_slots = slots; 125 break; 126 case 8: 127 no_of_slots = 0; 128 break; 129 default: 130 dev_err(dev, "Unsupported slots %d\n", slots); 131 return -EINVAL; 132 } 133 break; 134 case ACP63_PCI_ID: 135 case ACP70_PCI_ID: 136 case ACP71_PCI_ID: 137 switch (slots) { 138 case 1 ... 31: 139 no_of_slots = slots; 140 break; 141 case 32: 142 no_of_slots = 0; 143 break; 144 default: 145 dev_err(dev, "Unsupported slots %d\n", slots); 146 return -EINVAL; 147 } 148 break; 149 default: 150 dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev); 151 return -EINVAL; 152 } 153 154 slots = no_of_slots; 155 156 spin_lock_irq(&chip->acp_lock); 157 list_for_each_entry(stream, &chip->stream_list, list) { 158 switch (chip->acp_rev) { 159 case ACP_RN_PCI_ID: 160 case ACP_RMB_PCI_ID: 161 if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) 162 chip->tdm_tx_fmt[stream->dai_id - 1] = 163 FRM_LEN | (slots << 15) | (slot_len << 18); 164 else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) 165 chip->tdm_rx_fmt[stream->dai_id - 1] = 166 FRM_LEN | (slots << 15) | (slot_len << 18); 167 break; 168 case ACP63_PCI_ID: 169 case ACP70_PCI_ID: 170 case ACP71_PCI_ID: 171 if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK) 172 chip->tdm_tx_fmt[stream->dai_id - 1] = 173 FRM_LEN | (slots << 13) | (slot_len << 18); 174 else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE) 175 chip->tdm_rx_fmt[stream->dai_id - 1] = 176 FRM_LEN | (slots << 13) | (slot_len << 18); 177 break; 178 default: 179 dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev); 180 spin_unlock_irq(&chip->acp_lock); 181 return -EINVAL; 182 } 183 } 184 spin_unlock_irq(&chip->acp_lock); 185 return 0; 186 } 187 188 static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, 189 struct snd_soc_dai *dai) 190 { 191 struct device *dev = dai->component->dev; 192 struct acp_chip_info *chip; 193 struct acp_resource *rsrc; 194 u32 val; 195 u32 xfer_resolution; 196 u32 reg_val, fmt_reg, tdm_fmt; 197 u32 lrclk_div_val, bclk_div_val; 198 199 chip = dev_get_platdata(dev); 200 rsrc = chip->rsrc; 201 202 /* These values are as per Hardware Spec */ 203 switch (params_format(params)) { 204 case SNDRV_PCM_FORMAT_U8: 205 case SNDRV_PCM_FORMAT_S8: 206 xfer_resolution = 0x0; 207 break; 208 case SNDRV_PCM_FORMAT_S16_LE: 209 xfer_resolution = 0x02; 210 break; 211 case SNDRV_PCM_FORMAT_S24_LE: 212 xfer_resolution = 0x04; 213 break; 214 case SNDRV_PCM_FORMAT_S32_LE: 215 xfer_resolution = 0x05; 216 break; 217 default: 218 return -EINVAL; 219 } 220 221 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 222 switch (dai->driver->id) { 223 case I2S_BT_INSTANCE: 224 reg_val = ACP_BTTDM_ITER; 225 fmt_reg = ACP_BTTDM_TXFRMT; 226 break; 227 case I2S_SP_INSTANCE: 228 reg_val = ACP_I2STDM_ITER; 229 fmt_reg = ACP_I2STDM_TXFRMT; 230 break; 231 case I2S_HS_INSTANCE: 232 reg_val = ACP_HSTDM_ITER; 233 fmt_reg = ACP_HSTDM_TXFRMT; 234 break; 235 default: 236 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 237 return -EINVAL; 238 } 239 chip->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution; 240 } else { 241 switch (dai->driver->id) { 242 case I2S_BT_INSTANCE: 243 reg_val = ACP_BTTDM_IRER; 244 fmt_reg = ACP_BTTDM_RXFRMT; 245 break; 246 case I2S_SP_INSTANCE: 247 reg_val = ACP_I2STDM_IRER; 248 fmt_reg = ACP_I2STDM_RXFRMT; 249 break; 250 case I2S_HS_INSTANCE: 251 reg_val = ACP_HSTDM_IRER; 252 fmt_reg = ACP_HSTDM_RXFRMT; 253 break; 254 default: 255 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 256 return -EINVAL; 257 } 258 chip->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution; 259 } 260 261 val = readl(chip->base + reg_val); 262 val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK; 263 val = val | (xfer_resolution << 3); 264 writel(val, chip->base + reg_val); 265 266 if (chip->tdm_mode) { 267 val = readl(chip->base + reg_val); 268 writel(val | BIT(1), chip->base + reg_val); 269 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 270 tdm_fmt = chip->tdm_tx_fmt[dai->driver->id - 1]; 271 else 272 tdm_fmt = chip->tdm_rx_fmt[dai->driver->id - 1]; 273 writel(tdm_fmt, chip->base + fmt_reg); 274 } 275 276 if (rsrc->soc_mclk) { 277 switch (params_format(params)) { 278 case SNDRV_PCM_FORMAT_S16_LE: 279 switch (params_rate(params)) { 280 case 8000: 281 bclk_div_val = 768; 282 break; 283 case 16000: 284 bclk_div_val = 384; 285 break; 286 case 24000: 287 bclk_div_val = 256; 288 break; 289 case 32000: 290 bclk_div_val = 192; 291 break; 292 case 44100: 293 case 48000: 294 bclk_div_val = 128; 295 break; 296 case 88200: 297 case 96000: 298 bclk_div_val = 64; 299 break; 300 case 192000: 301 bclk_div_val = 32; 302 break; 303 default: 304 return -EINVAL; 305 } 306 lrclk_div_val = 32; 307 break; 308 case SNDRV_PCM_FORMAT_S32_LE: 309 switch (params_rate(params)) { 310 case 8000: 311 bclk_div_val = 384; 312 break; 313 case 16000: 314 bclk_div_val = 192; 315 break; 316 case 24000: 317 bclk_div_val = 128; 318 break; 319 case 32000: 320 bclk_div_val = 96; 321 break; 322 case 44100: 323 case 48000: 324 bclk_div_val = 64; 325 break; 326 case 88200: 327 case 96000: 328 bclk_div_val = 32; 329 break; 330 case 192000: 331 bclk_div_val = 16; 332 break; 333 default: 334 return -EINVAL; 335 } 336 lrclk_div_val = 64; 337 break; 338 default: 339 return -EINVAL; 340 } 341 342 switch (params_rate(params)) { 343 case 8000: 344 case 16000: 345 case 24000: 346 case 48000: 347 case 96000: 348 case 192000: 349 switch (params_channels(params)) { 350 case 2: 351 break; 352 case 4: 353 bclk_div_val = bclk_div_val >> 1; 354 lrclk_div_val = lrclk_div_val << 1; 355 break; 356 case 8: 357 bclk_div_val = bclk_div_val >> 2; 358 lrclk_div_val = lrclk_div_val << 2; 359 break; 360 case 16: 361 bclk_div_val = bclk_div_val >> 3; 362 lrclk_div_val = lrclk_div_val << 3; 363 break; 364 case 32: 365 bclk_div_val = bclk_div_val >> 4; 366 lrclk_div_val = lrclk_div_val << 4; 367 break; 368 default: 369 dev_err(dev, "Unsupported channels %#x\n", 370 params_channels(params)); 371 } 372 break; 373 default: 374 break; 375 } 376 chip->lrclk_div = lrclk_div_val; 377 chip->bclk_div = bclk_div_val; 378 } 379 return 0; 380 } 381 382 static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) 383 { 384 struct acp_stream *stream = substream->runtime->private_data; 385 struct device *dev = dai->component->dev; 386 struct acp_chip_info *chip = dev_get_platdata(dev); 387 struct acp_resource *rsrc = chip->rsrc; 388 u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg; 389 390 period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size); 391 buf_size = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); 392 393 switch (cmd) { 394 case SNDRV_PCM_TRIGGER_START: 395 case SNDRV_PCM_TRIGGER_RESUME: 396 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 397 stream->bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); 398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 399 switch (dai->driver->id) { 400 case I2S_BT_INSTANCE: 401 water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(chip); 402 reg_val = ACP_BTTDM_ITER; 403 ier_val = ACP_BTTDM_IER; 404 buf_reg = ACP_BT_TX_RINGBUFSIZE(chip); 405 break; 406 case I2S_SP_INSTANCE: 407 water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(chip); 408 reg_val = ACP_I2STDM_ITER; 409 ier_val = ACP_I2STDM_IER; 410 buf_reg = ACP_I2S_TX_RINGBUFSIZE(chip); 411 break; 412 case I2S_HS_INSTANCE: 413 water_val = ACP_HS_TX_INTR_WATERMARK_SIZE; 414 reg_val = ACP_HSTDM_ITER; 415 ier_val = ACP_HSTDM_IER; 416 buf_reg = ACP_HS_TX_RINGBUFSIZE; 417 break; 418 default: 419 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 420 return -EINVAL; 421 } 422 } else { 423 switch (dai->driver->id) { 424 case I2S_BT_INSTANCE: 425 water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(chip); 426 reg_val = ACP_BTTDM_IRER; 427 ier_val = ACP_BTTDM_IER; 428 buf_reg = ACP_BT_RX_RINGBUFSIZE(chip); 429 break; 430 case I2S_SP_INSTANCE: 431 water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(chip); 432 reg_val = ACP_I2STDM_IRER; 433 ier_val = ACP_I2STDM_IER; 434 buf_reg = ACP_I2S_RX_RINGBUFSIZE(chip); 435 break; 436 case I2S_HS_INSTANCE: 437 water_val = ACP_HS_RX_INTR_WATERMARK_SIZE; 438 reg_val = ACP_HSTDM_IRER; 439 ier_val = ACP_HSTDM_IER; 440 buf_reg = ACP_HS_RX_RINGBUFSIZE; 441 break; 442 default: 443 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 444 return -EINVAL; 445 } 446 } 447 448 writel(period_bytes, chip->base + water_val); 449 writel(buf_size, chip->base + buf_reg); 450 if (rsrc->soc_mclk) 451 acp_set_i2s_clk(chip, dai->driver->id); 452 val = readl(chip->base + reg_val); 453 val = val | BIT(0); 454 writel(val, chip->base + reg_val); 455 writel(1, chip->base + ier_val); 456 return 0; 457 case SNDRV_PCM_TRIGGER_STOP: 458 case SNDRV_PCM_TRIGGER_SUSPEND: 459 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 460 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 461 switch (dai->driver->id) { 462 case I2S_BT_INSTANCE: 463 reg_val = ACP_BTTDM_ITER; 464 break; 465 case I2S_SP_INSTANCE: 466 reg_val = ACP_I2STDM_ITER; 467 break; 468 case I2S_HS_INSTANCE: 469 reg_val = ACP_HSTDM_ITER; 470 break; 471 default: 472 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 473 return -EINVAL; 474 } 475 476 } else { 477 switch (dai->driver->id) { 478 case I2S_BT_INSTANCE: 479 reg_val = ACP_BTTDM_IRER; 480 break; 481 case I2S_SP_INSTANCE: 482 reg_val = ACP_I2STDM_IRER; 483 break; 484 case I2S_HS_INSTANCE: 485 reg_val = ACP_HSTDM_IRER; 486 break; 487 default: 488 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 489 return -EINVAL; 490 } 491 } 492 val = readl(chip->base + reg_val); 493 val = val & ~BIT(0); 494 writel(val, chip->base + reg_val); 495 496 if (!(readl(chip->base + ACP_BTTDM_ITER) & BIT(0)) && 497 !(readl(chip->base + ACP_BTTDM_IRER) & BIT(0))) 498 writel(0, chip->base + ACP_BTTDM_IER); 499 if (!(readl(chip->base + ACP_I2STDM_ITER) & BIT(0)) && 500 !(readl(chip->base + ACP_I2STDM_IRER) & BIT(0))) 501 writel(0, chip->base + ACP_I2STDM_IER); 502 if (!(readl(chip->base + ACP_HSTDM_ITER) & BIT(0)) && 503 !(readl(chip->base + ACP_HSTDM_IRER) & BIT(0))) 504 writel(0, chip->base + ACP_HSTDM_IER); 505 return 0; 506 default: 507 return -EINVAL; 508 } 509 510 return 0; 511 } 512 513 static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 514 { 515 struct device *dev = dai->component->dev; 516 struct acp_chip_info *chip = dev_get_platdata(dev); 517 struct acp_resource *rsrc = chip->rsrc; 518 struct acp_stream *stream = substream->runtime->private_data; 519 u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0; 520 u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl; 521 unsigned int dir = substream->stream; 522 523 chip = dev_get_platdata(dev); 524 switch (dai->driver->id) { 525 case I2S_SP_INSTANCE: 526 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 527 reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); 528 acp_fifo_addr = rsrc->sram_pte_offset + 529 SP_PB_FIFO_ADDR_OFFSET; 530 reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); 531 reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); 532 533 if (chip->acp_rev >= ACP70_PCI_ID) 534 phy_addr = ACP7x_I2S_SP_TX_MEM_WINDOW_START; 535 else 536 phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; 537 writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); 538 } else { 539 reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); 540 acp_fifo_addr = rsrc->sram_pte_offset + 541 SP_CAPT_FIFO_ADDR_OFFSET; 542 reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); 543 reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); 544 545 if (chip->acp_rev >= ACP70_PCI_ID) 546 phy_addr = ACP7x_I2S_SP_RX_MEM_WINDOW_START; 547 else 548 phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; 549 writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); 550 } 551 break; 552 case I2S_BT_INSTANCE: 553 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 554 reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); 555 acp_fifo_addr = rsrc->sram_pte_offset + 556 BT_PB_FIFO_ADDR_OFFSET; 557 reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); 558 reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); 559 560 if (chip->acp_rev >= ACP70_PCI_ID) 561 phy_addr = ACP7x_I2S_BT_TX_MEM_WINDOW_START; 562 else 563 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; 564 writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); 565 } else { 566 reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); 567 acp_fifo_addr = rsrc->sram_pte_offset + 568 BT_CAPT_FIFO_ADDR_OFFSET; 569 reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); 570 reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); 571 572 if (chip->acp_rev >= ACP70_PCI_ID) 573 phy_addr = ACP7x_I2S_BT_RX_MEM_WINDOW_START; 574 else 575 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; 576 writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); 577 } 578 break; 579 case I2S_HS_INSTANCE: 580 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 581 reg_dma_size = ACP_HS_TX_DMA_SIZE; 582 acp_fifo_addr = rsrc->sram_pte_offset + 583 HS_PB_FIFO_ADDR_OFFSET; 584 reg_fifo_addr = ACP_HS_TX_FIFOADDR; 585 reg_fifo_size = ACP_HS_TX_FIFOSIZE; 586 587 if (chip->acp_rev >= ACP70_PCI_ID) 588 phy_addr = ACP7x_I2S_HS_TX_MEM_WINDOW_START; 589 else 590 phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; 591 writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); 592 } else { 593 reg_dma_size = ACP_HS_RX_DMA_SIZE; 594 acp_fifo_addr = rsrc->sram_pte_offset + 595 HS_CAPT_FIFO_ADDR_OFFSET; 596 reg_fifo_addr = ACP_HS_RX_FIFOADDR; 597 reg_fifo_size = ACP_HS_RX_FIFOSIZE; 598 599 if (chip->acp_rev >= ACP70_PCI_ID) 600 phy_addr = ACP7x_I2S_HS_RX_MEM_WINDOW_START; 601 else 602 phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; 603 writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); 604 } 605 break; 606 default: 607 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 608 return -EINVAL; 609 } 610 611 writel(DMA_SIZE, chip->base + reg_dma_size); 612 writel(acp_fifo_addr, chip->base + reg_fifo_addr); 613 writel(FIFO_SIZE, chip->base + reg_fifo_size); 614 615 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); 616 ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | 617 BIT(BT_RX_THRESHOLD(rsrc->offset)) | 618 BIT(I2S_TX_THRESHOLD(rsrc->offset)) | 619 BIT(BT_TX_THRESHOLD(rsrc->offset)) | 620 BIT(HS_RX_THRESHOLD(rsrc->offset)) | 621 BIT(HS_TX_THRESHOLD(rsrc->offset)); 622 623 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); 624 625 return 0; 626 } 627 628 static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) 629 { 630 struct acp_stream *stream = substream->runtime->private_data; 631 struct device *dev = dai->component->dev; 632 struct acp_chip_info *chip = dev_get_platdata(dev); 633 struct acp_resource *rsrc = chip->rsrc; 634 unsigned int dir = substream->stream; 635 unsigned int irq_bit = 0; 636 637 switch (dai->driver->id) { 638 case I2S_SP_INSTANCE: 639 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 640 irq_bit = BIT(I2S_TX_THRESHOLD(rsrc->offset)); 641 stream->pte_offset = ACP_SRAM_SP_PB_PTE_OFFSET; 642 stream->fifo_offset = SP_PB_FIFO_ADDR_OFFSET; 643 } else { 644 irq_bit = BIT(I2S_RX_THRESHOLD(rsrc->offset)); 645 stream->pte_offset = ACP_SRAM_SP_CP_PTE_OFFSET; 646 stream->fifo_offset = SP_CAPT_FIFO_ADDR_OFFSET; 647 } 648 break; 649 case I2S_BT_INSTANCE: 650 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 651 irq_bit = BIT(BT_TX_THRESHOLD(rsrc->offset)); 652 stream->pte_offset = ACP_SRAM_BT_PB_PTE_OFFSET; 653 stream->fifo_offset = BT_PB_FIFO_ADDR_OFFSET; 654 } else { 655 irq_bit = BIT(BT_RX_THRESHOLD(rsrc->offset)); 656 stream->pte_offset = ACP_SRAM_BT_CP_PTE_OFFSET; 657 stream->fifo_offset = BT_CAPT_FIFO_ADDR_OFFSET; 658 } 659 break; 660 case I2S_HS_INSTANCE: 661 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 662 irq_bit = BIT(HS_TX_THRESHOLD(rsrc->offset)); 663 stream->pte_offset = ACP_SRAM_HS_PB_PTE_OFFSET; 664 stream->fifo_offset = HS_PB_FIFO_ADDR_OFFSET; 665 } else { 666 irq_bit = BIT(HS_RX_THRESHOLD(rsrc->offset)); 667 stream->pte_offset = ACP_SRAM_HS_CP_PTE_OFFSET; 668 stream->fifo_offset = HS_CAPT_FIFO_ADDR_OFFSET; 669 } 670 break; 671 default: 672 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 673 return -EINVAL; 674 } 675 676 /* Save runtime dai configuration in stream */ 677 stream->id = dai->driver->id + dir; 678 stream->dai_id = dai->driver->id; 679 stream->irq_bit = irq_bit; 680 stream->dir = substream->stream; 681 682 return 0; 683 } 684 685 const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops = { 686 .startup = acp_i2s_startup, 687 .hw_params = acp_i2s_hwparams, 688 .prepare = acp_i2s_prepare, 689 .trigger = acp_i2s_trigger, 690 .set_fmt = acp_i2s_set_fmt, 691 .set_tdm_slot = acp_i2s_set_tdm_slot, 692 }; 693 EXPORT_SYMBOL_NS_GPL(asoc_acp_cpu_dai_ops, "SND_SOC_ACP_COMMON"); 694 695 MODULE_DESCRIPTION("AMD ACP Audio I2S controller"); 696 MODULE_LICENSE("Dual BSD/GPL"); 697 MODULE_ALIAS(DRV_NAME); 698