drivers/iio/adc/ad7192.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7192.c
Extension
.c
Size
42384 bytes
Lines
1470
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 ad7192_chip_info {
	unsigned int			chip_id;
	const char			*name;
	const struct iio_chan_spec	*channels;
	u8				num_channels;
	const struct ad_sigma_delta_info	*sigma_delta_info;
	const struct iio_info		*info;
	int (*parse_channels)(struct iio_dev *indio_dev);
};

struct ad7192_state {
	const struct ad7192_chip_info	*chip_info;
	struct clk			*mclk;
	struct clk_hw			int_clk_hw;
	u16				int_vref_mv;
	u32				aincom_mv;
	u32				fclk;
	u32				mode;
	u32				conf;
	u32				scale_avail[8][2];
	u32				filter_freq_avail[4][2];
	u32				oversampling_ratio_avail[4];
	u8				gpocon;
	u8				clock_sel;
	struct mutex			lock;	/* protect sensor state */
	u8				syscalib_mode[8];

	struct ad_sigma_delta		sd;
};

static const char * const ad7192_syscalib_modes[] = {
	[AD7192_SYSCALIB_ZERO_SCALE] = "zero_scale",
	[AD7192_SYSCALIB_FULL_SCALE] = "full_scale",
};

static int ad7192_set_syscalib_mode(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan,
				    unsigned int mode)
{
	struct ad7192_state *st = iio_priv(indio_dev);

	st->syscalib_mode[chan->channel] = mode;

	return 0;
}

static int ad7192_get_syscalib_mode(struct iio_dev *indio_dev,
				    const struct iio_chan_spec *chan)
{
	struct ad7192_state *st = iio_priv(indio_dev);

	return st->syscalib_mode[chan->channel];
}

static ssize_t ad7192_write_syscalib(struct iio_dev *indio_dev,
				     uintptr_t private,
				     const struct iio_chan_spec *chan,
				     const char *buf, size_t len)
{
	struct ad7192_state *st = iio_priv(indio_dev);
	bool sys_calib;
	int ret, temp;

	ret = kstrtobool(buf, &sys_calib);
	if (ret)
		return ret;

	if (!iio_device_claim_direct(indio_dev))
		return -EBUSY;

	temp = st->syscalib_mode[chan->channel];
	if (sys_calib) {
		if (temp == AD7192_SYSCALIB_ZERO_SCALE)
			ret = ad_sd_calibrate(&st->sd, AD7192_MODE_CAL_SYS_ZERO,
					      chan->address);
		else
			ret = ad_sd_calibrate(&st->sd, AD7192_MODE_CAL_SYS_FULL,
					      chan->address);
	}

	iio_device_release_direct(indio_dev);

	return ret ? ret : len;
}

static const struct iio_enum ad7192_syscalib_mode_enum = {
	.items = ad7192_syscalib_modes,
	.num_items = ARRAY_SIZE(ad7192_syscalib_modes),
	.set = ad7192_set_syscalib_mode,
	.get = ad7192_get_syscalib_mode

Annotation

Implementation Notes