summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2015-10-18 21:17:24 -0600
committerSimon Glass <sjg@chromium.org>2015-11-19 20:13:40 -0700
commit3a85e4362aa830c0beb2b0253c0e70102b42f066 (patch)
tree6d4d0c459f99c7aec495048687018089aec94bc2
parent77c7f0459f1f8e6de004ca1d03a81df1a9792d70 (diff)
downloadblackbird-obmc-uboot-3a85e4362aa830c0beb2b0253c0e70102b42f066.tar.gz
blackbird-obmc-uboot-3a85e4362aa830c0beb2b0253c0e70102b42f066.zip
input: Add a function to add a keycode to the existing set
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 a 'break' code is sent. This means that the driver needs to 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 <sjg@chromium.org> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
-rw-r--r--drivers/input/input.c46
-rw-r--r--include/input.h20
2 files changed, 62 insertions, 4 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index e65942ec58..530bf5148b 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 71f3538db5..9942d6f77d 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
OpenPOWER on IntegriCloud