diff options
| author | Mark Brown <[email protected]> | 2022-08-16 14:47:35 +0100 | 
|---|---|---|
| committer | Mark Brown <[email protected]> | 2022-08-16 14:47:35 +0100 | 
| commit | 2d7ea7635a1286d5954b155a47e862cbcd48fff5 (patch) | |
| tree | c6fb88a123276a07c284aed9893e4d6717ed4c54 /sound/soc/amd/acp/acp-platform.c | |
| parent | 3b43a713f6b09ffbca468847000dabeaf92492df (diff) | |
| parent | 12229b7e50cfa95fda55b83a2617eafd6ac4c8c5 (diff) | |
Add support for linked list to store acp_stream and tdm support.
Merge series from Venkata Prasad Potturu <[email protected]>:
This patch is to add support for linked list to store acp_stream instead
static array and add tdm support for acp I2S stream.
Diffstat (limited to 'sound/soc/amd/acp/acp-platform.c')
| -rw-r--r-- | sound/soc/amd/acp/acp-platform.c | 40 | 
1 files changed, 19 insertions, 21 deletions
| diff --git a/sound/soc/amd/acp/acp-platform.c b/sound/soc/amd/acp/acp-platform.c index f561d39b33e2..beee53aedeaf 100644 --- a/sound/soc/amd/acp/acp-platform.c +++ b/sound/soc/amd/acp/acp-platform.c @@ -94,7 +94,7 @@ static irqreturn_t i2s_irq_handler(int irq, void *data)  	struct acp_resource *rsrc = adata->rsrc;  	struct acp_stream *stream;  	u16 i2s_flag = 0; -	u32 ext_intr_stat, ext_intr_stat1, i; +	u32 ext_intr_stat, ext_intr_stat1;  	if (!adata)  		return IRQ_NONE; @@ -104,14 +104,13 @@ static irqreturn_t i2s_irq_handler(int irq, void *data)  	ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(adata, rsrc->irqp_used)); -	for (i = 0; i < ACP_MAX_STREAM; i++) { -		stream = adata->stream[i]; +	spin_lock(&adata->acp_lock); +	list_for_each_entry(stream, &adata->stream_list, list) {  		if (stream && (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; -			break;  		}  		if (adata->rsrc->no_of_ctrls == 2) {  			if (stream && (ext_intr_stat1 & stream->irq_bit)) { @@ -119,10 +118,10 @@ static irqreturn_t i2s_irq_handler(int irq, void *data)  				       (rsrc->irqp_used - 1)));  				snd_pcm_period_elapsed(stream->substream);  				i2s_flag = 1; -				break;  			}  		}  	} +	spin_unlock(&adata->acp_lock);  	if (i2s_flag)  		return IRQ_HANDLED; @@ -146,9 +145,8 @@ static void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream  	writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);  } -static void config_acp_dma(struct acp_dev_data *adata, int cpu_id, int size) +static void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size)  { -	struct acp_stream *stream = adata->stream[cpu_id];  	struct snd_pcm_substream *substream = stream->substream;  	struct acp_resource *rsrc = adata->rsrc;  	dma_addr_t addr = substream->dma_buffer.addr; @@ -174,13 +172,10 @@ static void config_acp_dma(struct acp_dev_data *adata, int cpu_id, int size)  static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_substream *substream)  { -	struct snd_soc_pcm_runtime *soc_runtime = asoc_substream_to_rtd(substream); -	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_runtime, 0);  	struct snd_pcm_runtime *runtime = substream->runtime;  	struct device *dev = component->dev;  	struct acp_dev_data *adata = dev_get_drvdata(dev);  	struct acp_stream *stream; -	int stream_id = cpu_dai->driver->id * 2 + substream->stream;  	int ret;  	stream = kzalloc(sizeof(*stream), GFP_KERNEL); @@ -188,7 +183,10 @@ static int acp_dma_open(struct snd_soc_component *component, struct snd_pcm_subs  		return -ENOMEM;  	stream->substream = substream; -	adata->stream[stream_id] = stream; + +	spin_lock_irq(&adata->acp_lock); +	list_add_tail(&stream->list, &adata->stream_list); +	spin_unlock_irq(&adata->acp_lock);  	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)  		runtime->hw = acp_pcm_hardware_playback; @@ -212,16 +210,13 @@ static int acp_dma_hw_params(struct snd_soc_component *component,  			     struct snd_pcm_substream *substream,  			     struct snd_pcm_hw_params *params)  { -	struct snd_soc_pcm_runtime *soc_runtime = asoc_substream_to_rtd(substream);  	struct acp_dev_data *adata = snd_soc_component_get_drvdata(component); -	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_runtime, 0);  	struct acp_stream *stream = substream->runtime->private_data; -	int stream_id = cpu_dai->driver->id * 2 + substream->stream;  	u64 size = params_buffer_bytes(params);  	/* Configure ACP DMA block with params */  	config_pte_for_stream(adata, stream); -	config_acp_dma(adata, stream_id, size); +	config_acp_dma(adata, stream, size);  	return 0;  } @@ -261,16 +256,15 @@ static int acp_dma_new(struct snd_soc_component *component,  static int acp_dma_close(struct snd_soc_component *component,  			 struct snd_pcm_substream *substream)  { -	struct snd_soc_pcm_runtime *soc_runtime = asoc_substream_to_rtd(substream); -	struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(soc_runtime, 0);  	struct device *dev = component->dev;  	struct acp_dev_data *adata = dev_get_drvdata(dev); -	struct acp_stream *stream; -	int stream_id = cpu_dai->driver->id * 2 + substream->stream; +	struct acp_stream *stream = substream->runtime->private_data; -	stream = adata->stream[stream_id]; +	/* Remove entry from list */ +	spin_lock_irq(&adata->acp_lock); +	list_del(&stream->list); +	spin_unlock_irq(&adata->acp_lock);  	kfree(stream); -	adata->stream[stream_id] = NULL;  	return 0;  } @@ -305,6 +299,10 @@ int acp_platform_register(struct device *dev)  		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); |