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 case ACP72_PCI_ID: 376 acp_pgfsm_stat_reg = ACP70_PGFSM_STATUS; 377 acp_pgfsm_ctrl_reg = ACP70_PGFSM_CONTROL; 378 break; 379 default: 380 return -EINVAL; 381 } 382 383 val = readl(base + acp_pgfsm_stat_reg); 384 if (val == ACP_POWERED_ON) 385 return 0; 386 387 if ((val & ACP_PGFSM_STATUS_MASK) != ACP_POWER_ON_IN_PROGRESS) 388 writel(ACP_PGFSM_CNTL_POWER_ON_MASK, base + acp_pgfsm_ctrl_reg); 389 390 return readl_poll_timeout(base + acp_pgfsm_stat_reg, val, 391 !val, DELAY_US, ACP_TIMEOUT); 392 } 393 394 static int acp_reset(void __iomem *base) 395 { 396 u32 val; 397 int ret; 398 399 writel(1, base + ACP_SOFT_RESET); 400 ret = readl_poll_timeout(base + ACP_SOFT_RESET, val, val & ACP_SOFT_RST_DONE_MASK, 401 DELAY_US, ACP_TIMEOUT); 402 if (ret) 403 return ret; 404 405 writel(0, base + ACP_SOFT_RESET); 406 return readl_poll_timeout(base + ACP_SOFT_RESET, val, !val, DELAY_US, ACP_TIMEOUT); 407 } 408 409 int acp_init(struct acp_chip_info *chip) 410 { 411 int ret; 412 413 /* power on */ 414 ret = acp_power_on(chip); 415 if (ret) { 416 pr_err("ACP power on failed\n"); 417 return ret; 418 } 419 writel(0x01, chip->base + ACP_CONTROL); 420 421 /* Reset */ 422 ret = acp_reset(chip->base); 423 if (ret) { 424 pr_err("ACP reset failed\n"); 425 return ret; 426 } 427 if (chip->acp_rev >= ACP70_PCI_ID) 428 writel(0, chip->base + ACP_ZSC_DSP_CTRL); 429 return 0; 430 } 431 EXPORT_SYMBOL_NS_GPL(acp_init, "SND_SOC_ACP_COMMON"); 432 433 int acp_deinit(struct acp_chip_info *chip) 434 { 435 int ret; 436 437 /* Reset */ 438 ret = acp_reset(chip->base); 439 if (ret) 440 return ret; 441 442 if (chip->acp_rev < ACP70_PCI_ID) 443 writel(0, chip->base + ACP_CONTROL); 444 else 445 writel(0x01, chip->base + ACP_ZSC_DSP_CTRL); 446 return 0; 447 } 448 EXPORT_SYMBOL_NS_GPL(acp_deinit, "SND_SOC_ACP_COMMON"); 449 int acp_machine_select(struct acp_chip_info *chip) 450 { 451 struct snd_soc_acpi_mach *mach; 452 int size, platform; 453 454 if (chip->flag == FLAG_AMD_LEGACY_ONLY_DMIC && chip->is_pdm_dev) { 455 platform = chip->acp_rev; 456 chip->mach_dev = platform_device_register_data(chip->dev, "acp-pdm-mach", 457 PLATFORM_DEVID_NONE, &platform, 458 sizeof(platform)); 459 } else { 460 size = sizeof(*chip->machines); 461 mach = snd_soc_acpi_find_machine(chip->machines); 462 if (!mach) { 463 dev_err(chip->dev, "warning: No matching ASoC machine driver found\n"); 464 return -EINVAL; 465 } 466 mach->mach_params.subsystem_rev = chip->acp_rev; 467 chip->mach_dev = platform_device_register_data(chip->dev, mach->drv_name, 468 PLATFORM_DEVID_NONE, mach, size); 469 } 470 if (IS_ERR(chip->mach_dev)) 471 dev_warn(chip->dev, "Unable to register Machine device\n"); 472 return 0; 473 } 474 EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); 475 476 static void check_acp3x_config(struct acp_chip_info *chip) 477 { 478 u32 val; 479 480 val = readl(chip->base + ACP3X_PIN_CONFIG); 481 switch (val) { 482 case ACP_CONFIG_4: 483 chip->is_i2s_config = true; 484 chip->is_pdm_config = true; 485 break; 486 default: 487 chip->is_pdm_config = true; 488 break; 489 } 490 } 491 492 static void check_acp6x_config(struct acp_chip_info *chip) 493 { 494 u32 val; 495 496 val = readl(chip->base + ACP_PIN_CONFIG); 497 switch (val) { 498 case ACP_CONFIG_4: 499 case ACP_CONFIG_5: 500 case ACP_CONFIG_6: 501 case ACP_CONFIG_7: 502 case ACP_CONFIG_8: 503 case ACP_CONFIG_11: 504 case ACP_CONFIG_14: 505 chip->is_pdm_config = true; 506 break; 507 case ACP_CONFIG_9: 508 chip->is_i2s_config = true; 509 break; 510 case ACP_CONFIG_10: 511 case ACP_CONFIG_12: 512 case ACP_CONFIG_13: 513 chip->is_i2s_config = true; 514 chip->is_pdm_config = true; 515 break; 516 default: 517 break; 518 } 519 } 520 521 static void check_acp70_config(struct acp_chip_info *chip) 522 { 523 u32 val; 524 525 val = readl(chip->base + ACP_PIN_CONFIG); 526 switch (val) { 527 case ACP_CONFIG_4: 528 case ACP_CONFIG_5: 529 case ACP_CONFIG_6: 530 case ACP_CONFIG_7: 531 case ACP_CONFIG_8: 532 case ACP_CONFIG_11: 533 case ACP_CONFIG_14: 534 case ACP_CONFIG_17: 535 case ACP_CONFIG_18: 536 chip->is_pdm_config = true; 537 break; 538 case ACP_CONFIG_9: 539 chip->is_i2s_config = true; 540 break; 541 case ACP_CONFIG_10: 542 case ACP_CONFIG_12: 543 case ACP_CONFIG_13: 544 case ACP_CONFIG_19: 545 case ACP_CONFIG_20: 546 chip->is_i2s_config = true; 547 chip->is_pdm_config = true; 548 break; 549 default: 550 break; 551 } 552 } 553 554 void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip) 555 { 556 struct acpi_device *pdm_dev; 557 const union acpi_object *obj; 558 acpi_handle handle; 559 acpi_integer dmic_status; 560 u32 pdm_addr, ret; 561 562 switch (chip->acp_rev) { 563 case ACP_RN_PCI_ID: 564 pdm_addr = ACP_RENOIR_PDM_ADDR; 565 check_acp3x_config(chip); 566 break; 567 case ACP_RMB_PCI_ID: 568 pdm_addr = ACP_REMBRANDT_PDM_ADDR; 569 check_acp6x_config(chip); 570 break; 571 case ACP63_PCI_ID: 572 pdm_addr = ACP63_PDM_ADDR; 573 check_acp6x_config(chip); 574 break; 575 case ACP70_PCI_ID: 576 case ACP71_PCI_ID: 577 case ACP72_PCI_ID: 578 pdm_addr = ACP70_PDM_ADDR; 579 check_acp70_config(chip); 580 break; 581 default: 582 break; 583 } 584 585 if (chip->is_pdm_config) { 586 pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), pdm_addr, 0); 587 if (pdm_dev) { 588 if (!acpi_dev_get_property(pdm_dev, "acp-audio-device-type", 589 ACPI_TYPE_INTEGER, &obj) && 590 obj->integer.value == pdm_addr) 591 chip->is_pdm_dev = true; 592 } 593 594 handle = ACPI_HANDLE(&pci->dev); 595 ret = acpi_evaluate_integer(handle, "_WOV", NULL, &dmic_status); 596 if (!ACPI_FAILURE(ret)) 597 chip->is_pdm_dev = dmic_status; 598 } 599 } 600 EXPORT_SYMBOL_NS_GPL(check_acp_config, "SND_SOC_ACP_COMMON"); 601 602 struct snd_acp_hw_ops acp31_common_hw_ops; 603 EXPORT_SYMBOL_NS_GPL(acp31_common_hw_ops, "SND_SOC_ACP_COMMON"); 604 int acp31_hw_ops_init(struct acp_chip_info *chip) 605 { 606 memcpy(&acp31_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 607 chip->acp_hw_ops = &acp31_common_hw_ops; 608 609 return 0; 610 } 611 EXPORT_SYMBOL_NS_GPL(acp31_hw_ops_init, "SND_SOC_ACP_COMMON"); 612 613 struct snd_acp_hw_ops acp6x_common_hw_ops; 614 EXPORT_SYMBOL_NS_GPL(acp6x_common_hw_ops, "SND_SOC_ACP_COMMON"); 615 int acp6x_hw_ops_init(struct acp_chip_info *chip) 616 { 617 memcpy(&acp6x_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 618 chip->acp_hw_ops = &acp6x_common_hw_ops; 619 620 return 0; 621 } 622 EXPORT_SYMBOL_NS_GPL(acp6x_hw_ops_init, "SND_SOC_ACP_COMMON"); 623 624 struct snd_acp_hw_ops acp63_common_hw_ops; 625 EXPORT_SYMBOL_NS_GPL(acp63_common_hw_ops, "SND_SOC_ACP_COMMON"); 626 int acp63_hw_ops_init(struct acp_chip_info *chip) 627 { 628 memcpy(&acp63_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 629 chip->acp_hw_ops = &acp63_common_hw_ops; 630 631 return 0; 632 } 633 EXPORT_SYMBOL_NS_GPL(acp63_hw_ops_init, "SND_SOC_ACP_COMMON"); 634 635 struct snd_acp_hw_ops acp70_common_hw_ops; 636 EXPORT_SYMBOL_NS_GPL(acp70_common_hw_ops, "SND_SOC_ACP_COMMON"); 637 int acp70_hw_ops_init(struct acp_chip_info *chip) 638 { 639 memcpy(&acp70_common_hw_ops, &acp_common_hw_ops, sizeof(acp_common_hw_ops)); 640 chip->acp_hw_ops = &acp70_common_hw_ops; 641 642 return 0; 643 } 644 EXPORT_SYMBOL_NS_GPL(acp70_hw_ops_init, "SND_SOC_ACP_COMMON"); 645 646 MODULE_DESCRIPTION("AMD ACP legacy common features"); 647 MODULE_LICENSE("Dual BSD/GPL"); 648