diff options
Diffstat (limited to 'driver/temp_sensor')
-rw-r--r-- | driver/temp_sensor/g781.c | 85 | ||||
-rw-r--r-- | driver/temp_sensor/g781.h | 8 |
2 files changed, 92 insertions, 1 deletions
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 */ |