drivers/iio/adc/max14001.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/max14001.c
Extension
.c
Size
10813 bytes
Lines
392
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 max14001_state {
	const struct max14001_chip_info *chip_info;
	struct spi_device *spi;
	struct regmap *regmap;
	int vref_mV;
	bool spi_hw_has_lsb_first;

	/*
	 * The following buffers will be bit-reversed during device
	 * communication, because the device transmits and receives data
	 * LSB-first.
	 * DMA (thus cache coherency maintenance) requires the transfer
	 * buffers to live in their own cache lines.
	 */
	union {
		__be16 be;
		__le16 le;
	} spi_tx_buffer __aligned(IIO_DMA_MINALIGN);

	union {
		__be16 be;
		__le16 le;
	} spi_rx_buffer;
};

struct max14001_chip_info {
	const char *name;
};

static int max14001_read(void *context, unsigned int reg, unsigned int *val)
{
	struct max14001_state *st = context;
	struct spi_transfer xfers[] = {
		{
			.tx_buf = &st->spi_tx_buffer,
			.len = sizeof(st->spi_tx_buffer),
			.cs_change = 1,
		}, {
			.rx_buf = &st->spi_rx_buffer,
			.len = sizeof(st->spi_rx_buffer),
		},
	};
	int ret;
	unsigned int addr, data;

	/*
	 * Prepare SPI transmit buffer 16 bit-value and reverse bit order
	 * to align with the LSB-first input on SDI port in order to meet
	 * the device communication requirements. If the controller supports
	 * SPI_LSB_FIRST, this step will be handled by the SPI controller.
	 */
	addr = FIELD_PREP(MAX14001_MASK_ADDR, reg);

	if (st->spi_hw_has_lsb_first)
		st->spi_tx_buffer.le = cpu_to_le16(addr);
	else
		st->spi_tx_buffer.be = cpu_to_be16(bitrev16(addr));

	ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers));
	if (ret)
		return ret;

	/*
	 * Convert received 16-bit value to cpu-endian format and reverse
	 * bit order. If the controller supports SPI_LSB_FIRST, this step
	 * will be handled by the SPI controller.
	 */
	if (st->spi_hw_has_lsb_first)
		data = le16_to_cpu(st->spi_rx_buffer.le);
	else
		data = bitrev16(be16_to_cpu(st->spi_rx_buffer.be));

	*val = FIELD_GET(MAX14001_MASK_DATA, data);

	return 0;
}

static int max14001_write(struct max14001_state *st, unsigned int reg, unsigned int val)
{
	unsigned int addr;

	/*
	 * Prepare SPI transmit buffer 16 bit-value and reverse bit order
	 * to align with the LSB-first input on SDI port in order to meet
	 * the device communication requirements. If the controller supports
	 * SPI_LSB_FIRST, this step will be handled by the SPI controller.
	 */
	addr = FIELD_PREP(MAX14001_MASK_ADDR, reg) |
	       FIELD_PREP(MAX14001_MASK_WR, 1) |
	       FIELD_PREP(MAX14001_MASK_DATA, val);

Annotation

Implementation Notes