drivers/iio/adc/ad7606_spi.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7606_spi.c
Extension
.c
Size
14122 bytes
Lines
513
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 spi_bus_data {
	struct spi_offload *offload;
	struct spi_offload_trigger *offload_trigger;
	struct spi_transfer offload_xfer;
	struct spi_message offload_msg;
};

static u16 ad7616_spi_rd_wr_cmd(int addr, char is_write_op)
{
	/*
	 * The address of register consist of one w/r bit
	 * 6 bits of address followed by one reserved bit.
	 */
	return ((addr & 0x7F) << 1) | ((is_write_op & 0x1) << 7);
}

static u16 ad7606b_spi_rd_wr_cmd(int addr, char is_write_op)
{
	/*
	 * The address of register consists of one bit which
	 * specifies a read command placed in bit 6, followed by
	 * 6 bits of address.
	 */
	return (addr & 0x3F) | (((~is_write_op) & 0x1) << 6);
}

static int ad7606_spi_read_block(struct device *dev,
				 int count, void *buf)
{
	struct spi_device *spi = to_spi_device(dev);
	int i, ret;
	unsigned short *data = buf;
	__be16 *bdata = buf;

	ret = spi_read(spi, buf, count * 2);
	if (ret < 0) {
		dev_err(&spi->dev, "SPI read error\n");
		return ret;
	}

	for (i = 0; i < count; i++)
		data[i] = be16_to_cpu(bdata[i]);

	return 0;
}

static int ad7606_spi_read_block14to16(struct device *dev,
				       int count, void *buf)
{
	struct spi_device *spi = to_spi_device(dev);
	struct spi_transfer xfer = {
		.bits_per_word = 14,
		.len = count * sizeof(u16),
		.rx_buf = buf,
	};

	return spi_sync_transfer(spi, &xfer, 1);
}

static int ad7606_spi_read_block18to32(struct device *dev,
				       int count, void *buf)
{
	struct spi_device *spi = to_spi_device(dev);
	struct spi_transfer xfer = {
		.bits_per_word = 18,
		.len = count * sizeof(u32),
		.rx_buf = buf,
	};

	return spi_sync_transfer(spi, &xfer, 1);
}

static int ad7606_spi_reg_read(struct ad7606_state *st, unsigned int addr)
{
	struct spi_device *spi = to_spi_device(st->dev);
	struct spi_transfer t[] = {
		{
			.tx_buf = &st->d16[0],
			.len = 2,
			.cs_change = 1,
		}, {
			.rx_buf = &st->d16[1],
			.len = 2,
		},
	};
	int ret;

	st->d16[0] = cpu_to_be16(st->bops->rd_wr_cmd(addr, 0) << 8);

	ret = spi_sync_transfer(spi, t, ARRAY_SIZE(t));

Annotation

Implementation Notes