1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 #include <acpi/acpigen.h>
4 #include <acpi/acpigen_ps2_keybd.h>
5 #include <console/console.h>
6 #include <input-event-codes.h>
10 #define KEYMAP(scancode, keycode) (((uint32_t)(scancode) << 16) | (keycode & 0xFFFF))
11 #define SCANCODE(keymap) ((keymap >> 16) & 0xFFFF)
13 /* Possible keymaps for function keys in the top row */
14 static const uint32_t function_keymaps
[] = {
24 KEYMAP(0x44, KEY_F10
),
25 KEYMAP(0x57, KEY_F11
),
26 KEYMAP(0x58, KEY_F12
),
27 KEYMAP(0x59, KEY_F13
),
28 KEYMAP(0x5a, KEY_F14
),
29 KEYMAP(0x5b, KEY_F15
),
33 * Possible keymaps for action keys in the top row. This is a superset of
34 * possible keys. Individual keyboards will have a subset of these keys.
35 * The scancodes are true / condensed 1 byte scancodes from set-1
37 static const uint32_t action_keymaps
[] = {
38 [PS2_KEY_BACK
] = KEYMAP(0xea, KEY_BACK
), /* e06a */
39 [PS2_KEY_FORWARD
] = KEYMAP(0xe9, KEY_FORWARD
), /* e069 */
40 [PS2_KEY_REFRESH
] = KEYMAP(0xe7, KEY_REFRESH
), /* e067 */
41 [PS2_KEY_FULLSCREEN
] = KEYMAP(0x91, KEY_FULL_SCREEN
), /* e011 */
42 [PS2_KEY_OVERVIEW
] = KEYMAP(0x92, KEY_SCALE
), /* e012 */
43 [PS2_KEY_VOL_MUTE
] = KEYMAP(0xa0, KEY_MUTE
), /* e020 */
44 [PS2_KEY_VOL_DOWN
] = KEYMAP(0xae, KEY_VOLUMEDOWN
), /* e02e */
45 [PS2_KEY_VOL_UP
] = KEYMAP(0xb0, KEY_VOLUMEUP
), /* e030 */
46 [PS2_KEY_PLAY_PAUSE
] = KEYMAP(0x9a, KEY_PLAYPAUSE
), /* e01a */
47 [PS2_KEY_NEXT_TRACK
] = KEYMAP(0x99, KEY_NEXTSONG
), /* e019 */
48 [PS2_KEY_PREV_TRACK
] = KEYMAP(0x90, KEY_PREVIOUSSONG
), /* e010 */
49 [PS2_KEY_SNAPSHOT
] = KEYMAP(0x93, KEY_SYSRQ
), /* e013 */
50 [PS2_KEY_BRIGHTNESS_DOWN
] = KEYMAP(0x94, KEY_BRIGHTNESSDOWN
), /* e014 */
51 [PS2_KEY_BRIGHTNESS_UP
] = KEYMAP(0x95, KEY_BRIGHTNESSUP
), /* e015 */
52 [PS2_KEY_KBD_BKLIGHT_DOWN
] = KEYMAP(0x97, KEY_KBDILLUMDOWN
), /* e017 */
53 [PS2_KEY_KBD_BKLIGHT_UP
] = KEYMAP(0x98, KEY_KBDILLUMUP
), /* e018 */
54 [PS2_KEY_PRIVACY_SCRN_TOGGLE
] = KEYMAP(0x96, /* e016 */
55 KEY_PRIVACY_SCREEN_TOGGLE
),
56 [PS2_KEY_MICMUTE
] = KEYMAP(0x9b, KEY_MICMUTE
), /* e01b */
57 [PS2_KEY_KBD_BKLIGHT_TOGGLE
] = KEYMAP(0x9e, KEY_KBDILLUMTOGGLE
), /* e01e */
58 [PS2_KEY_MENU
] = KEYMAP(0xdd, KEY_CONTROLPANEL
), /* e0d5 */
61 /* Keymap for numeric keypad keys */
62 static uint32_t numeric_keypad_keymaps
[] = {
64 KEYMAP(0xc9, KEY_PAGEUP
),
65 KEYMAP(0xd1, KEY_PAGEDOWN
),
66 KEYMAP(0xc7, KEY_HOME
),
67 KEYMAP(0xcf, KEY_END
),
69 KEYMAP(0xd3, KEY_DELETE
),
70 KEYMAP(0xb5, KEY_KPSLASH
),
71 KEYMAP(0x37, KEY_KPASTERISK
),
72 KEYMAP(0x4a, KEY_KPMINUS
),
74 KEYMAP(0x47, KEY_KP7
),
75 KEYMAP(0x48, KEY_KP8
),
76 KEYMAP(0x49, KEY_KP9
),
77 KEYMAP(0x4e, KEY_KPPLUS
),
79 KEYMAP(0x4b, KEY_KP4
),
80 KEYMAP(0x4c, KEY_KP5
),
81 KEYMAP(0x4d, KEY_KP6
),
83 KEYMAP(0x4f, KEY_KP1
),
84 KEYMAP(0x50, KEY_KP2
),
85 KEYMAP(0x51, KEY_KP3
),
86 KEYMAP(0x9c, KEY_KPENTER
),
88 KEYMAP(0x52, KEY_KP0
),
89 KEYMAP(0x53, KEY_KPDOT
),
93 * Keymap for rest of non-top-row keys. This is a superset of all the possible
94 * keys that any chromeos keyboards can have.
96 static uint32_t rest_of_keymaps
[] = {
98 KEYMAP(0x01, KEY_ESC
),
100 KEYMAP(0x29, KEY_GRAVE
),
111 KEYMAP(0x0c, KEY_MINUS
),
112 KEYMAP(0x0d, KEY_EQUAL
),
113 KEYMAP(0x7d, KEY_YEN
), /* JP keyboards only */
114 KEYMAP(0x0e, KEY_BACKSPACE
),
116 KEYMAP(0x0f, KEY_TAB
),
127 KEYMAP(0x1a, KEY_LEFTBRACE
),
128 KEYMAP(0x1b, KEY_RIGHTBRACE
),
129 KEYMAP(0x2b, KEY_BACKSLASH
),
131 KEYMAP(0xdb, KEY_LEFTMETA
), /* Search Key */
141 KEYMAP(0x27, KEY_SEMICOLON
),
142 KEYMAP(0x28, KEY_APOSTROPHE
),
143 KEYMAP(0x1c, KEY_ENTER
),
145 KEYMAP(0x2a, KEY_LEFTSHIFT
),
146 KEYMAP(0x56, KEY_102ND
), /* UK keyboards only */
154 KEYMAP(0x33, KEY_COMMA
),
155 KEYMAP(0x34, KEY_DOT
),
156 KEYMAP(0x35, KEY_SLASH
),
157 KEYMAP(0x73, KEY_RO
), /* JP keyboards only */
158 KEYMAP(0x36, KEY_RIGHTSHIFT
),
160 KEYMAP(0x1d, KEY_LEFTCTRL
),
161 KEYMAP(0x38, KEY_LEFTALT
),
162 KEYMAP(0x7b, KEY_MUHENKAN
), /* JP keyboards only */
163 KEYMAP(0x39, KEY_SPACE
),
164 KEYMAP(0x79, KEY_HENKAN
), /* JP keyboards only */
165 KEYMAP(0xb8, KEY_RIGHTALT
),
166 KEYMAP(0x9d, KEY_RIGHTCTRL
),
168 KEYMAP(0xcb, KEY_LEFT
),
169 KEYMAP(0xd0, KEY_DOWN
),
170 KEYMAP(0xcd, KEY_RIGHT
),
171 KEYMAP(0xc8, KEY_UP
),
173 KEYMAP(0xde, KEY_POWER
),
176 static void ssdt_generate_physmap(struct acpi_dp
*dp
, uint8_t num_top_row_keys
,
177 enum ps2_action_key action_keys
[])
179 struct acpi_dp
*dp_array
;
180 enum ps2_action_key key
;
183 dp_array
= acpi_dp_new_table("function-row-physmap");
185 printk(BIOS_ERR
, "PS2K: couldn't write function-row-physmap\n");
189 printk(BIOS_INFO
, "PS2K: Physmap: [");
190 for (i
= 0; i
< num_top_row_keys
; i
++) {
191 key
= action_keys
[i
];
192 if (key
&& key
< ARRAY_SIZE(action_keymaps
)) {
193 keymap
= action_keymaps
[key
];
197 "PS2K: invalid top-action-key-%u: %u(skipped)\n",
200 acpi_dp_add_integer(dp_array
, NULL
, SCANCODE(keymap
));
201 printk(BIOS_INFO
, " %X", SCANCODE(keymap
));
204 printk(BIOS_INFO
, " ]\n");
205 acpi_dp_add_array(dp
, dp_array
);
208 static void ssdt_generate_keymap(struct acpi_dp
*dp
, uint8_t num_top_row_keys
,
209 enum ps2_action_key action_keys
[],
210 bool can_send_function_keys
,
211 bool has_numeric_keypad
,
212 bool has_scrnlock_key
)
214 struct acpi_dp
*dp_array
;
215 enum ps2_action_key key
;
217 unsigned int i
, total
= 0;
219 dp_array
= acpi_dp_new_table("linux,keymap");
221 printk(BIOS_ERR
, "PS2K: couldn't write linux,keymap\n");
225 /* Write out keymap for top row action keys */
226 for (i
= 0; i
< num_top_row_keys
; i
++) {
227 key
= action_keys
[i
];
228 if (!key
|| key
>= ARRAY_SIZE(action_keymaps
)) {
230 "PS2K: invalid top-action-key-%u: %u\n", i
, key
);
233 keymap
= action_keymaps
[key
];
234 acpi_dp_add_integer(dp_array
, NULL
, keymap
);
238 /* Write out keymap for function keys, if keyboard can send them */
239 if (can_send_function_keys
) {
240 for (i
= 0; i
< num_top_row_keys
; i
++) {
241 keymap
= function_keymaps
[i
];
242 acpi_dp_add_integer(dp_array
, NULL
, keymap
);
245 total
+= num_top_row_keys
;
248 /* Write out keymap for numeric keypad, if the keyboard has it */
249 if (has_numeric_keypad
) {
250 for (i
= 0; i
< ARRAY_SIZE(numeric_keypad_keymaps
); i
++) {
251 keymap
= numeric_keypad_keymaps
[i
];
252 acpi_dp_add_integer(dp_array
, NULL
, keymap
);
255 total
+= ARRAY_SIZE(numeric_keypad_keymaps
);
258 /* Provide keymap for screenlock only if it is present */
259 if (has_scrnlock_key
) {
260 acpi_dp_add_integer(dp_array
, NULL
, KEYMAP(0x5d, KEY_SLEEP
));
264 /* Write out keymap for rest of keys */
265 for (i
= 0; i
< ARRAY_SIZE(rest_of_keymaps
); i
++) {
266 keymap
= rest_of_keymaps
[i
];
267 acpi_dp_add_integer(dp_array
, NULL
, keymap
);
270 total
+= ARRAY_SIZE(rest_of_keymaps
);
271 printk(BIOS_INFO
, "PS2K: Passing %u keymaps to kernel\n", total
);
273 acpi_dp_add_array(dp
, dp_array
);
276 void acpigen_ps2_keyboard_dsd(const char *scope
, uint8_t num_top_row_keys
,
277 enum ps2_action_key action_keys
[],
278 bool can_send_function_keys
,
279 bool has_numeric_keypad
,
280 bool has_scrnlock_key
)
285 num_top_row_keys
< PS2_MIN_TOP_ROW_KEYS
||
286 num_top_row_keys
> PS2_MAX_TOP_ROW_KEYS
) {
287 printk(BIOS_ERR
, "PS2K: %s: invalid args\n", __func__
);
291 dsd
= acpi_dp_new_table("_DSD");
293 printk(BIOS_ERR
, "PS2K: couldn't write _DSD\n");
297 acpigen_write_scope(scope
);
298 ssdt_generate_physmap(dsd
, num_top_row_keys
, action_keys
);
299 ssdt_generate_keymap(dsd
, num_top_row_keys
, action_keys
,
300 can_send_function_keys
, has_numeric_keypad
,
303 acpigen_pop_len(); /* Scope */