[U-Boot] [PATCH 0/4] Keyboard input improvements

This is a small series of patches to improve keyboard input for matrix keyboards:
- Fix an fdt decoding bug which breaks seaboard - Permit key repeat/delay to be altered after init - Allow key ghosting filter to be enabled/disabled - Add a bit more debugging
Since this series mostly affects tegra I suggest that it goes through the tegra tree.
Simon Glass (4): input: Correct key_matrix fdt decoding input: Separate out keyboard repeat/delay from init input: Allow key ghosting filter to be disabled input: Add debugging for key matrix key codes
drivers/input/input.c | 13 +++++++++---- drivers/input/key_matrix.c | 22 ++++++++++++++++------ drivers/input/tegra-kbc.c | 7 ++++--- include/input.h | 14 ++++++++++---- include/key_matrix.h | 5 ++++- 5 files changed, 43 insertions(+), 18 deletions(-)

Some issues with this were not addressed in the previous series. Fix up the binding decoding to deal with what is actually expected in the fdt.
This corrects the broken keyboard on seaboard.
Signed-off-by: Simon Glass sjg@chromium.org --- drivers/input/key_matrix.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c index 715e57a..c08caa6 100644 --- a/drivers/input/key_matrix.c +++ b/drivers/input/key_matrix.c @@ -153,6 +153,8 @@ int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, int node) { const struct fdt_property *prop; + const char prefix[] = "linux,"; + int plen = sizeof(prefix) - 1; int offset;
/* Check each property name for ones that we understand */ @@ -168,16 +170,17 @@ int key_matrix_decode_fdt(struct key_matrix *config, const void *blob,
/* Name needs to match "1,<type>keymap" */ debug("%s: property '%s'\n", __func__, name); - if (strncmp(name, "1,", 2) || len < 8 || - strcmp(name + len - 6, "keymap")) + if (strncmp(name, prefix, plen) || + len < plen + 6 || + strcmp(name + len - 6, "keymap")) continue;
- len -= 8; + len -= plen + 6; if (len == 0) { config->plain_keycode = create_keymap(config, (u32 *)prop->data, fdt32_to_cpu(prop->len), KEY_FN, &config->fn_pos); - } else if (0 == strncmp(name + 2, "fn-", len)) { + } else if (0 == strncmp(name + plen, "fn-", len)) { config->fn_keycode = create_keymap(config, (u32 *)prop->data, fdt32_to_cpu(prop->len), -1, NULL);

It is inconvenient to have to specify the keyboard repeat and delay at init time if it is not yet available, so move this into a separate function.
Some drivers will want to do this when their keyboard init routine is actually called.
Signed-off-by: Simon Glass sjg@chromium.org --- drivers/input/input.c | 13 +++++++++---- drivers/input/tegra-kbc.c | 5 +++-- include/input.h | 14 ++++++++++---- 3 files changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c index 4eadd77..5b2b4b0 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -356,7 +356,8 @@ int input_send_keycodes(struct input_config *config, * insert another character if we later realise that we * have missed a repeat slot. */ - is_repeat = (int)get_timer(config->next_repeat_ms) >= 0; + is_repeat = config->repeat_rate_ms && + (int)get_timer(config->next_repeat_ms) >= 0; if (!is_repeat) return 0; } @@ -392,13 +393,17 @@ int input_add_table(struct input_config *config, int left_keycode, return 0; }
-int input_init(struct input_config *config, int leds, int repeat_delay_ms, +void input_set_delays(struct input_config *config, int repeat_delay_ms, int repeat_rate_ms) { - memset(config, '\0', sizeof(*config)); - config->leds = leds; config->repeat_delay_ms = repeat_delay_ms; config->repeat_rate_ms = repeat_rate_ms; +} + +int input_init(struct input_config *config, int leds) +{ + memset(config, '\0', sizeof(*config)); + config->leds = leds; if (input_add_table(config, -1, -1, kbd_plain_xlate, ARRAY_SIZE(kbd_plain_xlate)) || input_add_table(config, KEY_LEFTSHIFT, KEY_RIGHTSHIFT, diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c index f164791..9a30942 100644 --- a/drivers/input/tegra-kbc.c +++ b/drivers/input/tegra-kbc.c @@ -321,6 +321,8 @@ static int init_tegra_keyboard(void) debug("%s: No keyboard register found\n", __func__); return -1; } + input_set_delays(&config.input, KBC_REPEAT_DELAY_MS, + KBC_REPEAT_RATE_MS);
/* Decode the keyboard matrix information (16 rows, 8 columns) */ if (key_matrix_init(&config.matrix, 16, 8)) { @@ -356,8 +358,7 @@ int drv_keyboard_init(void) { struct stdio_dev dev;
- if (input_init(&config.input, 0, KBC_REPEAT_DELAY_MS, - KBC_REPEAT_RATE_MS)) { + if (input_init(&config.input, 0)) { debug("%s: Cannot set up input\n", __func__); return -1; } diff --git a/include/input.h b/include/input.h index 31b1ef9..0f4acb2 100644 --- a/include/input.h +++ b/include/input.h @@ -126,16 +126,22 @@ int input_getc(struct input_config *config); int input_stdio_register(struct stdio_dev *dev);
/** + * Set up the keyboard autorepeat delays + * + * @param repeat_delay_ms Delay before key auto-repeat starts (in ms) + * @param repeat_rate_ms Delay between successive key repeats (in ms) + */ +void input_set_delays(struct input_config *config, int repeat_delay_ms, + int repeat_rate_ms); + +/** * Set up the input handler with basic key maps. * * @param config Input state * @param leds Initial LED value (INPUT_LED_ mask), 0 suggested - * @param repeat_delay_ms Delay before key auto-repeat starts (in ms) - * @param repeat_rate_ms Delay between successive key repeats (in ms) * @return 0 if ok, -1 on error */ -int input_init(struct input_config *config, int leds, int repeat_delay_ms, - int repeat_rate_ms); +int input_init(struct input_config *config, int leds);
#ifdef CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE extern int overwrite_console(void);

Some keyboards will not need a key ghosting filter, so make this feature optional.
Signed-off-by: Simon Glass sjg@chromium.org --- drivers/input/key_matrix.c | 9 +++++++-- drivers/input/tegra-kbc.c | 2 +- include/key_matrix.h | 5 ++++- 3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c index c08caa6..287bf0d 100644 --- a/drivers/input/key_matrix.c +++ b/drivers/input/key_matrix.c @@ -46,6 +46,9 @@ static int has_ghosting(struct key_matrix *config, struct key_matrix_key *keys, int key_in_same_col = 0, key_in_same_row = 0; int i, j;
+ if (!config->ghost_filter || valid < 3) + return 0; + for (i = 0; i < valid; i++) { /* * Find 2 keys such that one key is in the same row @@ -92,7 +95,7 @@ int key_matrix_decode(struct key_matrix *config, struct key_matrix_key keys[], }
/* For a ghost key config, ignore the keypresses for this iteration. */ - if (valid >= 3 && has_ghosting(config, keys, valid)) { + if (has_ghosting(config, keys, valid)) { valid = 0; debug(" ghosting detected!\n"); } @@ -200,12 +203,14 @@ int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, return 0; }
-int key_matrix_init(struct key_matrix *config, int rows, int cols) +int key_matrix_init(struct key_matrix *config, int rows, int cols, + int ghost_filter) { memset(config, '\0', sizeof(*config)); config->num_rows = rows; config->num_cols = cols; config->key_count = rows * cols; + config->ghost_filter = ghost_filter; assert(config->key_count > 0);
return 0; diff --git a/drivers/input/tegra-kbc.c b/drivers/input/tegra-kbc.c index 9a30942..6f1cfd8 100644 --- a/drivers/input/tegra-kbc.c +++ b/drivers/input/tegra-kbc.c @@ -325,7 +325,7 @@ static int init_tegra_keyboard(void) KBC_REPEAT_RATE_MS);
/* Decode the keyboard matrix information (16 rows, 8 columns) */ - if (key_matrix_init(&config.matrix, 16, 8)) { + if (key_matrix_init(&config.matrix, 16, 8, 1)) { debug("%s: Could not init key matrix\n", __func__); return -1; } diff --git a/include/key_matrix.h b/include/key_matrix.h index f413314..9629716 100644 --- a/include/key_matrix.h +++ b/include/key_matrix.h @@ -40,6 +40,7 @@ struct key_matrix { const u8 *plain_keycode; /* key code for each row / column */ const u8 *fn_keycode; /* ...when Fn held down */ int fn_pos; /* position of Fn key in key (or -1) */ + int ghost_filter; /* non-zero to enable ghost filter */ };
/* Information about a particular key (row, column pair) in the matrix */ @@ -92,8 +93,10 @@ int key_matrix_decode_fdt(struct key_matrix *config, const void *blob, * @param config Keyboard matrix config * @param rows Number of rows in key matrix * @param cols Number of columns in key matrix + * @param ghost_filter Non-zero to enable ghost filtering * @return 0 if ok, -1 on error */ -int key_matrix_init(struct key_matrix *config, int rows, int cols); +int key_matrix_init(struct key_matrix *config, int rows, int cols, + int ghost_filter);
#endif

These are read from the fdt - add a debug feature to display the mapping on start-up.
See that we get debug output listing the keycodes
Signed-off-by: Simon Glass sjg@chromium.org --- drivers/input/key_matrix.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/input/key_matrix.c b/drivers/input/key_matrix.c index 287bf0d..946a186 100644 --- a/drivers/input/key_matrix.c +++ b/drivers/input/key_matrix.c @@ -145,6 +145,8 @@ static uchar *create_keymap(struct key_matrix *config, u32 *data, int len, key_code = tmp & 0xffff; entry = row * config->num_cols + col; map[entry] = key_code; + debug(" map %d, %d: pos=%d, keycode=%d\n", row, col, + entry, key_code); if (pos && map_keycode == key_code) *pos = entry; }

On Thu, Sep 27, 2012 at 06:18:39PM -0700, Simon Glass wrote:
This is a small series of patches to improve keyboard input for matrix keyboards:
- Fix an fdt decoding bug which breaks seaboard
- Permit key repeat/delay to be altered after init
- Allow key ghosting filter to be enabled/disabled
- Add a bit more debugging
Since this series mostly affects tegra I suggest that it goes through the tegra tree.
Simon Glass (4): input: Correct key_matrix fdt decoding input: Separate out keyboard repeat/delay from init input: Allow key ghosting filter to be disabled input: Add debugging for key matrix key codes
drivers/input/input.c | 13 +++++++++---- drivers/input/key_matrix.c | 22 ++++++++++++++++------ drivers/input/tegra-kbc.c | 7 ++++--- include/input.h | 14 ++++++++++---- include/key_matrix.h | 5 ++++- 5 files changed, 43 insertions(+), 18 deletions(-)
Things look fine to me and if you want I'd be OK with this going into u-boot/next, assuming it applies there cleanly.

Hi Tom
On Mon, Oct 1, 2012 at 10:21 AM, Tom Rini trini@ti.com wrote:
On Thu, Sep 27, 2012 at 06:18:39PM -0700, Simon Glass wrote:
This is a small series of patches to improve keyboard input for matrix keyboards:
- Fix an fdt decoding bug which breaks seaboard
- Permit key repeat/delay to be altered after init
- Allow key ghosting filter to be enabled/disabled
- Add a bit more debugging
Since this series mostly affects tegra I suggest that it goes through the tegra tree.
Simon Glass (4): input: Correct key_matrix fdt decoding input: Separate out keyboard repeat/delay from init input: Allow key ghosting filter to be disabled input: Add debugging for key matrix key codes
drivers/input/input.c | 13 +++++++++---- drivers/input/key_matrix.c | 22 ++++++++++++++++------ drivers/input/tegra-kbc.c | 7 ++++--- include/input.h | 14 ++++++++++---- include/key_matrix.h | 5 ++++- 5 files changed, 43 insertions(+), 18 deletions(-)
Things look fine to me and if you want I'd be OK with this going into u-boot/next, assuming it applies there cleanly.
That's fine with me, thanks.
FYI my intent one day is to update keyboard.c and others to use the input layer.
Regards, Simon
-- Tom

On Thu, Sep 27, 2012 at 06:18:39PM -0700, Simon Glass wrote:
This is a small series of patches to improve keyboard input for matrix keyboards:
- Fix an fdt decoding bug which breaks seaboard
- Permit key repeat/delay to be altered after init
- Allow key ghosting filter to be enabled/disabled
- Add a bit more debugging
Since this series mostly affects tegra I suggest that it goes through the tegra tree.
Simon Glass (4): input: Correct key_matrix fdt decoding input: Separate out keyboard repeat/delay from init input: Allow key ghosting filter to be disabled input: Add debugging for key matrix key codes
drivers/input/input.c | 13 +++++++++---- drivers/input/key_matrix.c | 22 ++++++++++++++++------ drivers/input/tegra-kbc.c | 7 ++++--- include/input.h | 14 ++++++++++---- include/key_matrix.h | 5 ++++- 5 files changed, 43 insertions(+), 18 deletions(-)
Applied to u-boot/next, thanks!
participants (2)
-
Simon Glass
-
Tom Rini