drivers/iio/adc/ad7779.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7779.c
Extension
.c
Size
26162 bytes
Lines
1051
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 ad7779_chip_info {
	const char *name;
	struct iio_chan_spec const *channels;
};

struct ad7779_state {
	struct spi_device *spi;
	const struct ad7779_chip_info *chip_info;
	struct clk *mclk;
	struct iio_trigger *trig;
	struct completion completion;
	unsigned int sampling_freq;
	enum ad7779_filter filter_enabled;
	struct iio_backend *back;
	/*
	 * DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache lines.
	 */
	struct {
		u32 chans[8];
		aligned_s64 timestamp;
	} data __aligned(IIO_DMA_MINALIGN);
	u32			spidata_tx[8];
	u8			reg_rx_buf[3];
	u8			reg_tx_buf[3];
	u8			reset_buf[8];
};

static const char * const ad7779_filter_type[] = {
	[AD7779_SINC3] = "sinc3",
	[AD7779_SINC5] = "sinc5",
};

static const char * const ad7779_power_supplies[] = {
	"avdd1", "avdd2", "avdd4",
};

static int ad7779_spi_read(struct ad7779_state *st, u8 reg, u8 *rbuf)
{
	int ret;
	u8 crc_buf[2];
	u8 exp_crc;
	struct spi_transfer t = {
		.tx_buf = st->reg_tx_buf,
		.rx_buf = st->reg_rx_buf,
	};

	st->reg_tx_buf[0] = AD7779_SPI_READ_CMD | FIELD_GET(AD7779_REG_MSK, reg);
	st->reg_tx_buf[1] = 0;

	if (reg == AD7779_REG_GEN_ERR_REG_1_EN) {
		t.len = 2;
	} else {
		t.len = 3;
		st->reg_tx_buf[2] = crc8(ad7779_crc8_table, st->reg_tx_buf,
					 t.len - 1, 0);
	}

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

	crc_buf[0] = AD7779_SPI_READ_CMD | FIELD_GET(AD7779_REG_MSK, reg);
	crc_buf[1] = st->reg_rx_buf[1];
	exp_crc = crc8(ad7779_crc8_table, crc_buf, ARRAY_SIZE(crc_buf), 0);
	if (reg != AD7779_REG_GEN_ERR_REG_1_EN && exp_crc != st->reg_rx_buf[2]) {
		dev_err(&st->spi->dev, "Bad CRC %x, expected %x",
			st->reg_rx_buf[2], exp_crc);
		return -EINVAL;
	}
	*rbuf = st->reg_rx_buf[1];

	return 0;
}

static int ad7779_spi_write(struct ad7779_state *st, u8 reg, u8 val)
{
	u8 length = 3;

	st->reg_tx_buf[0] = FIELD_GET(AD7779_REG_MSK, reg);
	st->reg_tx_buf[1] = val;
	if (reg == AD7779_REG_GEN_ERR_REG_1_EN)
		length = 2;
	else
		st->reg_tx_buf[2] = crc8(ad7779_crc8_table, st->reg_tx_buf,
					 length - 1, 0);

	return spi_write(st->spi, st->reg_tx_buf, length);
}

Annotation

Implementation Notes