sound/soc/qcom/lpass-sc7180.c

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

File Facts

System
Linux kernel
Corpus path
sound/soc/qcom/lpass-sc7180.c
Extension
.c
Size
9497 bytes
Lines
326
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->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);
	} else {
		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);
	}
	return chan;
}

static int sc7180_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id)
{
	if (dai_id == LPASS_DP_RX)
		clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map);
	else
		clear_bit(chan, &drvdata->dma_ch_bit_map);

	return 0;
}

static int sc7180_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;

	drvdata->num_clks = variant->num_clks;

	for (i = 0; i < drvdata->num_clks; i++)
		drvdata->clks[i].id = variant->clk_name[i];

	ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks);
	if (ret) {
		dev_err(dev, "Failed to get clocks %d\n", ret);
		return ret;
	}

	ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
	if (ret) {
		dev_err(dev, "sc7180 clk_enable failed\n");
		return ret;
	}

	return 0;
}

static int sc7180_lpass_exit(struct platform_device *pdev)
{
	struct lpass_data *drvdata = platform_get_drvdata(pdev);

	clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
	return 0;
}

static int sc7180_lpass_dev_resume(struct device *dev)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);

	return clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
}

static int sc7180_lpass_dev_suspend(struct device *dev)
{
	struct lpass_data *drvdata = dev_get_drvdata(dev);

Annotation

Implementation Notes