drivers/iio/dac/ad7293.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ad7293.c
Extension
.c
Size
23421 bytes
Lines
897
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 ad7293_state {
	struct spi_device *spi;
	/* Protect against concurrent accesses to the device, page selection and data content */
	struct mutex lock;
	struct gpio_desc *gpio_reset;
	bool vrefin_en;
	u8 page_select;
	u8 data[3] __aligned(IIO_DMA_MINALIGN);
};

static int ad7293_page_select(struct ad7293_state *st, unsigned int reg)
{
	int ret;

	if (st->page_select != FIELD_GET(AD7293_PAGE_ADDR_MSK, reg)) {
		st->data[0] = FIELD_GET(AD7293_REG_ADDR_MSK, AD7293_REG_PAGE_SELECT);
		st->data[1] = FIELD_GET(AD7293_PAGE_ADDR_MSK, reg);

		ret = spi_write(st->spi, &st->data[0], 2);
		if (ret)
			return ret;

		st->page_select = FIELD_GET(AD7293_PAGE_ADDR_MSK, reg);
	}

	return 0;
}

static int __ad7293_spi_read(struct ad7293_state *st, unsigned int reg,
			     u16 *val)
{
	int ret;
	unsigned int length;
	struct spi_transfer t = {0};

	length = FIELD_GET(AD7293_TRANSF_LEN_MSK, reg);

	ret = ad7293_page_select(st, reg);
	if (ret)
		return ret;

	st->data[0] = AD7293_READ | FIELD_GET(AD7293_REG_ADDR_MSK, reg);
	st->data[1] = 0x0;
	st->data[2] = 0x0;

	t.tx_buf = &st->data[0];
	t.rx_buf = &st->data[0];
	t.len = length + 1;

	ret = spi_sync_transfer(st->spi, &t, 1);
	if (ret)
		return ret;

	if (length == 1)
		*val = st->data[1];
	else
		*val = get_unaligned_be16(&st->data[1]);

	return 0;
}

static int ad7293_spi_read(struct ad7293_state *st, unsigned int reg,
			   u16 *val)
{
	int ret;

	mutex_lock(&st->lock);
	ret = __ad7293_spi_read(st, reg, val);
	mutex_unlock(&st->lock);

	return ret;
}

static int __ad7293_spi_write(struct ad7293_state *st, unsigned int reg,
			      u16 val)
{
	int ret;
	unsigned int length;

	length = FIELD_GET(AD7293_TRANSF_LEN_MSK, reg);

	ret = ad7293_page_select(st, reg);
	if (ret)
		return ret;

	st->data[0] = FIELD_GET(AD7293_REG_ADDR_MSK, reg);

	if (length == 1)
		st->data[1] = val;
	else

Annotation

Implementation Notes