mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	ASoC: amd: add platform devices for acp6x pdm driver and dmic driver
ACP6.x IP has PDM decoder block. Create a platform device for it, so that the PDM platform driver can be bound to this device. Pass PCI resources like MMIO to this platform device. Create a platform device for generic dmic codec driver. Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com> Link: https://lore.kernel.org/r/20211018112044.1705805-5-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
		
							parent
							
								
									8c7161f2c9
								
							
						
					
					
						commit
						fc329c1de4
					
				| @ -9,6 +9,10 @@ | ||||
| 
 | ||||
| #define ACP_DEVICE_ID 0x15E2 | ||||
| #define ACP6x_PHY_BASE_ADDRESS 0x1240000 | ||||
| #define ACP6x_REG_START		0x1240000 | ||||
| #define ACP6x_REG_END		0x1250200 | ||||
| #define ACP6x_DEVS		2 | ||||
| #define ACP6x_PDM_MODE		1 | ||||
| 
 | ||||
| #define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK	0x00010001 | ||||
| #define ACP_PGFSM_CNTL_POWER_ON_MASK	1 | ||||
| @ -22,6 +26,25 @@ | ||||
| #define ACP_ERROR_MASK 0x20000000 | ||||
| #define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF | ||||
| 
 | ||||
| enum acp_config { | ||||
| 	ACP_CONFIG_0 = 0, | ||||
| 	ACP_CONFIG_1, | ||||
| 	ACP_CONFIG_2, | ||||
| 	ACP_CONFIG_3, | ||||
| 	ACP_CONFIG_4, | ||||
| 	ACP_CONFIG_5, | ||||
| 	ACP_CONFIG_6, | ||||
| 	ACP_CONFIG_7, | ||||
| 	ACP_CONFIG_8, | ||||
| 	ACP_CONFIG_9, | ||||
| 	ACP_CONFIG_10, | ||||
| 	ACP_CONFIG_11, | ||||
| 	ACP_CONFIG_12, | ||||
| 	ACP_CONFIG_13, | ||||
| 	ACP_CONFIG_14, | ||||
| 	ACP_CONFIG_15, | ||||
| }; | ||||
| 
 | ||||
| static inline u32 acp6x_readl(void __iomem *base_addr) | ||||
| { | ||||
| 	return readl(base_addr - ACP6x_PHY_BASE_ADDRESS); | ||||
|  | ||||
| @ -9,11 +9,15 @@ | ||||
| #include <linux/module.h> | ||||
| #include <linux/io.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/platform_device.h> | ||||
| 
 | ||||
| #include "acp6x.h" | ||||
| 
 | ||||
| struct acp6x_dev_data { | ||||
| 	void __iomem *acp6x_base; | ||||
| 	struct resource *res; | ||||
| 	bool acp6x_audio_mode; | ||||
| 	struct platform_device *pdev[ACP6x_DEVS]; | ||||
| }; | ||||
| 
 | ||||
| static int acp6x_power_on(void __iomem *acp_base) | ||||
| @ -117,7 +121,9 @@ static int snd_acp6x_probe(struct pci_dev *pci, | ||||
| 			   const struct pci_device_id *pci_id) | ||||
| { | ||||
| 	struct acp6x_dev_data *adata; | ||||
| 	int ret; | ||||
| 	struct platform_device_info pdevinfo[ACP6x_DEVS]; | ||||
| 	int ret, index; | ||||
| 	int val = 0x00; | ||||
| 	u32 addr; | ||||
| 
 | ||||
| 	/* Yellow Carp device check */ | ||||
| @ -154,8 +160,62 @@ static int snd_acp6x_probe(struct pci_dev *pci, | ||||
| 	ret = acp6x_init(adata->acp6x_base); | ||||
| 	if (ret) | ||||
| 		goto release_regions; | ||||
| 	val = acp6x_readl(adata->acp6x_base + ACP_PIN_CONFIG); | ||||
| 	switch (val) { | ||||
| 	case ACP_CONFIG_0: | ||||
| 	case ACP_CONFIG_1: | ||||
| 	case ACP_CONFIG_2: | ||||
| 	case ACP_CONFIG_3: | ||||
| 	case ACP_CONFIG_9: | ||||
| 	case ACP_CONFIG_15: | ||||
| 		dev_info(&pci->dev, "Audio Mode %d\n", val); | ||||
| 		break; | ||||
| 	default: | ||||
| 		adata->res = devm_kzalloc(&pci->dev, | ||||
| 					  sizeof(struct resource), | ||||
| 					  GFP_KERNEL); | ||||
| 		if (!adata->res) { | ||||
| 			ret = -ENOMEM; | ||||
| 			goto de_init; | ||||
| 		} | ||||
| 
 | ||||
| 		adata->res->name = "acp_iomem"; | ||||
| 		adata->res->flags = IORESOURCE_MEM; | ||||
| 		adata->res->start = addr; | ||||
| 		adata->res->end = addr + (ACP6x_REG_END - ACP6x_REG_START); | ||||
| 
 | ||||
| 		adata->acp6x_audio_mode = ACP6x_PDM_MODE; | ||||
| 
 | ||||
| 		memset(&pdevinfo, 0, sizeof(pdevinfo)); | ||||
| 		pdevinfo[0].name = "acp_yc_pdm_dma"; | ||||
| 		pdevinfo[0].id = 0; | ||||
| 		pdevinfo[0].parent = &pci->dev; | ||||
| 		pdevinfo[0].num_res = 1; | ||||
| 		pdevinfo[0].res = adata->res; | ||||
| 
 | ||||
| 		pdevinfo[1].name = "dmic-codec"; | ||||
| 		pdevinfo[1].id = 0; | ||||
| 		pdevinfo[1].parent = &pci->dev; | ||||
| 
 | ||||
| 		for (index = 0; index < ACP6x_DEVS; index++) { | ||||
| 			adata->pdev[index] = | ||||
| 				platform_device_register_full(&pdevinfo[index]); | ||||
| 			if (IS_ERR(adata->pdev[index])) { | ||||
| 				dev_err(&pci->dev, "cannot register %s device\n", | ||||
| 					pdevinfo[index].name); | ||||
| 				ret = PTR_ERR(adata->pdev[index]); | ||||
| 				goto unregister_devs; | ||||
| 			} | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| 	return 0; | ||||
| unregister_devs: | ||||
| 	for (--index; index >= 0; index--) | ||||
| 		platform_device_unregister(adata->pdev[index]); | ||||
| de_init: | ||||
| 	if (acp6x_deinit(adata->acp6x_base)) | ||||
| 		dev_err(&pci->dev, "ACP de-init failed\n"); | ||||
| release_regions: | ||||
| 	pci_release_regions(pci); | ||||
| disable_pci: | ||||
| @ -167,9 +227,13 @@ disable_pci: | ||||
| static void snd_acp6x_remove(struct pci_dev *pci) | ||||
| { | ||||
| 	struct acp6x_dev_data *adata; | ||||
| 	int ret; | ||||
| 	int ret, index; | ||||
| 
 | ||||
| 	adata = pci_get_drvdata(pci); | ||||
| 	if (adata->acp6x_audio_mode == ACP6x_PDM_MODE) { | ||||
| 		for (index = 0; index < ACP6x_DEVS; index++) | ||||
| 			platform_device_unregister(adata->pdev[index]); | ||||
| 	} | ||||
| 	ret = acp6x_deinit(adata->acp6x_base); | ||||
| 	if (ret) | ||||
| 		dev_err(&pci->dev, "ACP de-init failed\n"); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Vijendar Mukunda
						Vijendar Mukunda