1 // SPDX-License-Identifier: GPL-2.0+ 2 // 3 // AMD ALSA SoC PCM Driver 4 // 5 //Copyright 2016 Advanced Micro Devices, Inc. 6 7 #include <linux/platform_device.h> 8 #include <linux/module.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/pm_runtime.h> 12 #include <sound/pcm.h> 13 #include <sound/pcm_params.h> 14 #include <sound/soc.h> 15 #include <sound/soc-dai.h> 16 17 #include "acp3x.h" 18 19 #define DRV_NAME "acp3x-i2s-audio" 20 21 struct i2s_dev_data { 22 bool tdm_mode; 23 unsigned int i2s_irq; 24 u32 tdm_fmt; 25 void __iomem *acp3x_base; 26 struct snd_pcm_substream *play_stream; 27 struct snd_pcm_substream *capture_stream; 28 }; 29 30 struct i2s_stream_instance { 31 u16 num_pages; 32 u16 channels; 33 u32 xfer_resolution; 34 struct page *pg; 35 u64 bytescount; 36 void __iomem *acp3x_base; 37 }; 38 39 static const struct snd_pcm_hardware acp3x_pcm_hardware_playback = { 40 .info = SNDRV_PCM_INFO_INTERLEAVED | 41 SNDRV_PCM_INFO_BLOCK_TRANSFER | 42 SNDRV_PCM_INFO_BATCH | 43 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, 44 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 45 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | 46 SNDRV_PCM_FMTBIT_S32_LE, 47 .channels_min = 2, 48 .channels_max = 8, 49 .rates = SNDRV_PCM_RATE_8000_96000, 50 .rate_min = 8000, 51 .rate_max = 96000, 52 .buffer_bytes_max = PLAYBACK_MAX_NUM_PERIODS * PLAYBACK_MAX_PERIOD_SIZE, 53 .period_bytes_min = PLAYBACK_MIN_PERIOD_SIZE, 54 .period_bytes_max = PLAYBACK_MAX_PERIOD_SIZE, 55 .periods_min = PLAYBACK_MIN_NUM_PERIODS, 56 .periods_max = PLAYBACK_MAX_NUM_PERIODS, 57 }; 58 59 static const struct snd_pcm_hardware acp3x_pcm_hardware_capture = { 60 .info = SNDRV_PCM_INFO_INTERLEAVED | 61 SNDRV_PCM_INFO_BLOCK_TRANSFER | 62 SNDRV_PCM_INFO_BATCH | 63 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME, 64 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 65 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S24_LE | 66 SNDRV_PCM_FMTBIT_S32_LE, 67 .channels_min = 2, 68 .channels_max = 2, 69 .rates = SNDRV_PCM_RATE_8000_48000, 70 .rate_min = 8000, 71 .rate_max = 48000, 72 .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE, 73 .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE, 74 .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE, 75 .periods_min = CAPTURE_MIN_NUM_PERIODS, 76 .periods_max = CAPTURE_MAX_NUM_PERIODS, 77 }; 78 79 static int acp3x_power_on(void __iomem *acp3x_base, bool on) 80 { 81 u16 val, mask; 82 u32 timeout; 83 84 if (on == true) { 85 val = 1; 86 mask = ACP3x_POWER_ON; 87 } else { 88 val = 0; 89 mask = ACP3x_POWER_OFF; 90 } 91 92 rv_writel(val, acp3x_base + mmACP_PGFSM_CONTROL); 93 timeout = 0; 94 while (true) { 95 val = rv_readl(acp3x_base + mmACP_PGFSM_STATUS); 96 if ((val & ACP3x_POWER_OFF_IN_PROGRESS) == mask) 97 break; 98 if (timeout > 100) { 99 pr_err("ACP3x power state change failure\n"); 100 return -ENODEV; 101 } 102 timeout++; 103 cpu_relax(); 104 } 105 return 0; 106 } 107 108 static int acp3x_reset(void __iomem *acp3x_base) 109 { 110 u32 val, timeout; 111 112 rv_writel(1, acp3x_base + mmACP_SOFT_RESET); 113 timeout = 0; 114 while (true) { 115 val = rv_readl(acp3x_base + mmACP_SOFT_RESET); 116 if ((val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK) || 117 timeout > 100) { 118 if (val & ACP3x_SOFT_RESET__SoftResetAudDone_MASK) 119 break; 120 return -ENODEV; 121 } 122 timeout++; 123 cpu_relax(); 124 } 125 126 rv_writel(0, acp3x_base + mmACP_SOFT_RESET); 127 timeout = 0; 128 while (true) { 129 val = rv_readl(acp3x_base + mmACP_SOFT_RESET); 130 if (!val || timeout > 100) { 131 if (!val) 132 break; 133 return -ENODEV; 134 } 135 timeout++; 136 cpu_relax(); 137 } 138 return 0; 139 } 140 141 static int acp3x_init(void __iomem *acp3x_base) 142 { 143 int ret; 144 145 /* power on */ 146 ret = acp3x_power_on(acp3x_base, true); 147 if (ret) { 148 pr_err("ACP3x power on failed\n"); 149 return ret; 150 } 151 /* Reset */ 152 ret = acp3x_reset(acp3x_base); 153 if (ret) { 154 pr_err("ACP3x reset failed\n"); 155 return ret; 156 } 157 return 0; 158 } 159 160 static int acp3x_deinit(void __iomem *acp3x_base) 161 { 162 int ret; 163 164 /* Reset */ 165 ret = acp3x_reset(acp3x_base); 166 if (ret) { 167 pr_err("ACP3x reset failed\n"); 168 return ret; 169 } 170 /* power off */ 171 ret = acp3x_power_on(acp3x_base, false); 172 if (ret) { 173 pr_err("ACP3x power off failed\n"); 174 return ret; 175 } 176 return 0; 177 } 178 179 static irqreturn_t i2s_irq_handler(int irq, void *dev_id) 180 { 181 u16 play_flag, cap_flag; 182 u32 val; 183 struct i2s_dev_data *rv_i2s_data = dev_id; 184 185 if (!rv_i2s_data) 186 return IRQ_NONE; 187 188 play_flag = 0; 189 cap_flag = 0; 190 val = rv_readl(rv_i2s_data->acp3x_base + mmACP_EXTERNAL_INTR_STAT); 191 if ((val & BIT(BT_TX_THRESHOLD)) && rv_i2s_data->play_stream) { 192 rv_writel(BIT(BT_TX_THRESHOLD), rv_i2s_data->acp3x_base + 193 mmACP_EXTERNAL_INTR_STAT); 194 snd_pcm_period_elapsed(rv_i2s_data->play_stream); 195 play_flag = 1; 196 } 197 198 if ((val & BIT(BT_RX_THRESHOLD)) && rv_i2s_data->capture_stream) { 199 rv_writel(BIT(BT_RX_THRESHOLD), rv_i2s_data->acp3x_base + 200 mmACP_EXTERNAL_INTR_STAT); 201 snd_pcm_period_elapsed(rv_i2s_data->capture_stream); 202 cap_flag = 1; 203 } 204 205 if (play_flag | cap_flag) 206 return IRQ_HANDLED; 207 else 208 return IRQ_NONE; 209 } 210 211 static void config_acp3x_dma(struct i2s_stream_instance *rtd, int direction) 212 { 213 u16 page_idx; 214 u64 addr; 215 u32 low, high, val, acp_fifo_addr; 216 struct page *pg = rtd->pg; 217 218 /* 8 scratch registers used to map one 64 bit address */ 219 if (direction == SNDRV_PCM_STREAM_PLAYBACK) 220 val = 0; 221 else 222 val = rtd->num_pages * 8; 223 224 /* Group Enable */ 225 rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base + 226 mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1); 227 rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base + 228 mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); 229 230 for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) { 231 /* Load the low address of page int ACP SRAM through SRBM */ 232 addr = page_to_phys(pg); 233 low = lower_32_bits(addr); 234 high = upper_32_bits(addr); 235 236 rv_writel(low, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val); 237 high |= BIT(31); 238 rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val 239 + 4); 240 /* Move to next physically contiguos page */ 241 val += 8; 242 pg++; 243 } 244 245 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 246 /* Config ringbuffer */ 247 rv_writel(MEM_WINDOW_START, rtd->acp3x_base + 248 mmACP_BT_TX_RINGBUFADDR); 249 rv_writel(MAX_BUFFER, rtd->acp3x_base + 250 mmACP_BT_TX_RINGBUFSIZE); 251 rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_TX_DMA_SIZE); 252 253 /* Config audio fifo */ 254 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + (rtd->num_pages * 8) 255 + PLAYBACK_FIFO_ADDR_OFFSET; 256 rv_writel(acp_fifo_addr, rtd->acp3x_base + 257 mmACP_BT_TX_FIFOADDR); 258 rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_TX_FIFOSIZE); 259 } else { 260 /* Config ringbuffer */ 261 rv_writel(MEM_WINDOW_START + MAX_BUFFER, rtd->acp3x_base + 262 mmACP_BT_RX_RINGBUFADDR); 263 rv_writel(MAX_BUFFER, rtd->acp3x_base + 264 mmACP_BT_RX_RINGBUFSIZE); 265 rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_RX_DMA_SIZE); 266 267 /* Config audio fifo */ 268 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + 269 (rtd->num_pages * 8) + CAPTURE_FIFO_ADDR_OFFSET; 270 rv_writel(acp_fifo_addr, rtd->acp3x_base + 271 mmACP_BT_RX_FIFOADDR); 272 rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_RX_FIFOSIZE); 273 } 274 275 /* Enable watermark/period interrupt to host */ 276 rv_writel(BIT(BT_TX_THRESHOLD) | BIT(BT_RX_THRESHOLD), 277 rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL); 278 } 279 280 static int acp3x_dma_open(struct snd_pcm_substream *substream) 281 { 282 int ret = 0; 283 284 struct snd_pcm_runtime *runtime = substream->runtime; 285 struct snd_soc_pcm_runtime *prtd = substream->private_data; 286 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, 287 DRV_NAME); 288 struct i2s_dev_data *adata = dev_get_drvdata(component->dev); 289 290 struct i2s_stream_instance *i2s_data = kzalloc(sizeof(struct i2s_stream_instance), 291 GFP_KERNEL); 292 if (!i2s_data) 293 return -EINVAL; 294 295 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 296 runtime->hw = acp3x_pcm_hardware_playback; 297 else 298 runtime->hw = acp3x_pcm_hardware_capture; 299 300 ret = snd_pcm_hw_constraint_integer(runtime, 301 SNDRV_PCM_HW_PARAM_PERIODS); 302 if (ret < 0) { 303 dev_err(component->dev, "set integer constraint failed\n"); 304 kfree(i2s_data); 305 return ret; 306 } 307 308 if (!adata->play_stream && !adata->capture_stream) 309 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 310 311 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 312 adata->play_stream = substream; 313 else 314 adata->capture_stream = substream; 315 316 i2s_data->acp3x_base = adata->acp3x_base; 317 runtime->private_data = i2s_data; 318 return 0; 319 } 320 321 static u64 acp_get_byte_count(struct i2s_stream_instance *rtd, int direction) 322 { 323 u64 byte_count; 324 325 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 326 byte_count = rv_readl(rtd->acp3x_base + 327 mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH); 328 byte_count |= rv_readl(rtd->acp3x_base + 329 mmACP_BT_TX_LINEARPOSITIONCNTR_LOW); 330 } else { 331 byte_count = rv_readl(rtd->acp3x_base + 332 mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH); 333 byte_count |= rv_readl(rtd->acp3x_base + 334 mmACP_BT_RX_LINEARPOSITIONCNTR_LOW); 335 } 336 return byte_count; 337 } 338 339 static int acp3x_dma_hw_params(struct snd_pcm_substream *substream, 340 struct snd_pcm_hw_params *params) 341 { 342 int status; 343 u64 size; 344 struct page *pg; 345 struct snd_pcm_runtime *runtime = substream->runtime; 346 struct i2s_stream_instance *rtd = runtime->private_data; 347 348 if (!rtd) 349 return -EINVAL; 350 351 size = params_buffer_bytes(params); 352 status = snd_pcm_lib_malloc_pages(substream, size); 353 if (status < 0) 354 return status; 355 356 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); 357 pg = virt_to_page(substream->dma_buffer.area); 358 if (pg) { 359 rtd->pg = pg; 360 rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); 361 config_acp3x_dma(rtd, substream->stream); 362 status = 0; 363 } else { 364 status = -ENOMEM; 365 } 366 return status; 367 } 368 369 static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream) 370 { 371 u32 pos = 0; 372 u32 buffersize = 0; 373 u64 bytescount = 0; 374 struct i2s_stream_instance *rtd = 375 substream->runtime->private_data; 376 377 buffersize = frames_to_bytes(substream->runtime, 378 substream->runtime->buffer_size); 379 bytescount = acp_get_byte_count(rtd, substream->stream); 380 if (bytescount > rtd->bytescount) 381 bytescount -= rtd->bytescount; 382 pos = do_div(bytescount, buffersize); 383 return bytes_to_frames(substream->runtime, pos); 384 } 385 386 static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd) 387 { 388 snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, 389 rtd->pcm->card->dev, 390 MIN_BUFFER, MAX_BUFFER); 391 return 0; 392 } 393 394 static int acp3x_dma_hw_free(struct snd_pcm_substream *substream) 395 { 396 return snd_pcm_lib_free_pages(substream); 397 } 398 399 static int acp3x_dma_mmap(struct snd_pcm_substream *substream, 400 struct vm_area_struct *vma) 401 { 402 return snd_pcm_lib_default_mmap(substream, vma); 403 } 404 405 static int acp3x_dma_close(struct snd_pcm_substream *substream) 406 { 407 struct snd_soc_pcm_runtime *prtd = substream->private_data; 408 struct i2s_stream_instance *rtd = substream->runtime->private_data; 409 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, 410 DRV_NAME); 411 struct i2s_dev_data *adata = dev_get_drvdata(component->dev); 412 413 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 414 adata->play_stream = NULL; 415 else 416 adata->capture_stream = NULL; 417 418 /* Disable ACP irq, when the current stream is being closed and 419 * another stream is also not active. 420 */ 421 if (!adata->play_stream && !adata->capture_stream) 422 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 423 kfree(rtd); 424 return 0; 425 } 426 427 static struct snd_pcm_ops acp3x_dma_ops = { 428 .open = acp3x_dma_open, 429 .close = acp3x_dma_close, 430 .ioctl = snd_pcm_lib_ioctl, 431 .hw_params = acp3x_dma_hw_params, 432 .hw_free = acp3x_dma_hw_free, 433 .pointer = acp3x_dma_pointer, 434 .mmap = acp3x_dma_mmap, 435 }; 436 437 438 static int acp3x_dai_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 439 { 440 441 struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); 442 443 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 444 case SND_SOC_DAIFMT_I2S: 445 adata->tdm_mode = false; 446 break; 447 case SND_SOC_DAIFMT_DSP_A: 448 adata->tdm_mode = true; 449 break; 450 default: 451 return -EINVAL; 452 } 453 454 return 0; 455 } 456 457 static int acp3x_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, 458 u32 rx_mask, int slots, int slot_width) 459 { 460 u32 val = 0; 461 u16 slot_len; 462 463 struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); 464 465 switch (slot_width) { 466 case SLOT_WIDTH_8: 467 slot_len = 8; 468 break; 469 case SLOT_WIDTH_16: 470 slot_len = 16; 471 break; 472 case SLOT_WIDTH_24: 473 slot_len = 24; 474 break; 475 case SLOT_WIDTH_32: 476 slot_len = 0; 477 break; 478 default: 479 return -EINVAL; 480 } 481 482 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); 483 rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_ITER); 484 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); 485 rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_IRER); 486 487 val = (FRM_LEN | (slots << 15) | (slot_len << 18)); 488 rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT); 489 rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT); 490 491 adata->tdm_fmt = val; 492 return 0; 493 } 494 495 static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream, 496 struct snd_pcm_hw_params *params, 497 struct snd_soc_dai *dai) 498 { 499 u32 val = 0; 500 struct i2s_stream_instance *rtd = substream->runtime->private_data; 501 502 switch (params_format(params)) { 503 case SNDRV_PCM_FORMAT_U8: 504 case SNDRV_PCM_FORMAT_S8: 505 rtd->xfer_resolution = 0x0; 506 break; 507 case SNDRV_PCM_FORMAT_S16_LE: 508 rtd->xfer_resolution = 0x02; 509 break; 510 case SNDRV_PCM_FORMAT_S24_LE: 511 rtd->xfer_resolution = 0x04; 512 break; 513 case SNDRV_PCM_FORMAT_S32_LE: 514 rtd->xfer_resolution = 0x05; 515 break; 516 default: 517 return -EINVAL; 518 } 519 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); 520 val = val | (rtd->xfer_resolution << 3); 521 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 522 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); 523 else 524 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); 525 526 return 0; 527 } 528 529 static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream, 530 int cmd, struct snd_soc_dai *dai) 531 { 532 int ret = 0; 533 struct i2s_stream_instance *rtd = substream->runtime->private_data; 534 u32 val, period_bytes; 535 536 period_bytes = frames_to_bytes(substream->runtime, 537 substream->runtime->period_size); 538 switch (cmd) { 539 case SNDRV_PCM_TRIGGER_START: 540 case SNDRV_PCM_TRIGGER_RESUME: 541 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 542 rtd->bytescount = acp_get_byte_count(rtd, substream->stream); 543 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 544 rv_writel(period_bytes, rtd->acp3x_base + 545 mmACP_BT_TX_INTR_WATERMARK_SIZE); 546 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); 547 val = val | BIT(0); 548 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); 549 } else { 550 rv_writel(period_bytes, rtd->acp3x_base + 551 mmACP_BT_RX_INTR_WATERMARK_SIZE); 552 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER); 553 val = val | BIT(0); 554 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); 555 } 556 rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER); 557 break; 558 case SNDRV_PCM_TRIGGER_STOP: 559 case SNDRV_PCM_TRIGGER_SUSPEND: 560 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 561 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 562 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); 563 val = val & ~BIT(0); 564 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); 565 } else { 566 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER); 567 val = val & ~BIT(0); 568 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); 569 } 570 rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER); 571 break; 572 default: 573 ret = -EINVAL; 574 break; 575 } 576 577 return ret; 578 } 579 580 static struct snd_soc_dai_ops acp3x_dai_i2s_ops = { 581 .hw_params = acp3x_dai_i2s_hwparams, 582 .trigger = acp3x_dai_i2s_trigger, 583 .set_fmt = acp3x_dai_i2s_set_fmt, 584 .set_tdm_slot = acp3x_dai_set_tdm_slot, 585 }; 586 587 static struct snd_soc_dai_driver acp3x_i2s_dai_driver = { 588 .playback = { 589 .rates = SNDRV_PCM_RATE_8000_96000, 590 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 591 SNDRV_PCM_FMTBIT_U8 | 592 SNDRV_PCM_FMTBIT_S24_LE | 593 SNDRV_PCM_FMTBIT_S32_LE, 594 .channels_min = 2, 595 .channels_max = 8, 596 597 .rate_min = 8000, 598 .rate_max = 96000, 599 }, 600 .capture = { 601 .rates = SNDRV_PCM_RATE_8000_48000, 602 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 603 SNDRV_PCM_FMTBIT_U8 | 604 SNDRV_PCM_FMTBIT_S24_LE | 605 SNDRV_PCM_FMTBIT_S32_LE, 606 .channels_min = 2, 607 .channels_max = 2, 608 .rate_min = 8000, 609 .rate_max = 48000, 610 }, 611 .ops = &acp3x_dai_i2s_ops, 612 }; 613 614 static const struct snd_soc_component_driver acp3x_i2s_component = { 615 .name = DRV_NAME, 616 .ops = &acp3x_dma_ops, 617 .pcm_new = acp3x_dma_new, 618 }; 619 620 static int acp3x_audio_probe(struct platform_device *pdev) 621 { 622 int status; 623 struct resource *res; 624 struct i2s_dev_data *adata; 625 unsigned int irqflags; 626 627 if (!pdev->dev.platform_data) { 628 dev_err(&pdev->dev, "platform_data not retrieved\n"); 629 return -ENODEV; 630 } 631 irqflags = *((unsigned int *)(pdev->dev.platform_data)); 632 633 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 634 if (!res) { 635 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); 636 return -ENODEV; 637 } 638 639 adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL); 640 if (!adata) 641 return -ENOMEM; 642 643 adata->acp3x_base = devm_ioremap(&pdev->dev, res->start, 644 resource_size(res)); 645 646 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 647 if (!res) { 648 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); 649 return -ENODEV; 650 } 651 652 adata->i2s_irq = res->start; 653 adata->play_stream = NULL; 654 adata->capture_stream = NULL; 655 656 dev_set_drvdata(&pdev->dev, adata); 657 /* Initialize ACP */ 658 status = acp3x_init(adata->acp3x_base); 659 if (status) 660 return -ENODEV; 661 status = devm_snd_soc_register_component(&pdev->dev, 662 &acp3x_i2s_component, 663 &acp3x_i2s_dai_driver, 1); 664 if (status) { 665 dev_err(&pdev->dev, "Fail to register acp i2s dai\n"); 666 goto dev_err; 667 } 668 status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler, 669 irqflags, "ACP3x_I2S_IRQ", adata); 670 if (status) { 671 dev_err(&pdev->dev, "ACP3x I2S IRQ request failed\n"); 672 goto dev_err; 673 } 674 675 pm_runtime_set_autosuspend_delay(&pdev->dev, 10000); 676 pm_runtime_use_autosuspend(&pdev->dev); 677 pm_runtime_enable(&pdev->dev); 678 return 0; 679 dev_err: 680 status = acp3x_deinit(adata->acp3x_base); 681 if (status) 682 dev_err(&pdev->dev, "ACP de-init failed\n"); 683 else 684 dev_info(&pdev->dev, "ACP de-initialized\n"); 685 /*ignore device status and return driver probe error*/ 686 return -ENODEV; 687 } 688 689 static int acp3x_audio_remove(struct platform_device *pdev) 690 { 691 int ret; 692 struct i2s_dev_data *adata = dev_get_drvdata(&pdev->dev); 693 694 ret = acp3x_deinit(adata->acp3x_base); 695 if (ret) 696 dev_err(&pdev->dev, "ACP de-init failed\n"); 697 else 698 dev_info(&pdev->dev, "ACP de-initialized\n"); 699 700 pm_runtime_disable(&pdev->dev); 701 return 0; 702 } 703 704 static int acp3x_resume(struct device *dev) 705 { 706 int status; 707 u32 val; 708 struct i2s_dev_data *adata = dev_get_drvdata(dev); 709 710 status = acp3x_init(adata->acp3x_base); 711 if (status) 712 return -ENODEV; 713 714 if (adata->play_stream && adata->play_stream->runtime) { 715 struct i2s_stream_instance *rtd = 716 adata->play_stream->runtime->private_data; 717 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK); 718 rv_writel((rtd->xfer_resolution << 3), 719 rtd->acp3x_base + mmACP_BTTDM_ITER); 720 if (adata->tdm_mode == true) { 721 rv_writel(adata->tdm_fmt, adata->acp3x_base + 722 mmACP_BTTDM_TXFRMT); 723 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); 724 rv_writel((val | 0x2), adata->acp3x_base + 725 mmACP_BTTDM_ITER); 726 } 727 } 728 729 if (adata->capture_stream && adata->capture_stream->runtime) { 730 struct i2s_stream_instance *rtd = 731 adata->capture_stream->runtime->private_data; 732 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE); 733 rv_writel((rtd->xfer_resolution << 3), 734 rtd->acp3x_base + mmACP_BTTDM_IRER); 735 if (adata->tdm_mode == true) { 736 rv_writel(adata->tdm_fmt, adata->acp3x_base + 737 mmACP_BTTDM_RXFRMT); 738 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); 739 rv_writel((val | 0x2), adata->acp3x_base + 740 mmACP_BTTDM_IRER); 741 } 742 } 743 744 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 745 return 0; 746 } 747 748 749 static int acp3x_pcm_runtime_suspend(struct device *dev) 750 { 751 int status; 752 struct i2s_dev_data *adata = dev_get_drvdata(dev); 753 754 status = acp3x_deinit(adata->acp3x_base); 755 if (status) 756 dev_err(dev, "ACP de-init failed\n"); 757 else 758 dev_info(dev, "ACP de-initialized\n"); 759 760 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 761 762 return 0; 763 } 764 765 static int acp3x_pcm_runtime_resume(struct device *dev) 766 { 767 int status; 768 struct i2s_dev_data *adata = dev_get_drvdata(dev); 769 770 status = acp3x_init(adata->acp3x_base); 771 if (status) 772 return -ENODEV; 773 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 774 return 0; 775 } 776 777 static const struct dev_pm_ops acp3x_pm_ops = { 778 .runtime_suspend = acp3x_pcm_runtime_suspend, 779 .runtime_resume = acp3x_pcm_runtime_resume, 780 .resume = acp3x_resume, 781 }; 782 783 static struct platform_driver acp3x_dma_driver = { 784 .probe = acp3x_audio_probe, 785 .remove = acp3x_audio_remove, 786 .driver = { 787 .name = "acp3x_rv_i2s", 788 .pm = &acp3x_pm_ops, 789 }, 790 }; 791 792 module_platform_driver(acp3x_dma_driver); 793 794 MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com"); 795 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 796 MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver"); 797 MODULE_LICENSE("GPL v2"); 798 MODULE_ALIAS("platform:" DRV_NAME); 799