sound/soc/qcom/lpass-sc7280.c

Source file repositories/reference/linux-study-clean/sound/soc/qcom/lpass-sc7280.c

File Facts

System
Linux kernel
Corpus path
sound/soc/qcom/lpass-sc7280.c
Extension
.c
Size
14503 bytes
Lines
456
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: implementation source
Status
source 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 (direction == SNDRV_PCM_STREAM_PLAYBACK) {
			chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
						   v->rdma_channels);

			if (chan >= v->rdma_channels)
				return -EBUSY;
		} else {
			chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
						  v->wrdma_channel_start +
						  v->wrdma_channels,
						  v->wrdma_channel_start);

			if (chan >= v->wrdma_channel_start + v->wrdma_channels)
				return -EBUSY;
		}
		set_bit(chan, &drvdata->dma_ch_bit_map);
		break;
	case LPASS_DP_RX:
		chan = find_first_zero_bit(&drvdata->hdmi_dma_ch_bit_map,
					   v->hdmi_rdma_channels);
		if (chan >= v->hdmi_rdma_channels)
			return -EBUSY;
		set_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
		break;
	case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9:
		chan = find_first_zero_bit(&drvdata->rxtx_dma_ch_bit_map,
					   v->rxtx_rdma_channels);
		if (chan >= v->rxtx_rdma_channels)
			return -EBUSY;
		break;
	case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8:
		chan = find_next_zero_bit(&drvdata->rxtx_dma_ch_bit_map,
					  v->rxtx_wrdma_channel_start +
					  v->rxtx_wrdma_channels,
					  v->rxtx_wrdma_channel_start);
		if (chan >= v->rxtx_wrdma_channel_start + v->rxtx_wrdma_channels)
			return -EBUSY;
		set_bit(chan, &drvdata->rxtx_dma_ch_bit_map);
		break;
	case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8:
		chan = find_next_zero_bit(&drvdata->va_dma_ch_bit_map,
					  v->va_wrdma_channel_start +
					  v->va_wrdma_channels,
					  v->va_wrdma_channel_start);
		if (chan >= v->va_wrdma_channel_start + v->va_wrdma_channels)
			return -EBUSY;
		set_bit(chan, &drvdata->va_dma_ch_bit_map);
		break;
	default:
		break;
	}

	return chan;
}

static int sc7280_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id)
{
	switch (dai_id) {
	case MI2S_PRIMARY ... MI2S_QUINARY:
		clear_bit(chan, &drvdata->dma_ch_bit_map);
		break;
	case LPASS_DP_RX:
		clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
		break;
	case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9:
	case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8:
		clear_bit(chan, &drvdata->rxtx_dma_ch_bit_map);
		break;
	case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8:
		clear_bit(chan, &drvdata->va_dma_ch_bit_map);
		break;
	default:
		break;
	}

	return 0;
}

static int sc7280_lpass_init(struct platform_device *pdev)
{
	struct lpass_data *drvdata = platform_get_drvdata(pdev);
	const struct lpass_variant *variant = drvdata->variant;
	struct device *dev = &pdev->dev;
	int ret, i;

	drvdata->clks = devm_kcalloc(dev, variant->num_clks,
				     sizeof(*drvdata->clks), GFP_KERNEL);
	if (!drvdata->clks)
		return -ENOMEM;

Annotation

Implementation Notes