Skip to content

Commit ee99355

Browse files
Josh-Tsaiamstan
authored andcommitted
fwk: create the temperature filter driver
Create the temperature filter driver to calculate the virtual temperature. example: / { named-temp-sensors { virtual_temp_sensor_memory: virtual-memory-f75303 { temp_host_warn = <108>; temp_host_high = <108>; temp_host_halt = <127>; temp_host_release_warn = <60>; temp_host_release_high = <60>; temp_host_release_halt = <122>; power-good-pin = <&gpio_slp_s3_l>; sensor = <&virtual_memory_f75303>; coefficients = <15 31 15 16384 (-31313) 14991>; }; }; }; &i2c7_0 { virtual_memory_f75303: virtual_memory_f75303@4d { compatible = "cros-ec,temp-sensor-f75303"; temperature-type = "F75303_IDX_REMOTE1"; reg = <0x4d>; }; }; BRANCH=fwk-dogwood-27111 BUG=None TEST=zmake build pass TEST=add the virtual sensor node in the devicetree, can print the value in the ec console via command "temps" Signed-off-by: Josh Tsai <Josh_Tsai@compal.com>
1 parent 82ef1a7 commit ee99355

7 files changed

Lines changed: 166 additions & 2 deletions

File tree

include/ec_commands.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3778,6 +3778,12 @@ struct ec_thermal_config {
37783778
uint32_t temp_host_release[EC_TEMP_THRESH_COUNT]; /* release levels */
37793779
uint32_t temp_fan_off; /* no active cooling needed */
37803780
uint32_t temp_fan_max; /* max active cooling needed */
3781+
/**
3782+
* (bug: 86ett7kn7)
3783+
* TODO: should not add the new variable in host command struct
3784+
* without cmd version
3785+
*/
3786+
int32_t coefficients[6]; /* coefficients to calculate the virtual temperature */
37813787
} __ec_align4;
37823788

37833789
/* Version 1 - get config for one sensor. */

zephyr/dts/bindings/temp/cros-ec,temp-sensors.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,10 @@ child-binding:
7272
type: int
7373
description:
7474
Temperature release threshold in degrees C of thermal shutdown
75+
76+
coefficients:
77+
type: array
78+
description:
79+
thermal_filter_update() uses six coefficients (b0, b1, b2, a0, a1, a2)
80+
to calculate the virtual temperature.
81+
Array values are all zero to disable virtual temperature.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* Copyright 2022 The ChromiumOS Authors
2+
* Use of this source code is governed by a BSD-style license that can be
3+
* found in the LICENSE file.
4+
*
5+
* Low pass filter for on die temperature
6+
*/
7+
#ifndef __CROS_EC_TEMPERATURE_FILTER_H
8+
#define __CROS_EC_TEMPERATURE_FILTER_H
9+
10+
#include "temp_sensor/temp_sensor.h"
11+
12+
/**
13+
* Check whether the temp sensor coefficients is zero or not.
14+
*
15+
* @param id temp sensor id
16+
* @return true if support (coefficients none zero)
17+
*/
18+
bool temperature_filter_is_support(enum temp_sensor_id id);
19+
20+
/**
21+
* Return the virtual temperature.
22+
*
23+
* @param id temp sensor id
24+
* @param temp_ptr the actual temperature value from the physical sensor
25+
* @return true if support (coefficients none zero)
26+
*/
27+
void temperature_filter_get_temp(enum temp_sensor_id id, int *temp_ptr);
28+
29+
/**
30+
* Calculate the virtual temperature with the coefficients.
31+
*
32+
* @param id temp sensor id
33+
* @param temp_ptr the actual temperature value from the physical sensor
34+
* @return true if support (coefficients none zero)
35+
*/
36+
void temperature_filter_update_temp(enum temp_sensor_id id, int temp_ptr);
37+
38+
#endif /* __CROS_EC_TEMPERATURE_FILTER_H */

zephyr/shim/src/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_SWITCHCAP_GPIO
7979
zephyr_library_sources_ifdef(CONFIG_CROS_EC_SWITCHCAP_LN9310
8080
switchcap_ln9310.c)
8181
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_TEMP_SENSOR temp_sensors.c
82-
thermal.c)
82+
thermal.c
83+
temperature_filter.c)
8384
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_TIMER hwtimer.c)
8485
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_I2C i2c.c)
8586
zephyr_library_sources_ifdef(CONFIG_SHIMMED_TASKS tasks.c)

zephyr/shim/src/temp_sensors.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "temp_sensor/temp_sensor.h"
2424
#include "temp_sensor/thermistor.h"
2525
#include "temp_sensor/tmp112.h"
26+
#include "temperature_filter.h"
2627

2728
#ifdef CONFIG_PLATFORM_EC_CUSTOMIZED_DESIGN
2829
#include "lotus/amd_r23m.h"
@@ -449,6 +450,7 @@ static bool temp_sensor_check_power(const struct temp_sensor_t *sensor)
449450
int temp_sensor_read(enum temp_sensor_id id, int *temp_ptr)
450451
{
451452
const struct temp_sensor_t *sensor;
453+
int rv = EC_SUCCESS;
452454

453455
if (id < 0 || id >= TEMP_SENSOR_COUNT)
454456
return EC_ERROR_INVAL;
@@ -457,7 +459,12 @@ int temp_sensor_read(enum temp_sensor_id id, int *temp_ptr)
457459
if (!temp_sensor_check_power(sensor))
458460
return EC_ERROR_NOT_POWERED;
459461

460-
return sensor->zephyr_info->read(sensor, temp_ptr);
462+
if (temperature_filter_is_support(id))
463+
temperature_filter_get_temp(id, temp_ptr);
464+
else
465+
rv = sensor->zephyr_info->read(sensor, temp_ptr);
466+
467+
return rv;
461468
}
462469

463470
void temp_sensors_update(void)
@@ -471,6 +478,18 @@ void temp_sensors_update(void)
471478
if (!temp_sensor_check_power(sensor))
472479
continue;
473480

481+
/**
482+
* thermal filter will use the one of physical sensor, so we don't
483+
* need to update the sensor again.
484+
*/
485+
if (temperature_filter_is_support(i)) {
486+
int temp_ptr;
487+
488+
if (!sensor->zephyr_info->read(sensor, &temp_ptr))
489+
temperature_filter_update_temp(i, temp_ptr);
490+
continue;
491+
}
492+
474493
sensor->zephyr_info->update_temperature(sensor->idx);
475494
}
476495
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/* Copyright 2025 The ChromiumOS Authors
2+
* Use of this source code is governed by a BSD-style license that can be
3+
* found in the LICENSE file.
4+
*/
5+
6+
#include "hooks.h"
7+
#include "math_util.h"
8+
#include "temperature_filter.h"
9+
#include "thermal.h"
10+
#include "util.h"
11+
12+
#define Q_SCALE 14
13+
/* scale input up to improve filter performance */
14+
#define IN_SCALE 7
15+
16+
struct temperature_filter_t {
17+
int32_t state[4];
18+
int32_t coeff[6];
19+
} filters[TEMP_SENSOR_COUNT];
20+
21+
static void temperature_filter_reset(enum temp_sensor_id id)
22+
{
23+
memset(&filters[id].state, 30 << IN_SCALE, sizeof(filters[id].state));
24+
}
25+
26+
static int temperature_filter_update(enum temp_sensor_id id, int value)
27+
{
28+
/* we can only accept a range in INT8*/
29+
value = MIN(value, INT8_MAX);
30+
value = MAX(value, INT8_MIN);
31+
32+
int out_scaled =
33+
filters[id].coeff[0] * (value << IN_SCALE) +
34+
filters[id].coeff[1] * filters[id].state[0] +
35+
filters[id].coeff[2] * filters[id].state[1] -
36+
filters[id].coeff[4] * filters[id].state[2] -
37+
filters[id].coeff[5] * filters[id].state[3];
38+
int out = out_scaled >> Q_SCALE;
39+
/* update delay line */
40+
filters[id].state[1] = filters[id].state[0];
41+
filters[id].state[3] = filters[id].state[2];
42+
filters[id].state[0] = value << IN_SCALE;
43+
filters[id].state[2] = out;
44+
45+
return out >> IN_SCALE;
46+
}
47+
48+
static int temperature_filter_get(enum temp_sensor_id id)
49+
{
50+
return filters[id].state[2] >> IN_SCALE;
51+
}
52+
53+
bool temperature_filter_is_support(enum temp_sensor_id id)
54+
{
55+
int zero[6] = {0};
56+
int rv;
57+
58+
rv = memcmp(thermal_params[id].coefficients, zero, 6);
59+
60+
/* No coefficients (zero arrays), return false */
61+
return !!rv;
62+
}
63+
64+
void temperature_filter_get_temp(enum temp_sensor_id id, int *temp_ptr)
65+
{
66+
*temp_ptr = C_TO_K(temperature_filter_get(id));
67+
}
68+
69+
void temperature_filter_update_temp(enum temp_sensor_id id, int temp_ptr)
70+
{
71+
/* The virtual temp is over range if we use the Kelvin */
72+
temperature_filter_update(id, K_TO_C(temp_ptr));
73+
}
74+
75+
static void temperature_filter_init(void)
76+
{
77+
for (int temp_id = 0; temp_id < TEMP_SENSOR_COUNT; temp_id++) {
78+
if (temperature_filter_is_support(temp_id))
79+
memcpy(filters[temp_id].coeff, thermal_params[temp_id].coefficients,
80+
sizeof(filters[temp_id].coeff));
81+
}
82+
}
83+
DECLARE_HOOK(HOOK_INIT, temperature_filter_init, HOOK_PRIO_DEFAULT);
84+
85+
static void temperature_filter_resume(void)
86+
{
87+
for (int temp_id = 0; temp_id < TEMP_SENSOR_COUNT; temp_id++) {
88+
if (temperature_filter_is_support(temp_id))
89+
temperature_filter_reset(temp_id);
90+
}
91+
}
92+
DECLARE_HOOK(HOOK_CHIPSET_RESUME, temperature_filter_resume, HOOK_PRIO_DEFAULT);

zephyr/shim/src/thermal.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
.temp_fan_max = C_TO_K(DT_PROP_OR(node_id, \
4444
temp_fan_max, \
4545
-273)), \
46+
.coefficients = DT_PROP_OR(node_id, coefficients, {0}), \
4647
}
4748

4849
struct ec_thermal_config thermal_params[] = {

0 commit comments

Comments
 (0)