summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2022-04-07 23:06:11 +0000
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-04-13 16:54:13 +0000
commit985fe9a5e746db7fc2f2ad11e13ce3a77e138a4b (patch)
treebd7e39c536d81f26a9e358ef3dcd996e9e68e668
parentc0333e1cbc5172d666831d5682a15f2cbd00a9cb (diff)
downloadchrome-ec-985fe9a5e746db7fc2f2ad11e13ce3a77e138a4b.tar.gz
RGBKBD: Support backlight control via EC_CMD_PWM_SET_DUTY
In a regular design, a keyboard backlight is connected to a PWM pin of an EC. With an RGB keyboard, the brightness control is part of the RGB keyboard functionality. Thus, EC_CMD_PWM_SET_DUTY with EC_PWM_TYPE_KB_LIGHT should be handled by an RGB keyboard API to control the keyboard backlight brightness. On host, run: localhost ~ # ectool pwmsetduty kb 0x8000 EC prints: RGBKBD: Set GCC to 128 BUG=b:228525798,b:226215987 BRANCH=None TEST=Taniks. See above. Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Change-Id: Id8f23ba67728f03664673834be0903e0f593e744 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3576897 Reviewed-by: Parth Malkan <parthmalkan@google.com> Reviewed-by: Zhuohao Lee <zhuohao@chromium.org>
-rw-r--r--common/pwm.c37
-rw-r--r--common/rgb_keyboard.c48
-rw-r--r--include/rgb_keyboard.h13
3 files changed, 75 insertions, 23 deletions
diff --git a/common/pwm.c b/common/pwm.c
index 74c079bbfd..7699405f3d 100644
--- a/common/pwm.c
+++ b/common/pwm.c
@@ -9,6 +9,7 @@
#include "hooks.h"
#include "host_command.h"
#include "pwm.h"
+#include "rgb_keyboard.h"
#include "util.h"
#ifdef CONFIG_PWM
@@ -64,11 +65,18 @@ host_command_pwm_set_duty(struct host_cmd_handler_args *args)
const struct ec_params_pwm_set_duty *p = args->params;
enum pwm_channel channel;
- if (get_target_channel(&channel, p->pwm_type, p->index))
- return EC_RES_INVALID_PARAM;
-
- pwm_set_raw_duty(channel, p->duty);
- pwm_enable(channel, p->duty > 0);
+ if (IS_ENABLED(CONFIG_RGB_KEYBOARD) &&
+ (p->pwm_type == EC_PWM_TYPE_KB_LIGHT)) {
+ uint8_t gcc = DIV_ROUND_NEAREST(p->duty * RGBKBD_MAX_GCC_LEVEL,
+ EC_PWM_MAX_DUTY);
+ if (rgbkbd_set_global_brightness(gcc))
+ return EC_RES_ERROR;
+ } else {
+ if (get_target_channel(&channel, p->pwm_type, p->index))
+ return EC_RES_INVALID_PARAM;
+ pwm_set_raw_duty(channel, p->duty);
+ pwm_enable(channel, p->duty > 0);
+ }
return EC_RES_SUCCESS;
}
@@ -82,12 +90,23 @@ host_command_pwm_get_duty(struct host_cmd_handler_args *args)
const struct ec_params_pwm_get_duty *p = args->params;
struct ec_response_pwm_get_duty *r = args->response;
- enum pwm_channel channel;
+ if (IS_ENABLED(CONFIG_RGB_KEYBOARD) &&
+ (p->pwm_type == EC_PWM_TYPE_KB_LIGHT)) {
+ uint8_t gcc;
- if (get_target_channel(&channel, p->pwm_type, p->index))
- return EC_RES_INVALID_PARAM;
+ if (rgbkbd_get_global_brightness(&gcc))
+ return EC_RES_ERROR;
+ r->duty = DIV_ROUND_NEAREST(gcc * EC_PWM_MAX_DUTY,
+ RGBKBD_MAX_GCC_LEVEL);
+ } else {
+ enum pwm_channel channel;
+
+ if (get_target_channel(&channel, p->pwm_type, p->index))
+ return EC_RES_INVALID_PARAM;
+
+ r->duty = pwm_get_raw_duty(channel);
+ }
- r->duty = pwm_get_raw_duty(channel);
args->response_size = sizeof(*r);
return EC_RES_SUCCESS;
diff --git a/common/rgb_keyboard.c b/common/rgb_keyboard.c
index f581d5ae1a..0f66e6c242 100644
--- a/common/rgb_keyboard.c
+++ b/common/rgb_keyboard.c
@@ -233,6 +233,38 @@ void rgbkbd_init_lookup_table(void)
*/
}
+int rgbkbd_set_global_brightness(uint8_t gcc)
+{
+ int e, grid;
+ int rv = EC_SUCCESS;
+
+ for (grid = 0; grid < rgbkbd_count; grid++) {
+ struct rgbkbd *ctx = &rgbkbds[grid];
+
+ e = ctx->cfg->drv->set_gcc(ctx, gcc);
+ if (e) {
+ CPRINTS("Failed to set GCC to %u for grid=%d (%d)",
+ gcc, grid, e);
+ rv = e;
+ continue;
+ }
+
+ ctx->gcc = gcc;
+ }
+
+ CPRINTS("Set GCC to %u", gcc);
+
+ /* Return EC_SUCCESS or the last error. */
+ return rv;
+}
+
+int rgbkbd_get_global_brightness(uint8_t *gcc)
+{
+ *gcc = rgbkbds[0].gcc;
+
+ return EC_SUCCESS;
+}
+
__overridable void board_enable_rgb_keyboard(bool enable) {}
static int rgbkbd_init(void)
@@ -307,19 +339,13 @@ static int rgbkbd_enable(int enable)
void rgbkbd_task(void *u)
{
uint32_t event;
- int i, rv;
board_enable_rgb_keyboard(true);
rgbkbd_init_lookup_table();
rgbkbd_init();
rgbkbd_enable(1);
- for (i = 0; i < rgbkbd_count; i++) {
- struct rgbkbd *ctx = &rgbkbds[i];
- rv = ctx->cfg->drv->set_gcc(ctx, 0x80);
- if (rv)
- CPRINTS("Failed to set GCC (%d)", rv);
- }
+ rgbkbd_set_global_brightness(0x80);
while (1) {
event = task_wait_event(100 * MSEC);
@@ -380,7 +406,6 @@ DECLARE_HOST_COMMAND(EC_CMD_RGBKBD, hc_rgbkbd, EC_VER_MASK(0));
test_export_static int cc_rgbk(int argc, char **argv)
{
- struct rgbkbd *ctx;
char *end, *comma;
struct rgb_s color;
int gcc, x, y, val;
@@ -421,12 +446,7 @@ test_export_static int cc_rgbk(int argc, char **argv)
gcc = strtoi(argv[1], &end, 0);
if (*end || gcc < 0 || gcc > UINT8_MAX)
return EC_ERROR_PARAM1;
- demo = RGBKBD_DEMO_OFF;
- for (i = 0; i < rgbkbd_count; i++) {
- ctx = &rgbkbds[i];
- ctx->cfg->drv->set_gcc(ctx, gcc);
- }
- return EC_SUCCESS;
+ return rgbkbd_set_global_brightness(gcc);
}
if (argc != 5)
diff --git a/include/rgb_keyboard.h b/include/rgb_keyboard.h
index 0500ce859f..f4c9540c63 100644
--- a/include/rgb_keyboard.h
+++ b/include/rgb_keyboard.h
@@ -12,6 +12,8 @@
/* Use this instead of '3' for readability where applicable. */
#define SIZE_OF_RGB sizeof(struct rgb_s)
+#define RGBKBD_MAX_GCC_LEVEL 0xff
+
enum rgbkbd_demo {
RGBKBD_DEMO_OFF = 0,
RGBKBD_DEMO_FLOW = 1,
@@ -37,6 +39,8 @@ struct rgbkbd {
const struct rgbkbd_cfg * const cfg;
/* Current state of the port */
enum rgbkbd_state state;
+ /* Global current control (a.k.a. backlight brightness) */
+ uint8_t gcc;
/* Buffer containing color info for each dot. */
struct rgb_s *buf;
};
@@ -173,3 +177,12 @@ __override_proto void board_enable_rgb_keyboard(bool enable);
*/
extern const uint8_t rgbkbd_map[];
extern const size_t rgbkbd_map_size;
+
+/**
+ * Set/get global brightness of the RGB keyboard.
+ *
+ * @param gcc Brightness level 0 ~ RGBKBD_MAX_GCC_LEVEL.
+ * @return enum ec_error_list;
+ */
+int rgbkbd_set_global_brightness(uint8_t gcc);
+int rgbkbd_get_global_brightness(uint8_t *gcc);