diff options
Diffstat (limited to 'common/rgb_keyboard.c')
-rw-r--r-- | common/rgb_keyboard.c | 268 |
1 files changed, 165 insertions, 103 deletions
diff --git a/common/rgb_keyboard.c b/common/rgb_keyboard.c index e77939ff9e..815e4a3435 100644 --- a/common/rgb_keyboard.c +++ b/common/rgb_keyboard.c @@ -23,15 +23,14 @@ #define CPRINTF(fmt, args...) cprintf(CC_RGBKBD, "RGBKBD: " fmt, ##args) #define CPRINTS(fmt, args...) cprints(CC_RGBKBD, "RGBKBD: " fmt, ##args) -test_export_static enum rgbkbd_demo demo = +test_export_static enum ec_rgbkbd_demo demo = #if defined(CONFIG_RGBKBD_DEMO_FLOW) - RGBKBD_DEMO_FLOW + EC_RGBKBD_DEMO_FLOW; #elif defined(CONFIG_RGBKBD_DEMO_DOT) - RGBKBD_DEMO_DOT + EC_RGBKBD_DEMO_DOT; #else - RGBKBD_DEMO_OFF + EC_RGBKBD_DEMO_OFF; #endif - ; const int default_demo_interval_ms = 250; test_export_static int demo_interval_ms = -1; @@ -41,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; @@ -183,16 +199,16 @@ static void rgbkbd_demo_dot(void) #endif } -static void rgbkbd_demo_run(enum rgbkbd_demo id) +static void rgbkbd_demo_run(enum ec_rgbkbd_demo id) { switch (id) { - case RGBKBD_DEMO_FLOW: + case EC_RGBKBD_DEMO_FLOW: rgbkbd_demo_flow(); break; - case RGBKBD_DEMO_DOT: + case EC_RGBKBD_DEMO_DOT: rgbkbd_demo_dot(); break; - case RGBKBD_DEMO_OFF: + case EC_RGBKBD_DEMO_OFF: default: break; } @@ -264,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; @@ -273,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; } } @@ -282,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; @@ -289,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) { @@ -299,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)", @@ -315,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; @@ -383,7 +431,7 @@ static int rgbkbd_enable(int enable) return rv; } -static void rgbkbd_demo_set(enum rgbkbd_demo new_demo) +static void rgbkbd_demo_set(enum ec_rgbkbd_demo new_demo) { CPRINTS("Setting demo %d with %d ms interval", demo, demo_interval_ms); @@ -394,7 +442,7 @@ static void rgbkbd_demo_set(enum rgbkbd_demo new_demo) rgbkbd_init(); rgbkbd_enable(1); - if (demo == RGBKBD_DEMO_OFF) + if (demo == EC_RGBKBD_DEMO_OFF) return; demo_interval_ms = default_demo_interval_ms; @@ -484,7 +532,7 @@ DECLARE_HOST_COMMAND(EC_CMD_RGBKBD_SET_COLOR, hc_rgbkbd_set_color, static enum ec_status hc_rgbkbd(struct host_cmd_handler_args *args) { const struct ec_params_rgbkbd *p = args->params; - enum ec_status rv = EC_RES_ERROR; + enum ec_status rv = EC_RES_SUCCESS; if (rgbkbd_late_init()) return EC_RES_ERROR; @@ -492,7 +540,15 @@ static enum ec_status hc_rgbkbd(struct host_cmd_handler_args *args) switch (p->subcmd) { case EC_RGBKBD_SUBCMD_CLEAR: rgbkbd_reset_color(p->color); - rv = EC_RES_SUCCESS; + break; + case EC_RGBKBD_SUBCMD_DEMO: + if (p->demo >= EC_RGBKBD_DEMO_COUNT) + 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; @@ -503,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; @@ -525,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 >= RGBKBD_DEMO_COUNT) + 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) @@ -565,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(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; @@ -612,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 |