drivers/iio/adc/ti-lmp92064.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ti-lmp92064.c
Extension
.c
Size
10392 bytes
Lines
384
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 lmp92064_adc_priv {
	int shunt_resistor_uohm;
	struct spi_device *spi;
	struct regmap *regmap;
};

static const struct iio_chan_spec lmp92064_adc_channels[] = {
	{
		.type = IIO_CURRENT,
		.address = TI_LMP92064_CHAN_INC,
		.info_mask_separate =
			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = TI_LMP92064_CHAN_INC,
		.scan_type = {
			.sign = 'u',
			.realbits = 12,
			.storagebits = 16,
		},
		.datasheet_name = "INC",
	},
	{
		.type = IIO_VOLTAGE,
		.address = TI_LMP92064_CHAN_INV,
		.info_mask_separate =
			BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
		.scan_index = TI_LMP92064_CHAN_INV,
		.scan_type = {
			.sign = 'u',
			.realbits = 12,
			.storagebits = 16,
		},
		.datasheet_name = "INV",
	},
	IIO_CHAN_SOFT_TIMESTAMP(2),
};

static const unsigned long lmp92064_scan_masks[] = {
	BIT(TI_LMP92064_CHAN_INC) | BIT(TI_LMP92064_CHAN_INV),
	0
};

static int lmp92064_read_meas(struct lmp92064_adc_priv *priv, u16 *res)
{
	__be16 raw[2];
	int ret;

	/*
	 * The ADC only latches in new samples if all DATA registers are read
	 * in descending sequential order.
	 * The ADC auto-decrements the register index with each clocked byte.
	 * Read both channels in single SPI transfer by selecting the highest
	 * register using the command below and clocking out all four data
	 * bytes.
	 */

	ret = regmap_bulk_read(priv->regmap, TI_LMP92064_REG_DATA_COUT_MSB,
			 &raw, sizeof(raw));

	if (ret) {
		dev_err(&priv->spi->dev, "regmap_bulk_read failed: %pe\n",
			ERR_PTR(ret));
		return ret;
	}

	res[0] = be16_to_cpu(raw[0]);
	res[1] = be16_to_cpu(raw[1]);

	return 0;
}

static int lmp92064_read_raw(struct iio_dev *indio_dev,
			     struct iio_chan_spec const *chan, int *val,
			     int *val2, long mask)
{
	struct lmp92064_adc_priv *priv = iio_priv(indio_dev);
	u16 raw[2];
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		ret = lmp92064_read_meas(priv, raw);
		if (ret < 0)
			return ret;

		*val = (chan->address == TI_LMP92064_CHAN_INC) ? raw[0] : raw[1];

		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		if (chan->address == TI_LMP92064_CHAN_INC) {
			/*

Annotation

Implementation Notes