drivers/iio/adc/rzg2l_adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/rzg2l_adc.c
Extension
.c
Size
14962 bytes
Lines
607
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 rzg2l_adc_hw_params {
	u16 default_adsmp[2];
	u16 adsmp_mask;
	u16 adint_inten_mask;
	u8 default_adcmp;
	u8 num_channels;
	bool adivc;
};

struct rzg2l_adc_data {
	const struct iio_chan_spec *channels;
	u8 num_channels;
};

struct rzg2l_adc {
	void __iomem *base;
	struct reset_control *presetn;
	struct reset_control *adrstn;
	const struct rzg2l_adc_data *data;
	const struct rzg2l_adc_hw_params *hw_params;
	struct completion completion;
	struct mutex lock;
	u16 last_val[RZG2L_ADC_MAX_CHANNELS];
};

/**
 * struct rzg2l_adc_channel - ADC channel descriptor
 * @name: ADC channel name
 * @type: ADC channel type
 */
struct rzg2l_adc_channel {
	const char * const name;
	enum iio_chan_type type;
};

static const struct rzg2l_adc_channel rzg2l_adc_channels[] = {
	{ "adc0", IIO_VOLTAGE },
	{ "adc1", IIO_VOLTAGE },
	{ "adc2", IIO_VOLTAGE },
	{ "adc3", IIO_VOLTAGE },
	{ "adc4", IIO_VOLTAGE },
	{ "adc5", IIO_VOLTAGE },
	{ "adc6", IIO_VOLTAGE },
	{ "adc7", IIO_VOLTAGE },
	{ "adc8", IIO_TEMP },
};

static unsigned int rzg2l_adc_readl(struct rzg2l_adc *adc, u32 reg)
{
	return readl(adc->base + reg);
}

static void rzg2l_adc_writel(struct rzg2l_adc *adc, unsigned int reg, u32 val)
{
	writel(val, adc->base + reg);
}

static void rzg2l_adc_pwr(struct rzg2l_adc *adc, bool on)
{
	u32 reg;

	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
	if (on)
		reg |= RZG2L_ADM0_PWDWNB;
	else
		reg &= ~RZG2L_ADM0_PWDWNB;
	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
	udelay(2);
}

static void rzg2l_adc_start_stop(struct rzg2l_adc *adc, bool start)
{
	int ret;
	u32 reg;

	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
	if (start)
		reg |= RZG2L_ADM0_ADCE;
	else
		reg &= ~RZG2L_ADM0_ADCE;
	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);

	if (start)
		return;

	ret = read_poll_timeout(rzg2l_adc_readl, reg, !(reg & (RZG2L_ADM0_ADBSY | RZG2L_ADM0_ADCE)),
				200, 1000, true, adc, RZG2L_ADM(0));
	if (ret)
		pr_err("%s stopping ADC timed out\n", __func__);
}

Annotation

Implementation Notes