diff options
-rw-r--r-- | board/prism/board.c | 2 | ||||
-rw-r--r-- | board/taniks/keyboard.c | 1 | ||||
-rw-r--r-- | common/rgb_keyboard.c | 237 | ||||
-rw-r--r-- | driver/led/aw20198.c | 14 | ||||
-rw-r--r-- | driver/led/is31fl3733b.c | 2 | ||||
-rw-r--r-- | driver/led/is31fl3743b.c | 20 | ||||
-rw-r--r-- | include/ec_commands.h | 8 | ||||
-rw-r--r-- | include/rgb_keyboard.h | 17 | ||||
-rw-r--r-- | test/rgb_keyboard.c | 10 | ||||
-rw-r--r-- | util/ectool.c | 23 |
10 files changed, 217 insertions, 117 deletions
diff --git a/board/prism/board.c b/board/prism/board.c index e35eaf9ef5..dc5c042db1 100644 --- a/board/prism/board.c +++ b/board/prism/board.c @@ -87,7 +87,6 @@ struct rgbkbd rgbkbds[] = { .col_len = RGB_GRID0_COL, .row_len = RGB_GRID0_ROW, }, - .init = &rgbkbd_default, .buf = grid0, }, [1] = { @@ -97,7 +96,6 @@ struct rgbkbd rgbkbds[] = { .col_len = RGB_GRID1_COL, .row_len = RGB_GRID1_ROW, }, - .init = &rgbkbd_default, .buf = grid1, }, }; diff --git a/board/taniks/keyboard.c b/board/taniks/keyboard.c index 9cecf57f51..99099b4661 100644 --- a/board/taniks/keyboard.c +++ b/board/taniks/keyboard.c @@ -58,7 +58,6 @@ struct rgbkbd rgbkbds[] = { .col_len = RGB_GRID0_COL, .row_len = RGB_GRID0_ROW, }, - .init = &rgbkbd_default, .buf = grid0, }, }; diff --git a/common/rgb_keyboard.c b/common/rgb_keyboard.c index aac7c48d61..815e4a3435 100644 --- a/common/rgb_keyboard.c +++ b/common/rgb_keyboard.c @@ -40,31 +40,48 @@ uint8_t rgbkbd_table[EC_RGBKBD_MAX_KEY_COUNT]; static enum rgbkbd_state rgbkbd_state; -const struct rgbkbd_init rgbkbd_default = { +const struct rgbkbd_init rgbkbd_init_default = { .gcc = RGBKBD_MAX_GCC_LEVEL / 2, - .scale = RGBKBD_MAX_SCALE, + .scale = { RGBKBD_MAX_SCALE, RGBKBD_MAX_SCALE, RGBKBD_MAX_SCALE }, .color = { .r = 0xff, .g = 0xff, .b = 0xff }, /* white */ }; +const struct rgbkbd_init *rgbkbd_init_setting = &rgbkbd_init_default; + +void rgbkbd_register_init_setting(const struct rgbkbd_init *setting) +{ + rgbkbd_init_setting = setting; +} + +/* Search the grid where x belongs to. */ +static struct rgbkbd *find_grid_from_x(int x, uint8_t *col) +{ + struct rgbkbd *ctx = NULL; + uint8_t grid; + + *col = 0; + for (grid = 0; grid < rgbkbd_count; grid++) { + ctx = &rgbkbds[grid]; + if (x < *col + ctx->cfg->col_len) + break; + *col += ctx->cfg->col_len; + } + + return ctx; +} + static int set_color_single(struct rgb_s color, int x, int y) { struct rgbkbd *ctx = &rgbkbds[0]; - uint8_t grid; - uint8_t col = 0; - uint8_t offset; + uint8_t grid, col, offset; int rv; if (rgbkbd_hsize <= x || rgbkbd_vsize <= y) { return EC_ERROR_OVERFLOW; } - /* Search the grid where x belongs to. */ - for (grid = 0; grid < rgbkbd_count; grid++, ctx++) { - if (x < col + ctx->cfg->col_len) - break; - col += ctx->cfg->col_len; - } - + ctx = find_grid_from_x(x, &col); + grid = RGBKBD_CTX_TO_GRID(ctx); offset = ctx->cfg->row_len * (x - col) + y; ctx->buf[offset] = color; @@ -263,7 +280,7 @@ static int rgbkbd_set_global_brightness(uint8_t gcc) return rv; } -static int rgbkbd_set_scale(uint8_t scale) +static int rgbkbd_reset_scale(struct rgb_s scale) { int e, i, rv = EC_SUCCESS; @@ -272,8 +289,8 @@ static int rgbkbd_set_scale(uint8_t scale) e = ctx->cfg->drv->set_scale(ctx, 0, scale, get_grid_size(ctx)); if (e) { - CPRINTS("Failed to set scale of GRID%d to %d (%d)", - i, scale, e); + CPRINTS("Failed to set scale to [%d,%d,%d] Grid%d (%d)", + scale.r, scale.g, scale.b, i, e); rv = e; } } @@ -281,6 +298,46 @@ static int rgbkbd_set_scale(uint8_t scale) return rv; } +static int rgbkbd_set_scale(struct rgb_s scale, uint8_t key) +{ + struct rgbkbd *ctx; + uint8_t j, col, grid, offset; + union rgbkbd_coord_u8 led; + int rv = EC_SUCCESS; + + j = rgbkbd_table[key]; + if (j == RGBKBD_NONE) + return rv; + + do { + led.u8 = rgbkbd_map[j++]; + if (led.u8 == RGBKBD_DELM) + /* Reached end of the group. */ + break; + ctx = find_grid_from_x(led.coord.x, &col); + grid = RGBKBD_CTX_TO_GRID(ctx); + /* + * offset is the relative position in our buffer where LED + * colors are cached. RGB is grouped as one. Note this differs + * from the external buffer (LED drivers' buffer) where RGB is + * individually counted. + * + * offset can be calculated by multiplying the horizontal + * position (x) by the size of the rows, then, adding the + * vertical position (y). + */ + offset = ctx->cfg->row_len * (led.coord.x - col) + led.coord.y; + rv = ctx->cfg->drv->set_scale(ctx, offset, scale, 1); + if (rv) { + CPRINTS("Failed to set scale to [%d,%d,%d] Grid%d (%d)", + scale.r, scale.g, scale.b, grid, rv); + return rv; + } + } while (led.u8 != RGBKBD_DELM); + + return rv; +} + static int rgbkbd_init(void) { int rv = EC_SUCCESS; @@ -288,8 +345,7 @@ static int rgbkbd_init(void) for (i = 0; i < rgbkbd_count; i++) { struct rgbkbd *ctx = &rgbkbds[i]; - uint8_t scale = ctx->init->scale; - uint8_t gcc = ctx->init->gcc; + uint8_t gcc = rgbkbd_init_setting->gcc; e = ctx->cfg->drv->init(ctx); if (e) { @@ -298,14 +354,6 @@ static int rgbkbd_init(void) continue; } - e = ctx->cfg->drv->set_scale(ctx, 0, scale, get_grid_size(ctx)); - if (e) { - CPRINTS("Failed to set scale of GRID%d to %d (%d)", - i, scale, rv); - rv = e; - continue; - } - e = ctx->cfg->drv->set_gcc(ctx, gcc); if (e) { CPRINTS("Failed to set GCC to %u for grid=%d (%d)", @@ -314,11 +362,12 @@ static int rgbkbd_init(void) continue; } - rgbkbd_reset_color(ctx->init->color); - CPRINTS("Initialized GRID%d", i); } + rv |= rgbkbd_reset_scale(rgbkbd_init_setting->scale); + rgbkbd_reset_color(rgbkbd_init_setting->color); + if (rv == EC_SUCCESS) rgbkbd_state = RGBKBD_STATE_INITIALIZED; @@ -497,6 +546,10 @@ static enum ec_status hc_rgbkbd(struct host_cmd_handler_args *args) return EC_RES_INVALID_PARAM; rgbkbd_demo_set(p->demo); break; + case EC_RGBKBD_SUBCMD_SET_SCALE: + if (rgbkbd_set_scale(p->set_scale.scale, p->set_scale.key)) + rv = EC_RES_ERROR; + break; default: rv = EC_RES_INVALID_PARAM; break; @@ -506,10 +559,26 @@ static enum ec_status hc_rgbkbd(struct host_cmd_handler_args *args) } DECLARE_HOST_COMMAND(EC_CMD_RGBKBD, hc_rgbkbd, EC_VER_MASK(0)); +static int int_to_rgb(const char *code, struct rgb_s *rgb) +{ + int val; + char *end; + + val = strtoi(code, &end, 0); + if (*end || val > EC_RGBKBD_MAX_RGB_COLOR) + return EC_ERROR_INVAL; + + rgb->r = (val >> 16) & 0xff; + rgb->g = (val >> 8) & 0xff; + rgb->b = (val >> 0) & 0xff; + + return EC_SUCCESS; +} + test_export_static int cc_rgb(int argc, char **argv) { char *end, *comma; - struct rgb_s color; + struct rgb_s rgb, scale; int gcc, x, y, val; int i, rv = EC_SUCCESS; @@ -528,39 +597,68 @@ test_export_static int cc_rgb(int argc, char **argv) y = strtoi(comma + 1, &end, 0); if (*end || y >= rgbkbd_vsize) return EC_ERROR_PARAM1; + + rv = int_to_rgb(argv[2], &rgb); + if (rv) + return EC_ERROR_PARAM2; + + rgbkbd_demo_set(EC_RGBKBD_DEMO_OFF); + + if (y < 0) { + /* Set all LEDs on column x. */ + ccprintf("Set column %d to 0x%02x%02x%02x\n", + x, rgb.r, rgb.g, rgb.b); + for (i = 0; i < rgbkbd_vsize; i++) + rv = set_color_single(rgb, x, i); + } else if (x < 0) { + /* Set all LEDs on row y. */ + ccprintf("Set row %d to 0x%02x%02x%02x\n", + y, rgb.r, rgb.g, rgb.b); + for (i = 0; i < rgbkbd_hsize; i++) + rv = set_color_single(rgb, i, y); + } else { + ccprintf("Set (%d,%d) to 0x%02x%02x%02x\n", + x, y, rgb.r, rgb.g, rgb.b); + rv = set_color_single(rgb, x, y); + } } else if (!strcasecmp(argv[1], "all")) { /* Usage 3 */ - x = -1; - y = -1; + rv = int_to_rgb(argv[2], &rgb); + if (rv) + return EC_ERROR_PARAM2; + + rgbkbd_demo_set(EC_RGBKBD_DEMO_OFF); + rgbkbd_reset_color(rgb); } else if (!strcasecmp(argv[1], "demo")) { /* Usage 4 */ val = strtoi(argv[2], &end, 0); if (*end || val >= EC_RGBKBD_DEMO_COUNT) return EC_ERROR_PARAM1; rgbkbd_demo_set(val); - return EC_SUCCESS; } else if (!strcasecmp(argv[1], "reset")) { + /* Usage 5: Reset */ rgbkbd_reset(); rv = rgbkbd_init(); if (rv) return rv; - return rgbkbd_enable(0); + rv = rgbkbd_enable(0); } else if (!strcasecmp(argv[1], "enable")) { - return rgbkbd_enable(1); + /* Usage 5: Enable */ + rv = rgbkbd_enable(1); } else if (!strcasecmp(argv[1], "disable")) { - return rgbkbd_enable(0); + /* Usage 5: Disable */ + rv = rgbkbd_enable(0); } else if (!strcasecmp(argv[1], "scale")) { /* Usage 6 */ - val = strtoi(argv[2], &end, 0); - if (*end || val > RGBKBD_MAX_SCALE) + rv = int_to_rgb(argv[2], &scale); + if (rv) return EC_ERROR_PARAM2; - return rgbkbd_set_scale(val); + rv = rgbkbd_reset_scale(scale); } else if (!strcasecmp(argv[1], "red")) { - color.r = 255; - color.g = 0; - color.b = 0; - rgbkbd_reset_color(color); - return EC_SUCCESS; + rgb.r = 255; + rgb.g = 0; + rgb.b = 0; + rgbkbd_reset_color(rgb); } else { /* Usage 1 */ if (argc != 2) @@ -568,46 +666,7 @@ test_export_static int cc_rgb(int argc, char **argv) gcc = strtoi(argv[1], &end, 0); if (*end || gcc < 0 || gcc > UINT8_MAX) return EC_ERROR_PARAM1; - return rgbkbd_set_global_brightness(gcc); - } - - if (argc != 5) - return EC_ERROR_PARAM_COUNT; - - val = strtoi(argv[2], &end, 0); - if (*end || val < 0 || val > UINT8_MAX) - return EC_ERROR_PARAM2; - color.r = val; - val = strtoi(argv[3], &end, 0); - if (*end || val < 0 || val > UINT8_MAX) - return EC_ERROR_PARAM3; - color.g = val; - val = strtoi(argv[4], &end, 0); - if (*end || val < 0 || val > UINT8_MAX) - return EC_ERROR_PARAM4; - color.b = val; - - rgbkbd_demo_set(EC_RGBKBD_DEMO_OFF); - if (y < 0 && x < 0) { - /* Usage 3 */ - rgbkbd_reset_color(color); - } else if (y < 0) { - /* Usage 2: Set all LEDs on column x. */ - ccprintf("Set column %d to 0x%02x%02x%02x\n", - x, color.r, color.g, color.b); - for (i = 0; i < rgbkbd_vsize; i++) - rv = set_color_single(color, x, i); - } else if (x < 0) { - /* Usage 2: Set all LEDs on row y. */ - ccprintf("Set row %d to 0x%02x%02x%02x\n", - y, color.r, color.g, color.b); - for (i = 0; i < rgbkbd_hsize; i++) - rv = set_color_single(color, i, y); - } else { - /* Usage 2 */ - ccprintf("Set (%d,%d) to 0x%02x%02x%02x\n", - x, y, color.r, color.g, color.b); - rv = set_color_single(color, x, y); + rv = rgbkbd_set_global_brightness(gcc); } return rv; @@ -615,12 +674,12 @@ test_export_static int cc_rgb(int argc, char **argv) #ifndef TEST_BUILD DECLARE_CONSOLE_COMMAND(rgb, cc_rgb, "\n" - "1. rgbk <global-brightness>\n" - "2. rgbk <col,row> <r-bright> <g-bright> <b-bright>\n" - "3. rgbk all <r-bright> <g-bright> <b-bright>\n" - "4. rgbk demo <id>\n" - "5. rgbk reset/enable/disable/red\n" - "6. rgbk scale <val>\n", - "Set color of RGB keyboard" + "1. rgb <global-brightness>\n" + "2. rgb <col,row> <24-bit RGB code>\n" + "3. rgb all <24-bit RGB code>\n" + "4. rgb demo <id>\n" + "5. rgb reset/enable/disable/red\n" + "6. rgb scale <24-bit RGB scale>\n", + "Control RGB keyboard" ); #endif diff --git a/driver/led/aw20198.c b/driver/led/aw20198.c index f307ae4a02..14dada114a 100644 --- a/driver/led/aw20198.c +++ b/driver/led/aw20198.c @@ -107,13 +107,13 @@ static int aw20198_set_color(struct rgbkbd *ctx, uint8_t offset, buf, frame_len, NULL, 0); } -static int aw20198_set_scale(struct rgbkbd *ctx, uint8_t offset, uint8_t scale, - uint8_t len) +static int aw20198_set_scale(struct rgbkbd *ctx, uint8_t offset, + struct rgb_s scale, uint8_t len) { uint8_t buf[sizeof(offset) + BUF_SIZE]; const int frame_len = len * SIZE_OF_RGB + sizeof(offset); const int frame_offset = offset * SIZE_OF_RGB; - int rv; + int i, rv; if (frame_offset + frame_len > sizeof(buf)) { return EC_ERROR_OVERFLOW; @@ -124,8 +124,12 @@ static int aw20198_set_scale(struct rgbkbd *ctx, uint8_t offset, uint8_t scale, return rv; } - buf[0] = offset * SIZE_OF_RGB; - memset(&buf[1], scale, len * SIZE_OF_RGB); + buf[0] = frame_offset; + for (i = 0; i < len; i++) { + buf[i * SIZE_OF_RGB + 1] = scale.r; + buf[i * SIZE_OF_RGB + 2] = scale.g; + buf[i * SIZE_OF_RGB + 3] = scale.b; + } return i2c_xfer(ctx->cfg->i2c, AW20198_I2C_ADDR_FLAG, buf, frame_len, NULL, 0); diff --git a/driver/led/is31fl3733b.c b/driver/led/is31fl3733b.c index 429743e51b..5b1df890f1 100644 --- a/driver/led/is31fl3733b.c +++ b/driver/led/is31fl3733b.c @@ -178,7 +178,7 @@ static int is31fl3733b_set_color(struct rgbkbd *ctx, uint8_t offset, } static int is31fl3733b_set_scale(struct rgbkbd *ctx, uint8_t offset, - uint8_t scale, uint8_t len) + struct rgb_s scale, uint8_t len) { /* is31fl3733b not support scale function */ return EC_SUCCESS; diff --git a/driver/led/is31fl3743b.c b/driver/led/is31fl3743b.c index df333f2c8e..a07b2f63f8 100644 --- a/driver/led/is31fl3743b.c +++ b/driver/led/is31fl3743b.c @@ -106,31 +106,37 @@ static int is31fl3743b_set_color(struct rgbkbd *ctx, uint8_t offset, msg->addr = frame_offset + 1; /* Register addr base is 1. */ for (i = 0; i < len; i++) { - msg->payload[i * SIZE_OF_RGB +0] = color[i].r; - msg->payload[i * SIZE_OF_RGB +1] = color[i].g; - msg->payload[i * SIZE_OF_RGB +2] = color[i].b; + msg->payload[i * SIZE_OF_RGB + 0] = color[i].r; + msg->payload[i * SIZE_OF_RGB + 1] = color[i].g; + msg->payload[i * SIZE_OF_RGB + 2] = color[i].b; } return spi_transaction(SPI(ctx->cfg->spi), buf, frame_len, NULL, 0); } static int is31fl3743b_set_scale(struct rgbkbd *ctx, uint8_t offset, - uint8_t scale, uint8_t len) + struct rgb_s scale, uint8_t len) { uint8_t buf[sizeof(struct is31fl3743b_msg) + IS31FL3743B_BUF_SIZE]; struct is31fl3743b_msg *msg = (void *)buf; const int frame_len = len * SIZE_OF_RGB + sizeof(*msg); + const int frame_offset = offset * SIZE_OF_RGB; + int i; msg->cmd.read = 0; msg->cmd.id = IS31FL3743B_CMD_ID; msg->cmd.page = IS31FL3743B_PAGE_SCALE; - if (offset + frame_len > sizeof(buf)) { + if (frame_offset + frame_len > sizeof(buf)) { return EC_ERROR_OVERFLOW; } - msg->addr = offset + 1; /* Address base is 1. */ - memset(msg->payload, scale, len * SIZE_OF_RGB); + msg->addr = frame_offset + 1; /* Address base is 1. */ + for (i = 0; i < len; i++) { + msg->payload[i * SIZE_OF_RGB + 0] = scale.r; + msg->payload[i * SIZE_OF_RGB + 1] = scale.g; + msg->payload[i * SIZE_OF_RGB + 2] = scale.b; + } return spi_transaction(SPI(ctx->cfg->spi), buf, frame_len, NULL, 0); } diff --git a/include/ec_commands.h b/include/ec_commands.h index a23785c260..d86063ba27 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -7139,6 +7139,7 @@ struct ec_response_i2c_control { #define EC_RGBKBD_MAX_KEY_COUNT 128 #define EC_RGBKBD_MAX_RGB_COLOR 0xFFFFFF +#define EC_RGBKBD_MAX_SCALE 0xFF enum rgbkbd_state { /* RGB keyboard is reset and not initialized. */ @@ -7157,6 +7158,7 @@ enum rgbkbd_state { enum ec_rgbkbd_subcmd { EC_RGBKBD_SUBCMD_CLEAR = 1, EC_RGBKBD_SUBCMD_DEMO = 2, + EC_RGBKBD_SUBCMD_SET_SCALE = 3, EC_RGBKBD_SUBCMD_COUNT }; @@ -7169,11 +7171,17 @@ enum ec_rgbkbd_demo { BUILD_ASSERT(EC_RGBKBD_DEMO_COUNT <= 255); +struct ec_rgbkbd_set_scale { + uint8_t key; + struct rgb_s scale; +}; + struct ec_params_rgbkbd { uint8_t subcmd; /* Sub-command (enum ec_rgbkbd_subcmd) */ union { struct rgb_s color; /* EC_RGBKBD_SUBCMD_CLEAR */ uint8_t demo; /* EC_RGBKBD_SUBCMD_DEMO */ + struct ec_rgbkbd_set_scale set_scale; }; } __ec_align1; diff --git a/include/rgb_keyboard.h b/include/rgb_keyboard.h index 3b781a8b95..e795389225 100644 --- a/include/rgb_keyboard.h +++ b/include/rgb_keyboard.h @@ -15,6 +15,8 @@ #define RGBKBD_MAX_GCC_LEVEL 0xff #define RGBKBD_MAX_SCALE 0xff +#define RGBKBD_CTX_TO_GRID(ctx) ((ctx) - &rgbkbds[0]) + struct rgbkbd_cfg { /* Driver for LED IC */ const struct rgbkbd_drv * const drv; @@ -32,18 +34,23 @@ struct rgbkbd_init { /* Global current control */ const uint8_t gcc; /* LED brightness */ - const uint8_t scale; + const struct rgb_s scale; /* Color */ const struct rgb_s color; }; -extern const struct rgbkbd_init rgbkbd_default; +/** + * Register init settings. + * + * Must be called before rgbkbd_drv->init() is called. + * + * @param setting + */ +void rgbkbd_register_init_setting(const struct rgbkbd_init *setting); struct rgbkbd { /* Static configuration */ const struct rgbkbd_cfg * const cfg; - /* Start-up settings */ - const struct rgbkbd_init * const init; /* Current state of the port */ enum rgbkbd_state state; /* Buffer containing color info for each dot. */ @@ -79,7 +86,7 @@ struct rgbkbd_drv { * @return enum ec_error_list */ int (*set_scale)(struct rgbkbd *ctx, uint8_t offset, - uint8_t scale, uint8_t len); + struct rgb_s scale, uint8_t len); /** * Set global current control. * diff --git a/test/rgb_keyboard.c b/test/rgb_keyboard.c index aff374bf33..a8da437f7c 100644 --- a/test/rgb_keyboard.c +++ b/test/rgb_keyboard.c @@ -35,7 +35,6 @@ struct rgbkbd rgbkbds[] = { .col_len = RGB_GRID0_COL, .row_len = RGB_GRID0_ROW, }, - .init = &rgbkbd_default, .buf = grid0, }, [1] = { @@ -45,7 +44,6 @@ struct rgbkbd rgbkbds[] = { .col_len = RGB_GRID1_COL, .row_len = RGB_GRID1_ROW, }, - .init = &rgbkbd_default, .buf = grid1, }, }; @@ -110,7 +108,7 @@ static int test_drv_set_color(struct rgbkbd *ctx, uint8_t offset, static int test_drv_set_scale(struct rgbkbd *ctx, uint8_t offset, - uint8_t scale, uint8_t len) + struct rgb_s scale, uint8_t len) { mock_state.count_drv_set_scale++; return EC_SUCCESS; @@ -224,8 +222,8 @@ static int test_rgbkbd_console_command(void) uint8_t offset; char *argv_demo[] = {"rgbk", "demo", "0"}; char *argv_gcc[] = {"rgbk", "100"}; - char *argv_color[] = {"rgbk", buf, "1", "2", "3"}; - char *argv_all[] = {"rgbk", "all", "1", "2", "3"}; + char *argv_color[] = {"rgbk", buf, "0x010203"}; + char *argv_all[] = {"rgbk", "all", "0x010203"}; /* Test 'rgbk demo 0'. */ before_test(); @@ -251,7 +249,7 @@ static int test_rgbkbd_console_command(void) sprintf(buf, "%d,%d", x, y); argc = ARRAY_SIZE(argv_color); zassert_equal(cc_rgb(argc, argv_color), EC_SUCCESS, - "rgbk %s 1 2 3", buf); + "rgbk %s 0x010203", buf); zassert_equal(ctx->buf[offset].r, 1, "R = 1"); zassert_equal(ctx->buf[offset].g, 2, "G = 2"); zassert_equal(ctx->buf[offset].b, 3, "B = 3"); diff --git a/util/ectool.c b/util/ectool.c index 28a141d65c..028828ebd5 100644 --- a/util/ectool.c +++ b/util/ectool.c @@ -1302,8 +1302,13 @@ static void cmd_rgbkbd_help(char *cmd) "\n" " Usage3: %s demo <num>\n" " Run demo-<num>. 0: Off, 1: Flow, 2: Dot.\n" + "\n" + " Usage4: %s scale <key> <val>\n" + " Set the scale parameter of key_<key> to <val>.\n" + " <val> is a 24-bit integer where scale values are encoded\n" + " as R=23:16, G=15:8, B=7:0.\n" "\n", - cmd, cmd, cmd); + cmd, cmd, cmd, cmd); } static int cmd_rgbkbd_parse_rgb_text(const char *text, struct rgb_s *color) @@ -1395,6 +1400,22 @@ static int cmd_rgbkbd(int argc, char *argv[]) p.subcmd = EC_RGBKBD_SUBCMD_DEMO; p.demo = val; rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), NULL, 0); + } else if (argc == 4 && !strcasecmp(argv[1], "scale")) { + /* Usage 4 */ + struct ec_params_rgbkbd p; + + val = strtol(argv[2], &e, 0); + if ((e && *e) || val > EC_RGBKBD_MAX_KEY_COUNT) { + fprintf(stderr, "Invalid key number: %s\n", argv[2]); + return -1; + } + p.set_scale.key = val; + if (cmd_rgbkbd_parse_rgb_text(argv[3], &p.set_scale.scale)) { + fprintf(stderr, "Invalid scale value: %s\n", argv[3]); + return -1; + } + p.subcmd = EC_RGBKBD_SUBCMD_SET_SCALE; + rv = ec_command(EC_CMD_RGBKBD, 0, &p, sizeof(p), NULL, 0); } else { /* Usage 1 */ rv = cmd_rgbkbd_set_color(argc, argv); |