drivers/iio/dac/ad5686.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ad5686.c
Extension
.c
Size
14301 bytes
Lines
564
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
/*
 * AD5686R, AD5685R, AD5684R Digital to analog converters  driver
 *
 * Copyright 2011 Analog Devices Inc.
 */

#include <linux/interrupt.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/regulator/consumer.h>

#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#include "ad5686.h"

static const char * const ad5686_powerdown_modes[] = {
	"1kohm_to_gnd",
	"100kohm_to_gnd",
	"three_state"
};

static inline unsigned int ad5686_pd_mask_shift(const struct iio_chan_spec *chan)
{
	if (chan->channel == chan->address)
		return chan->channel * 2;

	/* one-hot encoding is used in dual/quad channel devices */
	return __ffs(chan->address) * 2;
}

static int ad5686_get_powerdown_mode(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan)
{
	unsigned int shift = ad5686_pd_mask_shift(chan);
	struct ad5686_state *st = iio_priv(indio_dev);

	guard(mutex)(&st->lock);

	return ((st->pwr_down_mode >> shift) & 0x3U) - 1;
}

static int ad5686_set_powerdown_mode(struct iio_dev *indio_dev,
				     const struct iio_chan_spec *chan,
				     unsigned int mode)
{
	unsigned int shift = ad5686_pd_mask_shift(chan);
	struct ad5686_state *st = iio_priv(indio_dev);

	guard(mutex)(&st->lock);

	st->pwr_down_mode &= ~(0x3U << shift);
	st->pwr_down_mode |= (mode + 1) << shift;

	return 0;
}

static const struct iio_enum ad5686_powerdown_mode_enum = {
	.items = ad5686_powerdown_modes,
	.num_items = ARRAY_SIZE(ad5686_powerdown_modes),
	.get = ad5686_get_powerdown_mode,
	.set = ad5686_set_powerdown_mode,
};

static ssize_t ad5686_read_dac_powerdown(struct iio_dev *indio_dev,
		uintptr_t private, const struct iio_chan_spec *chan, char *buf)
{
	unsigned int shift = ad5686_pd_mask_shift(chan);
	struct ad5686_state *st = iio_priv(indio_dev);

	guard(mutex)(&st->lock);

	return sysfs_emit(buf, "%d\n", !!(st->pwr_down_mask & (0x3U << shift)));
}

static ssize_t ad5686_write_dac_powerdown(struct iio_dev *indio_dev,
					  uintptr_t private,
					  const struct iio_chan_spec *chan,
					  const char *buf,
					  size_t len)
{
	bool readin;
	int ret;
	struct ad5686_state *st = iio_priv(indio_dev);
	unsigned int val, ref_bit_msk;

Annotation

Implementation Notes