Hi Simon, On Mon, Oct 19, 2015 at 11:17 AM, Simon Glass <s...@chromium.org> wrote: > Most keyboards can be scanned to produce a list of the keycodes which are > depressed. With the i8042 keyboard this scanning is done internally and > only the processed results are returned. > > In this case, when a key is pressed, a 'make' code is sent. When the key > is released an 'unmake' code is sent. This means that the driver needs to
nits: 'unmake' -> 'break' > keep track of which keys are pressed. It also means that any protocol error > can lead to stuck keys. > > In order to support this type of keyboard, add a function when can be used > to provide a single keycode and either add it to the list of what is pressed > or remove it from the list. Then the normal input_send_keycodes() function > can be used to actually do the decoding work. > > Add debugging to display the ASCII characters written to the input queue > also. > > Signed-off-by: Simon Glass <s...@chromium.org> > --- Reviewed-by: Bin Meng <bmeng...@gmail.com> > > Changes in v2: None > > drivers/input/input.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- > include/input.h | 20 ++++++++++++++++++++ > 2 files changed, 62 insertions(+), 4 deletions(-) > > diff --git a/drivers/input/input.c b/drivers/input/input.c > index e65942e..530bf51 100644 > --- a/drivers/input/input.c > +++ b/drivers/input/input.c > @@ -107,6 +107,7 @@ static int input_queue_ascii(struct input_config *config, > int ch) > return -1; /* buffer full */ > config->fifo_in++; > } > + debug(" {%02x} ", ch); > config->fifo[config->fifo_in] = (uchar)ch; > > return 0; > @@ -394,8 +395,8 @@ static int input_keycodes_to_ascii(struct input_config > *config, > return ch_count; > } > > -int input_send_keycodes(struct input_config *config, > - int keycode[], int num_keycodes) > +static int _input_send_keycodes(struct input_config *config, int keycode[], > + int num_keycodes, bool do_send) > { > char ch[num_keycodes * ANSI_CHAR_MAX]; > int count, i, same = 0; > @@ -420,8 +421,10 @@ int input_send_keycodes(struct input_config *config, > > count = input_keycodes_to_ascii(config, keycode, num_keycodes, > ch, sizeof(ch), is_repeat ? 0 : same); > - for (i = 0; i < count; i++) > - input_queue_ascii(config, ch[i]); > + if (do_send) { > + for (i = 0; i < count; i++) > + input_queue_ascii(config, ch[i]); > + } > delay_ms = is_repeat ? > config->repeat_rate_ms : > config->repeat_delay_ms; > @@ -431,6 +434,41 @@ int input_send_keycodes(struct input_config *config, > return count; > } > > +int input_send_keycodes(struct input_config *config, int keycode[], > + int num_keycodes) > +{ > + return _input_send_keycodes(config, keycode, num_keycodes, true); > +} > + > +int input_add_keycode(struct input_config *config, int new_keycode, > + bool release) > +{ > + int keycode[INPUT_MAX_MODIFIERS + 1]; > + int count, i; > + > + /* Add the old keycodes which are not removed by this new one */ > + for (i = 0, count = 0; i < config->num_prev_keycodes; i++) { > + int code = config->prev_keycodes[i]; > + > + if (new_keycode == code) { > + if (release) > + continue; > + new_keycode = -1; > + } > + keycode[count++] = code; > + } > + > + if (!release && new_keycode != -1) > + keycode[count++] = new_keycode; > + debug("\ncodes for %02x/%d: ", new_keycode, release); > + for (i = 0; i < count; i++) > + debug("%02x ", keycode[i]); > + debug("\n"); > + > + /* Don't output any ASCII characters if this is a key release */ > + return _input_send_keycodes(config, keycode, count, !release); > +} > + > int input_add_table(struct input_config *config, int left_keycode, > int right_keycode, const uchar *xlate, int num_entries) > { > diff --git a/include/input.h b/include/input.h > index 71f3538..9942d6f 100644 > --- a/include/input.h > +++ b/include/input.h > @@ -76,6 +76,26 @@ struct stdio_dev; > int input_send_keycodes(struct input_config *config, int keycode[], int > count); > > /** > + * Add a new keycode to an existing list of keycodes > + * > + * This can be used to handle keyboards which do their own scanning. An > + * internal list of depressed keys is maintained by the input library. Then > + * this function is called to add a new key to the list (when a 'make code' > is > + * received), or remove a key (when a 'break code' is received). > + * > + * This function looks after maintenance of the list of active keys, and > calls > + * input_send_keycodes() with its updated list. > + * > + * @param config Input state > + * @param new_keycode New keycode to add/remove > + * @param release true if this key was released, false if depressed > + * @return number of ascii characters sent, or 0 if none, or -1 for an > + * internal error > + */ > +int input_add_keycode(struct input_config *config, int new_keycode, > + bool release); > + > +/** > * Add a new key translation table to the input > * > * @param config Input state > -- Regards, Bin _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot