1 /* ST Microelectronics LPS2XDF pressure and temperature sensor
2  *
3  * Copyright (c) 2023 STMicroelectronics
4  * Copyright (c) 2023 PHYTEC Messtechnik GmbH
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #ifndef ZEPHYR_DRIVERS_SENSOR_LPS2XDF_LPS2XDF_H_
10 #define ZEPHYR_DRIVERS_SENSOR_LPS2XDF_LPS2XDF_H_
11 
12 #include <stdint.h>
13 #include <stmemsc.h>
14 
15 #if DT_HAS_COMPAT_STATUS_OKAY(st_ilps22qs)
16 #include "ilps22qs_reg.h"
17 #endif
18 
19 #if DT_HAS_COMPAT_STATUS_OKAY(st_lps28dfw)
20 #include "lps28dfw_reg.h"
21 #endif
22 
23 #if DT_HAS_COMPAT_STATUS_OKAY(st_lps22df)
24 #include "lps22df_reg.h"
25 #endif
26 
27 #include <zephyr/drivers/spi.h>
28 #include <zephyr/drivers/i2c.h>
29 #include <zephyr/drivers/i3c.h>
30 #include <zephyr/drivers/sensor.h>
31 
32 #define LPS2XDF_SWRESET_WAIT_TIME_US 50
33 
34 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \
35 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \
36 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c))
37 	#define ON_I3C_BUS(cfg) (cfg->i3c.bus != NULL)
38 #else
39 	#define ON_I3C_BUS(cfg) (false)
40 #endif
41 
42 typedef int32_t (*api_lps2xdf_mode_set_odr_raw)(const struct device *dev, uint8_t odr);
43 typedef int32_t (*api_lps2xdf_sample_fetch)(const struct device *dev, enum sensor_channel chan);
44 #ifdef CONFIG_LPS2XDF_TRIGGER
45 typedef int (*api_lps2xdf_config_interrupt)(const struct device *dev);
46 typedef void (*api_lps2xdf_handle_interrupt)(const struct device *dev);
47 typedef int (*api_lps2xdf_trigger_set)(const struct device *dev,
48 				       const struct sensor_trigger *trig,
49 				       sensor_trigger_handler_t handler);
50 #endif
51 
52 struct lps2xdf_chip_api {
53 	api_lps2xdf_mode_set_odr_raw mode_set_odr_raw;
54 	api_lps2xdf_sample_fetch sample_fetch;
55 #ifdef CONFIG_LPS2XDF_TRIGGER
56 	api_lps2xdf_config_interrupt config_interrupt;
57 	api_lps2xdf_handle_interrupt handle_interrupt;
58 	api_lps2xdf_trigger_set trigger_set;
59 #endif
60 };
61 
62 
63 enum sensor_variant {
64 	DEVICE_VARIANT_LPS22DF = 0,
65 	DEVICE_VARIANT_LPS28DFW = 1,
66 	DEVICE_VARIANT_ILPS22QS = 2,
67 };
68 
69 
70 struct lps2xdf_config {
71 	stmdev_ctx_t ctx;
72 	union {
73 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i2c) || \
74 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i2c) || \
75 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i2c))
76 		const struct i2c_dt_spec i2c;
77 #endif
78 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, spi) ||\
79 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, spi))
80 		const struct spi_dt_spec spi;
81 #endif
82 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \
83 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \
84 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c))
85 		struct i3c_device_desc **i3c;
86 #endif
87 	} stmemsc_cfg;
88 	uint8_t odr;
89 	uint8_t lpf;
90 	uint8_t avg;
91 	uint8_t drdy_pulsed;
92 	bool fs;
93 #ifdef CONFIG_LPS2XDF_TRIGGER
94 	struct gpio_dt_spec gpio_int;
95 	bool trig_enabled;
96 #endif
97 
98 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \
99 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \
100 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c))
101 	struct {
102 		const struct device *bus;
103 		const struct i3c_device_id dev_id;
104 	} i3c;
105 #endif
106 	const struct lps2xdf_chip_api *chip_api;
107 };
108 
109 struct lps2xdf_data {
110 	int32_t sample_press;
111 	int16_t sample_temp;
112 
113 #ifdef CONFIG_LPS2XDF_TRIGGER
114 	struct gpio_callback gpio_cb;
115 
116 	const struct sensor_trigger *data_ready_trigger;
117 	sensor_trigger_handler_t handler_drdy;
118 	const struct device *dev;
119 
120 #if defined(CONFIG_LPS2XDF_TRIGGER_OWN_THREAD)
121 	K_KERNEL_STACK_MEMBER(thread_stack, CONFIG_LPS2XDF_THREAD_STACK_SIZE);
122 	struct k_thread thread;
123 	struct k_sem intr_sem;
124 #elif defined(CONFIG_LPS2XDF_TRIGGER_GLOBAL_THREAD)
125 	struct k_work work;
126 #endif
127 
128 #endif /* CONFIG_LPS2XDF_TRIGGER */
129 
130 #if (DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps22df, i3c) || \
131 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_ilps22qs, i3c) || \
132 	DT_HAS_COMPAT_ON_BUS_STATUS_OKAY(st_lps28dfw, i3c))
133 	struct i3c_device_desc *i3c_dev;
134 #endif
135 };
136 
137 #ifdef CONFIG_LPS2XDF_TRIGGER
138 int lps2xdf_config_int(const struct device *dev);
139 
140 int lps2xdf_trigger_set(const struct device *dev,
141 			const struct sensor_trigger *trig,
142 			sensor_trigger_handler_t handler);
143 
144 int lps2xdf_init_interrupt(const struct device *dev, enum sensor_variant variant);
145 #endif
146 
147 #endif /* ZEPHYR_DRIVERS_SENSOR_LPS2XDF_H_ */
148