17f85e42aSJean-Baptiste Maneyrol /* SPDX-License-Identifier: GPL-2.0-or-later */
27f85e42aSJean-Baptiste Maneyrol /*
37f85e42aSJean-Baptiste Maneyrol * Copyright (C) 2020 Invensense, Inc.
47f85e42aSJean-Baptiste Maneyrol */
57f85e42aSJean-Baptiste Maneyrol
67f85e42aSJean-Baptiste Maneyrol #ifndef INV_ICM42600_BUFFER_H_
77f85e42aSJean-Baptiste Maneyrol #define INV_ICM42600_BUFFER_H_
87f85e42aSJean-Baptiste Maneyrol
97f85e42aSJean-Baptiste Maneyrol #include <linux/kernel.h>
107f85e42aSJean-Baptiste Maneyrol #include <linux/bits.h>
117f85e42aSJean-Baptiste Maneyrol
127f85e42aSJean-Baptiste Maneyrol struct inv_icm42600_state;
137f85e42aSJean-Baptiste Maneyrol
147f85e42aSJean-Baptiste Maneyrol #define INV_ICM42600_SENSOR_GYRO BIT(0)
157f85e42aSJean-Baptiste Maneyrol #define INV_ICM42600_SENSOR_ACCEL BIT(1)
167f85e42aSJean-Baptiste Maneyrol #define INV_ICM42600_SENSOR_TEMP BIT(2)
177f85e42aSJean-Baptiste Maneyrol
187f85e42aSJean-Baptiste Maneyrol /**
197f85e42aSJean-Baptiste Maneyrol * struct inv_icm42600_fifo - FIFO state variables
207f85e42aSJean-Baptiste Maneyrol * @on: reference counter for FIFO on.
217f85e42aSJean-Baptiste Maneyrol * @en: bits field of INV_ICM42600_SENSOR_* for FIFO EN bits.
227f85e42aSJean-Baptiste Maneyrol * @period: FIFO internal period.
237f85e42aSJean-Baptiste Maneyrol * @watermark: watermark configuration values for accel and gyro.
247f85e42aSJean-Baptiste Maneyrol * @count: number of bytes in the FIFO data buffer.
257f85e42aSJean-Baptiste Maneyrol * @nb: gyro, accel and total samples in the FIFO data buffer.
267f85e42aSJean-Baptiste Maneyrol * @data: FIFO data buffer aligned for DMA (2kB + 32 bytes of read cache).
277f85e42aSJean-Baptiste Maneyrol */
287f85e42aSJean-Baptiste Maneyrol struct inv_icm42600_fifo {
297f85e42aSJean-Baptiste Maneyrol unsigned int on;
307f85e42aSJean-Baptiste Maneyrol unsigned int en;
31*a4135386SAndy Shevchenko u32 period;
327f85e42aSJean-Baptiste Maneyrol struct {
337f85e42aSJean-Baptiste Maneyrol unsigned int gyro;
347f85e42aSJean-Baptiste Maneyrol unsigned int accel;
35d7bd4736SJean-Baptiste Maneyrol unsigned int eff_gyro;
36d7bd4736SJean-Baptiste Maneyrol unsigned int eff_accel;
377f85e42aSJean-Baptiste Maneyrol } watermark;
387f85e42aSJean-Baptiste Maneyrol size_t count;
397f85e42aSJean-Baptiste Maneyrol struct {
407f85e42aSJean-Baptiste Maneyrol size_t gyro;
417f85e42aSJean-Baptiste Maneyrol size_t accel;
427f85e42aSJean-Baptiste Maneyrol size_t total;
437f85e42aSJean-Baptiste Maneyrol } nb;
44*a4135386SAndy Shevchenko u8 data[2080] __aligned(IIO_DMA_MINALIGN);
457f85e42aSJean-Baptiste Maneyrol };
467f85e42aSJean-Baptiste Maneyrol
477f85e42aSJean-Baptiste Maneyrol /* FIFO data packet */
487f85e42aSJean-Baptiste Maneyrol struct inv_icm42600_fifo_sensor_data {
497f85e42aSJean-Baptiste Maneyrol __be16 x;
507f85e42aSJean-Baptiste Maneyrol __be16 y;
517f85e42aSJean-Baptiste Maneyrol __be16 z;
527f85e42aSJean-Baptiste Maneyrol } __packed;
537f85e42aSJean-Baptiste Maneyrol #define INV_ICM42600_FIFO_DATA_INVALID -32768
547f85e42aSJean-Baptiste Maneyrol
inv_icm42600_fifo_get_sensor_data(__be16 d)55*a4135386SAndy Shevchenko static inline s16 inv_icm42600_fifo_get_sensor_data(__be16 d)
567f85e42aSJean-Baptiste Maneyrol {
577f85e42aSJean-Baptiste Maneyrol return be16_to_cpu(d);
587f85e42aSJean-Baptiste Maneyrol }
597f85e42aSJean-Baptiste Maneyrol
607f85e42aSJean-Baptiste Maneyrol static inline bool
inv_icm42600_fifo_is_data_valid(const struct inv_icm42600_fifo_sensor_data * s)617f85e42aSJean-Baptiste Maneyrol inv_icm42600_fifo_is_data_valid(const struct inv_icm42600_fifo_sensor_data *s)
627f85e42aSJean-Baptiste Maneyrol {
63*a4135386SAndy Shevchenko s16 x, y, z;
647f85e42aSJean-Baptiste Maneyrol
657f85e42aSJean-Baptiste Maneyrol x = inv_icm42600_fifo_get_sensor_data(s->x);
667f85e42aSJean-Baptiste Maneyrol y = inv_icm42600_fifo_get_sensor_data(s->y);
677f85e42aSJean-Baptiste Maneyrol z = inv_icm42600_fifo_get_sensor_data(s->z);
687f85e42aSJean-Baptiste Maneyrol
697f85e42aSJean-Baptiste Maneyrol if (x == INV_ICM42600_FIFO_DATA_INVALID &&
707f85e42aSJean-Baptiste Maneyrol y == INV_ICM42600_FIFO_DATA_INVALID &&
717f85e42aSJean-Baptiste Maneyrol z == INV_ICM42600_FIFO_DATA_INVALID)
727f85e42aSJean-Baptiste Maneyrol return false;
737f85e42aSJean-Baptiste Maneyrol
747f85e42aSJean-Baptiste Maneyrol return true;
757f85e42aSJean-Baptiste Maneyrol }
767f85e42aSJean-Baptiste Maneyrol
777f85e42aSJean-Baptiste Maneyrol ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
78*a4135386SAndy Shevchenko const void **gyro, const s8 **temp,
797f85e42aSJean-Baptiste Maneyrol const void **timestamp, unsigned int *odr);
807f85e42aSJean-Baptiste Maneyrol
817f85e42aSJean-Baptiste Maneyrol extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops;
827f85e42aSJean-Baptiste Maneyrol
837f85e42aSJean-Baptiste Maneyrol int inv_icm42600_buffer_init(struct inv_icm42600_state *st);
847f85e42aSJean-Baptiste Maneyrol
857f85e42aSJean-Baptiste Maneyrol void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st);
867f85e42aSJean-Baptiste Maneyrol
877f85e42aSJean-Baptiste Maneyrol int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st,
887f85e42aSJean-Baptiste Maneyrol unsigned int fifo_en);
897f85e42aSJean-Baptiste Maneyrol
907f85e42aSJean-Baptiste Maneyrol int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st);
917f85e42aSJean-Baptiste Maneyrol
927f85e42aSJean-Baptiste Maneyrol int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
937f85e42aSJean-Baptiste Maneyrol unsigned int max);
947f85e42aSJean-Baptiste Maneyrol
957f85e42aSJean-Baptiste Maneyrol int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st);
967f85e42aSJean-Baptiste Maneyrol
977f85e42aSJean-Baptiste Maneyrol int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
987f85e42aSJean-Baptiste Maneyrol unsigned int count);
997f85e42aSJean-Baptiste Maneyrol
1007f85e42aSJean-Baptiste Maneyrol #endif
101