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