drivers/iio/adc/exynos_adc.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/exynos_adc.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/exynos_adc.c
Extension
.c
Size
18130 bytes
Lines
722
Domain
Driver Families
Bucket
drivers/iio
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

struct exynos_adc {
	struct exynos_adc_data	*data;
	struct device		*dev;
	void __iomem		*regs;
	struct regmap		*pmu_map;
	struct clk		*clk;
	struct clk		*sclk;
	unsigned int		irq;
	struct regulator	*vdd;

	struct completion	completion;

	u32			value;
	unsigned int            version;

	/*
	 * Lock to protect from potential concurrent access to the
	 * completion callback during a manual conversion. For this driver
	 * a wait-callback is used to wait for the conversion result,
	 * so in the meantime no other read request (or conversion start)
	 * must be performed, otherwise it would interfere with the
	 * current conversion result.
	 */
	struct mutex		lock;
};

struct exynos_adc_data {
	int num_channels;
	bool needs_sclk;
	bool needs_adc_phy;
	int phy_offset;
	u32 mask;

	void (*init_hw)(struct exynos_adc *info);
	void (*exit_hw)(struct exynos_adc *info);
	void (*clear_irq)(struct exynos_adc *info);
	void (*start_conv)(struct exynos_adc *info, unsigned long addr);
};

static void exynos_adc_unprepare_clk(struct exynos_adc *info)
{
	if (info->data->needs_sclk)
		clk_unprepare(info->sclk);
	clk_unprepare(info->clk);
}

static int exynos_adc_prepare_clk(struct exynos_adc *info)
{
	int ret;

	ret = clk_prepare(info->clk);
	if (ret) {
		dev_err(info->dev, "failed preparing adc clock: %d\n", ret);
		return ret;
	}

	if (info->data->needs_sclk) {
		ret = clk_prepare(info->sclk);
		if (ret) {
			clk_unprepare(info->clk);
			dev_err(info->dev,
				"failed preparing sclk_adc clock: %d\n", ret);
			return ret;
		}
	}

	return 0;
}

static void exynos_adc_disable_clk(struct exynos_adc *info)
{
	if (info->data->needs_sclk)
		clk_disable(info->sclk);
	clk_disable(info->clk);
}

static int exynos_adc_enable_clk(struct exynos_adc *info)
{
	int ret;

	ret = clk_enable(info->clk);
	if (ret) {
		dev_err(info->dev, "failed enabling adc clock: %d\n", ret);
		return ret;
	}

	if (info->data->needs_sclk) {
		ret = clk_enable(info->sclk);
		if (ret) {
			clk_disable(info->clk);

Annotation

Implementation Notes