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) 2023 Advanced Micro Devices, Inc. 7 // 8 // Authors: Syed Saba Kareem <Syed.SabaKareem@amd.com> 9 // 10 11 /* 12 * Common file to be used by amd platforms 13 */ 14 15 #include "amd.h" 16 #include <linux/acpi.h> 17 #include <linux/pci.h> 18 #include <linux/export.h> 19 20 #include "../mach-config.h" 21 22 #define ACP_RENOIR_PDM_ADDR 0x02 23 #define ACP_REMBRANDT_PDM_ADDR 0x03 24 #define ACP63_PDM_ADDR 0x02 25 #define ACP70_PDM_ADDR 0x02 26 27 struct acp_resource rn_rsrc = { 28 .offset = 20, 29 .no_of_ctrls = 1, 30 .irqp_used = 0, 31 .irq_reg_offset = 0x1800, 32 .scratch_reg_offset = 0x12800, 33 .sram_pte_offset = 0x02052800, 34 }; 35 EXPORT_SYMBOL_NS_GPL(rn_rsrc, "SND_SOC_ACP_COMMON"); 36 37 struct acp_resource rmb_rsrc = { 38 .offset = 0, 39 .no_of_ctrls = 2, 40 .irqp_used = 1, 41 .soc_mclk = true, 42 .irq_reg_offset = 0x1a00, 43 .scratch_reg_offset = 0x12800, 44 .sram_pte_offset = 0x03802800, 45 }; 46 EXPORT_SYMBOL_NS_GPL(rmb_rsrc, "SND_SOC_ACP_COMMON"); 47 48 struct acp_resource acp63_rsrc = { 49 .offset = 0, 50 .no_of_ctrls = 2, 51 .irqp_used = 1, 52 .soc_mclk = true, 53 .irq_reg_offset = 0x1a00, 54 .scratch_reg_offset = 0x12800, 55 .sram_pte_offset = 0x03802800, 56 }; 57 EXPORT_SYMBOL_NS_GPL(acp63_rsrc, "SND_SOC_ACP_COMMON"); 58 59 struct acp_resource acp70_rsrc = { 60 .offset = 0, 61 .no_of_ctrls = 2, 62 .irqp_used = 1, 63 .soc_mclk = true, 64 .irq_reg_offset = 0x1a00, 65 .scratch_reg_offset = 0x10000, 66 .sram_pte_offset = 0x03800000, 67 }; 68 EXPORT_SYMBOL_NS_GPL(acp70_rsrc, "SND_SOC_ACP_COMMON"); 69 70 static const struct snd_acp_hw_ops acp_common_hw_ops = { 71 /* ACP hardware initilizations */ 72 .acp_init = acp_init, 73 .acp_deinit = acp_deinit, 74 75 /* ACP Interrupts*/ 76 .irq = acp_irq_handler, 77 .en_interrupts = acp_enable_interrupts, 78 .dis_interrupts = acp_disable_interrupts, 79 }; 80 81 irqreturn_t acp_irq_handler(int irq, void *data) 82 { 83 struct acp_chip_info *chip = data; 84 struct acp_resource *rsrc = chip->rsrc; 85 struct acp_stream *stream; 86 u16 i2s_flag = 0; 87 u32 ext_intr_stat, ext_intr_stat1; 88 89 if (rsrc->no_of_ctrls == 2) 90 ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1))); 91 92 ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); 93 94 spin_lock(&chip->acp_lock); 95 list_for_each_entry(stream, &chip->stream_list, list) { 96 if (ext_intr_stat & stream->irq_bit) { 97 writel(stream->irq_bit, 98 ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); 99 snd_pcm_period_elapsed(stream->substream); 100 i2s_flag = 1; 101 } 102 if (chip->rsrc->no_of_ctrls == 2) { 103 if (ext_intr_stat1 & stream->irq_bit) { 104 writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip, 105 (rsrc->irqp_used - 1))); 106 snd_pcm_period_elapsed(stream->substream); 107 i2s_flag = 1; 108 } 109 } 110 } 111 spin_unlock(&chip->acp_lock); 112 if (i2s_flag) 113 return IRQ_HANDLED; 114 115 return IRQ_NONE; 116 } 117 118 int acp_enable_interrupts(struct acp_chip_info *chip) 119 { 120 struct acp_resource *rsrc; 121 u32 ext_intr_ctrl; 122 123 rsrc = chip->rsrc; 124 writel(0x01, ACP_EXTERNAL_INTR_ENB(chip)); 125 ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); 126 ext_intr_ctrl |= ACP_ERROR_MASK; 127 writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); 128 129 return 0; 130 } 131 EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON"); 132 133 int acp_disable_interrupts(struct acp_chip_info *chip) 134 { 135 struct acp_resource *rsrc; 136 137 rsrc = chip->rsrc; 138 writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used)); 139 writel(0x00, ACP_EXTERNAL_INTR_ENB(chip)); 140 141 return 0; 142 } 143 EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON"); 144 145 static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream, 146 struct snd_soc_dai *dai) 147 { 148 struct snd_pcm_runtime *runtime = substream->runtime; 149 struct acp_stream *stream = runtime->private_data; 150 struct device *dev = dai->component->dev; 151 struct acp_chip_info *chip = dev_get_platdata(dev); 152 153 u32 physical_addr, pdm_size, period_bytes; 154 155 period_bytes = frames_to_bytes(runtime, runtime->period_size); 156 pdm_size = frames_to_bytes(runtime, runtime->buffer_size); 157 physical_addr = stream->reg_offset + MEM_WINDOW_START; 158 159 /* Init ACP PDM Ring buffer */ 160 writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR); 161 writel(pdm_size, chip->base + ACP_WOV_RX_RINGBUFSIZE); 162 writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE); 163 writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); 164 } 165 166 static void set_acp_pdm_clk(struct snd_pcm_substream *substream, 167 struct snd_soc_dai *dai) 168 { 169 struct device *dev = dai->component->dev; 170 struct acp_chip_info *chip = dev_get_platdata(dev); 171 unsigned int pdm_ctrl; 172 173 /* Enable default ACP PDM clk */ 174 writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL); 175 pdm_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL); 176 pdm_ctrl |= PDM_MISC_CTRL_MASK; 177 writel(pdm_ctrl, chip->base + ACP_WOV_MISC_CTRL); 178 set_acp_pdm_ring_buffer(substream, dai); 179 } 180 181 void restore_acp_pdm_params(struct snd_pcm_substream *substream, 182 struct acp_chip_info *chip) 183 { 184 struct snd_soc_dai *dai; 185 struct snd_soc_pcm_runtime *soc_runtime; 186 u32 ext_int_ctrl; 187 188 soc_runtime = snd_soc_substream_to_rtd(substream); 189 dai = snd_soc_rtd_to_cpu(soc_runtime, 0); 190 191 /* Programming channel mask and sampling rate */ 192 writel(chip->ch_mask, chip->base + ACP_WOV_PDM_NO_OF_CHANNELS); 193 writel(PDM_DEC_64, chip->base + ACP_WOV_PDM_DECIMATION_FACTOR); 194 195 /* Enabling ACP Pdm interuppts */ 196 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0)); 197 ext_int_ctrl |= PDM_DMA_INTR_MASK; 198 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, 0)); 199 set_acp_pdm_clk(substream, dai); 200 } 201 EXPORT_SYMBOL_NS_GPL(restore_acp_pdm_params, "SND_SOC_ACP_COMMON"); 202 203 static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream, 204 struct snd_soc_dai *dai) 205 { 206 struct device *dev = dai->component->dev; 207 struct acp_chip_info *chip = dev_get_platdata(dev); 208 struct acp_resource *rsrc = chip->rsrc; 209 struct acp_stream *stream = substream->runtime->private_data; 210 u32 reg_dma_size, reg_fifo_size, reg_fifo_addr; 211 u32 phy_addr, acp_fifo_addr, ext_int_ctrl; 212 unsigned int dir = substream->stream; 213 214 switch (dai->driver->id) { 215 case I2S_SP_INSTANCE: 216 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 217 reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip); 218 acp_fifo_addr = rsrc->sram_pte_offset + 219 SP_PB_FIFO_ADDR_OFFSET; 220 reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip); 221 reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip); 222 phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset; 223 writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip)); 224 } else { 225 reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip); 226 acp_fifo_addr = rsrc->sram_pte_offset + 227 SP_CAPT_FIFO_ADDR_OFFSET; 228 reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip); 229 reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip); 230 phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset; 231 writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip)); 232 } 233 break; 234 case I2S_BT_INSTANCE: 235 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 236 reg_dma_size = ACP_BT_TX_DMA_SIZE(chip); 237 acp_fifo_addr = rsrc->sram_pte_offset + 238 BT_PB_FIFO_ADDR_OFFSET; 239 reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip); 240 reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip); 241 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; 242 writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip)); 243 } else { 244 reg_dma_size = ACP_BT_RX_DMA_SIZE(chip); 245 acp_fifo_addr = rsrc->sram_pte_offset + 246 BT_CAPT_FIFO_ADDR_OFFSET; 247 reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip); 248 reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip); 249 phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset; 250 writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip)); 251 } 252 break; 253 case I2S_HS_INSTANCE: 254 if (dir == SNDRV_PCM_STREAM_PLAYBACK) { 255 reg_dma_size = ACP_HS_TX_DMA_SIZE; 256 acp_fifo_addr = rsrc->sram_pte_offset + 257 HS_PB_FIFO_ADDR_OFFSET; 258 reg_fifo_addr = ACP_HS_TX_FIFOADDR; 259 reg_fifo_size = ACP_HS_TX_FIFOSIZE; 260 phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset; 261 writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR); 262 } else { 263 reg_dma_size = ACP_HS_RX_DMA_SIZE; 264 acp_fifo_addr = rsrc->sram_pte_offset + 265 HS_CAPT_FIFO_ADDR_OFFSET; 266 reg_fifo_addr = ACP_HS_RX_FIFOADDR; 267 reg_fifo_size = ACP_HS_RX_FIFOSIZE; 268 phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset; 269 writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR); 270 } 271 break; 272 default: 273 dev_err(dev, "Invalid dai id %x\n", dai->driver->id); 274 return -EINVAL; 275 } 276 277 writel(DMA_SIZE, chip->base + reg_dma_size); 278 writel(acp_fifo_addr, chip->base + reg_fifo_addr); 279 writel(FIFO_SIZE, chip->base + reg_fifo_size); 280 281 ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); 282 ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) | 283 BIT(BT_RX_THRESHOLD(rsrc->offset)) | 284 BIT(I2S_TX_THRESHOLD(rsrc->offset)) | 285 BIT(BT_TX_THRESHOLD(rsrc->offset)) | 286 BIT(HS_RX_THRESHOLD(rsrc->offset)) | 287 BIT(HS_TX_THRESHOLD(rsrc->offset)); 288 289 writel(ext_int_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used)); 290 return 0; 291 } 292 293 int restore_acp_i2s_params(struct snd_pcm_substream *substream, 294 struct acp_chip_info *chip, 295 struct acp_stream *stream) 296 { 297 struct snd_soc_dai *dai; 298 struct snd_soc_pcm_runtime *soc_runtime; 299 u32 tdm_fmt, reg_val, fmt_reg, val; 300 301 soc_runtime = snd_soc_substream_to_rtd(substream); 302 dai = snd_soc_rtd_to_cpu(soc_runtime, 0); 303 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 304 tdm_fmt = chip->tdm_tx_fmt[stream->dai_id - 1]; 305 switch (stream->dai_id) { 306 case I2S_BT_INSTANCE: 307 reg_val = ACP_BTTDM_ITER; 308 fmt_reg = ACP_BTTDM_TXFRMT; 309 break; 310 case I2S_SP_INSTANCE: 311 reg_val = ACP_I2STDM_ITER; 312 fmt_reg = ACP_I2STDM_TXFRMT; 313 break; 314 case I2S_HS_INSTANCE: 315 reg_val = ACP_HSTDM_ITER; 316 fmt_reg = ACP_HSTDM_TXFRMT; 317 break; 318 default: 319 pr_err("Invalid dai id %x\n", stream->dai_id); 320 return -EINVAL; 321 } 322 val = chip->xfer_tx_resolution[stream->dai_id - 1] << 3; 323 } else { 324 tdm_fmt = chip->tdm_rx_fmt[stream->dai_id - 1]; 325 switch (stream->dai_id) { 326 case I2S_BT_INSTANCE: 327 reg_val = ACP_BTTDM_IRER; 328 fmt_reg = ACP_BTTDM_RXFRMT; 329 break; 330 case I2S_SP_INSTANCE: 331 reg_val = ACP_I2STDM_IRER; 332 fmt_reg = ACP_I2STDM_RXFRMT; 333 break; 334 case I2S_HS_INSTANCE: 335 reg_val = ACP_HSTDM_IRER; 336 fmt_reg = ACP_HSTDM_RXFRMT; 337 break; 338 default: 339 pr_err("Invalid dai id %x\n", stream->dai_id); 340 return -EINVAL; 341 } 342 val = chip->xfer_rx_resolution[stream->dai_id - 1] << 3; 343 } 344 writel(val, chip->base + reg_val); 345 if (chip->tdm_mode == TDM_ENABLE) { 346 writel(tdm_fmt, chip->base + fmt_reg); 347 val = readl(chip->base + reg_val); 348 writel(val | 0x2, chip->base + reg_val); 349 } 350 return set_acp_i2s_dma_fifo(substream, dai); 351 } 352 EXPORT_SYMBOL_NS_GPL(restore_acp_i2s_params, "SND_SOC_ACP_COMMON"); 353 354 static int acp_power_on(struct acp_chip_info *chip) 355 { 356 u32 val, acp_pgfsm_stat_reg, acp_pgfsm_ctrl_reg; 357 void __iomem *base; 358 359 base = chip->base; 360 switch (chip->acp_rev) { 361 case ACP_RN_PCI_ID: 362 acp_pgfsm_stat_reg = ACP_PGFSM_STATUS; 363 acp_pgfsm_ctrl_reg = ACP_PGFSM_CONTROL; 364 break; 365 case ACP_RMB_PCI_ID: 366 acp_pgfsm_stat_reg = ACP6X_PGFSM_STATUS; 367 acp_pgfsm_ctrl_reg = ACP6X_PGFSM_CONTROL; 368 break; 369 case ACP63_PCI_ID: 370 acp_pgfsm_stat_reg = ACP63_PGFSM_STATUS; 371 acp_pgfsm_ctrl_reg = ACP63_PGFSM_CONTROL; 372 break; 373 case ACP70_PCI_ID: 374 case ACP71_PCI_ID: 375 acp_pgfsm_stat_reg = ACP70_PGFSM_STATUS; 376 acp_pgfsm_ctrl_reg = ACP70_PGFSM_CONTROL; 377 break; 378 default: 379 return -EINVAL; 380 } 381 382 val = readl(base + acp_pgfsm_stat_reg); 383 if (val == ACP_POWERED_ON) 384 return 0; 385 386 if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS) 387 writel(ACP_PGFSM_CNTL_POWER_ON_MASK, base + acp_pgfsm_ctrl_reg); 388 389 return readl_poll_timeout(base + acp_pgfsm_stat_reg, val, 390 !val, DELAY_US, ACP_TIMEOUT); 391 } 392 393 static int acp_reset(void __iomem *base) 394 { 395 u32 val; 396 int ret; 397 398 writel(1, base + ACP_SOFT_RESET); 399 ret = readl_poll_timeout(base + ACP_SOFT_RESET, val, val & ACP_SOFT_RST_DONE_MASK, 400 DELAY_US, ACP_TIMEOUT); 401 if (ret) 402 return ret; 403 404 writel(0, base + ACP_SOFT_RESET); 405 return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT); 406 } 407 408 int acp_init(struct acp_chip_info *chip) 409 { 410 int ret; 411 412 /* power on */ 413 ret = acp_power_on(chip); 414 if (ret) { 415 pr_err("ACP power on failed\n"); 416 return ret; 417 } 418 writel(0x01, chip->base + ACP_CONTROL); 419 420 /* Reset */ 421 ret = acp_reset(chip->base); 422 if (ret) { 423 pr_err("ACP reset failed\n"); 424 return ret; 425 } 426 if (chip->acp_rev >= ACP70_PCI_ID) 427 writel(0, chip->base + ACP_ZSC_DSP_CTRL); 428 return 0; 429 } 430 EXPORT_SYMBOL_NS_GPL(acp_init, "SND_SOC_ACP_COMMON"); 431 432 int acp_deinit(struct acp_chip_info *chip) 433 { 434 int ret; 435 436 /* Reset */ 437 ret = acp_reset(chip->base); 438 if (ret) 439 return ret; 440 441 if (chip->acp_rev < ACP70_PCI_ID) 442 writel(0, chip->base + ACP_CONTROL); 443 else 444 writel(0x01, chip->base + ACP_ZSC_DSP_CTRL); 445 return 0; 446 } 447 EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); 448 int acp_machine_select(struct acp_chip_info *chip) 449 { 450 struct snd_soc_acpi_mach *mach; 451 int size, platform; 452 453 if (chip->flag == FLAG_AMD_LEGACY_ONLY_DMIC && chip->is_pdm_dev) { 454 platform = chip->acp_rev; 455 chip->mach_dev = platform_device_register_data(chip->dev, "acp-pdm-mach", 456 PLATFORM_DEVID_NONE, &platform, 457 sizeof(platform)); 458 } else { 459 size = sizeof(*chip->machines); 460 mach = snd_soc_acpi_find_machine(chip->machines); 461 if (!mach) { 462 dev_err(chip->dev, "warning: No matching ASoC machine driver found\n"); 463 return -EINVAL; 464 } 465 mach->mach_params.subsystem_rev = chip->acp_rev; 466 chip->mach_dev = platform_device_register_data(chip->dev, mach->drv_name, 467 PLATFORM_DEVID_NONE, mach, size); 468 } 469 if (IS_ERR(chip->mach_dev)) 470 dev_warn(chip->dev, "Unable to register Machine device\n"); 471 return 0; 472 } 473 EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); 474 475 static void check_acp3x_config(struct acp_chip_info *chip) 476 { 477 u32 val; 478 479 val = readl(chip->base + ACP3X_PIN_CONFIG); 480 switch (val) { 481 case ACP_CONFIG_4: 482 chip->is_i2s_config = true; 483 chip->is_pdm_config = true; 484 break; 485 default: 486 chip->is_pdm_config = true; 487 break; 488 } 489 } 490 491 static void check_acp6x_config(struct acp_chip_info *chip) 492 { 493 u32 val; 494 495 val = readl(chip->base + ACP_PIN_CONFIG); 496 switch (val) { 497 case ACP_CONFIG_4: 498 case ACP_CONFIG_5: 499 case ACP_CONFIG_6: 500 case ACP_CONFIG_7: 501 case ACP_CONFIG_8: 502 case ACP_CONFIG_11: 503 case ACP_CONFIG_14: 504 chip->is_pdm_config = true; 505 break; 506 case ACP_CONFIG_9: 507 chip->is_i2s_config = true; 508 break; 509 case ACP_CONFIG_10: 510 case ACP_CONFIG_12: 511 case ACP_CONFIG_13: 512 chip->is_i2s_config = true; 513 chip->is_pdm_config = true; 514 break; 515 default: 516 break; 517 } 518 } 519 520 static void check_acp70_config(struct acp_chip_info *chip) 521 { 522 u32 val; 523 524 val = readl(chip->base + ACP_PIN_CONFIG); 525 switch (val) { 526 case ACP_CONFIG_4: 527 case ACP_CONFIG_5: 528 case ACP_CONFIG_6: 529 case ACP_CONFIG_7: 530 case ACP_CONFIG_8: 531 case ACP_CONFIG_11: 532 case ACP_CONFIG_14: 533 case ACP_CONFIG_17: 534 case ACP_CONFIG_18: 535 chip->is_pdm_config = true; 536 break; 537 case ACP_CONFIG_9: 538 chip->is_i2s_config = true; 539 break; 540 case ACP_CONFIG_10: 541 case ACP_CONFIG_12: 542 case ACP_CONFIG_13: 543 case ACP_CONFIG_19: 544 case ACP_CONFIG_20: 545 chip->is_i2s_config = true; 546 chip->is_pdm_config = true; 547 break; 548 default: 549 break; 550 } 551 } 552 553 void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) 554 { 555 struct acpi_device *pdm_dev; 556 const union acpi_object *obj; 557 acpi_handle handle; 558 acpi_integer dmic_status; 559 u32 pdm_addr, ret; 560 561 switch (chip->acp_rev) { 562 case ACP_RN_PCI_ID: 563 pdm_addr = ACP_RENOIR_PDM_ADDR; 564 check_acp3x_config(chip); 565 break; 566 case ACP_RMB_PCI_ID: 567 pdm_addr = ACP_REMBRANDT_PDM_ADDR; 568 check_acp6x_config(chip); 569 break; 570 case ACP63_PCI_ID: 571 pdm_addr = ACP63_PDM_ADDR; 572 check_acp6x_config(chip); 573 break; 574 case ACP70_PCI_ID: 575 case ACP71_PCI_ID: 576 pdm_addr = ACP70_PDM_ADDR; 577 check_acp70_config(chip); 578 break; 579 default: 580 break; 581 } 582 583 if (chip->is_pdm_config) { 584 pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), pdm_addr, 0); 585 if (pdm_dev) { 586 if (!acpi_dev_get_property(pdm_dev, "acp-audio-device-type", 587 ACPI_TYPE_INTEGER, &obj) && 588 obj->integer.value == pdm_addr) 589 chip->is_pdm_dev = true; 590 } 591 592 handle = ACPI_HANDLE(&pci->dev); 593 ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); 594 if (!ACPI_FAILURE(ret)) 595 chip->is_pdm_dev = dmic_status; 596 } 597 } 598 EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON"); 599 600 struct snd_acp_hw_ops acp31_common_hw_ops; 601 EXPORT_SYMBOL_NS_GPL(acp31_common_hw_ops, "SND_SOC_ACP_COMMON"); 602 int acp31_hw_ops_init(struct acp_chip_info *chip) 603 { 604 memcpy(&acp31_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 605 chip->acp_hw_ops = &acp31_common_hw_ops; 606 607 return 0; 608 } 609 EXPORT_SYMBOL_NS_GPL(acp31_hw_ops_init, "SND_SOC_ACP_COMMON"); 610 611 struct snd_acp_hw_ops acp6x_common_hw_ops; 612 EXPORT_SYMBOL_NS_GPL(acp6x_common_hw_ops, "SND_SOC_ACP_COMMON"); 613 int acp6x_hw_ops_init(struct acp_chip_info *chip) 614 { 615 memcpy(&acp6x_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 616 chip->acp_hw_ops = &acp6x_common_hw_ops; 617 618 return 0; 619 } 620 EXPORT_SYMBOL_NS_GPL(acp6x_hw_ops_init, "SND_SOC_ACP_COMMON"); 621 622 struct snd_acp_hw_ops acp63_common_hw_ops; 623 EXPORT_SYMBOL_NS_GPL(acp63_common_hw_ops, "SND_SOC_ACP_COMMON"); 624 int acp63_hw_ops_init(struct acp_chip_info *chip) 625 { 626 memcpy(&acp63_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 627 chip->acp_hw_ops = &acp63_common_hw_ops; 628 629 return 0; 630 } 631 EXPORT_SYMBOL_NS_GPL(acp63_hw_ops_init, "SND_SOC_ACP_COMMON"); 632 633 struct snd_acp_hw_ops acp70_common_hw_ops; 634 EXPORT_SYMBOL_NS_GPL(acp70_common_hw_ops, "SND_SOC_ACP_COMMON"); 635 int acp70_hw_ops_init(struct acp_chip_info *chip) 636 { 637 memcpy(&acp70_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 638 chip->acp_hw_ops = &acp70_common_hw_ops; 639 640 return 0; 641 } 642 EXPORT_SYMBOL_NS_GPL(acp70_hw_ops_init, "SND_SOC_ACP_COMMON"); 643 644 MODULE_DESCRIPTION("AMD ACP legacy common features"); 645 MODULE_LICENSE("Dual BSD/GPL"); 646