drivers/iio/adc/ad4080.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad4080.c
Extension
.c
Size
21250 bytes
Lines
746
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 ad4080_chip_info {
	const char *name;
	unsigned int product_id;
	int num_scales;
	const unsigned int (*scale_table)[2];
	const struct iio_chan_spec *channels;
	unsigned int num_channels;
	unsigned int lvds_cnv_clk_cnt_max;
};

struct ad4080_state {
	struct regmap			*regmap;
	struct iio_backend		*back;
	const struct ad4080_chip_info	*info;
	/*
	 * Synchronize access to members the of driver state, and ensure
	 * atomicity of consecutive regmap operations.
	 */
	struct mutex			lock;
	unsigned int			num_lanes;
	unsigned long			clk_rate;
	enum ad4080_filter_type		filter_type;
	bool				lvds_cnv_en;
};

static const struct regmap_config ad4080_regmap_config = {
	.reg_bits = 16,
	.val_bits = 8,
	.read_flag_mask = BIT(7),
	.max_register = 0x29,
};

static int ad4080_reg_access(struct iio_dev *indio_dev, unsigned int reg,
			     unsigned int writeval, unsigned int *readval)
{
	struct ad4080_state *st = iio_priv(indio_dev);

	if (readval)
		return regmap_read(st->regmap, reg, readval);

	return regmap_write(st->regmap, reg, writeval);
}

static int ad4080_get_scale(struct ad4080_state *st, int *val, int *val2)
{
	unsigned int tmp;

	tmp = (st->info->scale_table[0][0] * 1000000ULL) >>
		    st->info->channels[0].scan_type.realbits;
	*val = tmp / 1000000;
	*val2 = tmp % 1000000;

	return IIO_VAL_INT_PLUS_NANO;
}

static unsigned int ad4080_get_dec_rate(struct iio_dev *dev,
					const struct iio_chan_spec *chan)
{
	struct ad4080_state *st = iio_priv(dev);
	int ret;
	unsigned int data;

	ret = regmap_read(st->regmap, AD4080_REG_FILTER_CONFIG, &data);
	if (ret)
		return ret;

	return 1 << (FIELD_GET(AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK, data) + 1);
}

static int ad4080_set_dec_rate(struct iio_dev *dev,
			       const struct iio_chan_spec *chan,
			       unsigned int mode)
{
	struct ad4080_state *st = iio_priv(dev);

	guard(mutex)(&st->lock);

	if ((st->filter_type >= SINC_5 && mode >= 512) || mode < 2)
		return -EINVAL;

	return regmap_update_bits(st->regmap, AD4080_REG_FILTER_CONFIG,
				  AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK,
				  FIELD_PREP(AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK,
					     (ilog2(mode) - 1)));
}

static int ad4080_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2, long m)
{

Annotation

Implementation Notes