summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/acpi.c5
-rw-r--r--common/build.mk1
-rw-r--r--common/keyboard_backlight.c149
-rw-r--r--common/pwm_kblight.c121
4 files changed, 174 insertions, 102 deletions
diff --git a/common/acpi.c b/common/acpi.c
index e21eb93b97..7ef3d81412 100644
--- a/common/acpi.c
+++ b/common/acpi.c
@@ -10,6 +10,7 @@
#include "dptf.h"
#include "hooks.h"
#include "host_command.h"
+#include "keyboard_backlight.h"
#include "lpc.h"
#include "ec_commands.h"
#include "tablet_mode.h"
@@ -147,7 +148,7 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
break;
#ifdef CONFIG_PWM_KBLIGHT
case EC_ACPI_MEM_KEYBOARD_BACKLIGHT:
- result = pwm_get_duty(PWM_CH_KBLIGHT);
+ result = kblight_get();
break;
#endif
#ifdef CONFIG_FANS
@@ -231,7 +232,7 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
* debug console.
*/
CPRINTF("\r[%T ACPI kblight %d]", data);
- pwm_set_duty(PWM_CH_KBLIGHT, data);
+ kblight_set(data);
break;
#endif
#ifdef CONFIG_FANS
diff --git a/common/build.mk b/common/build.mk
index 1dd7801455..1a0f27e5bf 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -87,6 +87,7 @@ common-$(CONFIG_POWER_BUTTON_X86)+=power_button_x86.o
common-$(CONFIG_PSTORE)+=pstore_commands.o
common-$(CONFIG_PWM)+=pwm.o
common-$(CONFIG_PWM_KBLIGHT)+=pwm_kblight.o
+common-$(CONFIG_PWM_KBLIGHT)+=keyboard_backlight.o
common-$(CONFIG_RMA_AUTH)+=rma_auth.o
common-$(CONFIG_RSA)+=rsa.o
common-$(CONFIG_ROLLBACK)+=rollback.o
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));
diff --git a/common/pwm_kblight.c b/common/pwm_kblight.c
index 13415b5c51..1db5b9e5bd 100644
--- a/common/pwm_kblight.c
+++ b/common/pwm_kblight.c
@@ -3,123 +3,44 @@
* found in the LICENSE file.
*/
-/* PWM control module for Chromebook keyboard backlight. */
+/* PWM control module for keyboard backlight. */
#include "common.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "host_command.h"
-#include "lid_switch.h"
+#include "keyboard_backlight.h"
#include "pwm.h"
#include "system.h"
#include "util.h"
-#define PWMKBD_SYSJUMP_TAG 0x504b /* "PK" */
-#define PWM_HOOK_VERSION 1
-/* Saved PWM state across sysjumps */
-struct pwm_kbd_state {
- uint8_t kblight_en;
- uint8_t kblight_percent;
-};
-
-/*****************************************************************************/
-/* Console commands */
+const enum pwm_channel kblight_pwm_ch = PWM_CH_KBLIGHT;
-static int command_kblight(int argc, char **argv)
+static int kblight_pwm_set(int percent)
{
- if (argc >= 2) {
- char *e;
- int i = strtoi(argv[1], &e, 0);
- if (*e)
- return EC_ERROR_PARAM1;
- pwm_set_duty(PWM_CH_KBLIGHT, i);
- }
-
- ccprintf("Keyboard backlight: %d%%\n", pwm_get_duty(PWM_CH_KBLIGHT));
+ pwm_set_duty(kblight_pwm_ch, percent);
return EC_SUCCESS;
}
-DECLARE_CONSOLE_COMMAND(kblight, command_kblight,
- "percent",
- "Set keyboard backlight");
-
-/*****************************************************************************/
-/* Host commands */
-
-int pwm_command_get_keyboard_backlight(struct host_cmd_handler_args *args)
-{
- struct ec_response_pwm_get_keyboard_backlight *r = args->response;
-
- r->percent = pwm_get_duty(PWM_CH_KBLIGHT);
- r->enabled = pwm_get_enabled(PWM_CH_KBLIGHT);
- args->response_size = sizeof(*r);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT,
- pwm_command_get_keyboard_backlight,
- EC_VER_MASK(0));
-
-int pwm_command_set_keyboard_backlight(struct host_cmd_handler_args *args)
-{
- const struct ec_params_pwm_set_keyboard_backlight *p = args->params;
-
- pwm_set_duty(PWM_CH_KBLIGHT, p->percent);
-
- return EC_RES_SUCCESS;
-}
-DECLARE_HOST_COMMAND(EC_CMD_PWM_SET_KEYBOARD_BACKLIGHT,
- pwm_command_set_keyboard_backlight,
- EC_VER_MASK(0));
-
-/*****************************************************************************/
-/* Hooks */
-static void pwm_kblight_init(void)
+static int kblight_pwm_get(void)
{
- const struct pwm_kbd_state *prev;
- int version, size;
-
- prev = (const struct pwm_kbd_state *)
- system_get_jump_tag(PWMKBD_SYSJUMP_TAG, &version, &size);
- if (prev && version == PWM_HOOK_VERSION && size == sizeof(*prev)) {
- /* Restore previous state. */
- pwm_enable(PWM_CH_KBLIGHT, prev->kblight_en);
- pwm_set_duty(PWM_CH_KBLIGHT, prev->kblight_percent);
- } else {
- /* Enable keyboard backlight control, turned down */
- pwm_set_duty(PWM_CH_KBLIGHT, 0);
- pwm_enable(PWM_CH_KBLIGHT, 1);
- }
+ return pwm_get_duty(kblight_pwm_ch);
}
-DECLARE_HOOK(HOOK_INIT, pwm_kblight_init, HOOK_PRIO_DEFAULT);
-static void pwm_kblight_preserve_state(void)
+static int kblight_pwm_init(void)
{
- struct pwm_kbd_state state;
-
- state.kblight_en = pwm_get_enabled(PWM_CH_KBLIGHT);
- state.kblight_percent = pwm_get_duty(PWM_CH_KBLIGHT);
-
- system_add_jump_tag(PWMKBD_SYSJUMP_TAG, PWM_HOOK_VERSION,
- sizeof(state), &state);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, pwm_kblight_preserve_state, HOOK_PRIO_DEFAULT);
-
-static void pwm_kblight_suspend(void)
-{
- pwm_set_duty(PWM_CH_KBLIGHT, 0);
+ /* dnojiri: Why do we need save/restore setting over sysjump? */
+ kblight_pwm_set(0);
+ pwm_enable(kblight_pwm_ch, 1);
+ return EC_SUCCESS;
}
-DECLARE_HOOK(HOOK_CHIPSET_SUSPEND, pwm_kblight_suspend, HOOK_PRIO_DEFAULT);
-static void pwm_kblight_shutdown(void)
+static int kblight_pwm_enable(int enable)
{
- pwm_set_duty(PWM_CH_KBLIGHT, 0);
+ pwm_enable(kblight_pwm_ch, enable);
+ return EC_SUCCESS;
}
-DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, pwm_kblight_shutdown, HOOK_PRIO_DEFAULT);
-static void pwm_kblight_lid_change(void)
-{
- pwm_enable(PWM_CH_KBLIGHT, lid_is_open());
-}
-DECLARE_HOOK(HOOK_LID_CHANGE, pwm_kblight_lid_change, HOOK_PRIO_DEFAULT);
+const struct kblight_drv kblight_pwm = {
+ .init = kblight_pwm_init,
+ .set = kblight_pwm_set,
+ .get = kblight_pwm_get,
+ .enable = kblight_pwm_enable,
+};