summaryrefslogtreecommitdiff
path: root/board/falco/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/falco/panel.c')
-rw-r--r--board/falco/panel.c131
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);
+