diff options
Diffstat (limited to 'board/falco/panel.c')
-rw-r--r-- | board/falco/panel.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/board/falco/panel.c b/board/falco/panel.c new file mode 100644 index 0000000000..863ad24e1f --- /dev/null +++ b/board/falco/panel.c @@ -0,0 +1,131 @@ +/* Copyright (c) 2013 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. + */ + +#include "common.h" +#include "gpio.h" +#include "hooks.h" +#include "host_command.h" +#include "lid_switch.h" + +/* + * Falco needs a 420ms delay for a 0->1 transition of the PCH's backlight + * enable signal. The reason is that Falco has a LVDS bridge which controls + * all the other signals for the panel except the backlight. In order to + * meet the penel power sequencing requirements a delay needs to be added. + * + * Additionally the LCDVCC needs to be delayed on a 0->1 transition of the + * PCH's EDP VDD enable signal to meet the panel specification. + */ + +#define BL_ENABLE_DELAY_US 420000 /* 420 ms delay */ +#define LCDVCC_ENABLE_DELAY_US 270000 /* 270 ms delay */ + +static int backlight_deferred_value; + +static void set_backlight_value(void) +{ + gpio_set_level(GPIO_ENABLE_BACKLIGHT, backlight_deferred_value); +} +DECLARE_DEFERRED(set_backlight_value); + +/** + * Update backlight state. + */ +static void update_backlight(void) +{ + int pch_value; + + pch_value = gpio_get_level(GPIO_PCH_BKLTEN); + + /* Immediately disable the backlight when the lid is closed or the PCH + * is instructing the backlight to be disabled. */ + if (!lid_is_open() || !pch_value) { + /* If there was a scheduled callback pending make sure it picks + * up the disabled value. */ + backlight_deferred_value = 0; + gpio_set_level(GPIO_ENABLE_BACKLIGHT, 0); + /* Cancel pending hook */ + hook_call_deferred(&set_backlight_value, -1); + return; + } + /* Handle a 0->1 transition by calling a deferred hook. */ + if (pch_value && !backlight_deferred_value) { + backlight_deferred_value = 1; + hook_call_deferred(&set_backlight_value, BL_ENABLE_DELAY_US); + } +} +DECLARE_HOOK(HOOK_LID_CHANGE, update_backlight, HOOK_PRIO_DEFAULT); + +void backlight_interrupt(enum gpio_signal signal) +{ + update_backlight(); +} + +/** + * Host command to toggle backlight. + */ +static int switch_command_enable_backlight(struct host_cmd_handler_args *args) +{ + const struct ec_params_switch_enable_backlight *p = args->params; + gpio_set_level(GPIO_ENABLE_BACKLIGHT, p->enabled); + return EC_RES_SUCCESS; +} +DECLARE_HOST_COMMAND(EC_CMD_SWITCH_ENABLE_BKLIGHT, + switch_command_enable_backlight, 0); + + +static int lcdvcc_en_deferred_value; + +static void set_lcdvcc_en_value(void) +{ + gpio_set_level(GPIO_EC_EDP_VDD_EN, lcdvcc_en_deferred_value); +} +DECLARE_DEFERRED(set_lcdvcc_en_value); + +void lcdvcc_interrupt(enum gpio_signal signal) +{ + int pch_value; + + pch_value = gpio_get_level(GPIO_PCH_EDP_VDD_EN); + + /* Immediately disable the LCDVCC when the PCH indicates as such. */ + if (!pch_value) { + /* If there was a scheduled callback pending make sure it picks + * up the disabled value. */ + lcdvcc_en_deferred_value = 0; + gpio_set_level(GPIO_EC_EDP_VDD_EN, 0); + /* Cancel pending hook */ + hook_call_deferred(&set_lcdvcc_en_value, -1); + return; + } + /* Handle a 0->1 transition by calling a deferred hook. */ + if (pch_value && !lcdvcc_en_deferred_value) { + lcdvcc_en_deferred_value = 1; + hook_call_deferred(&set_lcdvcc_en_value, + LCDVCC_ENABLE_DELAY_US); + } +} + +/** + * Initialize panel module. + */ +static void panel_init(void) +{ + /* Set initial deferred value and signal to the current PCH signal. */ + backlight_deferred_value = gpio_get_level(GPIO_PCH_BKLTEN); + set_backlight_value(); + + update_backlight(); + + gpio_enable_interrupt(GPIO_PCH_BKLTEN); + + /* The interrupt is enabled for the GPIO_PCH_EDP_VDD_EN in the + * chipset_haswell.c compilation unit. Initially set the value + * to whatever it current is reading. */ + lcdvcc_en_deferred_value = gpio_get_level(GPIO_PCH_EDP_VDD_EN); + set_lcdvcc_en_value(); +} +DECLARE_HOOK(HOOK_INIT, panel_init, HOOK_PRIO_DEFAULT); + |