1 /*
2 * Copyright (c) 2025 Würth Elektronik eiSos GmbH & Co. KG
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT we_wsen_pads_2511020213301
8
9 #include <string.h>
10
11 #include <zephyr/sys/__assert.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/logging/log.h>
14
15 #include "wsen_pads_2511020213301.h"
16
17 LOG_MODULE_REGISTER(WSEN_PADS_2511020213301, CONFIG_SENSOR_LOG_LEVEL);
18
19 /*
20 * List of supported output data rates. Index into this list is used as
21 * argument for PADS_setOutputDataRate()
22 */
23 static const int32_t pads_2511020213301_odr_list[] = {
24 0, 1, 10, 25, 50, 75, 100, 200,
25 };
26
27 #define SAMPLES_TO_DISCARD (uint8_t)2
28
29 #define MAX_POLL_STEP_COUNT 10
30
pads_2511020213301_sample_fetch(const struct device * dev,enum sensor_channel channel)31 static int pads_2511020213301_sample_fetch(const struct device *dev, enum sensor_channel channel)
32 {
33 struct pads_2511020213301_data *data = dev->data;
34 const struct pads_2511020213301_config *cfg = dev->config;
35
36 switch (channel) {
37 case SENSOR_CHAN_ALL:
38 case SENSOR_CHAN_AMBIENT_TEMP:
39 case SENSOR_CHAN_PRESS:
40 break;
41 default:
42 LOG_ERR("Fetching is not supported on channel %d.", channel);
43 return -ENOTSUP;
44 }
45
46 if (data->sensor_odr == PADS_outputDataRatePowerDown) {
47 if (PADS_enableOneShot(&data->sensor_interface, PADS_enable) != WE_SUCCESS) {
48 LOG_ERR("Failed to fetch %s sample.", "pressure");
49 return -EIO;
50 }
51
52 switch (cfg->configuration) {
53 case PADS_lowPower:
54 k_sleep(K_USEC(4700));
55 break;
56 case PADS_lowNoise:
57 k_sleep(K_USEC(13200));
58 break;
59 default:
60 LOG_ERR("Invalid sensor configuration");
61 return -EIO;
62 }
63
64 PADS_state_t one_shot_state;
65
66 do {
67 if (PADS_isOneShotEnabled(&data->sensor_interface, &one_shot_state) !=
68 WE_SUCCESS) {
69 LOG_ERR("Failed to check for data ready");
70 return -EIO;
71 }
72 } while (PADS_enable == one_shot_state);
73 } else {
74
75 bool data_ready = false;
76 int step_count = 0;
77 uint32_t step_sleep_duration =
78 ((uint32_t)1000000000 /
79 (pads_2511020213301_odr_list[data->sensor_odr] * 1000)) /
80 MAX_POLL_STEP_COUNT;
81
82 while (1) {
83 PADS_state_t pressure_state, temp_state;
84
85 pressure_state = temp_state = PADS_disable;
86
87 if (PADS_isDataAvailable(&data->sensor_interface, &temp_state,
88 &pressure_state) != WE_SUCCESS) {
89 LOG_ERR("Failed to check for data available");
90 return -EIO;
91 }
92
93 switch (channel) {
94 case SENSOR_CHAN_ALL:
95 data_ready = (pressure_state == PADS_enable &&
96 temp_state == PADS_enable);
97 break;
98 case SENSOR_CHAN_AMBIENT_TEMP:
99 data_ready = (temp_state == PADS_enable);
100 break;
101 case SENSOR_CHAN_PRESS:
102 data_ready = (pressure_state == PADS_enable);
103 break;
104 default:
105 break;
106 }
107
108 if (data_ready) {
109 break;
110 } else if (step_count >= MAX_POLL_STEP_COUNT) {
111 return -EIO;
112 }
113
114 step_count++;
115 k_sleep(K_USEC(step_sleep_duration));
116 }
117 }
118
119 switch (channel) {
120 case SENSOR_CHAN_ALL: {
121
122 if (PADS_getPressure_int(&data->sensor_interface, &data->pressure) != WE_SUCCESS) {
123 LOG_ERR("Failed to fetch %s sample.", "pressure");
124 return -EIO;
125 }
126
127 if (PADS_getTemperature_int(&data->sensor_interface, &data->temperature) !=
128 WE_SUCCESS) {
129 LOG_ERR("Failed to fetch %s sample.", "temperature");
130 return -EIO;
131 }
132
133 break;
134 }
135 case SENSOR_CHAN_AMBIENT_TEMP: {
136
137 if (PADS_getTemperature_int(&data->sensor_interface, &data->temperature) !=
138 WE_SUCCESS) {
139 LOG_ERR("Failed to fetch %s sample.", "temperature");
140 return -EIO;
141 }
142
143 break;
144 }
145 case SENSOR_CHAN_PRESS: {
146
147 if (PADS_getPressure_int(&data->sensor_interface, &data->pressure) != WE_SUCCESS) {
148 LOG_ERR("Failed to fetch %s sample.", "pressure");
149 return -EIO;
150 }
151
152 break;
153 }
154 default:
155 break;
156 }
157
158 return 0;
159 }
160
pads_2511020213301_channel_get(const struct device * dev,enum sensor_channel channel,struct sensor_value * value)161 static int pads_2511020213301_channel_get(const struct device *dev, enum sensor_channel channel,
162 struct sensor_value *value)
163 {
164 struct pads_2511020213301_data *data = dev->data;
165
166 switch (channel) {
167 case SENSOR_CHAN_AMBIENT_TEMP:
168 /* Convert temperature from 0.01 degrees Celsius to degrees Celsius */
169 value->val1 = data->temperature / 100;
170 value->val2 = ((int32_t)data->temperature % 100) * (1000000 / 100);
171 break;
172 case SENSOR_CHAN_PRESS:
173 /* Convert pressure from Pa to kPa */
174 value->val1 = data->pressure / 1000;
175 value->val2 = ((int32_t)data->pressure % 1000) * (1000000 / 1000);
176 break;
177 default:
178 LOG_ERR("Channel not supported %d", channel);
179 return -ENOTSUP;
180 }
181
182 return 0;
183 }
184
185 /* Set output data rate. See pads_2511020213301_odr_list for allowed values. */
pads_2511020213301_odr_set(const struct device * dev,const struct sensor_value * odr)186 static int pads_2511020213301_odr_set(const struct device *dev, const struct sensor_value *odr)
187 {
188 struct pads_2511020213301_data *data = dev->data;
189 const struct pads_2511020213301_config *cfg = dev->config;
190 int odr_index;
191
192 for (odr_index = 0; odr_index < ARRAY_SIZE(pads_2511020213301_odr_list); odr_index++) {
193 if (odr->val1 == pads_2511020213301_odr_list[odr_index] && odr->val2 == 0) {
194 break;
195 }
196 }
197
198 if (odr_index == ARRAY_SIZE(pads_2511020213301_odr_list)) {
199 /* ODR not allowed (was not found in pads_2511020213301_odr_list) */
200 LOG_ERR("Bad sampling frequency %d.%d", odr->val1, odr->val2);
201 return -EINVAL;
202 }
203
204 if (cfg->configuration == PADS_lowNoise &&
205 (PADS_outputDataRate_t)odr_index > PADS_outputDataRate75Hz) {
206 LOG_ERR("Failed to set ODR > 75Hz is not possible with low noise sensor "
207 "configuration.");
208 return -EIO;
209 }
210
211 if (PADS_setOutputDataRate(&data->sensor_interface, (PADS_outputDataRate_t)odr_index) !=
212 WE_SUCCESS) {
213 LOG_ERR("Failed to set output data rate");
214 return -EIO;
215 }
216
217 if (PADS_enableBlockDataUpdate(&data->sensor_interface,
218 (PADS_outputDataRate_t)odr_index !=
219 PADS_outputDataRatePowerDown
220 ? PADS_enable
221 : PADS_disable) != WE_SUCCESS) {
222 LOG_ERR("Failed to enable block data update.");
223 return -EIO;
224 }
225
226 data->sensor_odr = (PADS_outputDataRate_t)odr_index;
227
228 return 0;
229 }
230
231 /* Get output data rate. */
pads_2511020213301_odr_get(const struct device * dev,struct sensor_value * odr)232 static int pads_2511020213301_odr_get(const struct device *dev, struct sensor_value *odr)
233 {
234
235 struct pads_2511020213301_data *data = dev->data;
236
237 PADS_outputDataRate_t odr_index;
238
239 if (PADS_getOutputDataRate(&data->sensor_interface, &odr_index) != WE_SUCCESS) {
240 LOG_ERR("Failed to get output data rate");
241 return -EIO;
242 }
243
244 data->sensor_odr = odr_index;
245
246 odr->val1 = pads_2511020213301_odr_list[odr_index];
247 odr->val2 = 0;
248
249 return 0;
250 }
251
pads_2511020213301_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)252 static int pads_2511020213301_attr_get(const struct device *dev, enum sensor_channel chan,
253 enum sensor_attribute attr, struct sensor_value *val)
254 {
255
256 if (val == NULL) {
257 LOG_WRN("address of passed value is NULL.");
258 return -EFAULT;
259 }
260
261 switch ((int)attr) {
262 case SENSOR_ATTR_SAMPLING_FREQUENCY:
263 if (chan != SENSOR_CHAN_ALL) {
264 LOG_ERR("attr_get() is not supported on channel %d.", chan);
265 return -ENOTSUP;
266 }
267 return pads_2511020213301_odr_get(dev, val);
268 #ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD
269 case SENSOR_ATTR_WSEN_PADS_2511020213301_REFERENCE_POINT:
270 if (chan != SENSOR_CHAN_PRESS) {
271 LOG_ERR("attr_get() is not supported on channel %d.", chan);
272 return -ENOTSUP;
273 }
274 return pads_2511020213301_reference_point_get(dev, val);
275 case SENSOR_ATTR_UPPER_THRESH:
276 case SENSOR_ATTR_LOWER_THRESH:
277 if (chan != SENSOR_CHAN_PRESS) {
278 LOG_ERR("attr_get() is not supported on channel %d.", chan);
279 return -ENOTSUP;
280 }
281 return pads_2511020213301_threshold_get(dev, val);
282 #endif
283 default:
284 LOG_ERR("Operation not supported.");
285 return -ENOTSUP;
286 }
287
288 return 0;
289 }
290
pads_2511020213301_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)291 static int pads_2511020213301_attr_set(const struct device *dev, enum sensor_channel chan,
292 enum sensor_attribute attr, const struct sensor_value *val)
293 {
294 switch ((int)attr) {
295 case SENSOR_ATTR_SAMPLING_FREQUENCY:
296 if (chan != SENSOR_CHAN_ALL) {
297 LOG_ERR("attr_set() is not supported on channel %d.", chan);
298 return -ENOTSUP;
299 }
300 return pads_2511020213301_odr_set(dev, val);
301 #ifdef CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD
302 case SENSOR_ATTR_WSEN_PADS_2511020213301_REFERENCE_POINT:
303 if (chan != SENSOR_CHAN_PRESS) {
304 LOG_ERR("attr_set() is not supported on channel %d.", chan);
305 return -ENOTSUP;
306 }
307 return pads_2511020213301_reference_point_set(dev, val);
308 case SENSOR_ATTR_UPPER_THRESH:
309 case SENSOR_ATTR_LOWER_THRESH:
310 if (chan != SENSOR_CHAN_PRESS) {
311 LOG_ERR("attr_set() is not supported on channel %d.", chan);
312 return -ENOTSUP;
313 }
314 return pads_2511020213301_threshold_set(dev, val);
315 #endif
316 default:
317 LOG_ERR("Operation not supported.");
318 return -ENOTSUP;
319 }
320 }
321
322 static DEVICE_API(sensor, pads_2511020213301_driver_api) = {
323 .attr_set = pads_2511020213301_attr_set,
324 #if CONFIG_WSEN_PADS_2511020213301_TRIGGER
325 .trigger_set = pads_2511020213301_trigger_set,
326 #endif
327 .attr_get = pads_2511020213301_attr_get,
328 .sample_fetch = pads_2511020213301_sample_fetch,
329 .channel_get = pads_2511020213301_channel_get,
330 };
331
pads_2511020213301_init(const struct device * dev)332 static int pads_2511020213301_init(const struct device *dev)
333 {
334 const struct pads_2511020213301_config *config = dev->config;
335 struct pads_2511020213301_data *data = dev->data;
336 struct sensor_value odr;
337 uint8_t device_id;
338
339 /* Initialize WE sensor interface */
340 WE_sensorInterfaceType_t interface_type = data->sensor_interface.interfaceType;
341
342 PADS_getDefaultInterface(&data->sensor_interface);
343 data->sensor_interface.interfaceType = interface_type;
344
345 switch (data->sensor_interface.interfaceType) {
346 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(i2c)
347 case WE_i2c:
348 if (!i2c_is_ready_dt(&config->bus_cfg.i2c)) {
349 LOG_ERR("I2C bus device not ready");
350 return -ENODEV;
351 }
352 data->sensor_interface.handle = (void *)&config->bus_cfg.i2c;
353 break;
354 #endif
355 #if DT_ANY_INST_ON_BUS_STATUS_OKAY(spi)
356 case WE_spi:
357 if (!spi_is_ready_dt(&config->bus_cfg.spi)) {
358 LOG_ERR("SPI bus device not ready");
359 return -ENODEV;
360 }
361 data->sensor_interface.handle = (void *)&config->bus_cfg.spi;
362 break;
363 #endif
364 default:
365 LOG_ERR("Invalid interface type");
366 return -EINVAL;
367 }
368
369 /* needed after power up */
370 k_sleep(K_USEC(4500));
371
372 PADS_state_t boot_state = PADS_enable;
373
374 do {
375 if (PADS_getBootStatus(&data->sensor_interface, &boot_state) != WE_SUCCESS) {
376 LOG_ERR("Failed to get sensor reset state.");
377 return -EIO;
378 }
379 } while (PADS_enable == boot_state);
380
381 /* First communication test - check device ID */
382 if (PADS_getDeviceID(&data->sensor_interface, &device_id) != WE_SUCCESS) {
383 LOG_ERR("Failed to read device ID.");
384 return -EIO;
385 }
386
387 if (device_id != PADS_DEVICE_ID_VALUE) {
388 LOG_ERR("Invalid device ID 0x%x.", device_id);
389 return -EINVAL;
390 }
391
392 /* Reset sensor */
393 PADS_softReset(&data->sensor_interface, PADS_enable);
394 k_sleep(K_USEC(50));
395
396 PADS_state_t sw_reset;
397
398 do {
399 if (PADS_getSoftResetState(&data->sensor_interface, &sw_reset) != WE_SUCCESS) {
400 LOG_ERR("Failed to get sensor reset state.");
401 return -EIO;
402 }
403 } while (PADS_enable == sw_reset);
404
405 if (PADS_setPowerMode(&data->sensor_interface, config->configuration) != WE_SUCCESS) {
406 LOG_ERR("Failed to set sensor configuration.");
407 return -EIO;
408 }
409
410 odr.val1 = pads_2511020213301_odr_list[config->odr];
411 odr.val2 = 0;
412
413 if (pads_2511020213301_odr_set(dev, &odr) < 0) {
414 LOG_ERR("Failed to set output data rate.");
415 return -EIO;
416 }
417
418 if (PADS_enableLowPassFilter(&data->sensor_interface, config->alpf) != WE_SUCCESS) {
419 LOG_ERR("Failed to set additional low pass filter.");
420 return -EIO;
421 }
422
423 if (config->alpf == PADS_enable) {
424 if (PADS_setLowPassFilterConfig(&data->sensor_interface,
425 config->alpf_configuration) != WE_SUCCESS) {
426 LOG_ERR("Failed to set additional low pass filter configuration.");
427 return -EIO;
428 }
429
430 for (uint8_t i = 0; i < SAMPLES_TO_DISCARD; i++) {
431 pads_2511020213301_sample_fetch(dev, SENSOR_CHAN_ALL);
432 }
433
434 data->pressure = 0;
435 data->temperature = 0;
436 }
437
438 #if CONFIG_WSEN_PADS_2511020213301_TRIGGER
439 if (pads_2511020213301_init_interrupt(dev) < 0) {
440 LOG_ERR("Failed to initialize interrupt.");
441 return -EIO;
442 }
443 #endif
444
445 return 0;
446 }
447
448 #if DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 0
449 #warning "PADS driver enabled without any devices"
450 #endif
451
452 #ifdef CONFIG_WSEN_PADS_2511020213301_TRIGGER
453 #define PADS_2511020213301_CFG_IRQ(inst) \
454 .interrupt_gpio = GPIO_DT_SPEC_INST_GET(inst, interrupt_gpios)
455 #else
456 #define PADS_2511020213301_CFG_IRQ(inst)
457 #endif /* CONFIG_WSEN_PADS_2511020213301_TRIGGER */
458
459 #define PADS_2511020213301_CFG_ALPF(inst) \
460 .alpf = COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, additional_low_pass_filter), \
461 (PADS_enable), (PADS_disable))
462
463 #define PADS_2511020213301_CONFIG_COMMON(inst) \
464 .odr = (PADS_outputDataRate_t)(DT_INST_ENUM_IDX(inst, odr)), \
465 .configuration = (PADS_powerMode_t)(DT_INST_ENUM_IDX(inst, configuration)), \
466 .alpf_configuration = \
467 (PADS_filterConf_t)DT_INST_PROP(inst, additional_low_pass_filter_configuration), \
468 PADS_2511020213301_CFG_ALPF(inst), \
469 IF_ENABLED(CONFIG_WSEN_PADS_2511020213301_PRESSURE_THRESHOLD, \
470 (.threshold = (uint16_t)DT_INST_PROP_OR(inst, threshold, 0),)) \
471 COND_CODE_1(DT_INST_NODE_HAS_PROP(inst, interrupt_gpios), \
472 (PADS_2511020213301_CFG_IRQ(inst)), ())
473
474 /*
475 * Instantiation macros used when device is on SPI bus.
476 */
477
478 #define PADS_2511020213301_SPI_OPERATION \
479 (SPI_WORD_SET(8) | SPI_OP_MODE_MASTER | SPI_MODE_CPOL | SPI_MODE_CPHA)
480
481 #define PADS_2511020213301_CONFIG_SPI(inst) \
482 {.bus_cfg = \
483 { \
484 .spi = SPI_DT_SPEC_INST_GET(inst, PADS_2511020213301_SPI_OPERATION, 0), \
485 }, \
486 PADS_2511020213301_CONFIG_COMMON(inst)}
487
488 /*
489 * Instantiation macros used when device is on I2C bus.
490 */
491
492 #define PADS_2511020213301_CONFIG_I2C(inst) \
493 {.bus_cfg = \
494 { \
495 .i2c = I2C_DT_SPEC_INST_GET(inst), \
496 }, \
497 PADS_2511020213301_CONFIG_COMMON(inst)}
498
499 #define PADS_2511020213301_CONFIG_WE_INTERFACE(inst) \
500 {COND_CODE_1(DT_INST_ON_BUS(inst, i2c), \
501 (.sensor_interface = {.interfaceType = WE_i2c}), \
502 ()) COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
503 (.sensor_interface = {.interfaceType = WE_spi}), \
504 ()) }
505
506 /*
507 * Main instantiation macro. Use of COND_CODE_1() selects the right
508 * bus-specific macro at preprocessor time.
509 */
510 #define PADS_2511020213301_DEFINE(inst) \
511 static struct pads_2511020213301_data pads_2511020213301_data_##inst = \
512 PADS_2511020213301_CONFIG_WE_INTERFACE(inst); \
513 static const struct pads_2511020213301_config pads_2511020213301_config_##inst = \
514 COND_CODE_1(DT_INST_ON_BUS(inst, i2c),\
515 (PADS_2511020213301_CONFIG_I2C(inst)), \
516 ()) \
517 COND_CODE_1(DT_INST_ON_BUS(inst, spi), \
518 (PADS_2511020213301_CONFIG_SPI(inst)),\
519 ()); \
520 SENSOR_DEVICE_DT_INST_DEFINE(inst, pads_2511020213301_init, NULL, \
521 &pads_2511020213301_data_##inst, \
522 &pads_2511020213301_config_##inst, POST_KERNEL, \
523 CONFIG_SENSOR_INIT_PRIORITY, &pads_2511020213301_driver_api);
524
525 DT_INST_FOREACH_STATUS_OKAY(PADS_2511020213301_DEFINE)
526