From 2c846a307537782df252b967f2514db870131b2a Mon Sep 17 00:00:00 2001 From: David Huang Date: Mon, 20 Jul 2015 14:04:58 +0800 Subject: Gandof: Add G781 HW trigger point Add G781 HW protect function by setting ALARM point. ALARM trigger point : 77 degree C BRANCH=gandof BUG=chrome-os-partner:41633 TEST=Use G781 command through servo board to check temperature setting. Change-Id: I3be56a1063f550b96dbd1e5c0fe63adef7028279 Signed-off-by: David Huang Reviewed-on: https://chromium-review.googlesource.com/288243 Reviewed-by: Shawn N Tested-by: Saurabh Madan Commit-Queue: Saurabh Madan Trybot-Ready: Saurabh Madan --- board/gandof/board.h | 4 +++ board/gandof/gpio.inc | 2 +- chip/lm4/config_chip.h | 2 +- driver/temp_sensor/g781.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++- driver/temp_sensor/g781.h | 8 +++++ include/config.h | 1 + 6 files changed, 99 insertions(+), 3 deletions(-) diff --git a/board/gandof/board.h b/board/gandof/board.h index 6f38946f92..9969612245 100644 --- a/board/gandof/board.h +++ b/board/gandof/board.h @@ -39,6 +39,7 @@ #define CONFIG_SWITCH_DEDICATED_RECOVERY #define CONFIG_TEMP_SENSOR #define CONFIG_TEMP_SENSOR_G781 +#define CONFIG_TEMP_SENSOR_G781_INIT #define CONFIG_TEMP_SENSOR_POWER_GPIO GPIO_PP3300_DX_EN #define CONFIG_UART_HOST 2 #define CONFIG_USB_PORT_POWER_IN_S3 @@ -118,6 +119,9 @@ enum temp_sensor_id { TEMP_SENSOR_COUNT }; +/* G781 sensor HW setting */ +#define G781_LOCAL_TEMP_HIGH_LIMIT_VALUE 77 + /* Wireless signals */ #define WIRELESS_GPIO_WLAN GPIO_WLAN_OFF_L #define WIRELESS_GPIO_WWAN GPIO_PP3300_LTE_EN diff --git a/board/gandof/gpio.inc b/board/gandof/gpio.inc index 8dabff2d19..8d91851f33 100644 --- a/board/gandof/gpio.inc +++ b/board/gandof/gpio.inc @@ -25,7 +25,7 @@ GPIO(JTAG_TCK, C, 0, GPIO_DEFAULT, jtag_interrupt) GPIO(UART0_RX, A, 0, GPIO_PULL_UP | GPIO_INT_BOTH_DSLEEP, uart_deepsleep_interrupt) /* UART0 RX input */ /* Other inputs */ -GPIO(FAN_ALERT_L, B, 0, GPIO_INPUT, NULL) /* From thermal sensor */ +GPIO(FAN_ALERT_L, B, 0, GPIO_INT_LOW | GPIO_INT_FALLING, fan_alert_interrupt) /* From thermal sensor */ GPIO(PCH_SUSWARN_L, G, 2, GPIO_INT_BOTH, NULL) /* SUSWARN# signal from PCH */ GPIO(USB1_OC_L, E, 7, GPIO_INPUT, NULL) /* USB port overcurrent warning */ GPIO(USB2_OC_L, E, 0, GPIO_INPUT, NULL) /* USB port overcurrent warning */ diff --git a/chip/lm4/config_chip.h b/chip/lm4/config_chip.h index 88f6a76668..eb1df0b6cf 100644 --- a/chip/lm4/config_chip.h +++ b/chip/lm4/config_chip.h @@ -24,7 +24,7 @@ #define HOOK_TICK_INTERVAL (HOOK_TICK_INTERVAL_MS * MSEC) /* Maximum number of deferrable functions */ -#define DEFERRABLE_MAX_COUNT 8 +#define DEFERRABLE_MAX_COUNT 9 /* Number of I2C ports */ #define I2C_PORT_COUNT 6 diff --git a/driver/temp_sensor/g781.c b/driver/temp_sensor/g781.c index c178a37ace..33df02a7b5 100644 --- a/driver/temp_sensor/g781.c +++ b/driver/temp_sensor/g781.c @@ -11,11 +11,15 @@ #include "gpio.h" #include "i2c.h" #include "hooks.h" +#include "system.h" #include "util.h" static int temp_val_local; static int temp_val_remote; - +#ifdef CONFIG_TEMP_SENSOR_G781_INIT +static int temp_val_local_high_limit = 0xFF; +static int g781_reg_init = 1; +#endif /** * Determine whether the sensor is powered. * @@ -40,6 +44,25 @@ static int raw_write8(const int offset, int data) return i2c_write8(I2C_PORT_THERMAL, G781_I2C_ADDR, offset, data); } +#ifdef CONFIG_TEMP_SENSOR_G781_INIT +static int status_read8(int *data) +{ + int rv; + /* We use buf[1] here so it's aligned for DMA on STM32 */ + uint8_t buf[1]; + + i2c_lock(I2C_PORT_THERMAL, 1); + rv = i2c_xfer(I2C_PORT_THERMAL, G781_I2C_ALERT_ADDR, + 0, 0, buf, 1, I2C_XFER_SINGLE); + i2c_lock(I2C_PORT_THERMAL, 0); + + if (!rv) + *data = buf[0]; + + return rv; +} +#endif + static int get_temp(const int offset, int *temp_ptr) { int rv; @@ -80,8 +103,68 @@ int g781_get_val(int idx, int *temp_ptr) return EC_SUCCESS; } +static void temp_sensor_g781_init_deferred(void) +{ +#ifdef CONFIG_TEMP_SENSOR_G781_INIT + int alert_status, rv; + if (!g781_reg_init) + return; + + /* Make sure this init all alert status is clear */ + ccprintf("[%T Start G781 register init]\n"); + rv = status_read8(&alert_status); + if (rv < 0) + return; + + if (temp_val_local_high_limit == 0xFF) { + rv = get_temp(G781_LOCAL_TEMP_HIGH_LIMIT_R, + &temp_val_local_high_limit); + if ((rv == EC_SUCCESS) && (temp_val_local_high_limit + != G781_LOCAL_TEMP_HIGH_LIMIT_VALUE)) { + rv = set_temp(G781_LOCAL_TEMP_HIGH_LIMIT_W, + G781_LOCAL_TEMP_HIGH_LIMIT_VALUE); + if (rv < 0) + return; + } + } + g781_reg_init = EC_SUCCESS; + + ccprintf("[%T Enable G781 ALERT# interrupt\n"); + gpio_enable_interrupt(GPIO_FAN_ALERT_L); +#endif +} +DECLARE_DEFERRED(temp_sensor_g781_init_deferred); + +static void temp_sensor_g781_init(void) +{ + hook_call_deferred(temp_sensor_g781_init_deferred, 0); +} +DECLARE_HOOK(HOOK_INIT, temp_sensor_g781_init, HOOK_PRIO_TEMP_SENSOR); + +static void fan_alert_deferred(void) +{ +#ifdef CONFIG_TEMP_SENSOR_G781_INIT + ccprintf("[%T Fan alert force EC enter hibernate]\n"); + system_hibernate(0, 0); +#endif +} +DECLARE_DEFERRED(fan_alert_deferred); + +void fan_alert_interrupt(enum gpio_signal signal) +{ + hook_call_deferred(fan_alert_deferred, 0); + gpio_disable_interrupt(GPIO_FAN_ALERT_L); +} + static void temp_sensor_poll(void) { +#ifdef CONFIG_TEMP_SENSOR_G781_INIT + if (g781_reg_init) { + ccprintf("[%T Retry to init G781 register]\n"); + hook_call_deferred(temp_sensor_g781_init_deferred, 0); + } +#endif + if (!has_power()) return; diff --git a/driver/temp_sensor/g781.h b/driver/temp_sensor/g781.h index 6463155659..2909de5c23 100644 --- a/driver/temp_sensor/g781.h +++ b/driver/temp_sensor/g781.h @@ -9,6 +9,7 @@ #define __CROS_EC_TEMP_SENSOR_G781_H #define G781_I2C_ADDR 0x98 /* 7-bit address is 0x4C */ +#define G781_I2C_ALERT_ADDR 0x19 #define G781_IDX_INTERNAL 0 #define G781_IDX_EXTERNAL 1 @@ -67,4 +68,11 @@ */ int g781_get_val(int idx, int *temp_ptr); +/** + * Interrupt handler for fan alert. + * + * @param signal Signal which triggered the interrupt. + */ +void fan_alert_interrupt(enum gpio_signal signal); + #endif /* __CROS_EC_TEMP_SENSOR_G781_H */ diff --git a/include/config.h b/include/config.h index 1f31b1f7f1..efb76ad546 100644 --- a/include/config.h +++ b/include/config.h @@ -903,6 +903,7 @@ /* Support particular temperature sensor chips */ #undef CONFIG_TEMP_SENSOR_G781 /* G781 sensor, on I2C bus */ +#undef CONFIG_TEMP_SENSOR_G781_INIT /* G781 sensor init */ #undef CONFIG_TEMP_SENSOR_TMP006 /* TI TMP006 sensor, on I2C bus */ #undef CONFIG_TEMP_SENSOR_TMP432 /* TI TMP432 sensor, on I2C bus */ -- cgit v1.2.1