From 888d071fe701827c3bb1ec570e0215e32622d593 Mon Sep 17 00:00:00 2001 From: Benedikt Schmidt Date: Thu, 15 Feb 2024 11:42:42 +0100 Subject: [PATCH] drivers: sensor: implement output diagnostics sensor for TLE9104 Implement a sensor for the output diagnostics of the power train switch TLE9104. Signed-off-by: Benedikt Schmidt --- drivers/mfd/mfd_tle9104.c | 39 ++++++++ drivers/sensor/infineon/CMakeLists.txt | 1 + drivers/sensor/infineon/Kconfig | 1 + .../sensor/infineon/tle9104/CMakeLists.txt | 5 + drivers/sensor/infineon/tle9104/Kconfig | 10 ++ .../infineon/tle9104/tle9104_diagnostics.c | 96 +++++++++++++++++++ .../infineon/tle9104/tle9104_diagnostics.h | 23 +++++ .../sensor/infineon,tle9104-diagnostics.yaml | 15 +++ include/zephyr/drivers/mfd/tle9104.h | 8 ++ include/zephyr/drivers/sensor/tle9104.h | 18 ++++ 10 files changed, 216 insertions(+) create mode 100644 drivers/sensor/infineon/tle9104/CMakeLists.txt create mode 100644 drivers/sensor/infineon/tle9104/Kconfig create mode 100644 drivers/sensor/infineon/tle9104/tle9104_diagnostics.c create mode 100644 drivers/sensor/infineon/tle9104/tle9104_diagnostics.h create mode 100644 dts/bindings/sensor/infineon,tle9104-diagnostics.yaml create mode 100644 include/zephyr/drivers/sensor/tle9104.h diff --git a/drivers/mfd/mfd_tle9104.c b/drivers/mfd/mfd_tle9104.c index 3170a97d8f..313c59d5d7 100644 --- a/drivers/mfd/mfd_tle9104.c +++ b/drivers/mfd/mfd_tle9104.c @@ -368,6 +368,45 @@ int tle9104_get_diagnostics(const struct device *dev, return result; } +static int tle9104_clear_diagnostics_internal(const struct device *dev) +{ + enum tle9104_register read_reg; + uint8_t temp; + int result; + + result = tle9104_transceive_frame(dev, true, TLE9104REGISTER_DIAGOUT12ON, 0x00, &read_reg, + &temp); + if (result != 0) { + return result; + } + + result = tle9104_transceive_frame(dev, true, TLE9104REGISTER_DIAGOUT34ON, 0x00, &read_reg, + &temp); + if (result != 0) { + return result; + } + + result = tle9104_transceive_frame(dev, true, TLE9104REGISTER_DIAGOFF, 0x00, &read_reg, + &temp); + if (result != 0) { + return result; + } + + return 0; +} + +int tle9104_clear_diagnostics(const struct device *dev) +{ + struct tle9104_data *data = dev->data; + int result; + + k_mutex_lock(&data->lock, K_FOREVER); + result = tle9104_clear_diagnostics_internal(dev); + k_mutex_unlock(&data->lock); + + return result; +} + static int tle9104_init(const struct device *dev) { const struct tle9104_config *config = dev->config; diff --git a/drivers/sensor/infineon/CMakeLists.txt b/drivers/sensor/infineon/CMakeLists.txt index 5c0afd3c4e..5ebc1254db 100644 --- a/drivers/sensor/infineon/CMakeLists.txt +++ b/drivers/sensor/infineon/CMakeLists.txt @@ -3,5 +3,6 @@ # zephyr-keep-sorted-start add_subdirectory_ifdef(CONFIG_DPS310 dps310) +add_subdirectory_ifdef(CONFIG_TLE9104_DIAGNOSTICS tle9104) add_subdirectory_ifdef(CONFIG_XMC4XXX_TEMP xmc4xxx_temp) # zephyr-keep-sorted-stop diff --git a/drivers/sensor/infineon/Kconfig b/drivers/sensor/infineon/Kconfig index 92d95d20fb..678fa19475 100644 --- a/drivers/sensor/infineon/Kconfig +++ b/drivers/sensor/infineon/Kconfig @@ -3,5 +3,6 @@ # zephyr-keep-sorted-start source "drivers/sensor/infineon/dps310/Kconfig" +source "drivers/sensor/infineon/tle9104/Kconfig" source "drivers/sensor/infineon/xmc4xxx_temp/Kconfig" # zephyr-keep-sorted-stop diff --git a/drivers/sensor/infineon/tle9104/CMakeLists.txt b/drivers/sensor/infineon/tle9104/CMakeLists.txt new file mode 100644 index 0000000000..38edbca3b5 --- /dev/null +++ b/drivers/sensor/infineon/tle9104/CMakeLists.txt @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(tle9104_diagnostics.c) diff --git a/drivers/sensor/infineon/tle9104/Kconfig b/drivers/sensor/infineon/tle9104/Kconfig new file mode 100644 index 0000000000..ec4b9e1ab0 --- /dev/null +++ b/drivers/sensor/infineon/tle9104/Kconfig @@ -0,0 +1,10 @@ +# Copyright (c) 2024 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +config TLE9104_DIAGNOSTICS + bool "Output diagnostics of TLE9104" + default y + depends on DT_HAS_INFINEON_TLE9104_DIAGNOSTICS_ENABLED + help + Enable driver for the output diagnostics of the power train + switch TLE9104. diff --git a/drivers/sensor/infineon/tle9104/tle9104_diagnostics.c b/drivers/sensor/infineon/tle9104/tle9104_diagnostics.c new file mode 100644 index 0000000000..d1c820ab11 --- /dev/null +++ b/drivers/sensor/infineon/tle9104/tle9104_diagnostics.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT infineon_tle9104_diagnostics + +#include +#include +#include + +#include "tle9104_diagnostics.h" + +LOG_MODULE_REGISTER(TLE9104_DIAGNOSTICS, CONFIG_SENSOR_LOG_LEVEL); + +static int tle9104_diagnostics_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + const struct tle9104_diagnostics_config *config = dev->config; + struct tle9104_diagnostics_data *data = dev->data; + int result; + + __ASSERT_NO_MSG(chan == SENSOR_CHAN_ALL); + result = tle9104_get_diagnostics(config->parent, data->values); + if (result != 0) { + return result; + } + + result = tle9104_clear_diagnostics(config->parent); + if (result != 0) { + return result; + } + + return 0; +} + +static int tle9104_diagnostics_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *val) +{ + struct tle9104_diagnostics_data *data = dev->data; + + val->val1 = 0; + val->val2 = 0; + + switch (chan) { + case SENSOR_CHAN_TLE9104_OPEN_LOAD: + for (size_t i = 0; i < ARRAY_SIZE(data->values); ++i) { + if (data->values[i].off == TLE9104_OFFDIAG_OL) { + val->val1 |= BIT(i); + } + } + return 0; + case SENSOR_CHAN_TLE9104_OVER_CURRENT: + for (size_t i = 0; i < ARRAY_SIZE(data->values); ++i) { + if (data->values[i].on == TLE9104_ONDIAG_OCTIME || + data->values[i].on == TLE9104_ONDIAG_OCOT) { + val->val1 |= BIT(i); + } + } + return 0; + default: + LOG_ERR("%s: requesting unsupported channel %i", dev->name, chan); + return -ENOTSUP; + } +} + +static const struct sensor_driver_api tle9104_diagnostics_driver_api = { + .sample_fetch = tle9104_diagnostics_sample_fetch, + .channel_get = tle9104_diagnostics_channel_get, +}; + +int tle9104_diagnostics_init(const struct device *dev) +{ + const struct tle9104_diagnostics_config *config = dev->config; + + if (!device_is_ready(config->parent)) { + LOG_ERR("%s: parent device is not ready", dev->name); + return -ENODEV; + } + + return 0; +} + +#define TLE9104_DIAGNOSTICS_DEFINE(inst) \ + static struct tle9104_diagnostics_data tle9104_diagnostics_data_##inst; \ + \ + static const struct tle9104_diagnostics_config tle9104_diagnostics_config##inst = { \ + .parent = DEVICE_DT_GET(DT_PARENT(DT_DRV_INST(inst))), \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE( \ + inst, tle9104_diagnostics_init, NULL, &tle9104_diagnostics_data_##inst, \ + &tle9104_diagnostics_config##inst, POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \ + &tle9104_diagnostics_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(TLE9104_DIAGNOSTICS_DEFINE) diff --git a/drivers/sensor/infineon/tle9104/tle9104_diagnostics.h b/drivers/sensor/infineon/tle9104/tle9104_diagnostics.h new file mode 100644 index 0000000000..37f03952d7 --- /dev/null +++ b/drivers/sensor/infineon/tle9104/tle9104_diagnostics.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 SILA Embedded Solutions GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_SENSOR_INFINEON_TLE9104_TLE9104_DIAGNOSTICS_H_ +#define ZEPHYR_DRIVERS_SENSOR_INFINEON_TLE9104_TLE9104_DIAGNOSTICS_H_ + +#include +#include +#include + +struct tle9104_diagnostics_data { + struct gpio_tle9104_channel_diagnostics values[TLE9104_GPIO_COUNT]; +}; + +struct tle9104_diagnostics_config { + const struct device *parent; + uint8_t channel; +}; + +#endif /* ZEPHYR_DRIVERS_SENSOR_INFINEON_TLE9104_TLE9104_DIAGNOSTICS_H_ */ diff --git a/dts/bindings/sensor/infineon,tle9104-diagnostics.yaml b/dts/bindings/sensor/infineon,tle9104-diagnostics.yaml new file mode 100644 index 0000000000..521a2e74c9 --- /dev/null +++ b/dts/bindings/sensor/infineon,tle9104-diagnostics.yaml @@ -0,0 +1,15 @@ +# Copyright (c) 2024 SILA Embedded Solutions GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: Output diagnostics of the powertrain switch TLE9104 + +compatible: "infineon,tle9104-diagnostics" + +include: [sensor-device.yaml] + +on-bus: tle9104 + +properties: + "#sensor-cells": + type: int + const: 0 diff --git a/include/zephyr/drivers/mfd/tle9104.h b/include/zephyr/drivers/mfd/tle9104.h index a647f79c7e..bb17079065 100644 --- a/include/zephyr/drivers/mfd/tle9104.h +++ b/include/zephyr/drivers/mfd/tle9104.h @@ -52,6 +52,14 @@ struct gpio_tle9104_channel_diagnostics { */ int tle9104_get_diagnostics(const struct device *dev, struct gpio_tle9104_channel_diagnostics diag[TLE9104_GPIO_COUNT]); +/** + * @brief clear the diagnostics of the outputs + * + * @param dev instance of TLE9104 + * + * @retval 0 If successful. + */ +int tle9104_clear_diagnostics(const struct device *dev); /*! * @brief write output state * diff --git a/include/zephyr/drivers/sensor/tle9104.h b/include/zephyr/drivers/sensor/tle9104.h new file mode 100644 index 0000000000..d2829d8150 --- /dev/null +++ b/include/zephyr/drivers/sensor/tle9104.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2024 SILA Embedded Solutions GmbH + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_TLE9104_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_TLE9104_H_ + +#include + +enum sensor_channel_tle9104 { + /** Open load detected, boolean with one bit per output */ + SENSOR_CHAN_TLE9104_OPEN_LOAD = SENSOR_ATTR_PRIV_START, + /** Over current detected, boolean with one bit per output */ + SENSOR_CHAN_TLE9104_OVER_CURRENT, +}; + +#endif /* ZEPHYR_INCLUDE_DRIVERS_SENSOR_TLE9104_H_ */