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 <benedikt.schmidt@embedded-solutions.at>
This commit is contained in:
Benedikt Schmidt 2024-02-15 11:42:42 +01:00 committed by Carles Cufí
parent 84a40778af
commit 888d071fe7
10 changed files with 216 additions and 0 deletions

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -0,0 +1,5 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_sources(tle9104_diagnostics.c)

View file

@ -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.

View file

@ -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 <zephyr/drivers/sensor.h>
#include <zephyr/drivers/sensor/tle9104.h>
#include <zephyr/logging/log.h>
#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)

View file

@ -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 <stdint.h>
#include <zephyr/device.h>
#include <zephyr/drivers/mfd/tle9104.h>
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_ */

View file

@ -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

View file

@ -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
*

View file

@ -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 <zephyr/drivers/sensor.h>
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_ */