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 	} watermark;
36 	size_t count;
37 	struct {
38 		size_t gyro;
39 		size_t accel;
40 		size_t total;
41 	} nb;
42 	uint8_t data[2080] __aligned(IIO_DMA_MINALIGN);
43 };
44 
45 /* FIFO data packet */
46 struct inv_icm42600_fifo_sensor_data {
47 	__be16 x;
48 	__be16 y;
49 	__be16 z;
50 } __packed;
51 #define INV_ICM42600_FIFO_DATA_INVALID		-32768
52 
53 static inline int16_t inv_icm42600_fifo_get_sensor_data(__be16 d)
54 {
55 	return be16_to_cpu(d);
56 }
57 
58 static inline bool
59 inv_icm42600_fifo_is_data_valid(const struct inv_icm42600_fifo_sensor_data *s)
60 {
61 	int16_t x, y, z;
62 
63 	x = inv_icm42600_fifo_get_sensor_data(s->x);
64 	y = inv_icm42600_fifo_get_sensor_data(s->y);
65 	z = inv_icm42600_fifo_get_sensor_data(s->z);
66 
67 	if (x == INV_ICM42600_FIFO_DATA_INVALID &&
68 	    y == INV_ICM42600_FIFO_DATA_INVALID &&
69 	    z == INV_ICM42600_FIFO_DATA_INVALID)
70 		return false;
71 
72 	return true;
73 }
74 
75 ssize_t inv_icm42600_fifo_decode_packet(const void *packet, const void **accel,
76 					const void **gyro, const int8_t **temp,
77 					const void **timestamp, unsigned int *odr);
78 
79 extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops;
80 
81 int inv_icm42600_buffer_init(struct inv_icm42600_state *st);
82 
83 void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st);
84 
85 int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st,
86 				    unsigned int fifo_en);
87 
88 int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st);
89 
90 int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st,
91 				  unsigned int max);
92 
93 int inv_icm42600_buffer_fifo_parse(struct inv_icm42600_state *st);
94 
95 int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st,
96 				     unsigned int count);
97 
98 #endif
99