Lines Matching +full:soundwire +full:- +full:controller
1 // SPDX-License-Identifier: GPL-2.0+
19 #include <linux/soundwire/sdw_amd.h>
109 pdev_index = adata->sdw_dma_dev_index; in acp63_irq_thread()
110 sdw_dma_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev); in acp63_irq_thread()
113 if (adata->sdw0_dma_intr_stat[stream_index]) { in acp63_irq_thread()
114 if (sdw_dma_data->sdw0_dma_stream[stream_index]) in acp63_irq_thread()
115 snd_pcm_period_elapsed(sdw_dma_data->sdw0_dma_stream[stream_index]); in acp63_irq_thread()
116 adata->sdw0_dma_intr_stat[stream_index] = 0; in acp63_irq_thread()
120 if (adata->sdw1_dma_intr_stat[stream_index]) { in acp63_irq_thread()
121 if (sdw_dma_data->sdw1_dma_stream[stream_index]) in acp63_irq_thread()
122 snd_pcm_period_elapsed(sdw_dma_data->sdw1_dma_stream[stream_index]); in acp63_irq_thread()
123 adata->sdw1_dma_intr_stat[stream_index] = 0; in acp63_irq_thread()
149 ext_intr_stat = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
151 writel(ACP_SDW0_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
152 pdev_index = adata->sdw0_dev_index; in acp63_irq_handler()
153 amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev); in acp63_irq_handler()
155 schedule_work(&amd_manager->amd_sdw_irq_thread); in acp63_irq_handler()
159 ext_intr_stat1 = readl(adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
161 writel(ACP_SDW1_STAT, adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
162 pdev_index = adata->sdw1_dev_index; in acp63_irq_handler()
163 amd_manager = dev_get_drvdata(&adata->pdev[pdev_index]->dev); in acp63_irq_handler()
165 schedule_work(&amd_manager->amd_sdw_irq_thread); in acp63_irq_handler()
170 writel(ACP_ERROR_IRQ, adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
171 /* TODO: Report SoundWire Manager instance errors */ in acp63_irq_handler()
172 writel(0, adata->acp63_base + ACP_SW0_I2S_ERROR_REASON); in acp63_irq_handler()
173 writel(0, adata->acp63_base + ACP_SW1_I2S_ERROR_REASON); in acp63_irq_handler()
174 writel(0, adata->acp63_base + ACP_ERROR_STATUS); in acp63_irq_handler()
179 pdev_index = adata->pdm_dev_index; in acp63_irq_handler()
180 ps_pdm_data = dev_get_drvdata(&adata->pdev[pdev_index]->dev); in acp63_irq_handler()
181 writel(BIT(PDM_DMA_STAT), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
182 if (ps_pdm_data->capture_stream) in acp63_irq_handler()
183 snd_pcm_period_elapsed(ps_pdm_data->capture_stream); in acp63_irq_handler()
189 writel(BIT(index), adata->acp63_base + ACP_EXTERNAL_INTR_STAT); in acp63_irq_handler()
211 adata->sdw0_dma_intr_stat[stream_id] = 1; in acp63_irq_handler()
219 adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
220 adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_RX] = 1; in acp63_irq_handler()
226 adata->acp63_base + ACP_EXTERNAL_INTR_STAT1); in acp63_irq_handler()
227 adata->sdw1_dma_intr_stat[ACP_SDW1_AUDIO1_TX] = 1; in acp63_irq_handler()
254 * Found controller, find links supported. in sdw_amd_scan_controller()
256 ret = fwnode_property_read_u32_array((acp_data->sdw_fw_node), "mipi-sdw-manager-list", in sdw_amd_scan_controller()
260 dev_dbg(dev, "Failed to read mipi-sdw-manager-list: %d\n", ret); in sdw_amd_scan_controller()
261 return -EINVAL; in sdw_amd_scan_controller()
267 return -EINVAL; in sdw_amd_scan_controller()
271 dev_dbg(dev, "No SoundWire Managers detected\n"); in sdw_amd_scan_controller()
272 return -EINVAL; in sdw_amd_scan_controller()
274 dev_dbg(dev, "ACPI reports %d SoundWire Manager devices\n", count); in sdw_amd_scan_controller()
275 acp_data->sdw_manager_count = count; in sdw_amd_scan_controller()
277 snprintf(name, sizeof(name), "mipi-sdw-link-%d-subproperties", index); in sdw_amd_scan_controller()
278 link = fwnode_get_named_child_node(acp_data->sdw_fw_node, name); in sdw_amd_scan_controller()
281 return -EIO; in sdw_amd_scan_controller()
284 ret = fwnode_property_read_u32(link, "amd-sdw-power-mode", &acp_sdw_power_mode); in sdw_amd_scan_controller()
288 * when SoundWire configuration is selected from acp pin config, in sdw_amd_scan_controller()
289 * based on manager instances count, acp init/de-init sequence should be in sdw_amd_scan_controller()
291 * SoundWire manager instances. in sdw_amd_scan_controller()
294 acp_data->acp_reset = false; in sdw_amd_scan_controller()
310 dmic_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_DMIC_ADDR, 0); in get_acp63_device_config()
312 /* is_dmic_dev flag will be set when ACP PDM controller device exists */ in get_acp63_device_config()
313 if (!acpi_dev_get_property(dmic_dev, "acp-audio-device-type", in get_acp63_device_config()
315 obj->integer.value == ACP_DMIC_DEV) in get_acp63_device_config()
319 sdw_dev = acpi_find_child_device(ACPI_COMPANION(&pci->dev), ACP63_SDW_ADDR, 0); in get_acp63_device_config()
321 acp_data->sdw_fw_node = acpi_fwnode_handle(sdw_dev); in get_acp63_device_config()
322 ret = sdw_amd_scan_controller(&pci->dev); in get_acp63_device_config()
323 /* is_sdw_dev flag will be set when SoundWire Manager device exists */ in get_acp63_device_config()
328 return -ENODEV; in get_acp63_device_config()
329 dev_dbg(&pci->dev, "Audio Mode %d\n", config); in get_acp63_device_config()
336 acp_data->pdev_config = ACP63_PDM_DEV_CONFIG; in get_acp63_device_config()
337 acp_data->pdev_count = ACP63_PDM_MODE_DEVS; in get_acp63_device_config()
343 switch (acp_data->sdw_manager_count) { in get_acp63_device_config()
345 acp_data->pdev_config = ACP63_SDW_DEV_CONFIG; in get_acp63_device_config()
346 acp_data->pdev_count = ACP63_SDW0_MODE_DEVS; in get_acp63_device_config()
349 acp_data->pdev_config = ACP63_SDW_DEV_CONFIG; in get_acp63_device_config()
350 acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS; in get_acp63_device_config()
353 return -EINVAL; in get_acp63_device_config()
364 switch (acp_data->sdw_manager_count) { in get_acp63_device_config()
366 acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG; in get_acp63_device_config()
367 acp_data->pdev_count = ACP63_SDW0_PDM_MODE_DEVS; in get_acp63_device_config()
370 acp_data->pdev_config = ACP63_SDW_PDM_DEV_CONFIG; in get_acp63_device_config()
371 acp_data->pdev_count = ACP63_SDW0_SDW1_PDM_MODE_DEVS; in get_acp63_device_config()
374 return -EINVAL; in get_acp63_device_config()
377 acp_data->pdev_config = ACP63_PDM_DEV_CONFIG; in get_acp63_device_config()
378 acp_data->pdev_count = ACP63_PDM_MODE_DEVS; in get_acp63_device_config()
380 switch (acp_data->sdw_manager_count) { in get_acp63_device_config()
382 acp_data->pdev_config = ACP63_SDW_DEV_CONFIG; in get_acp63_device_config()
383 acp_data->pdev_count = ACP63_SDW0_MODE_DEVS; in get_acp63_device_config()
386 acp_data->pdev_config = ACP63_SDW_DEV_CONFIG; in get_acp63_device_config()
387 acp_data->pdev_count = ACP63_SDW0_SDW1_MODE_DEVS; in get_acp63_device_config()
390 return -EINVAL; in get_acp63_device_config()
409 pdevinfo->name = name; in acp63_fill_platform_dev_info()
410 pdevinfo->id = id; in acp63_fill_platform_dev_info()
411 pdevinfo->parent = parent; in acp63_fill_platform_dev_info()
412 pdevinfo->num_res = num_res; in acp63_fill_platform_dev_info()
413 pdevinfo->res = res; in acp63_fill_platform_dev_info()
414 pdevinfo->data = data; in acp63_fill_platform_dev_info()
415 pdevinfo->size_data = size_data; in acp63_fill_platform_dev_info()
416 pdevinfo->fwnode = fw_node; in acp63_fill_platform_dev_info()
427 parent = &pci->dev; in create_acp63_platform_devs()
428 dev_dbg(&pci->dev, in create_acp63_platform_devs()
429 "%s pdev_config:0x%x pdev_count:0x%x\n", __func__, adata->pdev_config, in create_acp63_platform_devs()
430 adata->pdev_count); in create_acp63_platform_devs()
431 if (adata->pdev_config) { in create_acp63_platform_devs()
432 adata->res = devm_kzalloc(&pci->dev, sizeof(struct resource), GFP_KERNEL); in create_acp63_platform_devs()
433 if (!adata->res) { in create_acp63_platform_devs()
434 ret = -ENOMEM; in create_acp63_platform_devs()
437 adata->res->flags = IORESOURCE_MEM; in create_acp63_platform_devs()
438 adata->res->start = addr; in create_acp63_platform_devs()
439 adata->res->end = addr + (ACP63_REG_END - ACP63_REG_START); in create_acp63_platform_devs()
443 switch (adata->pdev_config) { in create_acp63_platform_devs()
445 adata->pdm_dev_index = 0; in create_acp63_platform_devs()
447 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
448 acp63_fill_platform_dev_info(&pdevinfo[1], parent, NULL, "dmic-codec", in create_acp63_platform_devs()
454 if (adata->pdev_count == ACP63_SDW0_MODE_DEVS) { in create_acp63_platform_devs()
455 sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata), in create_acp63_platform_devs()
458 ret = -ENOMEM; in create_acp63_platform_devs()
462 sdw_pdata->instance = 0; in create_acp63_platform_devs()
463 sdw_pdata->acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
464 adata->sdw0_dev_index = 0; in create_acp63_platform_devs()
465 adata->sdw_dma_dev_index = 1; in create_acp63_platform_devs()
466 acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node, in create_acp63_platform_devs()
467 "amd_sdw_manager", 0, adata->res, 1, in create_acp63_platform_devs()
470 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
471 } else if (adata->pdev_count == ACP63_SDW0_SDW1_MODE_DEVS) { in create_acp63_platform_devs()
472 sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2, in create_acp63_platform_devs()
475 ret = -ENOMEM; in create_acp63_platform_devs()
481 sdw_pdata[0].acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
482 sdw_pdata[1].acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
483 sdw_pdata->acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
484 adata->sdw0_dev_index = 0; in create_acp63_platform_devs()
485 adata->sdw1_dev_index = 1; in create_acp63_platform_devs()
486 adata->sdw_dma_dev_index = 2; in create_acp63_platform_devs()
487 acp63_fill_platform_dev_info(&pdevinfo[0], parent, adata->sdw_fw_node, in create_acp63_platform_devs()
488 "amd_sdw_manager", 0, adata->res, 1, in create_acp63_platform_devs()
490 acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node, in create_acp63_platform_devs()
491 "amd_sdw_manager", 1, adata->res, 1, in create_acp63_platform_devs()
494 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
498 if (adata->pdev_count == ACP63_SDW0_PDM_MODE_DEVS) { in create_acp63_platform_devs()
499 sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata), in create_acp63_platform_devs()
502 ret = -ENOMEM; in create_acp63_platform_devs()
506 sdw_pdata->instance = 0; in create_acp63_platform_devs()
507 sdw_pdata->acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
508 adata->pdm_dev_index = 0; in create_acp63_platform_devs()
509 adata->sdw0_dev_index = 1; in create_acp63_platform_devs()
510 adata->sdw_dma_dev_index = 2; in create_acp63_platform_devs()
512 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
513 acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node, in create_acp63_platform_devs()
514 "amd_sdw_manager", 0, adata->res, 1, in create_acp63_platform_devs()
517 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
518 acp63_fill_platform_dev_info(&pdevinfo[3], parent, NULL, "dmic-codec", in create_acp63_platform_devs()
520 } else if (adata->pdev_count == ACP63_SDW0_SDW1_PDM_MODE_DEVS) { in create_acp63_platform_devs()
521 sdw_pdata = devm_kzalloc(&pci->dev, sizeof(struct acp_sdw_pdata) * 2, in create_acp63_platform_devs()
524 ret = -ENOMEM; in create_acp63_platform_devs()
529 sdw_pdata[0].acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
530 sdw_pdata[1].acp_sdw_lock = &adata->acp_lock; in create_acp63_platform_devs()
531 adata->pdm_dev_index = 0; in create_acp63_platform_devs()
532 adata->sdw0_dev_index = 1; in create_acp63_platform_devs()
533 adata->sdw1_dev_index = 2; in create_acp63_platform_devs()
534 adata->sdw_dma_dev_index = 3; in create_acp63_platform_devs()
536 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
537 acp63_fill_platform_dev_info(&pdevinfo[1], parent, adata->sdw_fw_node, in create_acp63_platform_devs()
538 "amd_sdw_manager", 0, adata->res, 1, in create_acp63_platform_devs()
540 acp63_fill_platform_dev_info(&pdevinfo[2], parent, adata->sdw_fw_node, in create_acp63_platform_devs()
541 "amd_sdw_manager", 1, adata->res, 1, in create_acp63_platform_devs()
544 0, adata->res, 1, NULL, 0); in create_acp63_platform_devs()
545 acp63_fill_platform_dev_info(&pdevinfo[4], parent, NULL, "dmic-codec", in create_acp63_platform_devs()
550 dev_dbg(&pci->dev, "No PDM or SoundWire manager devices found\n"); in create_acp63_platform_devs()
554 for (index = 0; index < adata->pdev_count; index++) { in create_acp63_platform_devs()
555 adata->pdev[index] = platform_device_register_full(&pdevinfo[index]); in create_acp63_platform_devs()
556 if (IS_ERR(adata->pdev[index])) { in create_acp63_platform_devs()
557 dev_err(&pci->dev, in create_acp63_platform_devs()
559 ret = PTR_ERR(adata->pdev[index]); in create_acp63_platform_devs()
565 for (--index; index >= 0; index--) in create_acp63_platform_devs()
566 platform_device_unregister(adata->pdev[index]); in create_acp63_platform_devs()
568 if (acp63_deinit(adata->acp63_base, &pci->dev)) in create_acp63_platform_devs()
569 dev_err(&pci->dev, "ACP de-init failed\n"); in create_acp63_platform_devs()
587 return -ENODEV; in snd_acp63_probe()
590 switch (pci->revision) { in snd_acp63_probe()
594 dev_dbg(&pci->dev, "acp63 pci device not found\n"); in snd_acp63_probe()
595 return -ENODEV; in snd_acp63_probe()
598 dev_err(&pci->dev, "pci_enable_device failed\n"); in snd_acp63_probe()
599 return -ENODEV; in snd_acp63_probe()
604 dev_err(&pci->dev, "pci_request_regions failed\n"); in snd_acp63_probe()
607 adata = devm_kzalloc(&pci->dev, sizeof(struct acp63_dev_data), in snd_acp63_probe()
610 ret = -ENOMEM; in snd_acp63_probe()
615 adata->acp63_base = devm_ioremap(&pci->dev, addr, in snd_acp63_probe()
617 if (!adata->acp63_base) { in snd_acp63_probe()
618 ret = -ENOMEM; in snd_acp63_probe()
624 * This flag should be set to false only when SoundWire manager power mode in snd_acp63_probe()
627 adata->acp_reset = true; in snd_acp63_probe()
630 mutex_init(&adata->acp_lock); in snd_acp63_probe()
631 ret = acp63_init(adata->acp63_base, &pci->dev); in snd_acp63_probe()
634 ret = devm_request_threaded_irq(&pci->dev, pci->irq, acp63_irq_handler, in snd_acp63_probe()
637 dev_err(&pci->dev, "ACP PCI IRQ request failed\n"); in snd_acp63_probe()
640 val = readl(adata->acp63_base + ACP_PIN_CONFIG); in snd_acp63_probe()
642 /* ACP PCI driver probe should be continued even PDM or SoundWire Devices are not found */ in snd_acp63_probe()
644 dev_dbg(&pci->dev, "get acp device config failed:%d\n", ret); in snd_acp63_probe()
649 dev_err(&pci->dev, "ACP platform devices creation failed\n"); in snd_acp63_probe()
653 pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS); in snd_acp63_probe()
654 pm_runtime_use_autosuspend(&pci->dev); in snd_acp63_probe()
655 pm_runtime_put_noidle(&pci->dev); in snd_acp63_probe()
656 pm_runtime_allow(&pci->dev); in snd_acp63_probe()
659 if (acp63_deinit(adata->acp63_base, &pci->dev)) in snd_acp63_probe()
660 dev_err(&pci->dev, "ACP de-init failed\n"); in snd_acp63_probe()
675 if (adata->acp_reset) { in snd_acp63_suspend()
676 ret = acp63_deinit(adata->acp63_base, dev); in snd_acp63_suspend()
678 dev_err(dev, "ACP de-init failed\n"); in snd_acp63_suspend()
689 if (adata->acp_reset) { in snd_acp63_resume()
690 ret = acp63_init(adata->acp63_base, dev); in snd_acp63_resume()
708 for (index = 0; index < adata->pdev_count; index++) in snd_acp63_remove()
709 platform_device_unregister(adata->pdev[index]); in snd_acp63_remove()
710 ret = acp63_deinit(adata->acp63_base, &pci->dev); in snd_acp63_remove()
712 dev_err(&pci->dev, "ACP de-init failed\n"); in snd_acp63_remove()
713 pm_runtime_forbid(&pci->dev); in snd_acp63_remove()
714 pm_runtime_get_noresume(&pci->dev); in snd_acp63_remove()