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(d: s->x); |
64 | y = inv_icm42600_fifo_get_sensor_data(d: s->y); |
65 | z = inv_icm42600_fifo_get_sensor_data(d: 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 | |