diff options
-rw-r--r-- | board/coral/board.c | 99 | ||||
-rw-r--r-- | board/coral/board.h | 2 | ||||
-rw-r--r-- | board/reef/board.c | 99 | ||||
-rw-r--r-- | board/reef/board.h | 2 | ||||
-rw-r--r-- | board/reef_it8320/board.c | 99 | ||||
-rw-r--r-- | board/reef_it8320/board.h | 2 | ||||
-rw-r--r-- | board/yorp/board.c | 118 | ||||
-rw-r--r-- | board/yorp/board.h | 4 | ||||
-rw-r--r-- | driver/build.mk | 1 | ||||
-rw-r--r-- | driver/temp_sensor/thermistor.c | 147 | ||||
-rw-r--r-- | driver/temp_sensor/thermistor.h | 42 | ||||
-rw-r--r-- | driver/temp_sensor/thermistor_ncp15wb.c | 52 | ||||
-rw-r--r-- | include/config.h | 18 | ||||
-rw-r--r-- | test/test_config.h | 1 |
14 files changed, 277 insertions, 409 deletions
diff --git a/board/coral/board.c b/board/coral/board.c index 3854e56f28..bc37b92d13 100644 --- a/board/coral/board.c +++ b/board/coral/board.c @@ -412,92 +412,23 @@ static void board_tcpc_init(void) } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_DEFAULT); -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 13.7Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define CHARGER_THERMISTOR_SCALING_FACTOR 13 -static const struct thermistor_data_pair charger_thermistor_data[] = { - { 3044 / CHARGER_THERMISTOR_SCALING_FACTOR, 0 }, - { 2890 / CHARGER_THERMISTOR_SCALING_FACTOR, 10 }, - { 2680 / CHARGER_THERMISTOR_SCALING_FACTOR, 20 }, - { 2418 / CHARGER_THERMISTOR_SCALING_FACTOR, 30 }, - { 2117 / CHARGER_THERMISTOR_SCALING_FACTOR, 40 }, - { 1800 / CHARGER_THERMISTOR_SCALING_FACTOR, 50 }, - { 1490 / CHARGER_THERMISTOR_SCALING_FACTOR, 60 }, - { 1208 / CHARGER_THERMISTOR_SCALING_FACTOR, 70 }, - { 966 / CHARGER_THERMISTOR_SCALING_FACTOR, 80 }, - { 860 / CHARGER_THERMISTOR_SCALING_FACTOR, 85 }, - { 766 / CHARGER_THERMISTOR_SCALING_FACTOR, 90 }, - { 679 / CHARGER_THERMISTOR_SCALING_FACTOR, 95 }, - { 603 / CHARGER_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info charger_thermistor_info = { - .scaling_factor = CHARGER_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(charger_thermistor_data), - .data = charger_thermistor_data, -}; - -int board_get_charger_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(NPCX_ADC_CH0); - - if (mv < 0) - return -1; - - *temp_ptr = thermistor_linear_interpolate(mv, &charger_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return 0; -} - -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 51.1Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define AMB_THERMISTOR_SCALING_FACTOR 11 -static const struct thermistor_data_pair amb_thermistor_data[] = { - { 2512 / AMB_THERMISTOR_SCALING_FACTOR, 0 }, - { 2158 / AMB_THERMISTOR_SCALING_FACTOR, 10 }, - { 1772 / AMB_THERMISTOR_SCALING_FACTOR, 20 }, - { 1398 / AMB_THERMISTOR_SCALING_FACTOR, 30 }, - { 1070 / AMB_THERMISTOR_SCALING_FACTOR, 40 }, - { 803 / AMB_THERMISTOR_SCALING_FACTOR, 50 }, - { 597 / AMB_THERMISTOR_SCALING_FACTOR, 60 }, - { 443 / AMB_THERMISTOR_SCALING_FACTOR, 70 }, - { 329 / AMB_THERMISTOR_SCALING_FACTOR, 80 }, - { 285 / AMB_THERMISTOR_SCALING_FACTOR, 85 }, - { 247 / AMB_THERMISTOR_SCALING_FACTOR, 90 }, - { 214 / AMB_THERMISTOR_SCALING_FACTOR, 95 }, - { 187 / AMB_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info amb_thermistor_info = { - .scaling_factor = AMB_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(amb_thermistor_data), - .data = amb_thermistor_data, -}; - -int board_get_ambient_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(NPCX_ADC_CH1); - - if (mv < 0) - return -1; - - *temp_ptr = thermistor_linear_interpolate(mv, &amb_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return 0; -} - - const struct temp_sensor_t temp_sensors[] = { /* FIXME(dhendrix): tweak action_delay_sec */ - {"Battery", TEMP_SENSOR_TYPE_BATTERY, charge_get_battery_temp, 0, 1}, - {"Ambient", TEMP_SENSOR_TYPE_BOARD, board_get_ambient_temp, 0, 5}, - {"Charger", TEMP_SENSOR_TYPE_BOARD, board_get_charger_temp, 1, 1}, + [TEMP_SENSOR_BATTERY] = {.name = "Battery", + .type = TEMP_SENSOR_TYPE_BATTERY, + .read = charge_get_battery_temp, + .idx = 0, + .action_delay_sec = 1}, + [TEMP_SENSOR_AMBIENT] = {.name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_AMB, + .action_delay_sec = 5}, + [TEMP_SENSOR_CHARGER] = {.name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_13k7_47k_4050b, + .idx = ADC_TEMP_SENSOR_CHARGER, + .action_delay_sec = 1}, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); diff --git a/board/coral/board.h b/board/coral/board.h index e392ac38a6..09f9dca66a 100644 --- a/board/coral/board.h +++ b/board/coral/board.h @@ -137,6 +137,8 @@ #define CONFIG_PWM_KBLIGHT #define CONFIG_TEMP_SENSOR #define CONFIG_THERMISTOR_NCP15WB +#define CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B #define CONFIG_DPTF #define CONFIG_DPTF_DEVICE_ORIENTATION #define CONFIG_SCI_GPIO GPIO_PCH_SCI_L diff --git a/board/reef/board.c b/board/reef/board.c index 977a10f70c..6df8b781ef 100644 --- a/board/reef/board.c +++ b/board/reef/board.c @@ -406,92 +406,23 @@ void board_tcpc_init(void) } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1); -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 13.7Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define CHARGER_THERMISTOR_SCALING_FACTOR 13 -static const struct thermistor_data_pair charger_thermistor_data[] = { - { 3044 / CHARGER_THERMISTOR_SCALING_FACTOR, 0 }, - { 2890 / CHARGER_THERMISTOR_SCALING_FACTOR, 10 }, - { 2680 / CHARGER_THERMISTOR_SCALING_FACTOR, 20 }, - { 2418 / CHARGER_THERMISTOR_SCALING_FACTOR, 30 }, - { 2117 / CHARGER_THERMISTOR_SCALING_FACTOR, 40 }, - { 1800 / CHARGER_THERMISTOR_SCALING_FACTOR, 50 }, - { 1490 / CHARGER_THERMISTOR_SCALING_FACTOR, 60 }, - { 1208 / CHARGER_THERMISTOR_SCALING_FACTOR, 70 }, - { 966 / CHARGER_THERMISTOR_SCALING_FACTOR, 80 }, - { 860 / CHARGER_THERMISTOR_SCALING_FACTOR, 85 }, - { 766 / CHARGER_THERMISTOR_SCALING_FACTOR, 90 }, - { 679 / CHARGER_THERMISTOR_SCALING_FACTOR, 95 }, - { 603 / CHARGER_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info charger_thermistor_info = { - .scaling_factor = CHARGER_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(charger_thermistor_data), - .data = charger_thermistor_data, -}; - -int board_get_charger_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(NPCX_ADC_CH0); - - if (mv < 0) - return -1; - - *temp_ptr = thermistor_linear_interpolate(mv, &charger_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return 0; -} - -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 51.1Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define AMB_THERMISTOR_SCALING_FACTOR 11 -static const struct thermistor_data_pair amb_thermistor_data[] = { - { 2512 / AMB_THERMISTOR_SCALING_FACTOR, 0 }, - { 2158 / AMB_THERMISTOR_SCALING_FACTOR, 10 }, - { 1772 / AMB_THERMISTOR_SCALING_FACTOR, 20 }, - { 1398 / AMB_THERMISTOR_SCALING_FACTOR, 30 }, - { 1070 / AMB_THERMISTOR_SCALING_FACTOR, 40 }, - { 803 / AMB_THERMISTOR_SCALING_FACTOR, 50 }, - { 597 / AMB_THERMISTOR_SCALING_FACTOR, 60 }, - { 443 / AMB_THERMISTOR_SCALING_FACTOR, 70 }, - { 329 / AMB_THERMISTOR_SCALING_FACTOR, 80 }, - { 285 / AMB_THERMISTOR_SCALING_FACTOR, 85 }, - { 247 / AMB_THERMISTOR_SCALING_FACTOR, 90 }, - { 214 / AMB_THERMISTOR_SCALING_FACTOR, 95 }, - { 187 / AMB_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info amb_thermistor_info = { - .scaling_factor = AMB_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(amb_thermistor_data), - .data = amb_thermistor_data, -}; - -int board_get_ambient_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(NPCX_ADC_CH1); - - if (mv < 0) - return -1; - - *temp_ptr = thermistor_linear_interpolate(mv, &amb_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return 0; -} - - const struct temp_sensor_t temp_sensors[] = { /* FIXME(dhendrix): tweak action_delay_sec */ - {"Battery", TEMP_SENSOR_TYPE_BATTERY, charge_get_battery_temp, 0, 1}, - {"Ambient", TEMP_SENSOR_TYPE_BOARD, board_get_ambient_temp, 0, 5}, - {"Charger", TEMP_SENSOR_TYPE_BOARD, board_get_charger_temp, 1, 1}, + [TEMP_SENSOR_BATTERY] = {.name = "Battery", + .type = TEMP_SENSOR_TYPE_BATTERY, + .read = charge_get_battery_temp, + .idx = 0, + .action_delay_sec = 1}, + [TEMP_SENSOR_AMBIENT] = {.name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_AMB, + .action_delay_sec = 5}, + [TEMP_SENSOR_CHARGER] = {.name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_13k7_47k_4050b, + .idx = ADC_TEMP_SENSOR_CHARGER, + .action_delay_sec = 1}, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); diff --git a/board/reef/board.h b/board/reef/board.h index 3734c1c65b..a0bb7751d4 100644 --- a/board/reef/board.h +++ b/board/reef/board.h @@ -132,6 +132,8 @@ #define CONFIG_PWM #define CONFIG_TEMP_SENSOR #define CONFIG_THERMISTOR_NCP15WB +#define CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B #define CONFIG_DPTF #define CONFIG_DPTF_DEVICE_ORIENTATION #define CONFIG_SCI_GPIO GPIO_PCH_SCI_L diff --git a/board/reef_it8320/board.c b/board/reef_it8320/board.c index 950f504d42..03ce723338 100644 --- a/board/reef_it8320/board.c +++ b/board/reef_it8320/board.c @@ -190,91 +190,22 @@ const int usb_port_enable[CONFIG_USB_PORT_POWER_SMART_PORT_COUNT] = { GPIO_USB1_ENABLE, }; -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 13.7Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define CHARGER_THERMISTOR_SCALING_FACTOR 13 -static const struct thermistor_data_pair charger_thermistor_data[] = { - { 3044 / CHARGER_THERMISTOR_SCALING_FACTOR, 0 }, - { 2890 / CHARGER_THERMISTOR_SCALING_FACTOR, 10 }, - { 2680 / CHARGER_THERMISTOR_SCALING_FACTOR, 20 }, - { 2418 / CHARGER_THERMISTOR_SCALING_FACTOR, 30 }, - { 2117 / CHARGER_THERMISTOR_SCALING_FACTOR, 40 }, - { 1800 / CHARGER_THERMISTOR_SCALING_FACTOR, 50 }, - { 1490 / CHARGER_THERMISTOR_SCALING_FACTOR, 60 }, - { 1208 / CHARGER_THERMISTOR_SCALING_FACTOR, 70 }, - { 966 / CHARGER_THERMISTOR_SCALING_FACTOR, 80 }, - { 860 / CHARGER_THERMISTOR_SCALING_FACTOR, 85 }, - { 766 / CHARGER_THERMISTOR_SCALING_FACTOR, 90 }, - { 679 / CHARGER_THERMISTOR_SCALING_FACTOR, 95 }, - { 603 / CHARGER_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info charger_thermistor_info = { - .scaling_factor = CHARGER_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(charger_thermistor_data), - .data = charger_thermistor_data, -}; - -int board_get_charger_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(ADC_TEMP_SENSOR_CHARGER); - - if (mv < 0) - return -1; - - *temp_ptr = thermistor_linear_interpolate(mv, &charger_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return 0; -} - -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 51.1Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define AMB_THERMISTOR_SCALING_FACTOR 11 -static const struct thermistor_data_pair amb_thermistor_data[] = { - { 2512 / AMB_THERMISTOR_SCALING_FACTOR, 0 }, - { 2158 / AMB_THERMISTOR_SCALING_FACTOR, 10 }, - { 1772 / AMB_THERMISTOR_SCALING_FACTOR, 20 }, - { 1398 / AMB_THERMISTOR_SCALING_FACTOR, 30 }, - { 1070 / AMB_THERMISTOR_SCALING_FACTOR, 40 }, - { 803 / AMB_THERMISTOR_SCALING_FACTOR, 50 }, - { 597 / AMB_THERMISTOR_SCALING_FACTOR, 60 }, - { 443 / AMB_THERMISTOR_SCALING_FACTOR, 70 }, - { 329 / AMB_THERMISTOR_SCALING_FACTOR, 80 }, - { 285 / AMB_THERMISTOR_SCALING_FACTOR, 85 }, - { 247 / AMB_THERMISTOR_SCALING_FACTOR, 90 }, - { 214 / AMB_THERMISTOR_SCALING_FACTOR, 95 }, - { 187 / AMB_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info amb_thermistor_info = { - .scaling_factor = AMB_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(amb_thermistor_data), - .data = amb_thermistor_data, -}; - -int board_get_ambient_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(ADC_TEMP_SENSOR_AMB); - - if (mv < 0) - return -1; - - *temp_ptr = thermistor_linear_interpolate(mv, &amb_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return 0; -} - const struct temp_sensor_t temp_sensors[] = { - /* FIXME(dhendrix): tweak action_delay_sec */ - {"Battery", TEMP_SENSOR_TYPE_BATTERY, charge_get_battery_temp, 0, 1}, - {"Ambient", TEMP_SENSOR_TYPE_BOARD, board_get_ambient_temp, 0, 5}, - {"Charger", TEMP_SENSOR_TYPE_BOARD, board_get_charger_temp, 1, 1}, + [TEMP_SENSOR_BATTERY] = {.name = "Battery", + .type = TEMP_SENSOR_TYPE_BATTERY, + .read = charge_get_battery_temp, + .idx = 0, + .action_delay_sec = 1}, + [TEMP_SENSOR_AMBIENT] = {.name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_AMB, + .action_delay_sec = 5}, + [TEMP_SENSOR_CHARGER] = {.name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_13k7_47k_4050b, + .idx = ADC_TEMP_SENSOR_CHARGER, + .action_delay_sec = 1}, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); diff --git a/board/reef_it8320/board.h b/board/reef_it8320/board.h index 106a23d971..84377e717a 100644 --- a/board/reef_it8320/board.h +++ b/board/reef_it8320/board.h @@ -114,6 +114,8 @@ #define CONFIG_TABLET_MODE #define CONFIG_TEMP_SENSOR #define CONFIG_THERMISTOR_NCP15WB +#define CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B #define CONFIG_DPTF #define CONFIG_DPTF_DEVICE_ORIENTATION #define CONFIG_SCI_GPIO GPIO_PCH_SCI_L diff --git a/board/yorp/board.c b/board/yorp/board.c index db72cbe744..f51ebab20b 100644 --- a/board/yorp/board.c +++ b/board/yorp/board.c @@ -33,9 +33,9 @@ #include "switch.h" #include "system.h" #include "tablet_mode.h" +#include "tcpci.h" #include "temp_sensor.h" #include "thermistor.h" -#include "tcpci.h" #include "usb_mux.h" #include "usbc_ppc.h" #include "util.h" @@ -83,108 +83,22 @@ const struct adc_t adc_channels[] = { }; BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 13.7Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define CHARGER_THERMISTOR_SCALING_FACTOR 13 -static const struct thermistor_data_pair charger_thermistor_data[] = { - { 3044 / CHARGER_THERMISTOR_SCALING_FACTOR, 0 }, - { 2890 / CHARGER_THERMISTOR_SCALING_FACTOR, 10 }, - { 2680 / CHARGER_THERMISTOR_SCALING_FACTOR, 20 }, - { 2418 / CHARGER_THERMISTOR_SCALING_FACTOR, 30 }, - { 2117 / CHARGER_THERMISTOR_SCALING_FACTOR, 40 }, - { 1800 / CHARGER_THERMISTOR_SCALING_FACTOR, 50 }, - { 1490 / CHARGER_THERMISTOR_SCALING_FACTOR, 60 }, - { 1208 / CHARGER_THERMISTOR_SCALING_FACTOR, 70 }, - { 966 / CHARGER_THERMISTOR_SCALING_FACTOR, 80 }, - { 860 / CHARGER_THERMISTOR_SCALING_FACTOR, 85 }, - { 766 / CHARGER_THERMISTOR_SCALING_FACTOR, 90 }, - { 679 / CHARGER_THERMISTOR_SCALING_FACTOR, 95 }, - { 603 / CHARGER_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info charger_thermistor_info = { - .scaling_factor = CHARGER_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(charger_thermistor_data), - .data = charger_thermistor_data, -}; - -int board_get_charger_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(NPCX_ADC_CH1); - - if (mv < 0) - return EC_ERROR_UNKNOWN; - - *temp_ptr = thermistor_linear_interpolate(mv, &charger_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return EC_SUCCESS; -} - -/* - * Data derived from Seinhart-Hart equation in a resistor divider circuit with - * Vdd=3300mV, R = 51.1Kohm, and Murata NCP15WB-series thermistor (B = 4050, - * T0 = 298.15, nominal resistance (R0) = 47Kohm). - */ -#define AMB_THERMISTOR_SCALING_FACTOR 11 -static const struct thermistor_data_pair amb_thermistor_data[] = { - { 2512 / AMB_THERMISTOR_SCALING_FACTOR, 0 }, - { 2158 / AMB_THERMISTOR_SCALING_FACTOR, 10 }, - { 1772 / AMB_THERMISTOR_SCALING_FACTOR, 20 }, - { 1398 / AMB_THERMISTOR_SCALING_FACTOR, 30 }, - { 1070 / AMB_THERMISTOR_SCALING_FACTOR, 40 }, - { 803 / AMB_THERMISTOR_SCALING_FACTOR, 50 }, - { 597 / AMB_THERMISTOR_SCALING_FACTOR, 60 }, - { 443 / AMB_THERMISTOR_SCALING_FACTOR, 70 }, - { 329 / AMB_THERMISTOR_SCALING_FACTOR, 80 }, - { 285 / AMB_THERMISTOR_SCALING_FACTOR, 85 }, - { 247 / AMB_THERMISTOR_SCALING_FACTOR, 90 }, - { 214 / AMB_THERMISTOR_SCALING_FACTOR, 95 }, - { 187 / AMB_THERMISTOR_SCALING_FACTOR, 100 }, -}; - -static const struct thermistor_info amb_thermistor_info = { - .scaling_factor = AMB_THERMISTOR_SCALING_FACTOR, - .num_pairs = ARRAY_SIZE(amb_thermistor_data), - .data = amb_thermistor_data, -}; - -int board_get_ambient_temp(int idx, int *temp_ptr) -{ - int mv = adc_read_channel(NPCX_ADC_CH0); - - if (mv < 0) - return EC_ERROR_UNKNOWN; - - *temp_ptr = thermistor_linear_interpolate(mv, &amb_thermistor_info); - *temp_ptr = C_TO_K(*temp_ptr); - return EC_SUCCESS; -} - const struct temp_sensor_t temp_sensors[] = { - { - .name = "Battery", - .type = TEMP_SENSOR_TYPE_BATTERY, - .read = charge_get_battery_temp, - .idx = 0, - .action_delay_sec = 1 - }, - { - .name = "Ambient", - .type = TEMP_SENSOR_TYPE_BOARD, - .read = board_get_ambient_temp, - .idx = 0, - .action_delay_sec = 5 - }, - { - .name = "Charger", - .type = TEMP_SENSOR_TYPE_BOARD, - .read = board_get_charger_temp, - .idx = 1, - .action_delay_sec = 1 - }, + [TEMP_SENSOR_BATTERY] = {.name = "Battery", + .type = TEMP_SENSOR_TYPE_BATTERY, + .read = charge_get_battery_temp, + .idx = 0, + .action_delay_sec = 1}, + [TEMP_SENSOR_AMBIENT] = {.name = "Ambient", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_51k1_47k_4050b, + .idx = ADC_TEMP_SENSOR_AMB, + .action_delay_sec = 5}, + [TEMP_SENSOR_CHARGER] = {.name = "Charger", + .type = TEMP_SENSOR_TYPE_BOARD, + .read = get_temp_3v3_13k7_47k_4050b, + .idx = ADC_TEMP_SENSOR_CHARGER, + .action_delay_sec = 1}, }; BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); diff --git a/board/yorp/board.h b/board/yorp/board.h index d491214f49..4623480d93 100644 --- a/board/yorp/board.h +++ b/board/yorp/board.h @@ -38,7 +38,9 @@ #define TABLET_MODE_GPIO_L GPIO_TABLET_MODE_L #define CONFIG_TEMP_SENSOR -#define CONFIG_THERMISTOR_NCP15WB +#define CONFIG_THERMISTOR +#define CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +#define CONFIG_STEINHART_HART_3V3_51K1_47K_4050B #define CONFIG_ACCEL_INTERRUPTS /* FIFO size is in power of 2. */ diff --git a/driver/build.mk b/driver/build.mk index 68a412423d..230ca34af3 100644 --- a/driver/build.mk +++ b/driver/build.mk @@ -94,6 +94,7 @@ driver-$(CONFIG_TOUCHPAD_ELAN)+=touchpad_elan.o driver-$(CONFIG_TOUCHPAD_ST)+=touchpad_st.o # Thermistors +driver-$(CONFIG_THERMISTOR)+=temp_sensor/thermistor.o driver-$(CONFIG_THERMISTOR_NCP15WB)+=temp_sensor/thermistor_ncp15wb.o # Type-C port controller (TCPC) drivers diff --git a/driver/temp_sensor/thermistor.c b/driver/temp_sensor/thermistor.c new file mode 100644 index 0000000000..d9c70f7386 --- /dev/null +++ b/driver/temp_sensor/thermistor.c @@ -0,0 +1,147 @@ +/* Copyright 2018 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. + */ + +/* Common thermistor code for Chrome EC */ + +#include "adc.h" +#include "common.h" +#include "thermistor.h" +#include "util.h" + +int thermistor_linear_interpolate(uint16_t mv, + const struct thermistor_info *info) +{ + const struct thermistor_data_pair *data = info->data; + int v_high = 0, v_low = 0, t_low, t_high, num_steps; + int head, tail, mid = 0; + + /* We need at least two points to form a line. */ + ASSERT(info->num_pairs >= 2); + + /* + * If input value is out of bounds return the lowest or highest + * value in the data sets provided. + */ + if (mv > data[0].mv * info->scaling_factor) + return data[0].temp; + else if (mv < data[info->num_pairs - 1].mv * info->scaling_factor) + return data[info->num_pairs - 1].temp; + + head = 0; + tail = info->num_pairs - 1; + while (head != tail) { + mid = (head + tail) / 2; + v_high = data[mid].mv * info->scaling_factor; + v_low = data[mid + 1].mv * info->scaling_factor; + + if ((mv <= v_high) && (mv >= v_low)) + break; + else if (mv > v_high) + tail = mid; + else if (mv < v_low) + head = mid + 1; + } + + t_low = data[mid].temp; + t_high = data[mid + 1].temp; + + /* + * The obvious way of doing this is to figure out how many mV per + * degree are in between the two points (mv_per_deg_c), and then how + * many of those exist between the input voltage and voltage of + * lower temperature : + * 1. mv_per_deg_c = (v_high - v_low) / (t_high - t_low) + * 2. num_steps = (v_high - mv) / mv_per_deg_c + * 3. result = t_low + num_steps + * + * Combine #1 and #2 to mitigate precision loss due to integer division. + */ + num_steps = ((v_high - mv) * (t_high - t_low)) / (v_high - v_low); + return t_low + num_steps; +} + +#ifdef CONFIG_STEINHART_HART_3V3_51K1_47K_4050B +/* + * Data derived from Steinhart-Hart equation in a resistor divider circuit with + * Vdd=3300mV, R = 51.1Kohm, and thermistor (B = 4050, T0 = 298.15 K, nominal + * resistance (R0) = 47Kohm). + */ +#define THERMISTOR_SCALING_FACTOR_51_47 11 +static const struct thermistor_data_pair thermistor_data_51_47[] = { + { 2512 / THERMISTOR_SCALING_FACTOR_51_47, 0 }, + { 2158 / THERMISTOR_SCALING_FACTOR_51_47, 10 }, + { 1772 / THERMISTOR_SCALING_FACTOR_51_47, 20 }, + { 1398 / THERMISTOR_SCALING_FACTOR_51_47, 30 }, + { 1070 / THERMISTOR_SCALING_FACTOR_51_47, 40 }, + { 803 / THERMISTOR_SCALING_FACTOR_51_47, 50 }, + { 597 / THERMISTOR_SCALING_FACTOR_51_47, 60 }, + { 443 / THERMISTOR_SCALING_FACTOR_51_47, 70 }, + { 329 / THERMISTOR_SCALING_FACTOR_51_47, 80 }, + { 285 / THERMISTOR_SCALING_FACTOR_51_47, 85 }, + { 247 / THERMISTOR_SCALING_FACTOR_51_47, 90 }, + { 214 / THERMISTOR_SCALING_FACTOR_51_47, 95 }, + { 187 / THERMISTOR_SCALING_FACTOR_51_47, 100 }, +}; + +static const struct thermistor_info thermistor_info_51_47 = { + .scaling_factor = THERMISTOR_SCALING_FACTOR_51_47, + .num_pairs = ARRAY_SIZE(thermistor_data_51_47), + .data = thermistor_data_51_47, +}; + +int get_temp_3v3_51k1_47k_4050b(int idx_adc, int *temp_ptr) +{ + int mv = adc_read_channel(idx_adc); + + if (mv < 0) + return EC_ERROR_UNKNOWN; + + *temp_ptr = thermistor_linear_interpolate(mv, &thermistor_info_51_47); + *temp_ptr = C_TO_K(*temp_ptr); + return EC_SUCCESS; +} +#endif /* CONFIG_STEINHART_HART_3V3_51K1_47K_4050B */ + +#ifdef CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +/* + * Data derived from Steinhart-Hart equation in a resistor divider circuit with + * Vdd=3300mV, R = 13.7Kohm, and thermistor (B = 4050, T0 = 298.15 K, nominal + * resistance (R0) = 47Kohm). + */ +#define THERMISTOR_SCALING_FACTOR_13_47 13 +static const struct thermistor_data_pair thermistor_data_13_47[] = { + { 3044 / THERMISTOR_SCALING_FACTOR_13_47, 0 }, + { 2890 / THERMISTOR_SCALING_FACTOR_13_47, 10 }, + { 2680 / THERMISTOR_SCALING_FACTOR_13_47, 20 }, + { 2418 / THERMISTOR_SCALING_FACTOR_13_47, 30 }, + { 2117 / THERMISTOR_SCALING_FACTOR_13_47, 40 }, + { 1800 / THERMISTOR_SCALING_FACTOR_13_47, 50 }, + { 1490 / THERMISTOR_SCALING_FACTOR_13_47, 60 }, + { 1208 / THERMISTOR_SCALING_FACTOR_13_47, 70 }, + { 966 / THERMISTOR_SCALING_FACTOR_13_47, 80 }, + { 860 / THERMISTOR_SCALING_FACTOR_13_47, 85 }, + { 766 / THERMISTOR_SCALING_FACTOR_13_47, 90 }, + { 679 / THERMISTOR_SCALING_FACTOR_13_47, 95 }, + { 603 / THERMISTOR_SCALING_FACTOR_13_47, 100 }, +}; + +static const struct thermistor_info thermistor_info_13_47 = { + .scaling_factor = THERMISTOR_SCALING_FACTOR_13_47, + .num_pairs = ARRAY_SIZE(thermistor_data_13_47), + .data = thermistor_data_13_47, +}; + +int get_temp_3v3_13k7_47k_4050b(int idx_adc, int *temp_ptr) +{ + int mv = adc_read_channel(idx_adc); + + if (mv < 0) + return EC_ERROR_UNKNOWN; + + *temp_ptr = thermistor_linear_interpolate(mv, &thermistor_info_13_47); + *temp_ptr = C_TO_K(*temp_ptr); + return EC_SUCCESS; +} +#endif /* CONFIG_STEINHART_HART_3V3_13K7_47K_4050B */ diff --git a/driver/temp_sensor/thermistor.h b/driver/temp_sensor/thermistor.h index af3ea398c8..49edee5451 100644 --- a/driver/temp_sensor/thermistor.h +++ b/driver/temp_sensor/thermistor.h @@ -33,7 +33,7 @@ struct thermistor_info { }; /** - * @brief Calculate temperature using linear interpolation of data points. + * 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. @@ -44,8 +44,9 @@ struct thermistor_info { * @return temperature in C */ int thermistor_linear_interpolate(uint16_t mv, - const struct thermistor_info *info); + const struct thermistor_info *info); +#ifdef CONFIG_THERMISTOR_NCP15WB /** * ncp15wb temperature conversion routine. * @@ -54,5 +55,42 @@ int thermistor_linear_interpolate(uint16_t mv, * @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 #endif /* __CROS_EC_TEMP_SENSOR_THERMISTOR_NCP15WB_H */ diff --git a/driver/temp_sensor/thermistor_ncp15wb.c b/driver/temp_sensor/thermistor_ncp15wb.c index dae8251575..51e884ed35 100644 --- a/driver/temp_sensor/thermistor_ncp15wb.c +++ b/driver/temp_sensor/thermistor_ncp15wb.c @@ -98,55 +98,3 @@ int ncp15wb_calculate_temp(uint16_t adc) return temp; } - -int thermistor_linear_interpolate(uint16_t mv, - const struct thermistor_info *info) -{ - const struct thermistor_data_pair *data = info->data; - int v_high = 0, v_low = 0, t_low, t_high, num_steps; - int head, tail, mid = 0; - - /* We need at least two points to form a line. */ - ASSERT(info->num_pairs >= 2); - - /* - * If input value is out of bounds return the lowest or highest - * value in the data sets provided. - */ - if (mv > data[0].mv * info->scaling_factor) - return data[0].temp; - else if (mv < data[info->num_pairs - 1].mv * info->scaling_factor) - return data[info->num_pairs - 1].temp; - - head = 0; - tail = info->num_pairs - 1; - while (head != tail) { - mid = (head + tail) / 2; - v_high = data[mid].mv * info->scaling_factor; - v_low = data[mid + 1].mv * info->scaling_factor; - - if ((mv <= v_high) && (mv >= v_low)) - break; - else if (mv > v_high) - tail = mid; - else if (mv < v_low) - head = mid + 1; - } - - t_low = data[mid].temp; - t_high = data[mid + 1].temp; - - /* - * The obvious way of doing this is to figure out how many mV per - * degree are in between the two points (mv_per_deg_c), and then how - * many of those exist between the input voltage and voltage of - * lower temperature : - * 1. mv_per_deg_c = (v_high - v_low) / (t_high - t_low) - * 2. num_steps = (v_high - mv) / mv_per_deg_c - * 3. result = t_low + num_steps - * - * Combine #1 and #2 to mitigate precision loss due to integer division. - */ - num_steps = ((v_high - mv) * (t_high - t_low)) / (v_high - v_low); - return t_low + num_steps; -} diff --git a/include/config.h b/include/config.h index b51cbfc5b8..423496b5af 100644 --- a/include/config.h +++ b/include/config.h @@ -2704,9 +2704,21 @@ #undef CONFIG_TEMP_SENSOR_TMP432 /* TI TMP432 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_F75303 /* Fintek F75303 sensor, on I2C bus */ +/* Compile common code for thermistor support */ +#undef CONFIG_THERMISTOR + +/* Support particular thermistors */ #undef CONFIG_THERMISTOR_NCP15WB /* NCP15WB thermistor */ /* + * If defined, image includes lookup tables and helper functions that convert + * thermistor ADC readings into degrees K based off of various circuit + * configurations. + */ +#undef CONFIG_STEINHART_HART_3V3_13K7_47K_4050B +#undef CONFIG_STEINHART_HART_3V3_51K1_47K_4050B + +/* * If defined, active-high GPIO which indicates temperature sensor chips are * powered. If not defined, temperature sensors are assumed to be always * powered. @@ -3665,6 +3677,12 @@ #endif /*****************************************************************************/ +/* Define derived thermistor common path */ +#ifdef CONFIG_THERMISTOR_NCP15WB +#define CONFIG_THERMISTOR +#endif + +/*****************************************************************************/ /* * Handle task-dependent configs. * diff --git a/test/test_config.h b/test/test_config.h index e0dfcf48bb..76e071b556 100644 --- a/test/test_config.h +++ b/test/test_config.h @@ -141,6 +141,7 @@ int board_discharge_on_ac(int enabled); #define CONFIG_I2C_MASTER #define CONFIG_TEMP_SENSOR #define CONFIG_THROTTLE_AP +#define CONFIG_THERMISTOR #define CONFIG_THERMISTOR_NCP15WB #define I2C_PORT_THERMAL 0 int ncp15wb_calculate_temp(uint16_t adc); |