drivers/iio/dac/ad9739a.c

Source file repositories/reference/linux-study-clean/drivers/iio/dac/ad9739a.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ad9739a.c
Extension
.c
Size
12628 bytes
Lines
470
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 ad9739a_state {
	struct iio_backend *back;
	struct regmap *regmap;
	unsigned long sample_rate;
};

static int ad9739a_oper_mode_get(struct iio_dev *indio_dev,
				 const struct iio_chan_spec *chan)
{
	struct ad9739a_state *st = iio_priv(indio_dev);
	u32 mode;
	int ret;

	ret = regmap_read(st->regmap, AD9739A_REG_DEC_CNT, &mode);
	if (ret)
		return ret;

	mode = FIELD_GET(AD9739A_DAC_DEC, mode);
	/* sanity check we get valid values from the HW */
	if (mode != AD9739A_NORMAL_MODE && mode != AD9739A_MIXED_MODE)
		return -EIO;
	if (!mode)
		return AD9739A_NORMAL_MODE;

	/*
	 * We get 2 from the device but for IIO modes, that means 1. Hence the
	 * minus 1.
	 */
	return AD9739A_MIXED_MODE - 1;
}

static int ad9739a_oper_mode_set(struct iio_dev *indio_dev,
				 const struct iio_chan_spec *chan, u32 mode)
{
	struct ad9739a_state *st = iio_priv(indio_dev);

	/*
	 * On the IIO interface we have 0 and 1 for mode. But for mixed_mode, we
	 * need to write 2 in the device. That's what the below check is about.
	 */
	if (mode == AD9739A_MIXED_MODE - 1)
		mode = AD9739A_MIXED_MODE;

	return regmap_update_bits(st->regmap, AD9739A_REG_DEC_CNT,
				  AD9739A_DAC_DEC, mode);
}

static int ad9739a_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct ad9739a_state *st = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_SAMP_FREQ:
		*val = st->sample_rate;
		*val2 = 0;
		return IIO_VAL_INT_64;
	default:
		return -EINVAL;
	}
}

static int ad9739a_buffer_preenable(struct iio_dev *indio_dev)
{
	struct ad9739a_state *st = iio_priv(indio_dev);

	return iio_backend_data_source_set(st->back, 0, IIO_BACKEND_EXTERNAL);
}

static int ad9739a_buffer_postdisable(struct iio_dev *indio_dev)
{
	struct ad9739a_state *st = iio_priv(indio_dev);

	return iio_backend_data_source_set(st->back, 0,
					   IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE);
}

static bool ad9739a_reg_accessible(struct device *dev, unsigned int reg)
{
	if (AD9739A_REG_IS_RESERVED(reg))
		return false;
	if (reg > AD9739A_REG_MU_STAT1 && reg < AD9739A_REG_ANA_CNT_1)
		return false;

	return true;
}

static int ad9739a_reset(struct device *dev, const struct ad9739a_state *st)
{

Annotation

Implementation Notes