diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/acpi.c | 5 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/keyboard_backlight.c | 149 | ||||
-rw-r--r-- | common/pwm_kblight.c | 121 |
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, +}; |