summaryrefslogtreecommitdiff
path: root/board/samus/extpower.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/samus/extpower.c')
-rw-r--r--board/samus/extpower.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/board/samus/extpower.c b/board/samus/extpower.c
new file mode 100644
index 0000000000..6100a83127
--- /dev/null
+++ b/board/samus/extpower.c
@@ -0,0 +1,64 @@
+/* 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.
+ */
+
+/*
+ * Pure GPIO-based external power detection, buffered to PCH.
+ * Drive high in S5-S0 when AC_PRESENT is high, otherwise drive low.
+ */
+
+#include "chipset.h"
+#include "common.h"
+#include "extpower.h"
+#include "gpio.h"
+#include "hooks.h"
+#include "host_command.h"
+
+int extpower_is_present(void)
+{
+ return gpio_get_level(GPIO_AC_PRESENT);
+}
+
+/**
+ * Deferred function to handle external power change
+ */
+static void extpower_deferred(void)
+{
+ hook_notify(HOOK_AC_CHANGE);
+
+ /* Forward notification to host */
+ if (extpower_is_present())
+ host_set_single_event(EC_HOST_EVENT_AC_CONNECTED);
+ else
+ host_set_single_event(EC_HOST_EVENT_AC_DISCONNECTED);
+}
+DECLARE_DEFERRED(extpower_deferred);
+
+static void extpower_buffer_to_pch(void)
+{
+ if (chipset_in_state(CHIPSET_STATE_HARD_OFF)) {
+ /* Drive low in G3 state */
+ gpio_set_level(GPIO_PCH_ACOK, 0);
+ } else {
+ /* Buffer from extpower in S5+ (where 3.3DSW enabled) */
+ gpio_set_level(GPIO_PCH_ACOK, extpower_is_present());
+ }
+}
+
+void extpower_interrupt(enum gpio_signal signal)
+{
+ extpower_buffer_to_pch();
+
+ /* Trigger deferred notification of external power change */
+ hook_call_deferred(extpower_deferred, 0);
+}
+
+static void extpower_init(void)
+{
+ extpower_buffer_to_pch();
+
+ /* Enable interrupts, now that we've initialized */
+ gpio_enable_interrupt(GPIO_AC_PRESENT);
+}
+DECLARE_HOOK(HOOK_INIT, extpower_init, HOOK_PRIO_DEFAULT);