Input: atkbd - receive and use physcode->keycode mapping from FW
Allow the firmware to specify the mapping between the scan code and the linux keycode. This takes the form of a "linux,keymap" property which is an array of u32 values, each value specifying mapping for a key. Signed-off-by: Rajat Jain <rajatja@google.com> Link: https://lore.kernel.org/r/20200427210259.91330-3-rajatja@google.com Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
Родитель
8f7b057abe
Коммит
9d17ad2369
|
@ -66,6 +66,9 @@ MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard conne
|
|||
|
||||
#define MAX_FUNCTION_ROW_KEYS 24
|
||||
|
||||
#define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF)
|
||||
#define KEYCODE(keymap) (keymap & 0xFFFF)
|
||||
|
||||
/*
|
||||
* Scancode to keycode tables. These are just the default setting, and
|
||||
* are loadable via a userland utility.
|
||||
|
@ -1032,6 +1035,39 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
|
|||
return code;
|
||||
}
|
||||
|
||||
static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd)
|
||||
{
|
||||
struct device *dev = &atkbd->ps2dev.serio->dev;
|
||||
int i, n;
|
||||
u32 *ptr;
|
||||
u16 scancode, keycode;
|
||||
|
||||
/* Parse "linux,keymap" property */
|
||||
n = device_property_count_u32(dev, "linux,keymap");
|
||||
if (n <= 0 || n > ATKBD_KEYMAP_SIZE)
|
||||
return -ENXIO;
|
||||
|
||||
ptr = kcalloc(n, sizeof(u32), GFP_KERNEL);
|
||||
if (!ptr)
|
||||
return -ENOMEM;
|
||||
|
||||
if (device_property_read_u32_array(dev, "linux,keymap", ptr, n)) {
|
||||
dev_err(dev, "problem parsing FW keymap property\n");
|
||||
kfree(ptr);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
|
||||
for (i = 0; i < n; i++) {
|
||||
scancode = SCANCODE(ptr[i]);
|
||||
keycode = KEYCODE(ptr[i]);
|
||||
atkbd->keycode[scancode] = keycode;
|
||||
}
|
||||
|
||||
kfree(ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* atkbd_set_keycode_table() initializes keyboard's keycode table
|
||||
* according to the selected scancode set
|
||||
|
@ -1039,13 +1075,16 @@ static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd,
|
|||
|
||||
static void atkbd_set_keycode_table(struct atkbd *atkbd)
|
||||
{
|
||||
struct device *dev = &atkbd->ps2dev.serio->dev;
|
||||
unsigned int scancode;
|
||||
int i, j;
|
||||
|
||||
memset(atkbd->keycode, 0, sizeof(atkbd->keycode));
|
||||
bitmap_zero(atkbd->force_release_mask, ATKBD_KEYMAP_SIZE);
|
||||
|
||||
if (atkbd->translated) {
|
||||
if (!atkbd_get_keymap_from_fwnode(atkbd)) {
|
||||
dev_dbg(dev, "Using FW keymap\n");
|
||||
} else if (atkbd->translated) {
|
||||
for (i = 0; i < 128; i++) {
|
||||
scancode = atkbd_unxlate_table[i];
|
||||
atkbd->keycode[i] = atkbd_set2_keycode[scancode];
|
||||
|
|
Загрузка…
Ссылка в новой задаче