Skip to content

Commit

Permalink
ASoC: amd: irq handler changes for ACP5x PCM dma driver
Browse files Browse the repository at this point in the history
Whenever audio data equal to the I2S FIFO watermark level are
produced/consumed, interrupt is generated.
Acknowledge the interrupt.

Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://lore.kernel.org/r/20210721180430.11571-7-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Vijendar Mukunda authored and Mark Brown committed Jul 22, 2021
1 parent 77f6144 commit fc2c806
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
61 changes: 60 additions & 1 deletion sound/soc/amd/vangogh/acp5x-pcm-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,55 @@ static const struct snd_soc_component_driver acp5x_i2s_component = {
.name = DRV_NAME,
};

static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
{
struct i2s_dev_data *vg_i2s_data;
u16 irq_flag;
u32 val;

vg_i2s_data = dev_id;
if (!vg_i2s_data)
return IRQ_NONE;

irq_flag = 0;
val = acp_readl(vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
if ((val & BIT(HS_TX_THRESHOLD)) && vg_i2s_data->play_stream) {
acp_writel(BIT(HS_TX_THRESHOLD), vg_i2s_data->acp5x_base +
ACP_EXTERNAL_INTR_STAT);
snd_pcm_period_elapsed(vg_i2s_data->play_stream);
irq_flag = 1;
}
if ((val & BIT(I2S_TX_THRESHOLD)) && vg_i2s_data->i2ssp_play_stream) {
acp_writel(BIT(I2S_TX_THRESHOLD),
vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
snd_pcm_period_elapsed(vg_i2s_data->i2ssp_play_stream);
irq_flag = 1;
}

if ((val & BIT(HS_RX_THRESHOLD)) && vg_i2s_data->capture_stream) {
acp_writel(BIT(HS_RX_THRESHOLD), vg_i2s_data->acp5x_base +
ACP_EXTERNAL_INTR_STAT);
snd_pcm_period_elapsed(vg_i2s_data->capture_stream);
irq_flag = 1;
}
if ((val & BIT(I2S_RX_THRESHOLD)) && vg_i2s_data->i2ssp_capture_stream) {
acp_writel(BIT(I2S_RX_THRESHOLD),
vg_i2s_data->acp5x_base + ACP_EXTERNAL_INTR_STAT);
snd_pcm_period_elapsed(vg_i2s_data->i2ssp_capture_stream);
irq_flag = 1;
}

if (irq_flag)
return IRQ_HANDLED;
else
return IRQ_NONE;
}

static int acp5x_audio_probe(struct platform_device *pdev)
{
struct resource *res;
struct i2s_dev_data *adata;
unsigned int irqflags;
int status;

if (!pdev->dev.platform_data) {
Expand All @@ -47,12 +92,26 @@ static int acp5x_audio_probe(struct platform_device *pdev)
resource_size(res));
if (!adata->acp5x_base)
return -ENOMEM;

res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
return -ENODEV;
}

adata->i2s_irq = res->start;
dev_set_drvdata(&pdev->dev, adata);
status = devm_snd_soc_register_component(&pdev->dev,
&acp5x_i2s_component,
NULL, 0);
if (status)
if (status) {
dev_err(&pdev->dev, "Fail to register acp i2s component\n");
return status;
}
status = devm_request_irq(&pdev->dev, adata->i2s_irq, i2s_irq_handler,
irqflags, "ACP5x_I2S_IRQ", adata);
if (status)
dev_err(&pdev->dev, "ACP5x I2S IRQ request failed\n");

return status;
}
Expand Down
9 changes: 9 additions & 0 deletions sound/soc/amd/vangogh/acp5x.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,18 @@
#define I2S_MODE 0
#define ACP5x_I2S_MODE 1
#define ACP5x_RES 4
#define I2S_RX_THRESHOLD 27
#define I2S_TX_THRESHOLD 28
#define HS_TX_THRESHOLD 24
#define HS_RX_THRESHOLD 23

struct i2s_dev_data {
unsigned int i2s_irq;
void __iomem *acp5x_base;
struct snd_pcm_substream *play_stream;
struct snd_pcm_substream *capture_stream;
struct snd_pcm_substream *i2ssp_play_stream;
struct snd_pcm_substream *i2ssp_capture_stream;
};

/* common header file uses exact offset rather than relative
Expand Down

0 comments on commit fc2c806

Please sign in to comment.