drivers/iio/dac/ltc2664.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ltc2664.c
Extension
.c
Size
19126 bytes
Lines
737
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 ltc2664_chip_info {
	const char *name;
	int (*scale_get)(const struct ltc2664_state *st, int c);
	int (*offset_get)(const struct ltc2664_state *st, int c);
	int measurement_type;
	unsigned int num_channels;
	const int (*span_helper)[2];
	unsigned int num_span;
	unsigned int internal_vref_mv;
	bool manual_span_support;
	bool rfsadj_support;
};

struct ltc2664_chan {
	/* indicates if the channel should be toggled */
	bool toggle_chan;
	/* indicates if the channel is in powered down state */
	bool powerdown;
	/* span code of the channel */
	u8 span;
	/* raw data of the current state of the chip registers (A/B) */
	u16 raw[2];
};

struct ltc2664_state {
	struct spi_device *spi;
	struct regmap *regmap;
	struct ltc2664_chan channels[LTC2672_MAX_CHANNEL];
	/* lock to protect against multiple access to the device and shared data */
	struct mutex lock;
	const struct ltc2664_chip_info *chip_info;
	struct iio_chan_spec *iio_channels;
	int vref_mv;
	u32 rfsadj_ohms;
	u32 toggle_sel;
	bool global_toggle;
};

static const int ltc2664_span_helper[][2] = {
	{ 0, 5000 },
	{ 0, 10000 },
	{ -5000, 5000 },
	{ -10000, 10000 },
	{ -2500, 2500 },
};

static const int ltc2672_span_helper[][2] = {
	{ 0, 0 },
	{ 0, 3125 },
	{ 0, 6250 },
	{ 0, 12500 },
	{ 0, 25000 },
	{ 0, 50000 },
	{ 0, 100000 },
	{ 0, 200000 },
	{ 0, 300000 },
};

static int ltc2664_scale_get(const struct ltc2664_state *st, int c)
{
	const struct ltc2664_chan *chan = &st->channels[c];
	const int (*span_helper)[2] = st->chip_info->span_helper;
	int span, fs;

	span = chan->span;
	if (span < 0)
		return span;

	fs = span_helper[span][1] - span_helper[span][0];

	return fs * st->vref_mv / 2500;
}

static int ltc2672_scale_get(const struct ltc2664_state *st, int c)
{
	const struct ltc2664_chan *chan = &st->channels[c];
	int span, fs;

	span = chan->span - 1;
	if (span < 0)
		return span;

	fs = 1000 * st->vref_mv;

	if (span == LTC2672_MAX_SPAN)
		return mul_u64_u32_div(4800, fs, st->rfsadj_ohms);

	return mul_u64_u32_div(LTC2672_SCALE_MULTIPLIER(span), fs, st->rfsadj_ohms);
}

Annotation

Implementation Notes