sound/soc/amd/acp/acp-legacy-common.c

Source file repositories/reference/linux-study-clean/sound/soc/amd/acp/acp-legacy-common.c

File Facts

System
Linux kernel
Corpus path
sound/soc/amd/acp/acp-legacy-common.c
Extension
.c
Size
18512 bytes
Lines
666
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ext_intr_stat & stream->irq_bit) {
			writel(stream->irq_bit,
			       ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
			snd_pcm_period_elapsed(stream->substream);
			i2s_flag = 1;
		}
		if (chip->rsrc->no_of_ctrls == 2) {
			if (ext_intr_stat1 & stream->irq_bit) {
				writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip,
				       (rsrc->irqp_used - 1)));
				snd_pcm_period_elapsed(stream->substream);
				i2s_flag = 1;
			}
		}
	}
	spin_unlock(&chip->acp_lock);
	if (i2s_flag)
		return IRQ_HANDLED;

	return IRQ_NONE;
}

int acp_enable_interrupts(struct acp_chip_info *chip)
{
	struct acp_resource *rsrc;
	u32 ext_intr_ctrl;

	rsrc = chip->rsrc;
	writel(0x01, ACP_EXTERNAL_INTR_ENB(chip));
	ext_intr_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
	ext_intr_ctrl |= ACP_ERROR_MASK;
	writel(ext_intr_ctrl, ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));

	return 0;
}
EXPORT_SYMBOL_NS_GPL(acp_enable_interrupts, "SND_SOC_ACP_COMMON");

int acp_disable_interrupts(struct acp_chip_info *chip)
{
	struct acp_resource *rsrc;

	rsrc = chip->rsrc;
	writel(ACP_EXT_INTR_STAT_CLEAR_MASK, ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
	writel(0x00, ACP_EXTERNAL_INTR_ENB(chip));

	return 0;
}
EXPORT_SYMBOL_NS_GPL(acp_disable_interrupts, "SND_SOC_ACP_COMMON");

static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream,
				    struct snd_soc_dai *dai)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct acp_stream *stream = runtime->private_data;
	struct device *dev = dai->component->dev;
	struct acp_chip_info *chip = dev_get_platdata(dev);

	u32 physical_addr, pdm_size, period_bytes;

	period_bytes = frames_to_bytes(runtime, runtime->period_size);
	pdm_size = frames_to_bytes(runtime, runtime->buffer_size);
	physical_addr = stream->reg_offset + MEM_WINDOW_START;

	/* Init ACP PDM Ring buffer */
	writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR);
	writel(pdm_size, chip->base + ACP_WOV_RX_RINGBUFSIZE);
	writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
	writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL);
}

static void set_acp_pdm_clk(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{
	struct device *dev = dai->component->dev;
	struct acp_chip_info *chip = dev_get_platdata(dev);
	unsigned int pdm_ctrl;

	/* Enable default ACP PDM clk */
	writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL);
	pdm_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL);
	pdm_ctrl |= PDM_MISC_CTRL_MASK;
	writel(pdm_ctrl, chip->base + ACP_WOV_MISC_CTRL);
	set_acp_pdm_ring_buffer(substream, dai);
}

void restore_acp_pdm_params(struct snd_pcm_substream *substream,
			    struct acp_chip_info *chip)
{
	struct snd_soc_dai *dai;
	struct snd_soc_pcm_runtime *soc_runtime;

Annotation

Implementation Notes