1 /*
2 * Copyright (c) 2023 Andriy Gelman <andriy.gelman@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT infineon_xmc4xxx_temp
8
9 #include <xmc_scu.h>
10
11 #include <zephyr/kernel.h>
12 #include <zephyr/device.h>
13 #include <zephyr/devicetree.h>
14 #include <zephyr/drivers/sensor.h>
15
16 #include <zephyr/logging/log.h>
17 LOG_MODULE_REGISTER(xmc4xxx_temp, CONFIG_SENSOR_LOG_LEVEL);
18
19 struct xmc4xxx_temp_data {
20 float temp_out;
21 };
22
xmc4xxx_temp_sample_fetch(const struct device * dev,enum sensor_channel chan)23 static int xmc4xxx_temp_sample_fetch(const struct device *dev, enum sensor_channel chan)
24 {
25 struct xmc4xxx_temp_data *data = dev->data;
26 int32_t val;
27 int ret;
28
29 if (chan != SENSOR_CHAN_ALL && chan != SENSOR_CHAN_DIE_TEMP) {
30 return -ENOTSUP;
31 }
32
33 ret = XMC_SCU_StartTemperatureMeasurement();
34 if (ret != 0) {
35 return -EBUSY;
36 }
37
38 while (XMC_SCU_IsTemperatureSensorBusy()) {
39 };
40
41 val = XMC_SCU_GetTemperatureMeasurement();
42 /* See Infineon XMC4500 Reference Manual Section 11.2.5.1 */
43 data->temp_out = (val - 605) / 2.05f;
44
45 return ret;
46 }
47
xmc4xxx_temp_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)48 static int xmc4xxx_temp_channel_get(const struct device *dev, enum sensor_channel chan,
49 struct sensor_value *val)
50 {
51 struct xmc4xxx_temp_data *data = dev->data;
52
53 if (chan != SENSOR_CHAN_DIE_TEMP) {
54 return -ENOTSUP;
55 }
56
57 return sensor_value_from_double(val, data->temp_out);
58 }
59
60 static DEVICE_API(sensor, xmc4xxx_temp_driver_api) = {
61 .sample_fetch = xmc4xxx_temp_sample_fetch,
62 .channel_get = xmc4xxx_temp_channel_get,
63 };
64
xmc4xxx_temp_init(const struct device * dev)65 static int xmc4xxx_temp_init(const struct device *dev)
66 {
67 ARG_UNUSED(dev);
68 XMC_SCU_EnableTemperatureSensor();
69
70 BUILD_ASSERT(CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET >= -64 &&
71 CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET <= 63);
72
73 BUILD_ASSERT(CONFIG_XMC4XXX_TEMP_CALIBRATE_GAIN >= 0 &&
74 CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET <= 63);
75
76 XMC_SCU_CalibrateTemperatureSensor(CONFIG_XMC4XXX_TEMP_CALIBRATE_OFFSET & 0x7f,
77 CONFIG_XMC4XXX_TEMP_CALIBRATE_GAIN);
78 return 0;
79 }
80
81 #define XMC4XXX_TEMP_DEFINE(inst) \
82 static struct xmc4xxx_temp_data xmc4xxx_temp_dev_data_##inst; \
83 \
84 SENSOR_DEVICE_DT_INST_DEFINE(inst, xmc4xxx_temp_init, NULL, \
85 &xmc4xxx_temp_dev_data_##inst, NULL, \
86 POST_KERNEL, CONFIG_SENSOR_INIT_PRIORITY, \
87 &xmc4xxx_temp_driver_api); \
88
89 DT_INST_FOREACH_STATUS_OKAY(XMC4XXX_TEMP_DEFINE)
90