drivers/iio/adc/max1241.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/max1241.c
Extension
.c
Size
4464 bytes
Lines
202
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 max1241 {
	struct spi_device *spi;
	struct mutex lock;
	struct regulator *vref;
	struct gpio_desc *shutdown;

	__be16 data __aligned(IIO_DMA_MINALIGN);
};

static const struct iio_chan_spec max1241_channels[] = {
	{
		.type = IIO_VOLTAGE,
		.indexed = 1,
		.channel = 0,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
				BIT(IIO_CHAN_INFO_SCALE),
	},
};

static int max1241_read(struct max1241 *adc)
{
	struct spi_transfer xfers[] = {
		/*
		 * Begin conversion by bringing /CS low for at least
		 * tconv us.
		 */
		{
			.len = 0,
			.delay.value = 8,
			.delay.unit = SPI_DELAY_UNIT_USECS,
		},
		/*
		 * Then read two bytes of data in our RX buffer.
		 */
		{
			.rx_buf = &adc->data,
			.len = 2,
		},
	};

	return spi_sync_transfer(adc->spi, xfers, ARRAY_SIZE(xfers));
}

static int max1241_read_raw(struct iio_dev *indio_dev,
			struct iio_chan_spec const *chan,
			int *val, int *val2, long mask)
{
	int ret, vref_uV;
	struct max1241 *adc = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		mutex_lock(&adc->lock);

		if (adc->shutdown) {
			gpiod_set_value(adc->shutdown, 0);
			udelay(MAX1241_SHUTDOWN_DELAY_USEC);
			ret = max1241_read(adc);
			gpiod_set_value(adc->shutdown, 1);
		} else
			ret = max1241_read(adc);

		if (ret) {
			mutex_unlock(&adc->lock);
			return ret;
		}

		*val = (be16_to_cpu(adc->data) >> 3) & MAX1241_VAL_MASK;

		mutex_unlock(&adc->lock);
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		vref_uV = regulator_get_voltage(adc->vref);

		if (vref_uV < 0)
			return vref_uV;

		*val = vref_uV / 1000;
		*val2 = 12;

		return IIO_VAL_FRACTIONAL_LOG2;
	default:
		return -EINVAL;
	}
}

static const struct iio_info max1241_info = {
	.read_raw = max1241_read_raw,
};

Annotation

Implementation Notes