drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c

Source file repositories/reference/linux-study-clean/drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c
Extension
.c
Size
16039 bytes
Lines
559
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_icm45600_fifo_1sensor_packet {
	u8 header;
	struct inv_icm45600_fifo_sensor_data data;
	s8 temp;
} __packed;

struct inv_icm45600_fifo_2sensors_packet {
	u8 header;
	struct inv_icm45600_fifo_sensor_data accel;
	struct inv_icm45600_fifo_sensor_data gyro;
	s8 temp;
	__le16 timestamp;
} __packed;

ssize_t inv_icm45600_fifo_decode_packet(const void *packet,
					const struct inv_icm45600_fifo_sensor_data **accel,
					const struct inv_icm45600_fifo_sensor_data **gyro,
					const s8 **temp,
					const __le16 **timestamp, unsigned int *odr)
{
	const struct inv_icm45600_fifo_1sensor_packet *pack1 = packet;
	const struct inv_icm45600_fifo_2sensors_packet *pack2 = packet;
	u8 header = *((const u8 *)packet);

	/* FIFO extended header */
	if (header & INV_ICM45600_FIFO_EXT_HEADER) {
		/* Not yet supported */
		return 0;
	}

	/* handle odr flags. */
	*odr = 0;
	if (header & INV_ICM45600_FIFO_HEADER_ODR_GYRO)
		*odr |= INV_ICM45600_SENSOR_GYRO;
	if (header & INV_ICM45600_FIFO_HEADER_ODR_ACCEL)
		*odr |= INV_ICM45600_SENSOR_ACCEL;

	/* Accel + Gyro data are present. */
	if ((header & INV_ICM45600_FIFO_HEADER_ACCEL) &&
	    (header & INV_ICM45600_FIFO_HEADER_GYRO)) {
		*accel = &pack2->accel;
		*gyro = &pack2->gyro;
		*temp = &pack2->temp;
		*timestamp = &pack2->timestamp;
		return sizeof(*pack2);
	}

	/* Accel data only. */
	if (header & INV_ICM45600_FIFO_HEADER_ACCEL) {
		*accel = &pack1->data;
		*gyro = NULL;
		*temp = &pack1->temp;
		*timestamp = NULL;
		return sizeof(*pack1);
	}

	/* Gyro data only. */
	if (header & INV_ICM45600_FIFO_HEADER_GYRO) {
		*accel = NULL;
		*gyro = &pack1->data;
		*temp = &pack1->temp;
		*timestamp = NULL;
		return sizeof(*pack1);
	}

	/* Invalid packet if here. */
	return -EINVAL;
}

void inv_icm45600_buffer_update_fifo_period(struct inv_icm45600_state *st)
{
	u32 period_gyro, period_accel;

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

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

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

int inv_icm45600_buffer_set_fifo_en(struct inv_icm45600_state *st,
				    unsigned int fifo_en)
{
	unsigned int mask;

Annotation

Implementation Notes