summaryrefslogtreecommitdiff
path: root/common/keyboard_backlight.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/keyboard_backlight.c')
-rw-r--r--common/keyboard_backlight.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/common/keyboard_backlight.c b/common/keyboard_backlight.c
new file mode 100644
index 0000000000..d17c2bd319
--- /dev/null
+++ b/common/keyboard_backlight.c
@@ -0,0 +1,149 @@
+/* Copyright 2018 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 "console.h"
+#include "ec_commands.h"
+#include "hooks.h"
+#include "host_command.h"
+#include "keyboard_backlight.h"
+#include "lid_switch.h"
+#include "timer.h"
+#include "util.h"
+
+#define CPRINTF(format, args...) cprintf(CC_KEYBOARD, format, ## args)
+#define CPRINTS(format, args...) cprints(CC_KEYBOARD, format, ## args)
+
+static struct kblight_conf kblight;
+static int current_percent;
+
+void __attribute__((weak)) board_kblight_init(void)
+{ }
+
+static int kblight_init(void)
+{
+ if (!kblight.drv || !kblight.drv->init)
+ return EC_ERROR_UNIMPLEMENTED;
+ return kblight.drv->init();
+}
+
+static void kblight_set_deferred(void)
+{
+ if (!kblight.drv || !kblight.drv->set)
+ return;
+ kblight.drv->set(current_percent);
+}
+DECLARE_DEFERRED(kblight_set_deferred);
+
+/*
+ * APIs
+ */
+int kblight_set(int percent)
+{
+ if (current_percent < 0 || 100 < current_percent)
+ return EC_ERROR_INVAL;
+ current_percent = percent;
+ /* Need to defer i2c in case it's called from an interrupt handler. */
+ hook_call_deferred(&kblight_set_deferred_data, 0);
+ return EC_SUCCESS;
+}
+
+int kblight_get(void)
+{
+ return current_percent;
+}
+
+int kblight_enable(int enable)
+{
+ if (!kblight.drv || !kblight.drv->enable)
+ return -1;
+ return kblight.drv->enable(enable);
+}
+
+int kblight_register(const struct kblight_drv *drv)
+{
+ kblight.drv = drv;
+ CPRINTS("kblight registered");
+ return EC_SUCCESS;
+}
+
+/*
+ * Hooks
+ */
+static void keyboard_backlight_init(void)
+{
+ /* Uses PWM by default. Can be customized by board_kblight_init */
+ kblight_register(&kblight_pwm);
+ board_kblight_init();
+ if (kblight_init())
+ CPRINTS("kblight init failed");
+}
+DECLARE_HOOK(HOOK_INIT, keyboard_backlight_init, HOOK_PRIO_DEFAULT);
+
+static void kblight_suspend(void)
+{
+ kblight_enable(0);
+}
+DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, kblight_suspend, HOOK_PRIO_DEFAULT);
+
+static void kblight_resume(void)
+{
+ if (lid_is_open()) {
+ kblight_enable(1);
+ kblight_set(current_percent);
+ }
+}
+DECLARE_HOOK(HOOK_CHIPSET_RESUME, kblight_resume, HOOK_PRIO_DEFAULT);
+
+static void kblight_lid_change(void)
+{
+ kblight_enable(lid_is_open());
+}
+DECLARE_HOOK(HOOK_LID_CHANGE, kblight_lid_change, HOOK_PRIO_DEFAULT);
+
+/*
+ * Console and host commands
+ */
+static int cc_kblight(int argc, char **argv)
+{
+ if (argc >= 2) {
+ char *e;
+ int i = strtoi(argv[1], &e, 0);
+ if (*e)
+ return EC_ERROR_PARAM1;
+ if (kblight_set(i))
+ return EC_ERROR_PARAM1;
+ }
+ ccprintf("Keyboard backlight: %d%%\n", kblight_get());
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(kblight, cc_kblight,
+ "percent",
+ "Get/set keyboard backlight");
+
+int hc_get_keyboard_backlight(struct host_cmd_handler_args *args)
+{
+ struct ec_response_pwm_get_keyboard_backlight *r = args->response;
+
+ r->percent = kblight_get();
+ r->enabled = 1; /* Deprecated */
+ args->response_size = sizeof(*r);
+
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT,
+ hc_get_keyboard_backlight,
+ EC_VER_MASK(0));
+
+int hc_set_keyboard_backlight(struct host_cmd_handler_args *args)
+{
+ const struct ec_params_pwm_set_keyboard_backlight *p = args->params;
+
+ if (kblight_set(p->percent))
+ return EC_RES_ERROR;
+ return EC_RES_SUCCESS;
+}
+DECLARE_HOST_COMMAND(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT,
+ hc_set_keyboard_backlight,
+ EC_VER_MASK(0));