drivers/iio/adc/ad7280a.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/ad7280a.c
Extension
.c
Size
30763 bytes
Lines
1110
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 ad7280_state {
	struct spi_device		*spi;
	struct iio_chan_spec		*channels;
	unsigned int			chain_last_alert_ignore;
	bool				thermistor_term_en;
	int				slave_num;
	int				scan_cnt;
	int				readback_delay_us;
	unsigned char			crc_tab[CRC8_TABLE_SIZE];
	u8				oversampling_ratio;
	u8				acquisition_time;
	unsigned char			ctrl_lb;
	unsigned char			cell_threshhigh;
	unsigned char			cell_threshlow;
	unsigned char			aux_threshhigh;
	unsigned char			aux_threshlow;
	unsigned char			cb_mask[AD7280A_MAX_CHAIN];
	struct mutex			lock; /* protect sensor state */

	__be32				tx __aligned(IIO_DMA_MINALIGN);
	__be32				rx;
};

static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned int val)
{
	unsigned char crc;

	crc = crc_tab[val >> 16 & 0xFF];
	crc = crc_tab[crc ^ (val >> 8 & 0xFF)];

	return crc ^ (val & 0xFF);
}

static int ad7280_check_crc(struct ad7280_state *st, unsigned int val)
{
	unsigned char crc = ad7280_calc_crc8(st->crc_tab, val >> 10);

	if (crc != ((val >> 2) & 0xFF))
		return -EIO;

	return 0;
}

/*
 * After initiating a conversion sequence we need to wait until the conversion
 * is done. The delay is typically in the range of 15..30us however depending on
 * the number of devices in the daisy chain, the number of averages taken,
 * conversion delays and acquisition time options it may take up to 250us, in
 * this case we better sleep instead of busy wait.
 */

static void ad7280_delay(struct ad7280_state *st)
{
	if (st->readback_delay_us < 50)
		udelay(st->readback_delay_us);
	else
		usleep_range(250, 500);
}

static int __ad7280_read32(struct ad7280_state *st, unsigned int *val)
{
	int ret;
	struct spi_transfer t = {
		.tx_buf	= &st->tx,
		.rx_buf = &st->rx,
		.len = sizeof(st->tx),
	};

	st->tx = cpu_to_be32(AD7280A_READ_TXVAL);

	ret = spi_sync_transfer(st->spi, &t, 1);
	if (ret)
		return ret;

	*val = be32_to_cpu(st->rx);

	return 0;
}

static int ad7280_write(struct ad7280_state *st, unsigned int devaddr,
			unsigned int addr, bool all, unsigned int val)
{
	unsigned int reg = FIELD_PREP(AD7280A_TRANS_WRITE_DEVADDR_MSK, devaddr) |
		FIELD_PREP(AD7280A_TRANS_WRITE_ADDR_MSK, addr) |
		FIELD_PREP(AD7280A_TRANS_WRITE_VAL_MSK, val) |
		FIELD_PREP(AD7280A_TRANS_WRITE_ALL_MSK, all);

	reg |= FIELD_PREP(AD7280A_TRANS_WRITE_CRC_MSK,
			ad7280_calc_crc8(st->crc_tab, reg >> 11));
	/* Reserved b010 pattern not included crc calc */

Annotation

Implementation Notes