diff options
Diffstat (limited to 'sound/soc/amd/acp/acp-platform.c')
-rw-r--r-- | sound/soc/amd/acp/acp-platform.c | 145 |
1 files changed, 36 insertions, 109 deletions
diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index aa330aeeb301..b3eddf76aaa4 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -21,7 +21,6 @@ #include <linux/dma-mapping.h> #include "amd.h" -#include "../mach-config.h" #include "acp-mach.h" #define DRV_NAME "acp_i2s_dma" @@ -108,101 +107,37 @@ static const struct snd_pcm_hardware acp6x_pcm_hardware_capture = { .periods_max = CAPTURE_MAX_NUM_PERIODS, }; -int acp_machine_select(struct acp_dev_data *adata) +void config_pte_for_stream(struct acp_chip_info *chip, struct acp_stream *stream) { - struct snd_soc_acpi_mach *mach; - int size, platform; - - if (adata->flag == FLAG_AMD_LEGACY_ONLY_DMIC) { - platform = adata->acp_rev; - adata->mach_dev = platform_device_register_data(adata->dev, "acp-pdm-mach", - PLATFORM_DEVID_NONE, &platform, - sizeof(platform)); - } else { - size = sizeof(*adata->machines); - mach = snd_soc_acpi_find_machine(adata->machines); - if (!mach) { - dev_err(adata->dev, "warning: No matching ASoC machine driver found\n"); - return -EINVAL; - } - mach->mach_params.subsystem_rev = adata->acp_rev; - adata->mach_dev = platform_device_register_data(adata->dev, mach->drv_name, - PLATFORM_DEVID_NONE, mach, size); - } - if (IS_ERR(adata->mach_dev)) - dev_warn(adata->dev, "Unable to register Machine device\n"); - return 0; -} -EXPORT_SYMBOL_NS_GPL(acp_machine_select, "SND_SOC_ACP_COMMON"); - -static irqreturn_t i2s_irq_handler(int irq, void *data) -{ - struct acp_dev_data *adata = data; - struct acp_resource *rsrc = adata->rsrc; - struct acp_stream *stream; - u16 i2s_flag = 0; - u32 ext_intr_stat, ext_intr_stat1; - - if (adata->rsrc->no_of_ctrls == 2) - ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(adata, (rsrc->irqp_used - 1))); - - ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - - spin_lock(&adata->acp_lock); - list_for_each_entry(stream, &adata->stream_list, list) { - if (ext_intr_stat & stream->irq_bit) { - writel(stream->irq_bit, - ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); - snd_pcm_period_elapsed(stream->substream); - i2s_flag = 1; - } - if (adata->rsrc->no_of_ctrls == 2) { - if (ext_intr_stat1 & stream->irq_bit) { - writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(adata, - (rsrc->irqp_used - 1))); - snd_pcm_period_elapsed(stream->substream); - i2s_flag = 1; - } - } - } - spin_unlock(&adata->acp_lock); - if (i2s_flag) - return IRQ_HANDLED; - - return IRQ_NONE; -} - -void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream) -{ - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; u32 reg_val; reg_val = rsrc->sram_pte_offset; stream->reg_offset = 0x02000000; - writel((reg_val + GRP1_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); + writel((reg_val + GRP1_OFFSET) | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_1); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1); - writel((reg_val + GRP2_OFFSET) | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); + writel((reg_val + GRP2_OFFSET) | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_2); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2); - writel(reg_val | BIT(31), adata->acp_base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5); - writel(PAGE_SIZE_4K_ENABLE, adata->acp_base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5); + writel(reg_val | BIT(31), chip->base + ACPAXI2AXI_ATU_BASE_ADDR_GRP_5); + writel(PAGE_SIZE_4K_ENABLE, chip->base + ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5); - writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL); + writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL); } EXPORT_SYMBOL_NS_GPL(config_pte_for_stream, "SND_SOC_ACP_COMMON"); -void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size) +void config_acp_dma(struct acp_chip_info *chip, struct acp_stream *stream, int size) { struct snd_pcm_substream *substream = stream->substream; - struct acp_resource *rsrc = adata->rsrc; + struct acp_resource *rsrc = chip->rsrc; dma_addr_t addr = substream->dma_buffer.addr; int num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT); u32 low, high, val; u16 page_idx; - switch (adata->acp_rev) { + switch (chip->acp_rev) { case ACP70_PCI_ID: case ACP71_PCI_ID: switch (stream->dai_id) { @@ -228,7 +163,7 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s val = 0x6000; break; default: - dev_err(adata->dev, "Invalid dai id %x\n", stream->dai_id); + dev_err(chip->dev, "Invalid dai id %x\n", stream->dai_id); return; } break; @@ -241,9 +176,9 @@ void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int s /* Load the low address of page int ACP SRAM through SRBM */ low = lower_32_bits(addr); high = upper_32_bits(addr); - writel(low, adata->acp_base + rsrc->scratch_reg_offset + val); + writel(low, chip->base + rsrc->scratch_reg_offset + val); high |= BIT(31); - writel(high, adata->acp_base + rsrc->scratch_reg_offset + val + 4); + writel(high, chip->base + rsrc->scratch_reg_offset + val + 4); /* Move to next physically contiguous page */ val += 8; @@ -256,7 +191,6 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs { struct snd_pcm_runtime *runtime = substream->runtime; struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); struct acp_chip_info *chip; struct acp_stream *stream; int ret; @@ -266,7 +200,7 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs return -ENOMEM; stream->substream = substream; - chip = dev_get_platdata(dev); + chip = dev_get_drvdata(dev->parent); switch (chip->acp_rev) { case ACP63_PCI_ID: case ACP70_PCI_ID: @@ -306,11 +240,11 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs } runtime->private_data = stream; - writel(1, ACP_EXTERNAL_INTR_ENB(adata)); + writel(1, ACP_EXTERNAL_INTR_ENB(chip)); - spin_lock_irq(&adata->acp_lock); - list_add_tail(&stream->list, &adata->stream_list); - spin_unlock_irq(&adata->acp_lock); + spin_lock_irq(&chip->acp_lock); + list_add_tail(&stream->list, &chip->stream_list); + spin_unlock_irq(&chip->acp_lock); return ret; } @@ -319,13 +253,14 @@ static int acp_dma_hw_params(struct snd_soc_component *component, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct acp_dev_data *adata = snd_soc_component_get_drvdata(component); + struct device *dev = component->dev; + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; u64 size = params_buffer_bytes(params); /* Configure ACP DMA block with params */ - config_pte_for_stream(adata, stream); - config_acp_dma(adata, stream, size); + config_pte_for_stream(chip, stream); + config_acp_dma(chip, stream, size); return 0; } @@ -334,7 +269,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; u32 pos, buffersize; u64 bytescount; @@ -342,7 +277,7 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_soc_component *component, buffersize = frames_to_bytes(substream->runtime, substream->runtime->buffer_size); - bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream); + bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream); if (bytescount > stream->bytescount) bytescount -= stream->bytescount; @@ -366,13 +301,13 @@ static int acp_dma_close(struct snd_soc_component *component, struct snd_pcm_substream *substream) { struct device *dev = component->dev; - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip = dev_get_drvdata(dev->parent); struct acp_stream *stream = substream->runtime->private_data; /* Remove entry from list */ - spin_lock_irq(&adata->acp_lock); + spin_lock_irq(&chip->acp_lock); list_del(&stream->list); - spin_unlock_irq(&adata->acp_lock); + spin_unlock_irq(&chip->acp_lock); kfree(stream); return 0; @@ -390,38 +325,30 @@ static const struct snd_soc_component_driver acp_pcm_component = { int acp_platform_register(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); + struct acp_chip_info *chip; struct snd_soc_dai_driver; unsigned int status; - status = devm_request_irq(dev, adata->i2s_irq, i2s_irq_handler, - IRQF_SHARED, "ACP_I2S_IRQ", adata); - if (status) { - dev_err(dev, "ACP I2S IRQ request failed\n"); - return status; + chip = dev_get_platdata(dev); + if (!chip || !chip->base) { + dev_err(dev, "ACP chip data is NULL\n"); + return -ENODEV; } status = devm_snd_soc_register_component(dev, &acp_pcm_component, - adata->dai_driver, - adata->num_dai); + chip->dai_driver, + chip->num_dai); if (status) { dev_err(dev, "Fail to register acp i2s component\n"); return status; } - INIT_LIST_HEAD(&adata->stream_list); - spin_lock_init(&adata->acp_lock); - return 0; } EXPORT_SYMBOL_NS_GPL(acp_platform_register, "SND_SOC_ACP_COMMON"); int acp_platform_unregister(struct device *dev) { - struct acp_dev_data *adata = dev_get_drvdata(dev); - - if (adata->mach_dev) - platform_device_unregister(adata->mach_dev); return 0; } EXPORT_SYMBOL_NS_GPL(acp_platform_unregister, "SND_SOC_ACP_COMMON"); |