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 u64 bytescount; 35 dma_addr_t dma_addr; 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 u32 low, high, val, acp_fifo_addr; 215 dma_addr_t addr = rtd->dma_addr; 216 217 /* 8 scratch registers used to map one 64 bit address */ 218 if (direction == SNDRV_PCM_STREAM_PLAYBACK) 219 val = 0; 220 else 221 val = rtd->num_pages * 8; 222 223 /* Group Enable */ 224 rv_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp3x_base + 225 mmACPAXI2AXI_ATU_BASE_ADDR_GRP_1); 226 rv_writel(PAGE_SIZE_4K_ENABLE, rtd->acp3x_base + 227 mmACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); 228 229 for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) { 230 /* Load the low address of page int ACP SRAM through SRBM */ 231 low = lower_32_bits(addr); 232 high = upper_32_bits(addr); 233 234 rv_writel(low, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val); 235 high |= BIT(31); 236 rv_writel(high, rtd->acp3x_base + mmACP_SCRATCH_REG_0 + val 237 + 4); 238 /* Move to next physically contiguos page */ 239 val += 8; 240 addr += PAGE_SIZE; 241 } 242 243 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 244 /* Config ringbuffer */ 245 rv_writel(MEM_WINDOW_START, rtd->acp3x_base + 246 mmACP_BT_TX_RINGBUFADDR); 247 rv_writel(MAX_BUFFER, rtd->acp3x_base + 248 mmACP_BT_TX_RINGBUFSIZE); 249 rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_TX_DMA_SIZE); 250 251 /* Config audio fifo */ 252 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + (rtd->num_pages * 8) 253 + PLAYBACK_FIFO_ADDR_OFFSET; 254 rv_writel(acp_fifo_addr, rtd->acp3x_base + 255 mmACP_BT_TX_FIFOADDR); 256 rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_TX_FIFOSIZE); 257 } else { 258 /* Config ringbuffer */ 259 rv_writel(MEM_WINDOW_START + MAX_BUFFER, rtd->acp3x_base + 260 mmACP_BT_RX_RINGBUFADDR); 261 rv_writel(MAX_BUFFER, rtd->acp3x_base + 262 mmACP_BT_RX_RINGBUFSIZE); 263 rv_writel(DMA_SIZE, rtd->acp3x_base + mmACP_BT_RX_DMA_SIZE); 264 265 /* Config audio fifo */ 266 acp_fifo_addr = ACP_SRAM_PTE_OFFSET + 267 (rtd->num_pages * 8) + CAPTURE_FIFO_ADDR_OFFSET; 268 rv_writel(acp_fifo_addr, rtd->acp3x_base + 269 mmACP_BT_RX_FIFOADDR); 270 rv_writel(FIFO_SIZE, rtd->acp3x_base + mmACP_BT_RX_FIFOSIZE); 271 } 272 273 /* Enable watermark/period interrupt to host */ 274 rv_writel(BIT(BT_TX_THRESHOLD) | BIT(BT_RX_THRESHOLD), 275 rtd->acp3x_base + mmACP_EXTERNAL_INTR_CNTL); 276 } 277 278 static int acp3x_dma_open(struct snd_pcm_substream *substream) 279 { 280 int ret = 0; 281 282 struct snd_pcm_runtime *runtime = substream->runtime; 283 struct snd_soc_pcm_runtime *prtd = substream->private_data; 284 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, 285 DRV_NAME); 286 struct i2s_dev_data *adata = dev_get_drvdata(component->dev); 287 288 struct i2s_stream_instance *i2s_data = kzalloc(sizeof(struct i2s_stream_instance), 289 GFP_KERNEL); 290 if (!i2s_data) 291 return -EINVAL; 292 293 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 294 runtime->hw = acp3x_pcm_hardware_playback; 295 else 296 runtime->hw = acp3x_pcm_hardware_capture; 297 298 ret = snd_pcm_hw_constraint_integer(runtime, 299 SNDRV_PCM_HW_PARAM_PERIODS); 300 if (ret < 0) { 301 dev_err(component->dev, "set integer constraint failed\n"); 302 kfree(i2s_data); 303 return ret; 304 } 305 306 if (!adata->play_stream && !adata->capture_stream) 307 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 308 309 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 310 adata->play_stream = substream; 311 else 312 adata->capture_stream = substream; 313 314 i2s_data->acp3x_base = adata->acp3x_base; 315 runtime->private_data = i2s_data; 316 return 0; 317 } 318 319 static u64 acp_get_byte_count(struct i2s_stream_instance *rtd, int direction) 320 { 321 u64 byte_count; 322 323 if (direction == SNDRV_PCM_STREAM_PLAYBACK) { 324 byte_count = rv_readl(rtd->acp3x_base + 325 mmACP_BT_TX_LINEARPOSITIONCNTR_HIGH); 326 byte_count |= rv_readl(rtd->acp3x_base + 327 mmACP_BT_TX_LINEARPOSITIONCNTR_LOW); 328 } else { 329 byte_count = rv_readl(rtd->acp3x_base + 330 mmACP_BT_RX_LINEARPOSITIONCNTR_HIGH); 331 byte_count |= rv_readl(rtd->acp3x_base + 332 mmACP_BT_RX_LINEARPOSITIONCNTR_LOW); 333 } 334 return byte_count; 335 } 336 337 static int acp3x_dma_hw_params(struct snd_pcm_substream *substream, 338 struct snd_pcm_hw_params *params) 339 { 340 int status; 341 u64 size; 342 struct snd_pcm_runtime *runtime = substream->runtime; 343 struct i2s_stream_instance *rtd = runtime->private_data; 344 345 if (!rtd) 346 return -EINVAL; 347 348 size = params_buffer_bytes(params); 349 status = snd_pcm_lib_malloc_pages(substream, size); 350 if (status < 0) 351 return status; 352 353 memset(substream->runtime->dma_area, 0, params_buffer_bytes(params)); 354 if (substream->dma_buffer.area) { 355 rtd->dma_addr = substream->dma_buffer.addr; 356 rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); 357 config_acp3x_dma(rtd, substream->stream); 358 status = 0; 359 } else { 360 status = -ENOMEM; 361 } 362 return status; 363 } 364 365 static snd_pcm_uframes_t acp3x_dma_pointer(struct snd_pcm_substream *substream) 366 { 367 u32 pos = 0; 368 u32 buffersize = 0; 369 u64 bytescount = 0; 370 struct i2s_stream_instance *rtd = 371 substream->runtime->private_data; 372 373 buffersize = frames_to_bytes(substream->runtime, 374 substream->runtime->buffer_size); 375 bytescount = acp_get_byte_count(rtd, substream->stream); 376 if (bytescount > rtd->bytescount) 377 bytescount -= rtd->bytescount; 378 pos = do_div(bytescount, buffersize); 379 return bytes_to_frames(substream->runtime, pos); 380 } 381 382 static int acp3x_dma_new(struct snd_soc_pcm_runtime *rtd) 383 { 384 struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, 385 DRV_NAME); 386 struct device *parent = component->dev->parent; 387 snd_pcm_lib_preallocate_pages_for_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, 388 parent, MIN_BUFFER, MAX_BUFFER); 389 return 0; 390 } 391 392 static int acp3x_dma_hw_free(struct snd_pcm_substream *substream) 393 { 394 return snd_pcm_lib_free_pages(substream); 395 } 396 397 static int acp3x_dma_mmap(struct snd_pcm_substream *substream, 398 struct vm_area_struct *vma) 399 { 400 return snd_pcm_lib_default_mmap(substream, vma); 401 } 402 403 static int acp3x_dma_close(struct snd_pcm_substream *substream) 404 { 405 struct snd_soc_pcm_runtime *prtd = substream->private_data; 406 struct i2s_stream_instance *rtd = substream->runtime->private_data; 407 struct snd_soc_component *component = snd_soc_rtdcom_lookup(prtd, 408 DRV_NAME); 409 struct i2s_dev_data *adata = dev_get_drvdata(component->dev); 410 411 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 412 adata->play_stream = NULL; 413 else 414 adata->capture_stream = NULL; 415 416 /* Disable ACP irq, when the current stream is being closed and 417 * another stream is also not active. 418 */ 419 if (!adata->play_stream && !adata->capture_stream) 420 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 421 kfree(rtd); 422 return 0; 423 } 424 425 static struct snd_pcm_ops acp3x_dma_ops = { 426 .open = acp3x_dma_open, 427 .close = acp3x_dma_close, 428 .ioctl = snd_pcm_lib_ioctl, 429 .hw_params = acp3x_dma_hw_params, 430 .hw_free = acp3x_dma_hw_free, 431 .pointer = acp3x_dma_pointer, 432 .mmap = acp3x_dma_mmap, 433 }; 434 435 436 static int acp3x_dai_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) 437 { 438 439 struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); 440 441 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 442 case SND_SOC_DAIFMT_I2S: 443 adata->tdm_mode = false; 444 break; 445 case SND_SOC_DAIFMT_DSP_A: 446 adata->tdm_mode = true; 447 break; 448 default: 449 return -EINVAL; 450 } 451 452 return 0; 453 } 454 455 static int acp3x_dai_set_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, 456 u32 rx_mask, int slots, int slot_width) 457 { 458 u32 val = 0; 459 u16 slot_len; 460 461 struct i2s_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai); 462 463 switch (slot_width) { 464 case SLOT_WIDTH_8: 465 slot_len = 8; 466 break; 467 case SLOT_WIDTH_16: 468 slot_len = 16; 469 break; 470 case SLOT_WIDTH_24: 471 slot_len = 24; 472 break; 473 case SLOT_WIDTH_32: 474 slot_len = 0; 475 break; 476 default: 477 return -EINVAL; 478 } 479 480 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); 481 rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_ITER); 482 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); 483 rv_writel((val | 0x2), adata->acp3x_base + mmACP_BTTDM_IRER); 484 485 val = (FRM_LEN | (slots << 15) | (slot_len << 18)); 486 rv_writel(val, adata->acp3x_base + mmACP_BTTDM_TXFRMT); 487 rv_writel(val, adata->acp3x_base + mmACP_BTTDM_RXFRMT); 488 489 adata->tdm_fmt = val; 490 return 0; 491 } 492 493 static int acp3x_dai_i2s_hwparams(struct snd_pcm_substream *substream, 494 struct snd_pcm_hw_params *params, 495 struct snd_soc_dai *dai) 496 { 497 u32 val = 0; 498 struct i2s_stream_instance *rtd = substream->runtime->private_data; 499 500 switch (params_format(params)) { 501 case SNDRV_PCM_FORMAT_U8: 502 case SNDRV_PCM_FORMAT_S8: 503 rtd->xfer_resolution = 0x0; 504 break; 505 case SNDRV_PCM_FORMAT_S16_LE: 506 rtd->xfer_resolution = 0x02; 507 break; 508 case SNDRV_PCM_FORMAT_S24_LE: 509 rtd->xfer_resolution = 0x04; 510 break; 511 case SNDRV_PCM_FORMAT_S32_LE: 512 rtd->xfer_resolution = 0x05; 513 break; 514 default: 515 return -EINVAL; 516 } 517 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); 518 val = val | (rtd->xfer_resolution << 3); 519 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 520 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); 521 else 522 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); 523 524 return 0; 525 } 526 527 static int acp3x_dai_i2s_trigger(struct snd_pcm_substream *substream, 528 int cmd, struct snd_soc_dai *dai) 529 { 530 int ret = 0; 531 struct i2s_stream_instance *rtd = substream->runtime->private_data; 532 u32 val, period_bytes; 533 534 period_bytes = frames_to_bytes(substream->runtime, 535 substream->runtime->period_size); 536 switch (cmd) { 537 case SNDRV_PCM_TRIGGER_START: 538 case SNDRV_PCM_TRIGGER_RESUME: 539 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 540 rtd->bytescount = acp_get_byte_count(rtd, substream->stream); 541 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 542 rv_writel(period_bytes, rtd->acp3x_base + 543 mmACP_BT_TX_INTR_WATERMARK_SIZE); 544 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); 545 val = val | BIT(0); 546 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); 547 } else { 548 rv_writel(period_bytes, rtd->acp3x_base + 549 mmACP_BT_RX_INTR_WATERMARK_SIZE); 550 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER); 551 val = val | BIT(0); 552 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); 553 } 554 rv_writel(1, rtd->acp3x_base + mmACP_BTTDM_IER); 555 break; 556 case SNDRV_PCM_TRIGGER_STOP: 557 case SNDRV_PCM_TRIGGER_SUSPEND: 558 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 559 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 560 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER); 561 val = val & ~BIT(0); 562 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_ITER); 563 } else { 564 val = rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER); 565 val = val & ~BIT(0); 566 rv_writel(val, rtd->acp3x_base + mmACP_BTTDM_IRER); 567 } 568 rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER); 569 break; 570 default: 571 ret = -EINVAL; 572 break; 573 } 574 575 return ret; 576 } 577 578 static struct snd_soc_dai_ops acp3x_dai_i2s_ops = { 579 .hw_params = acp3x_dai_i2s_hwparams, 580 .trigger = acp3x_dai_i2s_trigger, 581 .set_fmt = acp3x_dai_i2s_set_fmt, 582 .set_tdm_slot = acp3x_dai_set_tdm_slot, 583 }; 584 585 static struct snd_soc_dai_driver acp3x_i2s_dai_driver = { 586 .playback = { 587 .rates = SNDRV_PCM_RATE_8000_96000, 588 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 589 SNDRV_PCM_FMTBIT_U8 | 590 SNDRV_PCM_FMTBIT_S24_LE | 591 SNDRV_PCM_FMTBIT_S32_LE, 592 .channels_min = 2, 593 .channels_max = 8, 594 595 .rate_min = 8000, 596 .rate_max = 96000, 597 }, 598 .capture = { 599 .rates = SNDRV_PCM_RATE_8000_48000, 600 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8 | 601 SNDRV_PCM_FMTBIT_U8 | 602 SNDRV_PCM_FMTBIT_S24_LE | 603 SNDRV_PCM_FMTBIT_S32_LE, 604 .channels_min = 2, 605 .channels_max = 2, 606 .rate_min = 8000, 607 .rate_max = 48000, 608 }, 609 .ops = &acp3x_dai_i2s_ops, 610 }; 611 612 static const struct snd_soc_component_driver acp3x_i2s_component = { 613 .name = DRV_NAME, 614 .ops = &acp3x_dma_ops, 615 .pcm_new = acp3x_dma_new, 616 }; 617 618 static int acp3x_audio_probe(struct platform_device *pdev) 619 { 620 int status; 621 struct resource *res; 622 struct i2s_dev_data *adata; 623 unsigned int irqflags; 624 625 if (!pdev->dev.platform_data) { 626 dev_err(&pdev->dev, "platform_data not retrieved\n"); 627 return -ENODEV; 628 } 629 irqflags = *((unsigned int *)(pdev->dev.platform_data)); 630 631 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 632 if (!res) { 633 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); 634 return -ENODEV; 635 } 636 637 adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL); 638 if (!adata) 639 return -ENOMEM; 640 641 adata->acp3x_base = devm_ioremap(&pdev->dev, res->start, 642 resource_size(res)); 643 644 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 645 if (!res) { 646 dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n"); 647 return -ENODEV; 648 } 649 650 adata->i2s_irq = res->start; 651 adata->play_stream = NULL; 652 adata->capture_stream = NULL; 653 654 dev_set_drvdata(&pdev->dev, adata); 655 /* Initialize ACP */ 656 status = acp3x_init(adata->acp3x_base); 657 if (status) 658 return -ENODEV; 659 status = devm_snd_soc_register_component(&pdev->dev, 660 &acp3x_i2s_component, 661 &acp3x_i2s_dai_driver, 1); 662 if (status) { 663 dev_err(&pdev->dev, "Fail to register acp i2s dai\n"); 664 goto dev_err; 665 } 666 status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler, 667 irqflags, "ACP3x_I2S_IRQ", adata); 668 if (status) { 669 dev_err(&pdev->dev, "ACP3x I2S IRQ request failed\n"); 670 goto dev_err; 671 } 672 673 pm_runtime_set_autosuspend_delay(&pdev->dev, 10000); 674 pm_runtime_use_autosuspend(&pdev->dev); 675 pm_runtime_enable(&pdev->dev); 676 return 0; 677 dev_err: 678 status = acp3x_deinit(adata->acp3x_base); 679 if (status) 680 dev_err(&pdev->dev, "ACP de-init failed\n"); 681 else 682 dev_info(&pdev->dev, "ACP de-initialized\n"); 683 /*ignore device status and return driver probe error*/ 684 return -ENODEV; 685 } 686 687 static int acp3x_audio_remove(struct platform_device *pdev) 688 { 689 int ret; 690 struct i2s_dev_data *adata = dev_get_drvdata(&pdev->dev); 691 692 ret = acp3x_deinit(adata->acp3x_base); 693 if (ret) 694 dev_err(&pdev->dev, "ACP de-init failed\n"); 695 else 696 dev_info(&pdev->dev, "ACP de-initialized\n"); 697 698 pm_runtime_disable(&pdev->dev); 699 return 0; 700 } 701 702 static int acp3x_resume(struct device *dev) 703 { 704 int status; 705 u32 val; 706 struct i2s_dev_data *adata = dev_get_drvdata(dev); 707 708 status = acp3x_init(adata->acp3x_base); 709 if (status) 710 return -ENODEV; 711 712 if (adata->play_stream && adata->play_stream->runtime) { 713 struct i2s_stream_instance *rtd = 714 adata->play_stream->runtime->private_data; 715 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_PLAYBACK); 716 rv_writel((rtd->xfer_resolution << 3), 717 rtd->acp3x_base + mmACP_BTTDM_ITER); 718 if (adata->tdm_mode == true) { 719 rv_writel(adata->tdm_fmt, adata->acp3x_base + 720 mmACP_BTTDM_TXFRMT); 721 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_ITER); 722 rv_writel((val | 0x2), adata->acp3x_base + 723 mmACP_BTTDM_ITER); 724 } 725 } 726 727 if (adata->capture_stream && adata->capture_stream->runtime) { 728 struct i2s_stream_instance *rtd = 729 adata->capture_stream->runtime->private_data; 730 config_acp3x_dma(rtd, SNDRV_PCM_STREAM_CAPTURE); 731 rv_writel((rtd->xfer_resolution << 3), 732 rtd->acp3x_base + mmACP_BTTDM_IRER); 733 if (adata->tdm_mode == true) { 734 rv_writel(adata->tdm_fmt, adata->acp3x_base + 735 mmACP_BTTDM_RXFRMT); 736 val = rv_readl(adata->acp3x_base + mmACP_BTTDM_IRER); 737 rv_writel((val | 0x2), adata->acp3x_base + 738 mmACP_BTTDM_IRER); 739 } 740 } 741 742 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 743 return 0; 744 } 745 746 747 static int acp3x_pcm_runtime_suspend(struct device *dev) 748 { 749 int status; 750 struct i2s_dev_data *adata = dev_get_drvdata(dev); 751 752 status = acp3x_deinit(adata->acp3x_base); 753 if (status) 754 dev_err(dev, "ACP de-init failed\n"); 755 else 756 dev_info(dev, "ACP de-initialized\n"); 757 758 rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 759 760 return 0; 761 } 762 763 static int acp3x_pcm_runtime_resume(struct device *dev) 764 { 765 int status; 766 struct i2s_dev_data *adata = dev_get_drvdata(dev); 767 768 status = acp3x_init(adata->acp3x_base); 769 if (status) 770 return -ENODEV; 771 rv_writel(1, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB); 772 return 0; 773 } 774 775 static const struct dev_pm_ops acp3x_pm_ops = { 776 .runtime_suspend = acp3x_pcm_runtime_suspend, 777 .runtime_resume = acp3x_pcm_runtime_resume, 778 .resume = acp3x_resume, 779 }; 780 781 static struct platform_driver acp3x_dma_driver = { 782 .probe = acp3x_audio_probe, 783 .remove = acp3x_audio_remove, 784 .driver = { 785 .name = "acp3x_rv_i2s", 786 .pm = &acp3x_pm_ops, 787 }, 788 }; 789 790 module_platform_driver(acp3x_dma_driver); 791 792 MODULE_AUTHOR("Maruthi.Bayyavarapu@amd.com"); 793 MODULE_AUTHOR("Vijendar.Mukunda@amd.com"); 794 MODULE_DESCRIPTION("AMD ACP 3.x PCM Driver"); 795 MODULE_LICENSE("GPL v2"); 796 MODULE_ALIAS("platform:" DRV_NAME); 797