Lines Matching +full:soundwire +full:- +full:controller
1 // SPDX-License-Identifier: GPL-2.0-only
19 #include <linux/soundwire/sdw_amd.h>
20 #include "../mach-config.h"
109 sdw_dma_data = dev_get_drvdata(&adata->sdw_dma_dev->dev); in acp63_irq_thread()
112 if (adata->sdw0_dma_intr_stat[stream_index]) { in acp63_irq_thread()
113 if (sdw_dma_data->sdw0_dma_stream[stream_index]) in acp63_irq_thread()
114 snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]); in acp63_irq_thread()
115 adata->sdw0_dma_intr_stat[stream_index] = 0; in acp63_irq_thread()
119 if (adata->sdw1_dma_intr_stat[stream_index]) { in acp63_irq_thread()
120 if (sdw_dma_data->sdw1_dma_stream[stream_index]) in acp63_irq_thread()
121 snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]); in acp63_irq_thread()
122 adata->sdw1_dma_intr_stat[stream_index] = 0; in acp63_irq_thread()
147 ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
149 writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
150 amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev); in acp63_irq_handler()
152 schedule_work(&amd_manager->amd_sdw_irq_thread); in acp63_irq_handler()
156 ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
158 writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
159 amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev); in acp63_irq_handler()
161 schedule_work(&amd_manager->amd_sdw_irq_thread); in acp63_irq_handler()
166 writel(ACP_ERROR_IRQ, adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
167 /* TODO: Report SoundWire Manager instance errors */ in acp63_irq_handler()
168 writel(0, adata->acp63_base + ACP_SW0_I2S_ERROR_REASON); in acp63_irq_handler()
169 writel(0, adata->acp63_base + ACP_SW1_I2S_ERROR_REASON); in acp63_irq_handler()
170 writel(0, adata->acp63_base + ACP_ERROR_STATUS); in acp63_irq_handler()
175 ps_pdm_data = dev_get_drvdata(&adata->pdm_dev->dev); in acp63_irq_handler()
176 writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
177 if (ps_pdm_data->capture_stream) in acp63_irq_handler()
178 snd_pcm_period_elapsed(ps_pdm_data->capture_stream); in acp63_irq_handler()
184 writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
206 adata->sdw0_dma_intr_stat[stream_id] = 1; in acp63_irq_handler()
214 adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
215 adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1; in acp63_irq_handler()
221 adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
222 adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1; in acp63_irq_handler()
243 return -ENODEV; in acp_scan_sdw_devices()
247 return -ENODEV; in acp_scan_sdw_devices()
249 acp_data->info.handle = sdw_dev->handle; in acp_scan_sdw_devices()
250 acp_data->info.count = AMD_SDW_MAX_MANAGERS; in acp_scan_sdw_devices()
251 return amd_sdw_scan_controller(&acp_data->info); in acp_scan_sdw_devices()
262 sdw_res.addr = acp_data->addr; in amd_sdw_probe()
263 sdw_res.reg_range = acp_data->reg_range; in amd_sdw_probe()
264 sdw_res.handle = acp_data->info.handle; in amd_sdw_probe()
267 sdw_res.acp_lock = &acp_data->acp_lock; in amd_sdw_probe()
268 sdw_res.count = acp_data->info.count; in amd_sdw_probe()
269 sdw_res.mmio_base = acp_data->acp63_base; in amd_sdw_probe()
270 sdw_res.link_mask = acp_data->info.link_mask; in amd_sdw_probe()
271 ret = sdw_amd_probe(&sdw_res, &acp_data->sdw); in amd_sdw_probe()
273 dev_err(dev, "error: SoundWire probe failed\n"); in amd_sdw_probe()
279 if (acp_data->sdw) in amd_sdw_exit()
280 sdw_amd_exit(acp_data->sdw); in amd_sdw_exit()
281 acp_data->sdw = NULL; in amd_sdw_exit()
293 if (acp_data->info.count) { in acp63_sdw_machine_select()
294 ret = sdw_amd_get_slave_info(acp_data->sdw); in acp63_sdw_machine_select()
299 for (mach = acp_data->machines; mach; mach++) { in acp63_sdw_machine_select()
300 if (!mach->links) in acp63_sdw_machine_select()
302 link = mach->links; in acp63_sdw_machine_select()
303 for (i = 0; i < acp_data->info.count && link->num_adr; link++, i++) { in acp63_sdw_machine_select()
305 acp_data->sdw->ids, in acp63_sdw_machine_select()
306 acp_data->sdw->num_slaves)) in acp63_sdw_machine_select()
309 if (i == acp_data->info.count || !link->num_adr) in acp63_sdw_machine_select()
312 if (mach && mach->link_mask) { in acp63_sdw_machine_select()
313 mach->mach_params.links = mach->links; in acp63_sdw_machine_select()
314 mach->mach_params.link_mask = mach->link_mask; in acp63_sdw_machine_select()
318 dev_dbg(dev, "No SoundWire machine driver found\n"); in acp63_sdw_machine_select()
349 if (adata->is_sdw_dev && adata->is_sdw_config) { in acp63_machine_register()
350 size = sizeof(*adata->machines); in acp63_machine_register()
353 adata->mach_dev = platform_device_register_data(dev, mach->drv_name, in acp63_machine_register()
356 if (IS_ERR(adata->mach_dev)) { in acp63_machine_register()
358 "cannot register Machine device for SoundWire Interface\n"); in acp63_machine_register()
359 return PTR_ERR(adata->mach_dev); in acp63_machine_register()
363 } else if (adata->is_pdm_dev && !adata->is_sdw_dev && adata->is_pdm_config) { in acp63_machine_register()
364 adata->mach_dev = platform_device_register_data(dev, "acp_ps_mach", in acp63_machine_register()
366 if (IS_ERR(adata->mach_dev)) { in acp63_machine_register()
368 return PTR_ERR(adata->mach_dev); in acp63_machine_register()
383 config = readl(acp_data->acp63_base + ACP_PIN_CONFIG); in get_acp63_device_config()
389 acp_data->is_pdm_config = true; in get_acp63_device_config()
393 acp_data->is_sdw_config = true; in get_acp63_device_config()
401 acp_data->is_pdm_config = true; in get_acp63_device_config()
402 acp_data->is_sdw_config = true; in get_acp63_device_config()
408 if (acp_data->is_pdm_config) { in get_acp63_device_config()
409 pdm_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0); in get_acp63_device_config()
411 /* is_dmic_dev flag will be set when ACP PDM controller device exists */ in get_acp63_device_config()
412 if (!acpi_dev_get_property(pdm_dev, "acp-audio-device-type", in get_acp63_device_config()
414 obj->integer.value == ACP_DMIC_DEV) in get_acp63_device_config()
419 if (acp_data->is_sdw_config) { in get_acp63_device_config()
420 ret = acp_scan_sdw_devices(&pci->dev, ACP63_SDW_ADDR); in get_acp63_device_config()
421 if (!ret && acp_data->info.link_mask) in get_acp63_device_config()
425 acp_data->is_pdm_dev = is_dmic_dev; in get_acp63_device_config()
426 acp_data->is_sdw_dev = is_sdw_dev; in get_acp63_device_config()
428 dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n"); in get_acp63_device_config()
429 return -ENODEV; in get_acp63_device_config()
443 pdevinfo->name = name; in acp63_fill_platform_dev_info()
444 pdevinfo->id = id; in acp63_fill_platform_dev_info()
445 pdevinfo->parent = parent; in acp63_fill_platform_dev_info()
446 pdevinfo->num_res = num_res; in acp63_fill_platform_dev_info()
447 pdevinfo->res = res; in acp63_fill_platform_dev_info()
448 pdevinfo->data = data; in acp63_fill_platform_dev_info()
449 pdevinfo->size_data = size_data; in acp63_fill_platform_dev_info()
450 pdevinfo->fwnode = fw_node; in acp63_fill_platform_dev_info()
459 parent = &pci->dev; in create_acp63_platform_devs()
461 if (adata->is_sdw_dev || adata->is_pdm_dev) { in create_acp63_platform_devs()
462 adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL); in create_acp63_platform_devs()
463 if (!adata->res) { in create_acp63_platform_devs()
464 ret = -ENOMEM; in create_acp63_platform_devs()
467 adata->res->flags = IORESOURCE_MEM; in create_acp63_platform_devs()
468 adata->res->start = addr; in create_acp63_platform_devs()
469 adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START); in create_acp63_platform_devs()
473 if (adata->is_pdm_dev && adata->is_pdm_config) { in create_acp63_platform_devs()
475 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
477 adata->pdm_dev = platform_device_register_full(&pdevinfo); in create_acp63_platform_devs()
478 if (IS_ERR(adata->pdm_dev)) { in create_acp63_platform_devs()
479 dev_err(&pci->dev, in create_acp63_platform_devs()
481 ret = PTR_ERR(adata->pdm_dev); in create_acp63_platform_devs()
485 acp63_fill_platform_dev_info(&pdevinfo, parent, NULL, "dmic-codec", in create_acp63_platform_devs()
487 adata->dmic_codec_dev = platform_device_register_full(&pdevinfo); in create_acp63_platform_devs()
488 if (IS_ERR(adata->dmic_codec_dev)) { in create_acp63_platform_devs()
489 dev_err(&pci->dev, in create_acp63_platform_devs()
491 ret = PTR_ERR(adata->dmic_codec_dev); in create_acp63_platform_devs()
495 if (adata->is_sdw_dev && adata->is_sdw_config) { in create_acp63_platform_devs()
496 ret = amd_sdw_probe(&pci->dev); in create_acp63_platform_devs()
498 if (adata->is_pdm_dev) in create_acp63_platform_devs()
505 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
507 adata->sdw_dma_dev = platform_device_register_full(&pdevinfo); in create_acp63_platform_devs()
508 if (IS_ERR(adata->sdw_dma_dev)) { in create_acp63_platform_devs()
509 dev_err(&pci->dev, in create_acp63_platform_devs()
511 ret = PTR_ERR(adata->sdw_dma_dev); in create_acp63_platform_devs()
512 if (adata->is_pdm_dev) in create_acp63_platform_devs()
521 platform_device_unregister(adata->dmic_codec_dev); in create_acp63_platform_devs()
523 platform_device_unregister(adata->pdm_dev); in create_acp63_platform_devs()
525 if (acp63_deinit(adata->acp63_base, &pci->dev)) in create_acp63_platform_devs()
526 dev_err(&pci->dev, "ACP de-init failed\n"); in create_acp63_platform_devs()
543 return -ENODEV; in snd_acp63_probe()
546 switch (pci->revision) { in snd_acp63_probe()
550 dev_dbg(&pci->dev, "acp63 pci device not found\n"); in snd_acp63_probe()
551 return -ENODEV; in snd_acp63_probe()
554 dev_err(&pci->dev, "pci_enable_device failed\n"); in snd_acp63_probe()
555 return -ENODEV; in snd_acp63_probe()
560 dev_err(&pci->dev, "pci_request_regions failed\n"); in snd_acp63_probe()
563 adata = devm_kzalloc(&pci->dev, sizeof(struct acp63_dev_data), in snd_acp63_probe()
566 ret = -ENOMEM; in snd_acp63_probe()
571 adata->acp63_base = devm_ioremap(&pci->dev, addr, in snd_acp63_probe()
573 if (!adata->acp63_base) { in snd_acp63_probe()
574 ret = -ENOMEM; in snd_acp63_probe()
577 adata->addr = addr; in snd_acp63_probe()
578 adata->reg_range = ACP63_REG_END - ACP63_REG_START; in snd_acp63_probe()
581 mutex_init(&adata->acp_lock); in snd_acp63_probe()
582 ret = acp63_init(adata->acp63_base, &pci->dev); in snd_acp63_probe()
585 ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler, in snd_acp63_probe()
588 dev_err(&pci->dev, "ACP PCI IRQ request failed\n"); in snd_acp63_probe()
592 /* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */ in snd_acp63_probe()
594 dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret); in snd_acp63_probe()
599 dev_err(&pci->dev, "ACP platform devices creation failed\n"); in snd_acp63_probe()
602 ret = acp63_machine_register(&pci->dev); in snd_acp63_probe()
604 dev_err(&pci->dev, "ACP machine register failed\n"); in snd_acp63_probe()
608 device_set_wakeup_enable(&pci->dev, true); in snd_acp63_probe()
609 pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS); in snd_acp63_probe()
610 pm_runtime_use_autosuspend(&pci->dev); in snd_acp63_probe()
611 pm_runtime_put_noidle(&pci->dev); in snd_acp63_probe()
612 pm_runtime_allow(&pci->dev); in snd_acp63_probe()
615 if (acp63_deinit(adata->acp63_base, &pci->dev)) in snd_acp63_probe()
616 dev_err(&pci->dev, "ACP de-init failed\n"); in snd_acp63_probe()
629 sdw0_en = readl(adata->acp63_base + ACP_SW0_EN); in check_acp_sdw_enable_status()
630 sdw1_en = readl(adata->acp63_base + ACP_SW1_EN); in check_acp_sdw_enable_status()
638 val = readl(adata->acp63_base + ACP_SW0_WAKE_EN); in handle_acp63_sdw_pme_event()
639 if (val && adata->sdw->pdev[0]) in handle_acp63_sdw_pme_event()
640 pm_request_resume(&adata->sdw->pdev[0]->dev); in handle_acp63_sdw_pme_event()
642 val = readl(adata->acp63_base + ACP_SW1_WAKE_EN); in handle_acp63_sdw_pme_event()
643 if (val && adata->sdw->pdev[1]) in handle_acp63_sdw_pme_event()
644 pm_request_resume(&adata->sdw->pdev[1]->dev); in handle_acp63_sdw_pme_event()
653 if (adata->is_sdw_dev) { in snd_acp63_suspend()
654 adata->sdw_en_stat = check_acp_sdw_enable_status(adata); in snd_acp63_suspend()
655 if (adata->sdw_en_stat) in snd_acp63_suspend()
658 ret = acp63_deinit(adata->acp63_base, dev); in snd_acp63_suspend()
660 dev_err(dev, "ACP de-init failed\n"); in snd_acp63_suspend()
671 if (adata->sdw_en_stat) in snd_acp63_runtime_resume()
674 ret = acp63_init(adata->acp63_base, dev); in snd_acp63_runtime_resume()
680 if (!adata->sdw_en_stat) in snd_acp63_runtime_resume()
691 if (adata->sdw_en_stat) in snd_acp63_resume()
694 ret = acp63_init(adata->acp63_base, dev); in snd_acp63_resume()
712 if (adata->sdw) { in snd_acp63_remove()
714 platform_device_unregister(adata->sdw_dma_dev); in snd_acp63_remove()
716 if (adata->is_pdm_dev) { in snd_acp63_remove()
717 platform_device_unregister(adata->pdm_dev); in snd_acp63_remove()
718 platform_device_unregister(adata->dmic_codec_dev); in snd_acp63_remove()
720 if (adata->mach_dev) in snd_acp63_remove()
721 platform_device_unregister(adata->mach_dev); in snd_acp63_remove()
722 ret = acp63_deinit(adata->acp63_base, &pci->dev); in snd_acp63_remove()
724 dev_err(&pci->dev, "ACP de-init failed\n"); in snd_acp63_remove()
725 pm_runtime_forbid(&pci->dev); in snd_acp63_remove()
726 pm_runtime_get_noresume(&pci->dev); in snd_acp63_remove()