drivers/iio/adc/ti-ads131m02.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ti-ads131m02.c
Extension
.c
Size
28365 bytes
Lines
969
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 ads131m_configuration {
	const struct iio_chan_spec *channels;
	const char *name;
	u16 reset_ack;
	u8 num_channels;
	u8 supports_extref:1;
	u8 supports_xtal:1;
};

struct ads131m_priv {
	struct iio_dev *indio_dev;
	struct spi_device *spi;
	const struct ads131m_configuration *config;

	bool use_external_ref;
	int scale_val;
	int scale_val2;

	struct spi_transfer xfer;
	struct spi_message msg;

	/*
	 * Protects the shared tx_buffer and rx_buffer. More importantly,
	 * this serializes all SPI communication to ensure the atomicity
	 * of multi-cycle command sequences (like WREG, RREG, or RESET).
	 */
	struct mutex lock;

	/* DMA-safe buffers should be placed at the end of the struct. */
	u8 tx_buffer[ADS131M_FRAME_BYTES(ADS131M_MAX_CHANNELS)]
		__aligned(IIO_DMA_MINALIGN);
	u8 rx_buffer[ADS131M_FRAME_BYTES(ADS131M_MAX_CHANNELS)];
};

/**
 * ads131m_tx_frame_unlocked - Sends a command frame with Input CRC
 * @priv: Device private data structure.
 * @command: The 16-bit command to send (e.g., NULL, RREG, RESET).
 *
 * This function sends a command in Word 0, and its calculated 16-bit
 * CRC in Word 1, as required when Input CRC is enabled.
 *
 * Return: 0 on success, or a negative error code.
 */
static int ads131m_tx_frame_unlocked(struct ads131m_priv *priv, u32 command)
{
	struct iio_dev *indio_dev = priv->indio_dev;
	u16 crc;

	lockdep_assert_held(&priv->lock);

	memset(priv->tx_buffer, 0, ADS131M_FRAME_BYTES(indio_dev->num_channels));

	/* Word 0: 16-bit command, MSB-aligned in 24-bit word */
	put_unaligned_be16(command, &priv->tx_buffer[0]);

	/* Word 1: Input CRC. Calculated over the 3 bytes of Word 0. */
	crc = crc_itu_t(0xffff, priv->tx_buffer, 3);
	put_unaligned_be16(crc, &priv->tx_buffer[3]);

	return spi_sync(priv->spi, &priv->msg);
}

/**
 * ads131m_rx_frame_unlocked - Receives a full SPI data frame.
 * @priv: Device private data structure.
 *
 * This function sends a NULL command (with its CRC) to clock out a
 * full SPI frame from the device (e.g., response + channel data + CRC).
 *
 * Return: 0 on success, or a negative error code.
 */
static int ads131m_rx_frame_unlocked(struct ads131m_priv *priv)
{
	return ads131m_tx_frame_unlocked(priv, ADS131M_CMD_NULL);
}

/**
 * ads131m_check_status_crc_err - Checks for an Input CRC error.
 * @priv: Device private data structure.
 *
 * Sends a NULL command to fetch the STATUS register and checks the
 * CRC_ERR bit. This is used to verify the integrity of the previous
 * command (like RREG or WREG).
 *
 * Return: 0 on success, -EIO if CRC_ERR bit is set.
 */
static int ads131m_check_status_crc_err(struct ads131m_priv *priv)
{
	struct device *dev = &priv->spi->dev;

Annotation

Implementation Notes