xref: /linux/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2020 Invensense, Inc.
4  */
5 
6 #ifndef INV_ICM42600_BUFFER_H_
7 #define INV_ICM42600_BUFFER_H_
8 
9 #include <linux/kernel.h>
10 #include <linux/bits.h>
11 
12 struct inv_icm42600_state;
13 
14 #define INV_ICM42600_SENSOR_GYRO	BIT(0)
15 #define INV_ICM42600_SENSOR_ACCEL	BIT(1)
16 #define INV_ICM42600_SENSOR_TEMP	BIT(2)
17 
18 /**
19  * struct inv_icm42600_fifo - FIFO state variables
20  * @on:		reference counter for FIFO on.
21  * @en:		bits field of INV_ICM42600_SENSOR_* for FIFO EN bits.
22  * @period:	FIFO internal period.
23  * @watermark:	watermark configuration values for accel and gyro.
24  * @count:	number of bytes in the FIFO data buffer.
25  * @nb:		gyro, accel and total samples in the FIFO data buffer.
26  * @data:	FIFO data buffer aligned for DMA (2kB + 32 bytes of read cache).
27  */
28 struct inv_icm42600_fifo {
29 	unsigned int on;
30 	unsigned int en;
31 	uint32_t period;
32 	struct {
33 		unsigned int gyro;
34 		unsigned int accel;
35 		unsigned int eff_gyro;
36 		unsigned int eff_accel;
37 	} watermark;
38 	size_t count;
39 	struct {
40 		size_t gyro;
41 		size_t accel;
42 		size_t total;
43 	} nb;
44 	uint8_t data[2080] __aligned(IIO_DMA_MINALIGN);
45 };
46 
47 /* FIFO data packet */
48 struct inv_icm42600_fifo_sensor_data {
49 	__be16 x;
50 	__be16 y;
51 	__be16 z;
52 } __packed;
53 #define INV_ICM42600_FIFO_DATA_INVALID		-32768
54 
55 static inline int16_t inv_icm42600_fifo_get_sensor_data(__be16 d)
56 {
57 	return be16_to_cpu(d);
58 }
59 
60 static inline bool
61 inv_icm42600_fifo_is_data_valid(const struct inv_icm42600_fifo_sensor_data *s)
62 {
63 	int16_t x, y, z;
64 
65 	x = inv_icm42600_fifo_get_sensor_data(s->x);
66 	y = inv_icm42600_fifo_get_sensor_data(s->y);
67 	z = inv_icm42600_fifo_get_sensor_data(s->z);
68 
69 	if (x == INV_ICM42600_FIFO_DATA_INVALID &&
70 	    y == INV_ICM42600_FIFO_DATA_INVALID &&
71 	    z == INV_ICM42600_FIFO_DATA_INVALID)
72 		return false;
73 
74 	return true;
75 }
76 
77 ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
78 					const void **gyro, const int8_t **temp,
79 					const void **timestamp, unsigned int *odr);
80 
81 extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops;
82 
83 int inv_icm42600_buffer_init(struct inv_icm42600_state *st);
84 
85 void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st);
86 
87 int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st,
88 				    unsigned int fifo_en);
89 
90 int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st);
91 
92 int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
93 				  unsigned int max);
94 
95 int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st);
96 
97 int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
98 				     unsigned int count);
99 
100 #endif
101