drivers/iio/adc/ltc2497-core.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ltc2497-core.c
Extension
.c
Size
6363 bytes
Lines
245
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

// SPDX-License-Identifier: GPL-2.0-only
/*
 * ltc2497-core.c - Common code for Analog Devices/Linear Technology
 * LTC2496 and LTC2497 ADCs
 *
 * Copyright (C) 2017 Analog Devices Inc.
 */

#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regulator/consumer.h>

#include "ltc2497.h"

#define LTC2497_SGL			BIT(4)
#define LTC2497_DIFF			0
#define LTC2497_SIGN			BIT(3)

static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata)
{
	s64 time_elapsed;

	time_elapsed = ktime_ms_delta(ktime_get(), ddata->time_prev);

	if (time_elapsed < LTC2497_CONVERSION_TIME_MS) {
		/* delay if conversion time not passed
		 * since last read or write
		 */
		if (msleep_interruptible(
		    LTC2497_CONVERSION_TIME_MS - time_elapsed))
			return -ERESTARTSYS;

		return 0;
	}

	if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) {
		/* We're in automatic mode -
		 * so the last reading is still not outdated
		 */
		return 0;
	}

	return 1;
}

static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, int *val)
{
	int ret;

	ret = ltc2497core_wait_conv(ddata);
	if (ret < 0)
		return ret;

	if (ret || ddata->addr_prev != address) {
		ret = ddata->result_and_measure(ddata, address, NULL);
		if (ret < 0)
			return ret;
		ddata->addr_prev = address;

		if (msleep_interruptible(LTC2497_CONVERSION_TIME_MS))
			return -ERESTARTSYS;
	}

	ret = ddata->result_and_measure(ddata, address, val);
	if (ret < 0)
		return ret;

	ddata->time_prev = ktime_get();

	return ret;
}

static int ltc2497core_read_raw(struct iio_dev *indio_dev,
			    struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&ddata->lock);
		ret = ltc2497core_read(ddata, chan->address, val);
		mutex_unlock(&ddata->lock);
		if (ret < 0)
			return ret;

Annotation

Implementation Notes