drivers/iio/adc/ti-ads1298.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ti-ads1298.c
Extension
.c
Size
21322 bytes
Lines
772
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 ads1298_private {
	const struct ads1298_chip_info *chip_info;
	struct spi_device *spi;
	struct regulator *reg_avdd;
	struct regulator *reg_vref;
	struct clk *clk;
	struct regmap *regmap;
	struct completion completion;
	struct iio_trigger *trig;
	struct spi_transfer rdata_xfer;
	struct spi_message rdata_msg;
	spinlock_t irq_busy_lock; /* Handshake between SPI and DRDY irqs */
	/*
	 * rdata_xfer_busy increments when a DRDY occurs and decrements when SPI
	 * completion is reported. Hence its meaning is:
	 * 0 = Waiting for DRDY interrupt
	 * 1 = SPI transfer in progress
	 * 2 = DRDY during SPI transfer, start another transfer on completion
	 * >2 = Multiple DRDY during transfer, lost rdata_xfer_busy - 2 samples
	 */
	unsigned int rdata_xfer_busy;

	/* Temporary storage for demuxing data after SPI transfer */
	u32 bounce_buffer[ADS1298_MAX_CHANNELS];

	/* For synchronous SPI exchanges (read/write registers) */
	u8 cmd_buffer[ADS1298_SPI_CMD_BUFFER_SIZE] __aligned(IIO_DMA_MINALIGN);

	/* Buffer used for incoming SPI data */
	u8 rx_buffer[ADS1298_SPI_RDATA_BUFFER_SIZE_MAX];
	/* Contains the RDATA command and zeroes to clock out */
	u8 tx_buffer[ADS1298_SPI_RDATA_BUFFER_SIZE_MAX];
};

/* Three bytes per sample in RX buffer, starting at offset 4 */
#define ADS1298_OFFSET_IN_RX_BUFFER(index)	(3 * (index) + 4)

#define ADS1298_CHAN(index)				\
{							\
	.type = IIO_VOLTAGE,				\
	.indexed = 1,					\
	.channel = index,				\
	.address = ADS1298_OFFSET_IN_RX_BUFFER(index),	\
	.info_mask_separate =				\
		BIT(IIO_CHAN_INFO_RAW) |		\
		BIT(IIO_CHAN_INFO_SCALE),		\
	.info_mask_shared_by_all =			\
		BIT(IIO_CHAN_INFO_SAMP_FREQ) |		\
		BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),	\
	.scan_index = index,				\
	.scan_type = {					\
		.sign = 's',				\
		.realbits = ADS1298_BITS_PER_SAMPLE,	\
		.storagebits = 32,			\
		.endianness = IIO_CPU,			\
	},						\
}

static const struct iio_chan_spec ads1298_channels[] = {
	ADS1298_CHAN(0),
	ADS1298_CHAN(1),
	ADS1298_CHAN(2),
	ADS1298_CHAN(3),
	ADS1298_CHAN(4),
	ADS1298_CHAN(5),
	ADS1298_CHAN(6),
	ADS1298_CHAN(7),
};

static int ads1298_write_cmd(struct ads1298_private *priv, u8 command)
{
	struct spi_transfer xfer = {
		.tx_buf = priv->cmd_buffer,
		.rx_buf = priv->cmd_buffer,
		.len = 1,
		.speed_hz = ADS1298_SPI_BUS_SPEED_SLOW,
		.delay = {
			.value = 2,
			.unit = SPI_DELAY_UNIT_USECS,
		},
	};

	priv->cmd_buffer[0] = command;

	return spi_sync_transfer(priv->spi, &xfer, 1);
}

static int ads1298_read_one(struct ads1298_private *priv, int chan_index)
{
	int ret;

Annotation

Implementation Notes