blob: d17c2bd319fd459411adde7d5d619b890c4526df [file] [log] [blame]
/* 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));