summaryrefslogtreecommitdiff
path: root/docs/zephyr/zephyr_temperature_sensor.md
blob: 8ee87a84f75a93c2fa5c73700d37778c97d1c804 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# Zephyr EC Temperature Sensors

- [Zephyr EC Temperature Sensors](#zephyr-ec-temperature-sensors)
	- [Overview](#overview)
		- [Zephyr-supported Temperature Sensors](#zephyr-supported-temperature-sensors)
			- [Supported Thermistor Configurations](#supported-thermistor-configurations)
		- [Legacy EC Temperature Sensors](#legacy-ec-temperature-sensors)
	- [Kconfig Options](#kconfig-options)
	- [Device Tree Nodes](#device-tree-nodes)
		- [Thermistors](#thermistors)
			- [Thermistor Circuit](#thermistor-circuit)
	- [Board-specific code](#board-specific-code)
	- [Threads](#threads)
		- [Thermistors](#thermistors-1)
		- [I2C-based Sensors](#i2c-based-sensors)
- [Testing and Debugging](#testing-and-debugging)

## Overview
Temperature sensors are critical for monitoring the operating temperature of
the device and taking action if temperatures rise beyond safe levels by
throttling or shutting down the AP.

### Zephyr-supported Temperature Sensors

| Part | File | Description |
|---|---|---|
| TMP112 | [driver/temp_sensor/tmp112.h](../../driver/temp_sensor/tmp112.h) | SMBus / I2C temperature sensor |
| Thermistors | [driver/temp_sensor/thermistor.c](../../driver/temp_sensor/thermistor.c) | Various analog thermistor configurations |

#### Supported Thermistor Configurations

   * `thermistor_3V3_30K9_47K_4050B`
   * `thermistor_3V0_22K6_47K_4050B`
   * `thermistor_3V3_13K7_47K_4050B`
   * `thermistor_3V3_51K1_47K_4050B`

See [zephyr/include/cros/thermistor/thermistor.dtsi](../../zephyr/include/cros/thermistor/thermistor.dtsi)
and [zephyr/test/drivers/overlay.dts](../../zephyr/test/drivers/overlay.dts)
to see where these are defined.

### Legacy EC Temperature Sensors
These models have drivers written for the legacy EC code, but would need
further work to adapt to Zephyr.

| Part # | File | Description |
|---|---|---|
| ADT7481 | [driver/temp_sensor/adt7481.h](../../driver/temp_sensor/adt7481.h) | SMBus / I2C 3-channel temperature sensor (local + 2x remote) |
| R19ME4070 | [driver/temp_sensor/amd_r19me4070.h](../../driver/temp_sensor/amd_r19me4070.h) | AMD GPU, but has an onboard temperature sensor. |
| BD99992GW | [driver/temp_sensor/bd99992gw.h](../../driver/temp_sensor/bd99992gw.h) | This is a PMIC, but has an onboard temp sensor. |
| F75303 | [driver/temp_sensor/f75303.h](../../driver/temp_sensor/f75303.h) | SMBus / I2C 3-channel temperature sensor (local + 2x remote) |
| G781/G782 | [driver/temp_sensor/g78x.h](../../driver/temp_sensor/g78x.h) | SMBus / I2C 2-channel temperature sensor (local + remote) |
| G753 | [driver/temp_sensor/g753.h](../../driver/temp_sensor/g753.h) | SMBus / I2C single-channel temperature sensor |
| OTI502 | [driver/temp_sensor/oti502.h](../../driver/temp_sensor/oti502.h) | I2C ambient plus infrared temperature sensor |
| PCT2075 | [driver/temp_sensor/pct2075.h](../../driver/temp_sensor/pct2075.h) | I2C temperature sensor |
| SB-TSI | [driver/temp_sensor/sb_tsi.h](../../driver/temp_sensor/sb_tsi.h) | I2C temp sensor on the AMD Stony Ridge FT4 SOC |
| NCP15WB | [driver/temp_sensor/thermistor_ncp15wb.c](../../driver/temp_sensor/thermistor_ncp15wb.c) | NTC thermistor (used with ADC) |
| TMP006 | [driver/temp_sensor/tmp006.h](../../driver/temp_sensor/tmp006.h) | SMBus / I2C infrared temperature sensor |
| TMP112 | [driver/temp_sensor/tmp112.h](../../driver/temp_sensor/tmp112.h) | SMBus / I2C temperature sensor |
| TMP411 | [driver/temp_sensor/tmp411.h](../../driver/temp_sensor/tmp411.h) | SMBus / I2C 2-channel temperature sensor (local + remote) |
| TMP432 | [driver/temp_sensor/tmp432.h](../../driver/temp_sensor/tmp432.h) | SMBus / I2C 2-channel temperature sensor (local + remote) |
| TMP468 | [driver/temp_sensor/tmp468.h](../../driver/temp_sensor/tmp468.h) | SMBus / I2C 9-channel temperature sensor (local + 8x remote) |

## Kconfig Options

Overall support for temperature sensors is enabled using the config flag
`PLATFORM_EC_TEMP_SENSOR`. See [zephyr/Kconfig.temperature](../../zephyr/Kconfig.temperature)
for more information. A separate config flag, `PLATFORM_EC_THERMISTOR`, is needed
if analog thermistor sensors are being used. This option is dependent on ADCs
being supported. These flags are configured in each board’s `prj.conf` file.

There are no sensor-specific Kconfig options for specifying sensor types,
drivers, or configuration. This is handled by the device tree (see below)
on Zephyr-based boards.

## Device Tree Nodes

Temperature sensors are declared as separate nodes and additional properties are
defined by the `cros-ec,temp-sensors` node in the device tree. This example is
from [zephyr/projects/brya/temp_sensors.dts](../../zephyr/projects/brya/temp_sensors.dts):

```
	temp_ddr_soc: ddr_soc {
		compatible = "cros-ec,temp-sensor-thermistor";
		thermistor = <&thermistor_3V3_30K9_47K_4050B>;
		adc = <&adc_ddr_soc>;
	};

	named-temp-sensors {
		compatible = "cros-ec,temp-sensors";
		ddr_soc {
			temp_fan_off = <35>;
			temp_fan_max = <60>;
			temp_host_high = <85>;
			temp_host_halt = <90>;
			temp_host_release_high = <80>;
			sensor = <&temp_ddr_soc>;
		};
```

More information about temperature sensor device tree settings can be found in the
following locations:

 * [cros_ec_temp_sensor.yaml](../../zephyr/dts/bindings/temp/cros_ec_temp_sensor.yaml) - Common properties
 * [cors_ec_temp_sensor_thermistor.yaml](../../zephyr/dts/bindings/temp/cors_ec_temp_sensor_thermistor.yaml) - Special properties for analog thermistors
 * [cros_ec_temp_sensor_tmp112.yaml](../../zephyr/dts/bindings/temp/cros_ec_temp_sensor_tmp112.yaml) - Properties for the TMP112 I2C-based sensor

### Thermistors

In addition to setting up the sensors, each type of supported thermistor needs to
have calibration data saved in the device tree that is used to compute temperature
values from the ADC counts / measured voltages. Example from
[zephyr/include/cros/thermistor/thermistor.dtsi](../../zephyr/include/cros/thermistor/thermistor.dtsi).

This must only be done once for each type of thermistor. Most boards should be
covered by one of the existing types and can simply reference them in the device
tree named-temp-sensors nodes.

```
	thermistor_3V3_30K9_47K_4050B: thermistor-3V3-30K9-47K-4050B {
		status = "disabled";
		compatible = "cros-ec,thermistor";
		scaling-factor = <11>;
		num-pairs = <10>;
		steinhart-reference-mv = <3300>;
		steinhart-reference-res = <30900>;
		/*
		 * Data derived from Steinhart-Hart equation in a resistor
		 * divider circuit with Vdd=3300mV, R = 30.9Kohm, and thermistor
		 * (B = 4050, T0 = 298.15 K, nominal resistance (R0) = 47Kohm).
		 */
		sample-datum-0 {
			milivolt = <(2753 / 11)>;
			temp = <0>;
			sample-index = <0>;
		};
		sample-datum-1 {
			milivolt = <(2487 / 11)>;
			temp = <10>;
			sample-index = <1>;
		};
		/* . . . */
```

#### Thermistor Circuit

Type `thermistor_3V3_30K9_47K_4050B` corresponds to this circuit:

![Schematic of a thermistor voltage divider](thermistor_schematic.png)

The thermistor naming scheme is as follows:
 * `3V3` - The voltage divider is supplied from a 3.3V rail.
 * `30K9` - The high side of the voltage divider is a 30.9K ohm resistor.
 * `47K` - The nominal thermistor resistance (R_0) is 47K ohm.
 * `4050B` - Coefficient B in the Steinhart–Hart thermistor equation is 4050.

## Board-specific code

No board-specific code is required. Temperature sensors are automatically configured
based on information in the device tree.

## Threads

There is no dedicated thread for monitoring temperature sensors. The sensor data is
ultimately consumed by the thermal engine’s `thermal_control()` function in
[common/thermal.c](../../common/thermal.c), which runs every second in the TICK
thread by registering it as a callback with the Hook API.

The mechanism for pulling in temperature data depends on the type of sensor:

### Thermistors

Thermistor-based temperature sensor readings are measured and processed on-the-fly
whenever requested, so the TICK thread reads from the ADC directly during the
`thermal_control()` routine.

### I2C-based Sensors

Most I2C-based sensors involve an extra step. Their drivers separately set up an
internal function to run on a one second interval (also on the TICK task using the
Hook API). For example, the TMP006 does this in [tmp006.c](../../driver/temp_sensor/tmp006.c):

```c
static void tmp006_poll(void)
{
	int i;

	for (i = 0; i < TMP006_COUNT; ++i)
		tmp006_poll_sensor(i);
}
DECLARE_HOOK(HOOK_SECOND, tmp006_poll, HOOK_PRIO_TEMP_SENSOR);
```

The poll function only updates an internal struct within the driver with the latest
reading(s). These values then get read by the thermal engine through the same,
standard API as the thermistors. This spares the thermal routine from having to
wait on I2C accesses.

However, not all temperature sensor drivers follow this approach. For instance,
the [SB-TSI driver](../../driver/temp_sensor/sb_tsi.c) simply performs the I2C
transaction to read the temperature directly in the public `sb_tsi_get_val()`
function.

# Testing and Debugging

Temperature sensors can be queried with the `temps` console command:

```
> temps
  Charger             : 303 K = 30 C
  SOC                 : 303 K = 30 C
  CPU                 : 301 K = 28 C
```