1 /*
2  * Copyright (c) 2024 SILA Embedded Solutions GmbH
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT infineon_tle9104_diagnostics
8 
9 #include <zephyr/drivers/sensor.h>
10 #include <zephyr/drivers/sensor/tle9104.h>
11 #include <zephyr/logging/log.h>
12 
13 #include "tle9104_diagnostics.h"
14 
15 LOG_MODULE_REGISTER(TLE9104_DIAGNOSTICS, CONFIG_SENSOR_LOG_LEVEL);
16 
tle9104_diagnostics_sample_fetch(const struct device * dev,enum sensor_channel chan)17 static int tle9104_diagnostics_sample_fetch(const struct device *dev, enum sensor_channel chan)
18 {
19 	const struct tle9104_diagnostics_config *config = dev->config;
20 	struct tle9104_diagnostics_data *data = dev->data;
21 	int result;
22 
23 	__ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL);
24 	result = tle9104_get_diagnostics(config->parent, data->values);
25 	if (result != 0) {
26 		return result;
27 	}
28 
29 	result = tle9104_clear_diagnostics(config->parent);
30 	if (result != 0) {
31 		return result;
32 	}
33 
34 	return 0;
35 }
36 
tle9104_diagnostics_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)37 static int tle9104_diagnostics_channel_get(const struct device *dev, enum sensor_channel chan,
38 					   struct sensor_value *val)
39 {
40 	struct tle9104_diagnostics_data *data = dev->data;
41 
42 	val->val1 = 0;
43 	val->val2 = 0;
44 
45 	switch (chan) {
46 	case SENSOR_CHAN_TLE9104_OPEN_LOAD:
47 		for (size_t i = 0; i < ARRAY_SIZE(data->values); ++i) {
48 			if (data->values[i].off == TLE9104_OFFDIAG_OL) {
49 				val->val1 |= BIT(i);
50 			}
51 		}
52 		return 0;
53 	case SENSOR_CHAN_TLE9104_OVER_CURRENT:
54 		for (size_t i = 0; i < ARRAY_SIZE(data->values); ++i) {
55 			if (data->values[i].on == TLE9104_ONDIAG_OCTIME ||
56 			    data->values[i].on == TLE9104_ONDIAG_OCOT) {
57 				val->val1 |= BIT(i);
58 			}
59 		}
60 		return 0;
61 	default:
62 		LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan);
63 		return -ENOTSUP;
64 	}
65 }
66 
67 static DEVICE_API(sensor, tle9104_diagnostics_driver_api) = {
68 	.sample_fetch = tle9104_diagnostics_sample_fetch,
69 	.channel_get = tle9104_diagnostics_channel_get,
70 };
71 
tle9104_diagnostics_init(const struct device * dev)72 int tle9104_diagnostics_init(const struct device *dev)
73 {
74 	const struct tle9104_diagnostics_config *config = dev->config;
75 
76 	if (!device_is_ready(config->parent)) {
77 		LOG_ERR("%s: parent device is not ready", dev->name);
78 		return -ENODEV;
79 	}
80 
81 	return 0;
82 }
83 
84 #define TLE9104_DIAGNOSTICS_DEFINE(inst)                                                           \
85 	static struct tle9104_diagnostics_data tle9104_diagnostics_data_##inst;                    \
86                                                                                                    \
87 	static const struct tle9104_diagnostics_config tle9104_diagnostics_config##inst = {        \
88 		.parent = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))),                             \
89 	};                                                                                         \
90                                                                                                    \
91 	SENSOR_DEVICE_DT_INST_DEFINE(                                                              \
92 		inst, tle9104_diagnostics_init, NULL, &tle9104_diagnostics_data_##inst,            \
93 		&tle9104_diagnostics_config##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY,       \
94 		&tle9104_diagnostics_driver_api);
95 
96 DT_INST_FOREACH_STATUS_OKAY(TLE9104_DIAGNOSTICS_DEFINE)
97