drivers/iio/dac/ti-dac7612.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ti-dac7612.c
Extension
.c
Size
4655 bytes
Lines
194
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 dac7612 {
	struct spi_device *spi;
	struct gpio_desc *loaddacs;
	uint16_t cache[2];

	/*
	 * Lock to protect the state of the device from potential concurrent
	 * write accesses from userspace. The write operation requires an
	 * SPI write, then toggling of a GPIO, so the lock aims to protect
	 * the sanity of the entire sequence of operation.
	 */
	struct mutex lock;

	/*
	 * DMA (thus cache coherency maintenance) may require the
	 * transfer buffers to live in their own cache lines.
	 */
	uint8_t data[2] __aligned(IIO_DMA_MINALIGN);
};

static int dac7612_cmd_single(struct dac7612 *priv, int channel, u16 val)
{
	int ret;

	priv->data[0] = BIT(DAC7612_START) | (channel << DAC7612_ADDRESS);
	priv->data[0] |= val >> 8;
	priv->data[1] = val & 0xff;

	priv->cache[channel] = val;

	ret = spi_write(priv->spi, priv->data, sizeof(priv->data));
	if (ret)
		return ret;

	gpiod_set_value(priv->loaddacs, 1);
	gpiod_set_value(priv->loaddacs, 0);

	return 0;
}

#define dac7612_CHANNEL(chan, name) {				\
	.type = IIO_VOLTAGE,					\
	.channel = (chan),					\
	.indexed = 1,						\
	.output = 1,						\
	.datasheet_name = name,					\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\
}

static const struct iio_chan_spec dac7612_channels[] = {
	dac7612_CHANNEL(0, "OUTA"),
	dac7612_CHANNEL(1, "OUTB"),
};

static int dac7612_read_raw(struct iio_dev *iio_dev,
			    const struct iio_chan_spec *chan,
			    int *val, int *val2, long mask)
{
	struct dac7612 *priv;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		priv = iio_priv(iio_dev);
		*val = priv->cache[chan->channel];
		return IIO_VAL_INT;

	case IIO_CHAN_INFO_SCALE:
		*val = 1;
		return IIO_VAL_INT;

	default:
		return -EINVAL;
	}
}

static int dac7612_write_raw(struct iio_dev *iio_dev,
			     const struct iio_chan_spec *chan,
			     int val, int val2, long mask)
{
	struct dac7612 *priv = iio_priv(iio_dev);
	int ret;

	if (mask != IIO_CHAN_INFO_RAW)
		return -EINVAL;

	if ((val >= BIT(DAC7612_RESOLUTION)) || val < 0 || val2)
		return -EINVAL;

	if (val == priv->cache[chan->channel])

Annotation

Implementation Notes