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