162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// Copyright(c) 2020 Intel Corporation. All rights reserved. 462306a36Sopenharmony_ci// 562306a36Sopenharmony_ci// Author: Cezary Rojewski <cezary.rojewski@intel.com> 662306a36Sopenharmony_ci// 762306a36Sopenharmony_ci// Special thanks to: 862306a36Sopenharmony_ci// Marcin Barlik <marcin.barlik@intel.com> 962306a36Sopenharmony_ci// Piotr Papierkowski <piotr.papierkowski@intel.com> 1062306a36Sopenharmony_ci// 1162306a36Sopenharmony_ci// for sharing LPT-LP and WTP-LP AudioDSP architecture expertise and 1262306a36Sopenharmony_ci// helping backtrack its historical background 1362306a36Sopenharmony_ci// 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/acpi.h> 1662306a36Sopenharmony_ci#include <linux/dma-mapping.h> 1762306a36Sopenharmony_ci#include <linux/interrupt.h> 1862306a36Sopenharmony_ci#include <linux/module.h> 1962306a36Sopenharmony_ci#include <linux/pci.h> 2062306a36Sopenharmony_ci#include <linux/platform_device.h> 2162306a36Sopenharmony_ci#include <linux/pm_runtime.h> 2262306a36Sopenharmony_ci#include <sound/intel-dsp-config.h> 2362306a36Sopenharmony_ci#include <sound/soc.h> 2462306a36Sopenharmony_ci#include <sound/soc-acpi.h> 2562306a36Sopenharmony_ci#include "core.h" 2662306a36Sopenharmony_ci#include "registers.h" 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#define CREATE_TRACE_POINTS 2962306a36Sopenharmony_ci#include "trace.h" 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistatic int __maybe_unused catpt_suspend(struct device *dev) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci struct catpt_dev *cdev = dev_get_drvdata(dev); 3462306a36Sopenharmony_ci struct dma_chan *chan; 3562306a36Sopenharmony_ci int ret; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci chan = catpt_dma_request_config_chan(cdev); 3862306a36Sopenharmony_ci if (IS_ERR(chan)) 3962306a36Sopenharmony_ci return PTR_ERR(chan); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci memset(&cdev->dx_ctx, 0, sizeof(cdev->dx_ctx)); 4262306a36Sopenharmony_ci ret = catpt_ipc_enter_dxstate(cdev, CATPT_DX_STATE_D3, &cdev->dx_ctx); 4362306a36Sopenharmony_ci if (ret) { 4462306a36Sopenharmony_ci ret = CATPT_IPC_ERROR(ret); 4562306a36Sopenharmony_ci goto release_dma_chan; 4662306a36Sopenharmony_ci } 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci ret = catpt_dsp_stall(cdev, true); 4962306a36Sopenharmony_ci if (ret) 5062306a36Sopenharmony_ci goto release_dma_chan; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci ret = catpt_store_memdumps(cdev, chan); 5362306a36Sopenharmony_ci if (ret) { 5462306a36Sopenharmony_ci dev_err(cdev->dev, "store memdumps failed: %d\n", ret); 5562306a36Sopenharmony_ci goto release_dma_chan; 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci ret = catpt_store_module_states(cdev, chan); 5962306a36Sopenharmony_ci if (ret) { 6062306a36Sopenharmony_ci dev_err(cdev->dev, "store module states failed: %d\n", ret); 6162306a36Sopenharmony_ci goto release_dma_chan; 6262306a36Sopenharmony_ci } 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci ret = catpt_store_streams_context(cdev, chan); 6562306a36Sopenharmony_ci if (ret) 6662306a36Sopenharmony_ci dev_err(cdev->dev, "store streams ctx failed: %d\n", ret); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_cirelease_dma_chan: 6962306a36Sopenharmony_ci dma_release_channel(chan); 7062306a36Sopenharmony_ci if (ret) 7162306a36Sopenharmony_ci return ret; 7262306a36Sopenharmony_ci return catpt_dsp_power_down(cdev); 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic int __maybe_unused catpt_resume(struct device *dev) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci struct catpt_dev *cdev = dev_get_drvdata(dev); 7862306a36Sopenharmony_ci int ret, i; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci ret = catpt_dsp_power_up(cdev); 8162306a36Sopenharmony_ci if (ret) 8262306a36Sopenharmony_ci return ret; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci if (!try_module_get(dev->driver->owner)) { 8562306a36Sopenharmony_ci dev_info(dev, "module unloading, skipping fw boot\n"); 8662306a36Sopenharmony_ci return 0; 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci module_put(dev->driver->owner); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci ret = catpt_boot_firmware(cdev, true); 9162306a36Sopenharmony_ci if (ret) { 9262306a36Sopenharmony_ci dev_err(cdev->dev, "boot firmware failed: %d\n", ret); 9362306a36Sopenharmony_ci return ret; 9462306a36Sopenharmony_ci } 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci /* reconfigure SSP devices after Dx transition */ 9762306a36Sopenharmony_ci for (i = 0; i < CATPT_SSP_COUNT; i++) { 9862306a36Sopenharmony_ci if (cdev->devfmt[i].iface == UINT_MAX) 9962306a36Sopenharmony_ci continue; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci ret = catpt_ipc_set_device_format(cdev, &cdev->devfmt[i]); 10262306a36Sopenharmony_ci if (ret) 10362306a36Sopenharmony_ci return CATPT_IPC_ERROR(ret); 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci return 0; 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic int __maybe_unused catpt_runtime_suspend(struct device *dev) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci if (!try_module_get(dev->driver->owner)) { 11262306a36Sopenharmony_ci dev_info(dev, "module unloading, skipping suspend\n"); 11362306a36Sopenharmony_ci return 0; 11462306a36Sopenharmony_ci } 11562306a36Sopenharmony_ci module_put(dev->driver->owner); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci return catpt_suspend(dev); 11862306a36Sopenharmony_ci} 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_cistatic int __maybe_unused catpt_runtime_resume(struct device *dev) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci return catpt_resume(dev); 12362306a36Sopenharmony_ci} 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic const struct dev_pm_ops catpt_dev_pm = { 12662306a36Sopenharmony_ci SET_SYSTEM_SLEEP_PM_OPS(catpt_suspend, catpt_resume) 12762306a36Sopenharmony_ci SET_RUNTIME_PM_OPS(catpt_runtime_suspend, catpt_runtime_resume, NULL) 12862306a36Sopenharmony_ci}; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/* machine board owned by CATPT is removed with this hook */ 13162306a36Sopenharmony_cistatic void board_pdev_unregister(void *data) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci platform_device_unregister(data); 13462306a36Sopenharmony_ci} 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic int catpt_register_board(struct catpt_dev *cdev) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci const struct catpt_spec *spec = cdev->spec; 13962306a36Sopenharmony_ci struct snd_soc_acpi_mach *mach; 14062306a36Sopenharmony_ci struct platform_device *board; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci mach = snd_soc_acpi_find_machine(spec->machines); 14362306a36Sopenharmony_ci if (!mach) { 14462306a36Sopenharmony_ci dev_info(cdev->dev, "no machines present\n"); 14562306a36Sopenharmony_ci return 0; 14662306a36Sopenharmony_ci } 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci mach->mach_params.platform = "catpt-platform"; 14962306a36Sopenharmony_ci board = platform_device_register_data(NULL, mach->drv_name, 15062306a36Sopenharmony_ci PLATFORM_DEVID_NONE, 15162306a36Sopenharmony_ci (const void *)mach, sizeof(*mach)); 15262306a36Sopenharmony_ci if (IS_ERR(board)) { 15362306a36Sopenharmony_ci dev_err(cdev->dev, "board register failed\n"); 15462306a36Sopenharmony_ci return PTR_ERR(board); 15562306a36Sopenharmony_ci } 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci return devm_add_action_or_reset(cdev->dev, board_pdev_unregister, 15862306a36Sopenharmony_ci board); 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_cistatic int catpt_probe_components(struct catpt_dev *cdev) 16262306a36Sopenharmony_ci{ 16362306a36Sopenharmony_ci int ret; 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci ret = catpt_dsp_power_up(cdev); 16662306a36Sopenharmony_ci if (ret) 16762306a36Sopenharmony_ci return ret; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci ret = catpt_dmac_probe(cdev); 17062306a36Sopenharmony_ci if (ret) { 17162306a36Sopenharmony_ci dev_err(cdev->dev, "DMAC probe failed: %d\n", ret); 17262306a36Sopenharmony_ci goto err_dmac_probe; 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci ret = catpt_first_boot_firmware(cdev); 17662306a36Sopenharmony_ci if (ret) { 17762306a36Sopenharmony_ci dev_err(cdev->dev, "first fw boot failed: %d\n", ret); 17862306a36Sopenharmony_ci goto err_boot_fw; 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci ret = catpt_register_plat_component(cdev); 18262306a36Sopenharmony_ci if (ret) { 18362306a36Sopenharmony_ci dev_err(cdev->dev, "register plat comp failed: %d\n", ret); 18462306a36Sopenharmony_ci goto err_boot_fw; 18562306a36Sopenharmony_ci } 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci ret = catpt_register_board(cdev); 18862306a36Sopenharmony_ci if (ret) { 18962306a36Sopenharmony_ci dev_err(cdev->dev, "register board failed: %d\n", ret); 19062306a36Sopenharmony_ci goto err_reg_board; 19162306a36Sopenharmony_ci } 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* reflect actual ADSP state in pm_runtime */ 19462306a36Sopenharmony_ci pm_runtime_set_active(cdev->dev); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci pm_runtime_set_autosuspend_delay(cdev->dev, 2000); 19762306a36Sopenharmony_ci pm_runtime_use_autosuspend(cdev->dev); 19862306a36Sopenharmony_ci pm_runtime_mark_last_busy(cdev->dev); 19962306a36Sopenharmony_ci pm_runtime_enable(cdev->dev); 20062306a36Sopenharmony_ci return 0; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cierr_reg_board: 20362306a36Sopenharmony_ci snd_soc_unregister_component(cdev->dev); 20462306a36Sopenharmony_cierr_boot_fw: 20562306a36Sopenharmony_ci catpt_dmac_remove(cdev); 20662306a36Sopenharmony_cierr_dmac_probe: 20762306a36Sopenharmony_ci catpt_dsp_power_down(cdev); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci return ret; 21062306a36Sopenharmony_ci} 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_cistatic void catpt_dev_init(struct catpt_dev *cdev, struct device *dev, 21362306a36Sopenharmony_ci const struct catpt_spec *spec) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci cdev->dev = dev; 21662306a36Sopenharmony_ci cdev->spec = spec; 21762306a36Sopenharmony_ci init_completion(&cdev->fw_ready); 21862306a36Sopenharmony_ci INIT_LIST_HEAD(&cdev->stream_list); 21962306a36Sopenharmony_ci spin_lock_init(&cdev->list_lock); 22062306a36Sopenharmony_ci mutex_init(&cdev->clk_mutex); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* 22362306a36Sopenharmony_ci * Mark both device formats as uninitialized. Once corresponding 22462306a36Sopenharmony_ci * cpu_dai's pcm is created, proper values are assigned. 22562306a36Sopenharmony_ci */ 22662306a36Sopenharmony_ci cdev->devfmt[CATPT_SSP_IFACE_0].iface = UINT_MAX; 22762306a36Sopenharmony_ci cdev->devfmt[CATPT_SSP_IFACE_1].iface = UINT_MAX; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci catpt_ipc_init(&cdev->ipc, dev); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci catpt_sram_init(&cdev->dram, spec->host_dram_offset, 23262306a36Sopenharmony_ci catpt_dram_size(cdev)); 23362306a36Sopenharmony_ci catpt_sram_init(&cdev->iram, spec->host_iram_offset, 23462306a36Sopenharmony_ci catpt_iram_size(cdev)); 23562306a36Sopenharmony_ci} 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_cistatic int catpt_acpi_probe(struct platform_device *pdev) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci const struct catpt_spec *spec; 24062306a36Sopenharmony_ci struct catpt_dev *cdev; 24162306a36Sopenharmony_ci struct device *dev = &pdev->dev; 24262306a36Sopenharmony_ci const struct acpi_device_id *id; 24362306a36Sopenharmony_ci struct resource *res; 24462306a36Sopenharmony_ci int ret; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci id = acpi_match_device(dev->driver->acpi_match_table, dev); 24762306a36Sopenharmony_ci if (!id) 24862306a36Sopenharmony_ci return -ENODEV; 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci ret = snd_intel_acpi_dsp_driver_probe(dev, id->id); 25162306a36Sopenharmony_ci if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SST) { 25262306a36Sopenharmony_ci dev_dbg(dev, "CATPT ACPI driver not selected, aborting probe\n"); 25362306a36Sopenharmony_ci return -ENODEV; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci cdev = devm_kzalloc(dev, sizeof(*cdev), GFP_KERNEL); 25762306a36Sopenharmony_ci if (!cdev) 25862306a36Sopenharmony_ci return -ENOMEM; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci spec = (const struct catpt_spec *)id->driver_data; 26162306a36Sopenharmony_ci catpt_dev_init(cdev, dev, spec); 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci /* map DSP bar address */ 26462306a36Sopenharmony_ci cdev->lpe_ba = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 26562306a36Sopenharmony_ci if (IS_ERR(cdev->lpe_ba)) 26662306a36Sopenharmony_ci return PTR_ERR(cdev->lpe_ba); 26762306a36Sopenharmony_ci cdev->lpe_base = res->start; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci /* map PCI bar address */ 27062306a36Sopenharmony_ci cdev->pci_ba = devm_platform_ioremap_resource(pdev, 1); 27162306a36Sopenharmony_ci if (IS_ERR(cdev->pci_ba)) 27262306a36Sopenharmony_ci return PTR_ERR(cdev->pci_ba); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /* alloc buffer for storing DRAM context during dx transitions */ 27562306a36Sopenharmony_ci cdev->dxbuf_vaddr = dmam_alloc_coherent(dev, catpt_dram_size(cdev), 27662306a36Sopenharmony_ci &cdev->dxbuf_paddr, GFP_KERNEL); 27762306a36Sopenharmony_ci if (!cdev->dxbuf_vaddr) 27862306a36Sopenharmony_ci return -ENOMEM; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci ret = platform_get_irq(pdev, 0); 28162306a36Sopenharmony_ci if (ret < 0) 28262306a36Sopenharmony_ci return ret; 28362306a36Sopenharmony_ci cdev->irq = ret; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci platform_set_drvdata(pdev, cdev); 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci ret = devm_request_threaded_irq(dev, cdev->irq, catpt_dsp_irq_handler, 28862306a36Sopenharmony_ci catpt_dsp_irq_thread, 28962306a36Sopenharmony_ci IRQF_SHARED, "AudioDSP", cdev); 29062306a36Sopenharmony_ci if (ret) 29162306a36Sopenharmony_ci return ret; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci return catpt_probe_components(cdev); 29462306a36Sopenharmony_ci} 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_cistatic void catpt_acpi_remove(struct platform_device *pdev) 29762306a36Sopenharmony_ci{ 29862306a36Sopenharmony_ci struct catpt_dev *cdev = platform_get_drvdata(pdev); 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_ci pm_runtime_disable(cdev->dev); 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci snd_soc_unregister_component(cdev->dev); 30362306a36Sopenharmony_ci catpt_dmac_remove(cdev); 30462306a36Sopenharmony_ci catpt_dsp_power_down(cdev); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci catpt_sram_free(&cdev->iram); 30762306a36Sopenharmony_ci catpt_sram_free(&cdev->dram); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic struct snd_soc_acpi_mach lpt_machines[] = { 31162306a36Sopenharmony_ci { 31262306a36Sopenharmony_ci .id = "INT33CA", 31362306a36Sopenharmony_ci .drv_name = "hsw_rt5640", 31462306a36Sopenharmony_ci }, 31562306a36Sopenharmony_ci {} 31662306a36Sopenharmony_ci}; 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_cistatic struct snd_soc_acpi_mach wpt_machines[] = { 31962306a36Sopenharmony_ci { 32062306a36Sopenharmony_ci .id = "INT33CA", 32162306a36Sopenharmony_ci .drv_name = "hsw_rt5640", 32262306a36Sopenharmony_ci }, 32362306a36Sopenharmony_ci { 32462306a36Sopenharmony_ci .id = "INT343A", 32562306a36Sopenharmony_ci .drv_name = "bdw_rt286", 32662306a36Sopenharmony_ci }, 32762306a36Sopenharmony_ci { 32862306a36Sopenharmony_ci .id = "10EC5650", 32962306a36Sopenharmony_ci .drv_name = "bdw-rt5650", 33062306a36Sopenharmony_ci }, 33162306a36Sopenharmony_ci { 33262306a36Sopenharmony_ci .id = "RT5677CE", 33362306a36Sopenharmony_ci .drv_name = "bdw-rt5677", 33462306a36Sopenharmony_ci }, 33562306a36Sopenharmony_ci {} 33662306a36Sopenharmony_ci}; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_cistatic struct catpt_spec lpt_desc = { 33962306a36Sopenharmony_ci .machines = lpt_machines, 34062306a36Sopenharmony_ci .core_id = 0x01, 34162306a36Sopenharmony_ci .host_dram_offset = 0x000000, 34262306a36Sopenharmony_ci .host_iram_offset = 0x080000, 34362306a36Sopenharmony_ci .host_shim_offset = 0x0E7000, 34462306a36Sopenharmony_ci .host_dma_offset = { 0x0F0000, 0x0F8000 }, 34562306a36Sopenharmony_ci .host_ssp_offset = { 0x0E8000, 0x0E9000 }, 34662306a36Sopenharmony_ci .dram_mask = LPT_VDRTCTL0_DSRAMPGE_MASK, 34762306a36Sopenharmony_ci .iram_mask = LPT_VDRTCTL0_ISRAMPGE_MASK, 34862306a36Sopenharmony_ci .d3srampgd_bit = LPT_VDRTCTL0_D3SRAMPGD, 34962306a36Sopenharmony_ci .d3pgd_bit = LPT_VDRTCTL0_D3PGD, 35062306a36Sopenharmony_ci .pll_shutdown = lpt_dsp_pll_shutdown, 35162306a36Sopenharmony_ci}; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_cistatic struct catpt_spec wpt_desc = { 35462306a36Sopenharmony_ci .machines = wpt_machines, 35562306a36Sopenharmony_ci .core_id = 0x02, 35662306a36Sopenharmony_ci .host_dram_offset = 0x000000, 35762306a36Sopenharmony_ci .host_iram_offset = 0x0A0000, 35862306a36Sopenharmony_ci .host_shim_offset = 0x0FB000, 35962306a36Sopenharmony_ci .host_dma_offset = { 0x0FE000, 0x0FF000 }, 36062306a36Sopenharmony_ci .host_ssp_offset = { 0x0FC000, 0x0FD000 }, 36162306a36Sopenharmony_ci .dram_mask = WPT_VDRTCTL0_DSRAMPGE_MASK, 36262306a36Sopenharmony_ci .iram_mask = WPT_VDRTCTL0_ISRAMPGE_MASK, 36362306a36Sopenharmony_ci .d3srampgd_bit = WPT_VDRTCTL0_D3SRAMPGD, 36462306a36Sopenharmony_ci .d3pgd_bit = WPT_VDRTCTL0_D3PGD, 36562306a36Sopenharmony_ci .pll_shutdown = wpt_dsp_pll_shutdown, 36662306a36Sopenharmony_ci}; 36762306a36Sopenharmony_ci 36862306a36Sopenharmony_cistatic const struct acpi_device_id catpt_ids[] = { 36962306a36Sopenharmony_ci { "INT33C8", (unsigned long)&lpt_desc }, 37062306a36Sopenharmony_ci { "INT3438", (unsigned long)&wpt_desc }, 37162306a36Sopenharmony_ci { } 37262306a36Sopenharmony_ci}; 37362306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, catpt_ids); 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic struct platform_driver catpt_acpi_driver = { 37662306a36Sopenharmony_ci .probe = catpt_acpi_probe, 37762306a36Sopenharmony_ci .remove_new = catpt_acpi_remove, 37862306a36Sopenharmony_ci .driver = { 37962306a36Sopenharmony_ci .name = "intel_catpt", 38062306a36Sopenharmony_ci .acpi_match_table = catpt_ids, 38162306a36Sopenharmony_ci .pm = &catpt_dev_pm, 38262306a36Sopenharmony_ci .dev_groups = catpt_attr_groups, 38362306a36Sopenharmony_ci }, 38462306a36Sopenharmony_ci}; 38562306a36Sopenharmony_cimodule_platform_driver(catpt_acpi_driver); 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ciMODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>"); 38862306a36Sopenharmony_ciMODULE_DESCRIPTION("Intel LPT/WPT AudioDSP driver"); 38962306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 390