drivers/iio/dac/max22007.c

Source file repositories/reference/linux-study-clean/drivers/iio/dac/max22007.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/max22007.c
Extension
.c
Size
12938 bytes
Lines
492
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 max22007_state {
	struct spi_device *spi;
	struct regmap *regmap;
	struct iio_chan_spec *iio_chans;
	u8 tx_buf[4] __aligned(IIO_DMA_MINALIGN);
	u8 rx_buf[4];
};

static int max22007_spi_read(void *context, const void *reg, size_t reg_size,
			     void *val, size_t val_size)
{
	struct max22007_state *st = context;
	u8 calculated_crc, received_crc;
	u8 rx_buf[4];
	u8 reg_byte;
	int ret;

	if (reg_size != 1)
		return -EINVAL;

	if (val_size == 0 || val_size > 3)
		return -EINVAL;

	memcpy(&reg_byte, reg, 1);

	ret = spi_write_then_read(st->spi, &reg_byte, 1, rx_buf,
				  val_size + MAX22007_CRC_OVERHEAD);
	if (ret) {
		dev_err(&st->spi->dev, "SPI transfer failed: %d\n", ret);
		return ret;
	}

	calculated_crc = crc8(max22007_crc8_table, &reg_byte, 1, 0x00);
	calculated_crc = crc8(max22007_crc8_table, rx_buf, 2, calculated_crc);
	received_crc = rx_buf[val_size];

	if (calculated_crc != received_crc) {
		dev_err(&st->spi->dev, "CRC mismatch on read register %02x\n", reg_byte);
		return -EIO;
	}

	memcpy(val, rx_buf, val_size);

	return 0;
}

static int max22007_spi_write(void *context, const void *data, size_t count)
{
	struct max22007_state *st = context;
	struct spi_transfer xfer = {
		.tx_buf = st->tx_buf,
		.rx_buf = st->rx_buf,
	};

	if (count + MAX22007_CRC_OVERHEAD > sizeof(st->tx_buf))
		return -EINVAL;

	memset(st->tx_buf, 0, sizeof(st->tx_buf));

	xfer.len = count + MAX22007_CRC_OVERHEAD;

	memcpy(st->tx_buf, data, count);
	st->tx_buf[count] = crc8(max22007_crc8_table, st->tx_buf,
				 sizeof(st->tx_buf) - 1, 0x00);

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

static bool max22007_reg_readable(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case MAX22007_REV_ID_REG:
	case MAX22007_STAT_INTR_REG:
	case MAX22007_CONFIG_REG:
	case MAX22007_CONTROL_REG:
	case MAX22007_CHANNEL_MODE_REG:
	case MAX22007_SOFT_RESET_REG:
	case MAX22007_GPIO_CTRL_REG:
	case MAX22007_GPIO_DATA_REG:
	case MAX22007_GPI_EDGE_INT_CTRL_REG:
	case MAX22007_GPI_INT_STATUS_REG:
		return true;
	case MAX22007_DAC_CHANNEL_REG(0) ... MAX22007_DAC_CHANNEL_REG(MAX22007_NUM_CHANNELS - 1):
		return true;
	default:
		return false;
	}
}

static bool max22007_reg_writable(struct device *dev, unsigned int reg)

Annotation

Implementation Notes