drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c

Source file repositories/reference/linux-study-clean/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c
Extension
.c
Size
16616 bytes
Lines
599
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 inv_icm42600_fifo_1sensor_packet {
	u8 header;
	struct inv_icm42600_fifo_sensor_data data;
	s8 temp;
} __packed;
#define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE		8

struct inv_icm42600_fifo_2sensors_packet {
	u8 header;
	struct inv_icm42600_fifo_sensor_data accel;
	struct inv_icm42600_fifo_sensor_data gyro;
	s8 temp;
	__be16 timestamp;
} __packed;
#define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE		16

ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
					const void **gyro, const s8 **temp,
					const void **timestamp, unsigned int *odr)
{
	const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet;
	const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet;
	u8 header = *((const u8 *)packet);

	/* FIFO empty */
	if (header & INV_ICM42600_FIFO_HEADER_MSG) {
		*accel = NULL;
		*gyro = NULL;
		*temp = NULL;
		*timestamp = NULL;
		*odr = 0;
		return 0;
	}

	/* handle odr flags */
	*odr = 0;
	if (header & INV_ICM42600_FIFO_HEADER_ODR_GYRO)
		*odr |= INV_ICM42600_SENSOR_GYRO;
	if (header & INV_ICM42600_FIFO_HEADER_ODR_ACCEL)
		*odr |= INV_ICM42600_SENSOR_ACCEL;

	/* accel + gyro */
	if ((header & INV_ICM42600_FIFO_HEADER_ACCEL) &&
	    (header & INV_ICM42600_FIFO_HEADER_GYRO)) {
		*accel = &pack2->accel;
		*gyro = &pack2->gyro;
		*temp = &pack2->temp;
		*timestamp = &pack2->timestamp;
		return INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE;
	}

	/* accel only */
	if (header & INV_ICM42600_FIFO_HEADER_ACCEL) {
		*accel = &pack1->data;
		*gyro = NULL;
		*temp = &pack1->temp;
		*timestamp = NULL;
		return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
	}

	/* gyro only */
	if (header & INV_ICM42600_FIFO_HEADER_GYRO) {
		*accel = NULL;
		*gyro = &pack1->data;
		*temp = &pack1->temp;
		*timestamp = NULL;
		return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE;
	}

	/* invalid packet if here */
	return -EINVAL;
}

void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st)
{
	u32 period_gyro, period_accel;

	if (st->fifo.en & INV_ICM42600_SENSOR_GYRO)
		period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr);
	else
		period_gyro = U32_MAX;

	if (st->fifo.en & INV_ICM42600_SENSOR_ACCEL)
		period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr);
	else
		period_accel = U32_MAX;

	st->fifo.period = min(period_gyro, period_accel);
}

Annotation

Implementation Notes