Linux 6.7-rc7
[linux-modified.git] / drivers / iio / imu / inv_icm42600 / inv_icm42600_buffer.h
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