drivers/iio/adc/ad7606.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7606.c
Extension
.c
Size
45699 bytes
Lines
1713
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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

if (ret == 0 && (pins[0] != reg || pins[1] != reg)) {
			dev_err(dev,
				"Differential pins must be the same as 'reg'");
			return -EINVAL;
		}

		*differential = (ret == 0);

		if (*differential && !*bipolar) {
			dev_err(dev,
				"'bipolar' must be added for diff channel %d\n",
				reg);
			return -EINVAL;
		}

		ci = &st->chan_info[reg - 1];

		ci->r_gain = 0;
		ret = fwnode_property_read_u32(child, "adi,rfilter-ohms",
					       &ci->r_gain);
		if (ret == 0 && ci->r_gain > AD7606_CALIB_GAIN_MAX)
			return -EINVAL;

		return 0;
	}

	return 0;
}

static int ad7606c_18bit_chan_scale_setup(struct iio_dev *indio_dev,
					  struct iio_chan_spec *chan)
{
	struct ad7606_state *st = iio_priv(indio_dev);
	struct ad7606_chan_info *ci = &st->chan_info[chan->scan_index];
	bool bipolar, differential;
	int ret;

	if (!st->sw_mode_en) {
		ci->range = 0;
		ci->scale_avail = ad7606_18bit_hw_scale_avail;
		ci->num_scales = ARRAY_SIZE(ad7606_18bit_hw_scale_avail);
		return 0;
	}

	ret = ad7606_get_chan_config(indio_dev, chan->scan_index, &bipolar,
				     &differential);
	if (ret)
		return ret;

	if (differential) {
		ci->scale_avail = ad7606c_18bit_differential_bipolar_scale_avail;
		ci->num_scales =
			ARRAY_SIZE(ad7606c_18bit_differential_bipolar_scale_avail);
		/* Bipolar differential ranges start at 8 (b1000) */
		ci->reg_offset = 8;
		ci->range = 1;
		chan->differential = 1;
		chan->channel2 = chan->channel;

		return 0;
	}

	chan->differential = 0;

	if (bipolar) {
		ci->scale_avail = ad7606c_18bit_single_ended_bipolar_scale_avail;
		ci->num_scales =
			ARRAY_SIZE(ad7606c_18bit_single_ended_bipolar_scale_avail);
		/* Bipolar single-ended ranges start at 0 (b0000) */
		ci->reg_offset = 0;
		ci->range = 3;
		chan->scan_type.sign = 's';

		return 0;
	}

	ci->scale_avail = ad7606c_18bit_single_ended_unipolar_scale_avail;
	ci->num_scales =
		ARRAY_SIZE(ad7606c_18bit_single_ended_unipolar_scale_avail);
	/* Unipolar single-ended ranges start at 5 (b0101) */
	ci->reg_offset = 5;
	ci->range = 1;
	chan->scan_type.sign = 'u';

	return 0;
}

static int ad7606c_16bit_chan_scale_setup(struct iio_dev *indio_dev,
					  struct iio_chan_spec *chan)
{

Annotation

Implementation Notes