drivers/iio/adc/ad7405.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7405.c
Extension
.c
Size
6195 bytes
Lines
254
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 ad7405_chip_info {
	const char *name;
	const unsigned int full_scale_mv;
};

struct ad7405_state {
	struct iio_backend *back;
	const struct ad7405_chip_info *info;
	unsigned int ref_frequency;
	unsigned int dec_rate;
};

static int ad7405_set_dec_rate(struct iio_dev *indio_dev,
			       const struct iio_chan_spec *chan,
			       unsigned int dec_rate)
{
	struct ad7405_state *st = iio_priv(indio_dev);
	int ret;

	if (dec_rate > 4096 || dec_rate < 32)
		return -EINVAL;

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

	ret = iio_backend_oversampling_ratio_set(st->back, chan->scan_index, dec_rate);
	iio_device_release_direct(indio_dev);

	if (ret < 0)
		return ret;

	st->dec_rate = dec_rate;

	return 0;
}

static int ad7405_read_raw(struct iio_dev *indio_dev,
			   const struct iio_chan_spec *chan, int *val,
			   int *val2, long info)
{
	struct ad7405_state *st = iio_priv(indio_dev);

	switch (info) {
	case IIO_CHAN_INFO_SCALE:
		*val = st->info->full_scale_mv;
		*val2 = indio_dev->channels[0].scan_type.realbits - 1;
		return IIO_VAL_FRACTIONAL_LOG2;
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		*val = st->dec_rate;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SAMP_FREQ:
		*val = DIV_ROUND_CLOSEST_ULL(st->ref_frequency, st->dec_rate);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_OFFSET:
		*val = -(1 << (indio_dev->channels[0].scan_type.realbits - 1));
		return IIO_VAL_INT;
	default:
		return -EINVAL;
	}
}

static int ad7405_write_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan, int val,
			    int val2, long info)
{
	switch (info) {
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		if (val < 0)
			return -EINVAL;
		return ad7405_set_dec_rate(indio_dev, chan, val);
	default:
		return -EINVAL;
	}
}

static int ad7405_read_avail(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan,
			     const int **vals, int *type, int *length,
			     long info)
{
	switch (info) {
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		*vals = ad7405_dec_rates_range;
		*type = IIO_VAL_INT;
		return IIO_AVAIL_RANGE;
	default:
		return -EINVAL;
	}
}

Annotation

Implementation Notes