summaryrefslogtreecommitdiff
path: root/include/driver/temp_sensor/thermistor.h
blob: adcd5c5be40dd12b99b3064c2f5403c0b0474213 (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
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/* Thermistor module for Chrome EC */

#ifndef __CROS_EC_TEMP_SENSOR_THERMISTOR_H
#define __CROS_EC_TEMP_SENSOR_THERMISTOR_H

struct thermistor_data_pair {
	uint8_t mv;	/* Scaled voltage level at ADC (in mV) */
	uint8_t temp;	/* Temperature in Celsius */
};

struct thermistor_info {
	uint8_t scaling_factor;	/* Scaling factor for voltage in data pair. */
	uint8_t num_pairs;	/* Number of data pairs. */

	/*
	 * Values between given data pairs will be calculated as points on
	 * a line. Pairs can be derived using the Steinhart-Hart equation.
	 *
	 * Guidelines for data sets:
	 * - Must contain at least two pairs.
	 * - First and last pairs are the max and min.
	 * - Pairs must be sorted in descending order.
	 * - 5 pairs should provide reasonable accuracy in most cases. Use
	 *   points where the slope changes significantly or to recalibrate
	 *   the algorithm if needed.
	 */
	const struct thermistor_data_pair *data;
};

/**
 * Calculate temperature using linear interpolation of data points.
 *
 * Given a set of datapoints, the algorithm will calculate the "step" in
 * between each one in order to interpolate missing entries.
 *
 * @param mv	Value read from ADC (in millivolts).
 * @param info	Reference data set and info.
 *
 * @return	temperature in C
 */
int thermistor_linear_interpolate(uint16_t mv,
				  const struct thermistor_info *info);

#ifdef CONFIG_THERMISTOR_NCP15WB
/**
 * ncp15wb temperature conversion routine.
 *
 * @param adc	10bit raw data on adc.
 *
 * @return	temperature in C.
 */
int ncp15wb_calculate_temp(uint16_t adc);
#endif /* CONFIG_THERMISTOR_NCP15WB */

#ifdef CONFIG_STEINHART_HART_3V3_13K7_47K_4050B
/**
 * Reads the specified ADC channel and uses a lookup table and interpolation to
 * return a temperature in degrees K.
 *
 * The lookup table is based off of a resistor divider circuit on 3.3V with a
 * 13.7K resistor in series with a thermistor with nominal value of 47K (at 25C)
 * and a B (25/100) value of 4050.
 *
 * @param idx_adc	The idx value from the temp_sensor_t struct, which is
 *			the ADC channel to read and convert to degrees K
 * @param temp_ptr	Destination for temperature (in degrees K)
 *
 * @return EC_SUCCESS, or non-zero if error.
 */
int get_temp_3v3_13k7_47k_4050b(int idx_adc, int *temp_ptr);
#endif

#ifdef CONFIG_STEINHART_HART_3V3_51K1_47K_4050B
/**
 * Reads the specified ADC channel and uses a lookup table and interpolation to
 * return a temperature in degrees K.
 *
 * The lookup table is based off of a resistor divider circuit on 3.3V with a
 * 51.1K resistor in series with a thermistor with nominal value of 47K (at 25C)
 * and a B (25/100) value of 4050.
 *
 * @param idx_adc	The idx value from the temp_sensor_t struct, which is
 *			the ADC channel to read and convert to degrees K
 * @param temp_ptr	Destination for temperature (in degrees K)
 *
 * @return EC_SUCCESS, or non-zero if error.
 */
int get_temp_3v3_51k1_47k_4050b(int idx_adc, int *temp_ptr);
#endif

#ifdef CONFIG_STEINHART_HART_6V0_51K1_47K_4050B
/**
 * Reads the specified ADC channel and uses a lookup table and interpolation to
 * return a temperature in degrees K.
 *
 * The lookup table is based off of a resistor divider circuit on 6.0V with a
 * 51.1K resistor in series with a thermistor with nominal value of 47K (at 25C)
 * and a B (25/100) value of 4050.
 *
 * @param idx_adc	The idx value from the temp_sensor_t struct, which is
 *			the ADC channel to read and convert to degrees K
 * @param temp_ptr	Destination for temperature (in degrees K)
 *
 * @return EC_SUCCESS, or non-zero if error.
 */
int get_temp_6v0_51k1_47k_4050b(int idx_adc, int *temp_ptr);
#endif

#ifdef CONFIG_STEINHART_HART_3V0_22K6_47K_4050B
/**
 * Reads the specified ADC channel and uses a lookup table and interpolation to
 * return a temperature in degrees K.
 *
 * The lookup table is based off of a resistor divider circuit on 3V with a
 * 22.6K resistor in series with a thermistor with nominal value of 47K (at 25C)
 * and a B (25/100) value of 4050.
 *
 * @param idx_adc	The idx value from the temp_sensor_t struct, which is
 *			the ADC channel to read and convert to degrees K
 * @param temp_ptr	Destination for temperature (in degrees K)
 *
 * @return EC_SUCCESS, or non-zero if error.
 */
int get_temp_3v0_22k6_47k_4050b(int idx_adc, int *temp_ptr);
#endif

#ifdef CONFIG_STEINHART_HART_3V3_30K9_47K_4050B
/**
 * Reads the specified ADC channel and uses a lookup table and interpolation to
 * return a temperature in degrees K.
 *
 * The lookup table is based off of a resistor divider circuit on 3.3V with a
 * 30.9K resistor in series with a thermistor with nominal value of 47K (at 25C)
 * and a B (25/100) value of 4050.
 *
 * @param idx_adc	The idx value from the temp_sensor_t struct, which is
 *			the ADC channel to read and convert to degrees K
 * @param temp_ptr	Destination for temperature (in degrees K)
 *
 * @return EC_SUCCESS, or non-zero if error.
 */
int get_temp_3v3_30k9_47k_4050b(int idx_adc, int *temp_ptr);
#endif

/**
 * Reads the sensor's ADC channel and uses a lookup table and interpolation to
 * argument thermistor_info for interpolation to return a temperature in degrees
 * K.
 *
 * @param idx_adc	The idx value from the temp_sensor_t struct, which is
 *			the ADC channel to read and convert to degrees K
 * @param temp_ptr	Destination for temperature (in degrees K)
 * @param info	Structure containing information about the underlying thermistor
 * that is necessary to interpolate temperature
 *
 * @return EC_SUCCESS, or non-zero if error.
 */
int thermistor_get_temperature(int idx_adc, int *temp_ptr,
			       const struct thermistor_info *info);

#endif /* __CROS_EC_TEMP_SENSOR_THERMISTOR_NCP15WB_H */