| 1 | // SPDX-License-Identifier: GPL-2.0-only | 
|---|
| 2 | /* | 
|---|
| 3 | * AT and PS/2 keyboard driver | 
|---|
| 4 | * | 
|---|
| 5 | * Copyright (c) 1999-2002 Vojtech Pavlik | 
|---|
| 6 | */ | 
|---|
| 7 |  | 
|---|
| 8 |  | 
|---|
| 9 | /* | 
|---|
| 10 | * This driver can handle standard AT keyboards and PS/2 keyboards in | 
|---|
| 11 | * Translated and Raw Set 2 and Set 3, as well as AT keyboards on dumb | 
|---|
| 12 | * input-only controllers and AT keyboards connected over a one way RS232 | 
|---|
| 13 | * converter. | 
|---|
| 14 | */ | 
|---|
| 15 |  | 
|---|
| 16 | #include <linux/delay.h> | 
|---|
| 17 | #include <linux/module.h> | 
|---|
| 18 | #include <linux/slab.h> | 
|---|
| 19 | #include <linux/interrupt.h> | 
|---|
| 20 | #include <linux/init.h> | 
|---|
| 21 | #include <linux/input.h> | 
|---|
| 22 | #include <linux/input/vivaldi-fmap.h> | 
|---|
| 23 | #include <linux/serio.h> | 
|---|
| 24 | #include <linux/workqueue.h> | 
|---|
| 25 | #include <linux/libps2.h> | 
|---|
| 26 | #include <linux/mutex.h> | 
|---|
| 27 | #include <linux/dmi.h> | 
|---|
| 28 | #include <linux/property.h> | 
|---|
| 29 |  | 
|---|
| 30 | #define DRIVER_DESC	"AT and PS/2 keyboard driver" | 
|---|
| 31 |  | 
|---|
| 32 | MODULE_AUTHOR( "Vojtech Pavlik <vojtech@suse.cz>"); | 
|---|
| 33 | MODULE_DESCRIPTION(DRIVER_DESC); | 
|---|
| 34 | MODULE_LICENSE( "GPL"); | 
|---|
| 35 |  | 
|---|
| 36 | static int atkbd_set = 2; | 
|---|
| 37 | module_param_named(set, atkbd_set, int, 0); | 
|---|
| 38 | MODULE_PARM_DESC(set, "Select keyboard code set (2 = default, 3 = PS/2 native)"); | 
|---|
| 39 |  | 
|---|
| 40 | #if defined(__i386__) || defined(__x86_64__) || defined(__hppa__) || defined(__loongarch__) | 
|---|
| 41 | static bool atkbd_reset; | 
|---|
| 42 | #else | 
|---|
| 43 | static bool atkbd_reset = true; | 
|---|
| 44 | #endif | 
|---|
| 45 | module_param_named(reset, atkbd_reset, bool, 0); | 
|---|
| 46 | MODULE_PARM_DESC(reset, "Reset keyboard during initialization"); | 
|---|
| 47 |  | 
|---|
| 48 | static bool atkbd_softrepeat; | 
|---|
| 49 | module_param_named(softrepeat, atkbd_softrepeat, bool, 0); | 
|---|
| 50 | MODULE_PARM_DESC(softrepeat, "Use software keyboard repeat"); | 
|---|
| 51 |  | 
|---|
| 52 | static bool atkbd_softraw = true; | 
|---|
| 53 | module_param_named(softraw, atkbd_softraw, bool, 0); | 
|---|
| 54 | MODULE_PARM_DESC(softraw, "Use software generated rawmode"); | 
|---|
| 55 |  | 
|---|
| 56 | static bool atkbd_scroll; | 
|---|
| 57 | module_param_named(scroll, atkbd_scroll, bool, 0); | 
|---|
| 58 | MODULE_PARM_DESC(scroll, "Enable scroll-wheel on MS Office and similar keyboards"); | 
|---|
| 59 |  | 
|---|
| 60 | static bool ; | 
|---|
| 61 | module_param_named(extra, atkbd_extra, bool, 0); | 
|---|
| 62 | MODULE_PARM_DESC(extra, "Enable extra LEDs and keys on IBM RapidAcces, EzKey and similar keyboards"); | 
|---|
| 63 |  | 
|---|
| 64 | static bool atkbd_terminal; | 
|---|
| 65 | module_param_named(terminal, atkbd_terminal, bool, 0); | 
|---|
| 66 | MODULE_PARM_DESC(terminal, "Enable break codes on an IBM Terminal keyboard connected via AT/PS2"); | 
|---|
| 67 |  | 
|---|
| 68 | #define SCANCODE(keymap)	((keymap >> 16) & 0xFFFF) | 
|---|
| 69 | #define KEYCODE(keymap)		(keymap & 0xFFFF) | 
|---|
| 70 |  | 
|---|
| 71 | /* | 
|---|
| 72 | * Scancode to keycode tables. These are just the default setting, and | 
|---|
| 73 | * are loadable via a userland utility. | 
|---|
| 74 | */ | 
|---|
| 75 |  | 
|---|
| 76 | #define ATKBD_KEYMAP_SIZE	512 | 
|---|
| 77 |  | 
|---|
| 78 | static const unsigned short atkbd_set2_keycode[ATKBD_KEYMAP_SIZE] = { | 
|---|
| 79 |  | 
|---|
| 80 | #ifdef CONFIG_KEYBOARD_ATKBD_HP_KEYCODES | 
|---|
| 81 |  | 
|---|
| 82 | /* XXX: need a more general approach */ | 
|---|
| 83 |  | 
|---|
| 84 | #include "hpps2atkbd.h"	/* include the keyboard scancodes */ | 
|---|
| 85 |  | 
|---|
| 86 | #else | 
|---|
| 87 | 0, 67, 65, 63, 61, 59, 60, 88,183, 68, 66, 64, 62, 15, 41,117, | 
|---|
| 88 | 184, 56, 42, 93, 29, 16,  2,  0,185,  0, 44, 31, 30, 17,  3,  0, | 
|---|
| 89 | 186, 46, 45, 32, 18,  5,  4, 95,187, 57, 47, 33, 20, 19,  6,183, | 
|---|
| 90 | 188, 49, 48, 35, 34, 21,  7,184,189,  0, 50, 36, 22,  8,  9,185, | 
|---|
| 91 | 190, 51, 37, 23, 24, 11, 10,  0,191, 52, 53, 38, 39, 25, 12,  0, | 
|---|
| 92 | 192, 89, 40,  0, 26, 13,  0,193, 58, 54, 28, 27,  0, 43,  0,194, | 
|---|
| 93 | 0, 86, 91, 90, 92,  0, 14, 94,  0, 79,124, 75, 71,121,  0,  0, | 
|---|
| 94 | 82, 83, 80, 76, 77, 72,  1, 69, 87, 78, 81, 74, 55, 73, 70, 99, | 
|---|
| 95 |  | 
|---|
| 96 | 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, | 
|---|
| 97 | 217,100,255,  0, 97,165,  0,  0,156,  0,  0,  0,  0,  0,  0,125, | 
|---|
| 98 | 173,114,  0,113,  0,  0,  0,126,128,  0,  0,140,  0,  0,  0,127, | 
|---|
| 99 | 159,  0,115,  0,164,  0,  0,116,158,  0,172,166,  0,  0,  0,142, | 
|---|
| 100 | 157,  0,  0,  0,  0,  0,  0,  0,155,  0, 98,  0,  0,163,  0,  0, | 
|---|
| 101 | 226,  0,  0,  0,  0,  0,  0,  0,  0,255, 96,  0,  0,  0,143,  0, | 
|---|
| 102 | 0,  0,  0,  0,  0,  0,  0,  0,  0,107,  0,105,102,  0,  0,112, | 
|---|
| 103 | 110,111,108,112,106,103,  0,119,  0,118,109,  0, 99,104,119,  0, | 
|---|
| 104 |  | 
|---|
| 105 | 0,  0,  0, 65, 99, | 
|---|
| 106 | #endif | 
|---|
| 107 | }; | 
|---|
| 108 |  | 
|---|
| 109 | static const unsigned short atkbd_set3_keycode[ATKBD_KEYMAP_SIZE] = { | 
|---|
| 110 |  | 
|---|
| 111 | 0,  0,  0,  0,  0,  0,  0, 59,  1,138,128,129,130, 15, 41, 60, | 
|---|
| 112 | 131, 29, 42, 86, 58, 16,  2, 61,133, 56, 44, 31, 30, 17,  3, 62, | 
|---|
| 113 | 134, 46, 45, 32, 18,  5,  4, 63,135, 57, 47, 33, 20, 19,  6, 64, | 
|---|
| 114 | 136, 49, 48, 35, 34, 21,  7, 65,137,100, 50, 36, 22,  8,  9, 66, | 
|---|
| 115 | 125, 51, 37, 23, 24, 11, 10, 67,126, 52, 53, 38, 39, 25, 12, 68, | 
|---|
| 116 | 113,114, 40, 43, 26, 13, 87, 99, 97, 54, 28, 27, 43, 43, 88, 70, | 
|---|
| 117 | 108,105,119,103,111,107, 14,110,  0, 79,106, 75, 71,109,102,104, | 
|---|
| 118 | 82, 83, 80, 76, 77, 72, 69, 98,  0, 96, 81,  0, 78, 73, 55,183, | 
|---|
| 119 |  | 
|---|
| 120 | 184,185,186,187, 74, 94, 92, 93,  0,  0,  0,125,126,127,112,  0, | 
|---|
| 121 | 0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168, | 
|---|
| 122 | 148,149,147,140 | 
|---|
| 123 | }; | 
|---|
| 124 |  | 
|---|
| 125 | static const unsigned short atkbd_unxlate_table[128] = { | 
|---|
| 126 | 0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13, | 
|---|
| 127 | 21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27, | 
|---|
| 128 | 35, 43, 52, 51, 59, 66, 75, 76, 82, 14, 18, 93, 26, 34, 33, 42, | 
|---|
| 129 | 50, 49, 58, 65, 73, 74, 89,124, 17, 41, 88,  5,  6,  4, 12,  3, | 
|---|
| 130 | 11,  2, 10,  1,  9,119,126,108,117,125,123,107,115,116,121,105, | 
|---|
| 131 | 114,122,112,113,127, 96, 97,120,  7, 15, 23, 31, 39, 47, 55, 63, | 
|---|
| 132 | 71, 79, 86, 94,  8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 87,111, | 
|---|
| 133 | 19, 25, 57, 81, 83, 92, 95, 98, 99,100,101,103,104,106,109,110 | 
|---|
| 134 | }; | 
|---|
| 135 |  | 
|---|
| 136 | #define ATKBD_CMD_SETLEDS	0x10ed | 
|---|
| 137 | #define ATKBD_CMD_GSCANSET	0x11f0 | 
|---|
| 138 | #define ATKBD_CMD_SSCANSET	0x10f0 | 
|---|
| 139 | #define ATKBD_CMD_GETID		0x02f2 | 
|---|
| 140 | #define ATKBD_CMD_SETREP	0x10f3 | 
|---|
| 141 | #define ATKBD_CMD_ENABLE	0x00f4 | 
|---|
| 142 | #define ATKBD_CMD_RESET_DIS	0x00f5	/* Reset to defaults and disable */ | 
|---|
| 143 | #define ATKBD_CMD_RESET_DEF	0x00f6	/* Reset to defaults */ | 
|---|
| 144 | #define ATKBD_CMD_SETALL_MB	0x00f8	/* Set all keys to give break codes */ | 
|---|
| 145 | #define ATKBD_CMD_SETALL_MBR	0x00fa  /* ... and repeat */ | 
|---|
| 146 | #define ATKBD_CMD_RESET_BAT	0x02ff | 
|---|
| 147 | #define ATKBD_CMD_RESEND	0x00fe | 
|---|
| 148 | #define ATKBD_CMD_EX_ENABLE	0x10ea | 
|---|
| 149 | #define ATKBD_CMD_EX_SETLEDS	0x20eb | 
|---|
| 150 | #define ATKBD_CMD_OK_GETID	0x02e8 | 
|---|
| 151 |  | 
|---|
| 152 | #define ATKBD_RET_ACK		0xfa | 
|---|
| 153 | #define ATKBD_RET_NAK		0xfe | 
|---|
| 154 | #define ATKBD_RET_BAT		0xaa | 
|---|
| 155 | #define ATKBD_RET_EMUL0		0xe0 | 
|---|
| 156 | #define ATKBD_RET_EMUL1		0xe1 | 
|---|
| 157 | #define ATKBD_RET_RELEASE	0xf0 | 
|---|
| 158 | #define ATKBD_RET_HANJA		0xf1 | 
|---|
| 159 | #define ATKBD_RET_HANGEUL	0xf2 | 
|---|
| 160 | #define ATKBD_RET_ERR		0xff | 
|---|
| 161 |  | 
|---|
| 162 | #define ATKBD_KEY_UNKNOWN	0 | 
|---|
| 163 | #define ATKBD_KEY_NULL		255 | 
|---|
| 164 |  | 
|---|
| 165 | #define ATKBD_SCR_1		0xfffe | 
|---|
| 166 | #define ATKBD_SCR_2		0xfffd | 
|---|
| 167 | #define ATKBD_SCR_4		0xfffc | 
|---|
| 168 | #define ATKBD_SCR_8		0xfffb | 
|---|
| 169 | #define ATKBD_SCR_CLICK		0xfffa | 
|---|
| 170 | #define ATKBD_SCR_LEFT		0xfff9 | 
|---|
| 171 | #define ATKBD_SCR_RIGHT		0xfff8 | 
|---|
| 172 |  | 
|---|
| 173 | #define ATKBD_SPECIAL		ATKBD_SCR_RIGHT | 
|---|
| 174 |  | 
|---|
| 175 | #define ATKBD_LED_EVENT_BIT	0 | 
|---|
| 176 | #define ATKBD_REP_EVENT_BIT	1 | 
|---|
| 177 |  | 
|---|
| 178 | #define ATKBD_XL_ERR		0x01 | 
|---|
| 179 | #define ATKBD_XL_BAT		0x02 | 
|---|
| 180 | #define ATKBD_XL_ACK		0x04 | 
|---|
| 181 | #define ATKBD_XL_NAK		0x08 | 
|---|
| 182 | #define ATKBD_XL_HANGEUL	0x10 | 
|---|
| 183 | #define ATKBD_XL_HANJA		0x20 | 
|---|
| 184 |  | 
|---|
| 185 | static const struct { | 
|---|
| 186 | unsigned short keycode; | 
|---|
| 187 | unsigned char set2; | 
|---|
| 188 | } atkbd_scroll_keys[] = { | 
|---|
| 189 | { ATKBD_SCR_1,     0xc5 }, | 
|---|
| 190 | { ATKBD_SCR_2,     0x9d }, | 
|---|
| 191 | { ATKBD_SCR_4,     0xa4 }, | 
|---|
| 192 | { ATKBD_SCR_8,     0x9b }, | 
|---|
| 193 | { ATKBD_SCR_CLICK, 0xe0 }, | 
|---|
| 194 | { ATKBD_SCR_LEFT,  0xcb }, | 
|---|
| 195 | { ATKBD_SCR_RIGHT, 0xd2 }, | 
|---|
| 196 | }; | 
|---|
| 197 |  | 
|---|
| 198 | /* | 
|---|
| 199 | * The atkbd control structure | 
|---|
| 200 | */ | 
|---|
| 201 |  | 
|---|
| 202 | struct atkbd { | 
|---|
| 203 |  | 
|---|
| 204 | struct ps2dev ps2dev; | 
|---|
| 205 | struct input_dev *dev; | 
|---|
| 206 |  | 
|---|
| 207 | /* Written only during init */ | 
|---|
| 208 | char name[64]; | 
|---|
| 209 | char phys[32]; | 
|---|
| 210 |  | 
|---|
| 211 | unsigned short id; | 
|---|
| 212 | unsigned short keycode[ATKBD_KEYMAP_SIZE]; | 
|---|
| 213 | DECLARE_BITMAP(force_release_mask, ATKBD_KEYMAP_SIZE); | 
|---|
| 214 | unsigned char set; | 
|---|
| 215 | bool translated; | 
|---|
| 216 | bool ; | 
|---|
| 217 | bool write; | 
|---|
| 218 | bool softrepeat; | 
|---|
| 219 | bool softraw; | 
|---|
| 220 | bool scroll; | 
|---|
| 221 | bool enabled; | 
|---|
| 222 |  | 
|---|
| 223 | /* Accessed only from interrupt */ | 
|---|
| 224 | unsigned char emul; | 
|---|
| 225 | bool resend; | 
|---|
| 226 | bool release; | 
|---|
| 227 | unsigned long xl_bit; | 
|---|
| 228 | unsigned int last; | 
|---|
| 229 | unsigned long time; | 
|---|
| 230 | unsigned long err_count; | 
|---|
| 231 |  | 
|---|
| 232 | struct delayed_work event_work; | 
|---|
| 233 | unsigned long event_jiffies; | 
|---|
| 234 | unsigned long event_mask; | 
|---|
| 235 |  | 
|---|
| 236 | /* Serializes reconnect(), attr->set() and event work */ | 
|---|
| 237 | struct mutex mutex; | 
|---|
| 238 |  | 
|---|
| 239 | struct vivaldi_data vdata; | 
|---|
| 240 | }; | 
|---|
| 241 |  | 
|---|
| 242 | /* | 
|---|
| 243 | * System-specific keymap fixup routine | 
|---|
| 244 | */ | 
|---|
| 245 | static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); | 
|---|
| 246 | static void *atkbd_platform_fixup_data; | 
|---|
| 247 | static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); | 
|---|
| 248 |  | 
|---|
| 249 | /* | 
|---|
| 250 | * Certain keyboards to not like ATKBD_CMD_RESET_DIS and stop responding | 
|---|
| 251 | * to many commands until full reset (ATKBD_CMD_RESET_BAT) is performed. | 
|---|
| 252 | */ | 
|---|
| 253 | static bool atkbd_skip_deactivate; | 
|---|
| 254 |  | 
|---|
| 255 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | 
|---|
| 256 | ssize_t (*handler)(struct atkbd *, char *)); | 
|---|
| 257 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 
|---|
| 258 | ssize_t (*handler)(struct atkbd *, const char *, size_t)); | 
|---|
| 259 | #define ATKBD_DEFINE_ATTR(_name)						\ | 
|---|
| 260 | static ssize_t atkbd_show_##_name(struct atkbd *, char *);			\ | 
|---|
| 261 | static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t);		\ | 
|---|
| 262 | static ssize_t atkbd_do_show_##_name(struct device *d,				\ | 
|---|
| 263 | struct device_attribute *attr, char *b)		\ | 
|---|
| 264 | {										\ | 
|---|
| 265 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name);		\ | 
|---|
| 266 | }										\ | 
|---|
| 267 | static ssize_t atkbd_do_set_##_name(struct device *d,				\ | 
|---|
| 268 | struct device_attribute *attr, const char *b, size_t s)	\ | 
|---|
| 269 | {										\ | 
|---|
| 270 | return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name);		\ | 
|---|
| 271 | }										\ | 
|---|
| 272 | static struct device_attribute atkbd_attr_##_name =				\ | 
|---|
| 273 | __ATTR(_name, S_IWUSR | S_IRUGO, atkbd_do_show_##_name, atkbd_do_set_##_name); | 
|---|
| 274 |  | 
|---|
| 275 | ATKBD_DEFINE_ATTR(extra); | 
|---|
| 276 | ATKBD_DEFINE_ATTR(force_release); | 
|---|
| 277 | ATKBD_DEFINE_ATTR(scroll); | 
|---|
| 278 | ATKBD_DEFINE_ATTR(set); | 
|---|
| 279 | ATKBD_DEFINE_ATTR(softrepeat); | 
|---|
| 280 | ATKBD_DEFINE_ATTR(softraw); | 
|---|
| 281 |  | 
|---|
| 282 | #define ATKBD_DEFINE_RO_ATTR(_name)						\ | 
|---|
| 283 | static ssize_t atkbd_show_##_name(struct atkbd *, char *);			\ | 
|---|
| 284 | static ssize_t atkbd_do_show_##_name(struct device *d,				\ | 
|---|
| 285 | struct device_attribute *attr, char *b)		\ | 
|---|
| 286 | {										\ | 
|---|
| 287 | return atkbd_attr_show_helper(d, b, atkbd_show_##_name);		\ | 
|---|
| 288 | }										\ | 
|---|
| 289 | static struct device_attribute atkbd_attr_##_name =				\ | 
|---|
| 290 | __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL); | 
|---|
| 291 |  | 
|---|
| 292 | ATKBD_DEFINE_RO_ATTR(err_count); | 
|---|
| 293 | ATKBD_DEFINE_RO_ATTR(function_row_physmap); | 
|---|
| 294 |  | 
|---|
| 295 | static struct attribute *atkbd_attributes[] = { | 
|---|
| 296 | &atkbd_attr_extra.attr, | 
|---|
| 297 | &atkbd_attr_force_release.attr, | 
|---|
| 298 | &atkbd_attr_scroll.attr, | 
|---|
| 299 | &atkbd_attr_set.attr, | 
|---|
| 300 | &atkbd_attr_softrepeat.attr, | 
|---|
| 301 | &atkbd_attr_softraw.attr, | 
|---|
| 302 | &atkbd_attr_err_count.attr, | 
|---|
| 303 | &atkbd_attr_function_row_physmap.attr, | 
|---|
| 304 | NULL | 
|---|
| 305 | }; | 
|---|
| 306 |  | 
|---|
| 307 | static ssize_t atkbd_show_function_row_physmap(struct atkbd *atkbd, char *buf) | 
|---|
| 308 | { | 
|---|
| 309 | return vivaldi_function_row_physmap_show(data: &atkbd->vdata, buf); | 
|---|
| 310 | } | 
|---|
| 311 |  | 
|---|
| 312 | static struct atkbd *atkbd_from_serio(struct serio *serio) | 
|---|
| 313 | { | 
|---|
| 314 | struct ps2dev *ps2dev = serio_get_drvdata(serio); | 
|---|
| 315 |  | 
|---|
| 316 | return container_of(ps2dev, struct atkbd, ps2dev); | 
|---|
| 317 | } | 
|---|
| 318 |  | 
|---|
| 319 | static umode_t atkbd_attr_is_visible(struct kobject *kobj, | 
|---|
| 320 | struct attribute *attr, int i) | 
|---|
| 321 | { | 
|---|
| 322 | struct device *dev = kobj_to_dev(kobj); | 
|---|
| 323 | struct serio *serio = to_serio_port(dev); | 
|---|
| 324 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 325 |  | 
|---|
| 326 | if (attr == &atkbd_attr_function_row_physmap.attr && | 
|---|
| 327 | !atkbd->vdata.num_function_row_keys) | 
|---|
| 328 | return 0; | 
|---|
| 329 |  | 
|---|
| 330 | return attr->mode; | 
|---|
| 331 | } | 
|---|
| 332 |  | 
|---|
| 333 | static const struct attribute_group atkbd_attribute_group = { | 
|---|
| 334 | .attrs	= atkbd_attributes, | 
|---|
| 335 | .is_visible = atkbd_attr_is_visible, | 
|---|
| 336 | }; | 
|---|
| 337 |  | 
|---|
| 338 | __ATTRIBUTE_GROUPS(atkbd_attribute); | 
|---|
| 339 |  | 
|---|
| 340 | static const unsigned int xl_table[] = { | 
|---|
| 341 | ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, | 
|---|
| 342 | ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, | 
|---|
| 343 | }; | 
|---|
| 344 |  | 
|---|
| 345 | /* | 
|---|
| 346 | * Checks if we should mangle the scancode to extract 'release' bit | 
|---|
| 347 | * in translated mode. | 
|---|
| 348 | */ | 
|---|
| 349 | static bool atkbd_need_xlate(unsigned long xl_bit, unsigned char code) | 
|---|
| 350 | { | 
|---|
| 351 | int i; | 
|---|
| 352 |  | 
|---|
| 353 | if (code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1) | 
|---|
| 354 | return false; | 
|---|
| 355 |  | 
|---|
| 356 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) | 
|---|
| 357 | if (code == xl_table[i]) | 
|---|
| 358 | return test_bit(i, &xl_bit); | 
|---|
| 359 |  | 
|---|
| 360 | return true; | 
|---|
| 361 | } | 
|---|
| 362 |  | 
|---|
| 363 | /* | 
|---|
| 364 | * Calculates new value of xl_bit so the driver can distinguish | 
|---|
| 365 | * between make/break pair of scancodes for select keys and PS/2 | 
|---|
| 366 | * protocol responses. | 
|---|
| 367 | */ | 
|---|
| 368 | static void atkbd_calculate_xl_bit(struct atkbd *atkbd, unsigned char code) | 
|---|
| 369 | { | 
|---|
| 370 | int i; | 
|---|
| 371 |  | 
|---|
| 372 | for (i = 0; i < ARRAY_SIZE(xl_table); i++) { | 
|---|
| 373 | if (!((code ^ xl_table[i]) & 0x7f)) { | 
|---|
| 374 | if (code & 0x80) | 
|---|
| 375 | __clear_bit(i, &atkbd->xl_bit); | 
|---|
| 376 | else | 
|---|
| 377 | __set_bit(i, &atkbd->xl_bit); | 
|---|
| 378 | break; | 
|---|
| 379 | } | 
|---|
| 380 | } | 
|---|
| 381 | } | 
|---|
| 382 |  | 
|---|
| 383 | /* | 
|---|
| 384 | * Encode the scancode, 0xe0 prefix, and high bit into a single integer, | 
|---|
| 385 | * keeping kernel 2.4 compatibility for set 2 | 
|---|
| 386 | */ | 
|---|
| 387 | static unsigned int atkbd_compat_scancode(struct atkbd *atkbd, unsigned int code) | 
|---|
| 388 | { | 
|---|
| 389 | if (atkbd->set == 3) { | 
|---|
| 390 | if (atkbd->emul == 1) | 
|---|
| 391 | code |= 0x100; | 
|---|
| 392 | } else { | 
|---|
| 393 | code = (code & 0x7f) | ((code & 0x80) << 1); | 
|---|
| 394 | if (atkbd->emul == 1) | 
|---|
| 395 | code |= 0x80; | 
|---|
| 396 | } | 
|---|
| 397 |  | 
|---|
| 398 | return code; | 
|---|
| 399 | } | 
|---|
| 400 |  | 
|---|
| 401 | /* | 
|---|
| 402 | * Tries to handle frame or parity error by requesting the keyboard controller | 
|---|
| 403 | * to resend the last byte. This historically not done on x86 as controllers | 
|---|
| 404 | * there typically do not implement this command. | 
|---|
| 405 | */ | 
|---|
| 406 | static bool __maybe_unused atkbd_handle_frame_error(struct ps2dev *ps2dev, | 
|---|
| 407 | u8 data, unsigned int flags) | 
|---|
| 408 | { | 
|---|
| 409 | struct atkbd *atkbd = container_of(ps2dev, struct atkbd, ps2dev); | 
|---|
| 410 | struct serio *serio = ps2dev->serio; | 
|---|
| 411 |  | 
|---|
| 412 | if ((flags & (SERIO_FRAME | SERIO_PARITY)) && | 
|---|
| 413 | (~flags & SERIO_TIMEOUT) && | 
|---|
| 414 | !atkbd->resend && atkbd->write) { | 
|---|
| 415 | dev_warn(&serio->dev, "Frame/parity error: %02x\n", flags); | 
|---|
| 416 | serio_write(serio, ATKBD_CMD_RESEND); | 
|---|
| 417 | atkbd->resend = true; | 
|---|
| 418 | return true; | 
|---|
| 419 | } | 
|---|
| 420 |  | 
|---|
| 421 | if (!flags && data == ATKBD_RET_ACK) | 
|---|
| 422 | atkbd->resend = false; | 
|---|
| 423 |  | 
|---|
| 424 | return false; | 
|---|
| 425 | } | 
|---|
| 426 |  | 
|---|
| 427 | static enum ps2_disposition atkbd_pre_receive_byte(struct ps2dev *ps2dev, | 
|---|
| 428 | u8 data, unsigned int flags) | 
|---|
| 429 | { | 
|---|
| 430 | struct serio *serio = ps2dev->serio; | 
|---|
| 431 |  | 
|---|
| 432 | dev_dbg(&serio->dev, "Received %02x flags %02x\n", data, flags); | 
|---|
| 433 |  | 
|---|
| 434 | #if !defined(__i386__) && !defined (__x86_64__) | 
|---|
| 435 | if (atkbd_handle_frame_error(ps2dev, data, flags)) | 
|---|
| 436 | return PS2_IGNORE; | 
|---|
| 437 | #endif | 
|---|
| 438 |  | 
|---|
| 439 | return PS2_PROCESS; | 
|---|
| 440 | } | 
|---|
| 441 |  | 
|---|
| 442 | static void atkbd_receive_byte(struct ps2dev *ps2dev, u8 data) | 
|---|
| 443 | { | 
|---|
| 444 | struct serio *serio = ps2dev->serio; | 
|---|
| 445 | struct atkbd *atkbd = container_of(ps2dev, struct atkbd, ps2dev); | 
|---|
| 446 | struct input_dev *dev = atkbd->dev; | 
|---|
| 447 | unsigned int code = data; | 
|---|
| 448 | int scroll = 0, hscroll = 0, click = -1; | 
|---|
| 449 | int value; | 
|---|
| 450 | unsigned short keycode; | 
|---|
| 451 |  | 
|---|
| 452 | pm_wakeup_event(dev: &serio->dev, msec: 0); | 
|---|
| 453 |  | 
|---|
| 454 | if (!atkbd->enabled) | 
|---|
| 455 | return; | 
|---|
| 456 |  | 
|---|
| 457 | input_event(dev, EV_MSC, MSC_RAW, value: code); | 
|---|
| 458 |  | 
|---|
| 459 | if (atkbd_platform_scancode_fixup) | 
|---|
| 460 | code = atkbd_platform_scancode_fixup(atkbd, code); | 
|---|
| 461 |  | 
|---|
| 462 | if (atkbd->translated) { | 
|---|
| 463 |  | 
|---|
| 464 | if (atkbd->emul || atkbd_need_xlate(xl_bit: atkbd->xl_bit, code)) { | 
|---|
| 465 | atkbd->release = code >> 7; | 
|---|
| 466 | code &= 0x7f; | 
|---|
| 467 | } | 
|---|
| 468 |  | 
|---|
| 469 | if (!atkbd->emul) | 
|---|
| 470 | atkbd_calculate_xl_bit(atkbd, code: data); | 
|---|
| 471 | } | 
|---|
| 472 |  | 
|---|
| 473 | switch (code) { | 
|---|
| 474 | case ATKBD_RET_BAT: | 
|---|
| 475 | atkbd->enabled = false; | 
|---|
| 476 | serio_reconnect(serio: atkbd->ps2dev.serio); | 
|---|
| 477 | return; | 
|---|
| 478 | case ATKBD_RET_EMUL0: | 
|---|
| 479 | atkbd->emul = 1; | 
|---|
| 480 | return; | 
|---|
| 481 | case ATKBD_RET_EMUL1: | 
|---|
| 482 | atkbd->emul = 2; | 
|---|
| 483 | return; | 
|---|
| 484 | case ATKBD_RET_RELEASE: | 
|---|
| 485 | atkbd->release = true; | 
|---|
| 486 | return; | 
|---|
| 487 | case ATKBD_RET_ACK: | 
|---|
| 488 | case ATKBD_RET_NAK: | 
|---|
| 489 | if (printk_ratelimit()) | 
|---|
| 490 | dev_warn(&serio->dev, | 
|---|
| 491 | "Spurious %s on %s. " | 
|---|
| 492 | "Some program might be trying to access hardware directly.\n", | 
|---|
| 493 | data == ATKBD_RET_ACK ? "ACK": "NAK", serio->phys); | 
|---|
| 494 | return; | 
|---|
| 495 | case ATKBD_RET_ERR: | 
|---|
| 496 | atkbd->err_count++; | 
|---|
| 497 | dev_dbg(&serio->dev, "Keyboard on %s reports too many keys pressed.\n", | 
|---|
| 498 | serio->phys); | 
|---|
| 499 | return; | 
|---|
| 500 | } | 
|---|
| 501 |  | 
|---|
| 502 | code = atkbd_compat_scancode(atkbd, code); | 
|---|
| 503 |  | 
|---|
| 504 | if (atkbd->emul && --atkbd->emul) | 
|---|
| 505 | return; | 
|---|
| 506 |  | 
|---|
| 507 | keycode = atkbd->keycode[code]; | 
|---|
| 508 |  | 
|---|
| 509 | if (!(atkbd->release && test_bit(code, atkbd->force_release_mask))) | 
|---|
| 510 | if (keycode != ATKBD_KEY_NULL) | 
|---|
| 511 | input_event(dev, EV_MSC, MSC_SCAN, value: code); | 
|---|
| 512 |  | 
|---|
| 513 | switch (keycode) { | 
|---|
| 514 | case ATKBD_KEY_NULL: | 
|---|
| 515 | break; | 
|---|
| 516 | case ATKBD_KEY_UNKNOWN: | 
|---|
| 517 | dev_warn(&serio->dev, | 
|---|
| 518 | "Unknown key %s (%s set %d, code %#x on %s).\n", | 
|---|
| 519 | atkbd->release ? "released": "pressed", | 
|---|
| 520 | atkbd->translated ? "translated": "raw", | 
|---|
| 521 | atkbd->set, code, serio->phys); | 
|---|
| 522 | dev_warn(&serio->dev, | 
|---|
| 523 | "Use 'setkeycodes %s%02x <keycode>' to make it known.\n", | 
|---|
| 524 | code & 0x80 ? "e0": "", code & 0x7f); | 
|---|
| 525 | input_sync(dev); | 
|---|
| 526 | break; | 
|---|
| 527 | case ATKBD_SCR_1: | 
|---|
| 528 | scroll = 1; | 
|---|
| 529 | break; | 
|---|
| 530 | case ATKBD_SCR_2: | 
|---|
| 531 | scroll = 2; | 
|---|
| 532 | break; | 
|---|
| 533 | case ATKBD_SCR_4: | 
|---|
| 534 | scroll = 4; | 
|---|
| 535 | break; | 
|---|
| 536 | case ATKBD_SCR_8: | 
|---|
| 537 | scroll = 8; | 
|---|
| 538 | break; | 
|---|
| 539 | case ATKBD_SCR_CLICK: | 
|---|
| 540 | click = !atkbd->release; | 
|---|
| 541 | break; | 
|---|
| 542 | case ATKBD_SCR_LEFT: | 
|---|
| 543 | hscroll = -1; | 
|---|
| 544 | break; | 
|---|
| 545 | case ATKBD_SCR_RIGHT: | 
|---|
| 546 | hscroll = 1; | 
|---|
| 547 | break; | 
|---|
| 548 | default: | 
|---|
| 549 | if (atkbd->release) { | 
|---|
| 550 | value = 0; | 
|---|
| 551 | atkbd->last = 0; | 
|---|
| 552 | } else if (!atkbd->softrepeat && test_bit(keycode, dev->key)) { | 
|---|
| 553 | /* Workaround Toshiba laptop multiple keypress */ | 
|---|
| 554 | value = time_before(jiffies, atkbd->time) && atkbd->last == code ? 1 : 2; | 
|---|
| 555 | } else { | 
|---|
| 556 | value = 1; | 
|---|
| 557 | atkbd->last = code; | 
|---|
| 558 | atkbd->time = jiffies + msecs_to_jiffies(m: dev->rep[REP_DELAY]) / 2; | 
|---|
| 559 | } | 
|---|
| 560 |  | 
|---|
| 561 | input_event(dev, EV_KEY, code: keycode, value); | 
|---|
| 562 | input_sync(dev); | 
|---|
| 563 |  | 
|---|
| 564 | if (value && test_bit(code, atkbd->force_release_mask)) { | 
|---|
| 565 | input_event(dev, EV_MSC, MSC_SCAN, value: code); | 
|---|
| 566 | input_report_key(dev, code: keycode, value: 0); | 
|---|
| 567 | input_sync(dev); | 
|---|
| 568 | } | 
|---|
| 569 | } | 
|---|
| 570 |  | 
|---|
| 571 | if (atkbd->scroll) { | 
|---|
| 572 | if (click != -1) | 
|---|
| 573 | input_report_key(dev, BTN_MIDDLE, value: click); | 
|---|
| 574 | input_report_rel(dev, REL_WHEEL, | 
|---|
| 575 | value: atkbd->release ? -scroll : scroll); | 
|---|
| 576 | input_report_rel(dev, REL_HWHEEL, value: hscroll); | 
|---|
| 577 | input_sync(dev); | 
|---|
| 578 | } | 
|---|
| 579 |  | 
|---|
| 580 | atkbd->release = false; | 
|---|
| 581 | } | 
|---|
| 582 |  | 
|---|
| 583 | static int atkbd_set_repeat_rate(struct atkbd *atkbd) | 
|---|
| 584 | { | 
|---|
| 585 | const short period[32] = | 
|---|
| 586 | { 33,  37,  42,  46,  50,  54,  58,  63,  67,  75,  83,  92, 100, 109, 116, 125, | 
|---|
| 587 | 133, 149, 167, 182, 200, 217, 232, 250, 270, 303, 333, 370, 400, 435, 470, 500 }; | 
|---|
| 588 | const short delay[4] = | 
|---|
| 589 | { 250, 500, 750, 1000 }; | 
|---|
| 590 |  | 
|---|
| 591 | struct input_dev *dev = atkbd->dev; | 
|---|
| 592 | unsigned char param; | 
|---|
| 593 | int i = 0, j = 0; | 
|---|
| 594 |  | 
|---|
| 595 | while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD]) | 
|---|
| 596 | i++; | 
|---|
| 597 | dev->rep[REP_PERIOD] = period[i]; | 
|---|
| 598 |  | 
|---|
| 599 | while (j < ARRAY_SIZE(delay) - 1 && delay[j] < dev->rep[REP_DELAY]) | 
|---|
| 600 | j++; | 
|---|
| 601 | dev->rep[REP_DELAY] = delay[j]; | 
|---|
| 602 |  | 
|---|
| 603 | param = i | (j << 5); | 
|---|
| 604 | return ps2_command(ps2dev: &atkbd->ps2dev, param: ¶m, ATKBD_CMD_SETREP); | 
|---|
| 605 | } | 
|---|
| 606 |  | 
|---|
| 607 | static int atkbd_set_leds(struct atkbd *atkbd) | 
|---|
| 608 | { | 
|---|
| 609 | struct input_dev *dev = atkbd->dev; | 
|---|
| 610 | unsigned char param[2]; | 
|---|
| 611 |  | 
|---|
| 612 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | 
|---|
| 613 | | (test_bit(LED_NUML,    dev->led) ? 2 : 0) | 
|---|
| 614 | | (test_bit(LED_CAPSL,   dev->led) ? 4 : 0); | 
|---|
| 615 | if (ps2_command(ps2dev: &atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) | 
|---|
| 616 | return -1; | 
|---|
| 617 |  | 
|---|
| 618 | if (atkbd->extra) { | 
|---|
| 619 | param[0] = 0; | 
|---|
| 620 | param[1] = (test_bit(LED_COMPOSE, dev->led) ? 0x01 : 0) | 
|---|
| 621 | | (test_bit(LED_SLEEP,   dev->led) ? 0x02 : 0) | 
|---|
| 622 | | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | 
|---|
| 623 | | (test_bit(LED_MISC,    dev->led) ? 0x10 : 0) | 
|---|
| 624 | | (test_bit(LED_MUTE,    dev->led) ? 0x20 : 0); | 
|---|
| 625 | if (ps2_command(ps2dev: &atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS)) | 
|---|
| 626 | return -1; | 
|---|
| 627 | } | 
|---|
| 628 |  | 
|---|
| 629 | return 0; | 
|---|
| 630 | } | 
|---|
| 631 |  | 
|---|
| 632 | /* | 
|---|
| 633 | * atkbd_event_work() is used to complete processing of events that | 
|---|
| 634 | * can not be processed by input_event() which is often called from | 
|---|
| 635 | * interrupt context. | 
|---|
| 636 | */ | 
|---|
| 637 |  | 
|---|
| 638 | static void atkbd_event_work(struct work_struct *work) | 
|---|
| 639 | { | 
|---|
| 640 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); | 
|---|
| 641 |  | 
|---|
| 642 | guard(mutex)(T: &atkbd->mutex); | 
|---|
| 643 |  | 
|---|
| 644 | if (!atkbd->enabled) { | 
|---|
| 645 | /* | 
|---|
| 646 | * Serio ports are resumed asynchronously so while driver core | 
|---|
| 647 | * thinks that device is already fully operational in reality | 
|---|
| 648 | * it may not be ready yet. In this case we need to keep | 
|---|
| 649 | * rescheduling till reconnect completes. | 
|---|
| 650 | */ | 
|---|
| 651 | schedule_delayed_work(dwork: &atkbd->event_work, | 
|---|
| 652 | delay: msecs_to_jiffies(m: 100)); | 
|---|
| 653 | } else { | 
|---|
| 654 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, addr: &atkbd->event_mask)) | 
|---|
| 655 | atkbd_set_leds(atkbd); | 
|---|
| 656 |  | 
|---|
| 657 | if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, addr: &atkbd->event_mask)) | 
|---|
| 658 | atkbd_set_repeat_rate(atkbd); | 
|---|
| 659 | } | 
|---|
| 660 | } | 
|---|
| 661 |  | 
|---|
| 662 | /* | 
|---|
| 663 | * Schedule switch for execution. We need to throttle requests, | 
|---|
| 664 | * otherwise keyboard may become unresponsive. | 
|---|
| 665 | */ | 
|---|
| 666 | static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) | 
|---|
| 667 | { | 
|---|
| 668 | unsigned long delay = msecs_to_jiffies(m: 50); | 
|---|
| 669 |  | 
|---|
| 670 | if (time_after(jiffies, atkbd->event_jiffies + delay)) | 
|---|
| 671 | delay = 0; | 
|---|
| 672 |  | 
|---|
| 673 | atkbd->event_jiffies = jiffies; | 
|---|
| 674 | set_bit(nr: event_bit, addr: &atkbd->event_mask); | 
|---|
| 675 | mb(); | 
|---|
| 676 | schedule_delayed_work(dwork: &atkbd->event_work, delay); | 
|---|
| 677 | } | 
|---|
| 678 |  | 
|---|
| 679 | /* | 
|---|
| 680 | * Event callback from the input module. Events that change the state of | 
|---|
| 681 | * the hardware are processed here. If action can not be performed in | 
|---|
| 682 | * interrupt context it is offloaded to atkbd_event_work. | 
|---|
| 683 | */ | 
|---|
| 684 |  | 
|---|
| 685 | static int atkbd_event(struct input_dev *dev, | 
|---|
| 686 | unsigned int type, unsigned int code, int value) | 
|---|
| 687 | { | 
|---|
| 688 | struct atkbd *atkbd = input_get_drvdata(dev); | 
|---|
| 689 |  | 
|---|
| 690 | if (!atkbd->write) | 
|---|
| 691 | return -1; | 
|---|
| 692 |  | 
|---|
| 693 | switch (type) { | 
|---|
| 694 |  | 
|---|
| 695 | case EV_LED: | 
|---|
| 696 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); | 
|---|
| 697 | return 0; | 
|---|
| 698 |  | 
|---|
| 699 | case EV_REP: | 
|---|
| 700 | if (!atkbd->softrepeat) | 
|---|
| 701 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); | 
|---|
| 702 | return 0; | 
|---|
| 703 |  | 
|---|
| 704 | default: | 
|---|
| 705 | return -1; | 
|---|
| 706 | } | 
|---|
| 707 | } | 
|---|
| 708 |  | 
|---|
| 709 | /* | 
|---|
| 710 | * atkbd_enable() signals that interrupt handler is allowed to | 
|---|
| 711 | * generate input events. | 
|---|
| 712 | */ | 
|---|
| 713 |  | 
|---|
| 714 | static inline void atkbd_enable(struct atkbd *atkbd) | 
|---|
| 715 | { | 
|---|
| 716 | guard(serio_pause_rx)(T: atkbd->ps2dev.serio); | 
|---|
| 717 |  | 
|---|
| 718 | atkbd->enabled = true; | 
|---|
| 719 | } | 
|---|
| 720 |  | 
|---|
| 721 | /* | 
|---|
| 722 | * atkbd_disable() tells input handler that all incoming data except | 
|---|
| 723 | * for ACKs and command response should be dropped. | 
|---|
| 724 | */ | 
|---|
| 725 |  | 
|---|
| 726 | static inline void atkbd_disable(struct atkbd *atkbd) | 
|---|
| 727 | { | 
|---|
| 728 | guard(serio_pause_rx)(T: atkbd->ps2dev.serio); | 
|---|
| 729 |  | 
|---|
| 730 | atkbd->enabled = false; | 
|---|
| 731 | } | 
|---|
| 732 |  | 
|---|
| 733 | static int atkbd_activate(struct atkbd *atkbd) | 
|---|
| 734 | { | 
|---|
| 735 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 
|---|
| 736 |  | 
|---|
| 737 | /* | 
|---|
| 738 | * Enable the keyboard to receive keystrokes. | 
|---|
| 739 | */ | 
|---|
| 740 |  | 
|---|
| 741 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_ENABLE)) { | 
|---|
| 742 | dev_err(&ps2dev->serio->dev, | 
|---|
| 743 | "Failed to enable keyboard on %s\n", | 
|---|
| 744 | ps2dev->serio->phys); | 
|---|
| 745 | return -1; | 
|---|
| 746 | } | 
|---|
| 747 |  | 
|---|
| 748 | return 0; | 
|---|
| 749 | } | 
|---|
| 750 |  | 
|---|
| 751 | /* | 
|---|
| 752 | * atkbd_deactivate() resets and disables the keyboard from sending | 
|---|
| 753 | * keystrokes. | 
|---|
| 754 | */ | 
|---|
| 755 |  | 
|---|
| 756 | static void atkbd_deactivate(struct atkbd *atkbd) | 
|---|
| 757 | { | 
|---|
| 758 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 
|---|
| 759 |  | 
|---|
| 760 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_DIS)) | 
|---|
| 761 | dev_err(&ps2dev->serio->dev, | 
|---|
| 762 | "Failed to deactivate keyboard on %s\n", | 
|---|
| 763 | ps2dev->serio->phys); | 
|---|
| 764 | } | 
|---|
| 765 |  | 
|---|
| 766 | #ifdef CONFIG_X86 | 
|---|
| 767 | static bool atkbd_is_portable_device(void) | 
|---|
| 768 | { | 
|---|
| 769 | static const char * const chassis_types[] = { | 
|---|
| 770 | "8",	/* Portable */ | 
|---|
| 771 | "9",	/* Laptop */ | 
|---|
| 772 | "10",	/* Notebook */ | 
|---|
| 773 | "14",	/* Sub-Notebook */ | 
|---|
| 774 | "31",	/* Convertible */ | 
|---|
| 775 | "32",	/* Detachable */ | 
|---|
| 776 | }; | 
|---|
| 777 | int i; | 
|---|
| 778 |  | 
|---|
| 779 | for (i = 0; i < ARRAY_SIZE(chassis_types); i++) | 
|---|
| 780 | if (dmi_match(f: DMI_CHASSIS_TYPE, str: chassis_types[i])) | 
|---|
| 781 | return true; | 
|---|
| 782 |  | 
|---|
| 783 | return false; | 
|---|
| 784 | } | 
|---|
| 785 |  | 
|---|
| 786 | /* | 
|---|
| 787 | * On many modern laptops ATKBD_CMD_GETID may cause problems, on these laptops | 
|---|
| 788 | * the controller is always in translated mode. In this mode mice/touchpads will | 
|---|
| 789 | * not work. So in this case simply assume a keyboard is connected to avoid | 
|---|
| 790 | * confusing some laptop keyboards. | 
|---|
| 791 | * | 
|---|
| 792 | * Skipping ATKBD_CMD_GETID ends up using a fake keyboard id. Using the standard | 
|---|
| 793 | * 0xab83 id is ok in translated mode, only atkbd_select_set() checks atkbd->id | 
|---|
| 794 | * and in translated mode that is a no-op. | 
|---|
| 795 | */ | 
|---|
| 796 | static bool atkbd_skip_getid(struct atkbd *atkbd) | 
|---|
| 797 | { | 
|---|
| 798 | return atkbd->translated && atkbd_is_portable_device(); | 
|---|
| 799 | } | 
|---|
| 800 | #else | 
|---|
| 801 | static inline bool atkbd_skip_getid(struct atkbd *atkbd) { return false; } | 
|---|
| 802 | #endif | 
|---|
| 803 |  | 
|---|
| 804 | /* | 
|---|
| 805 | * atkbd_probe() probes for an AT keyboard on a serio port. | 
|---|
| 806 | */ | 
|---|
| 807 |  | 
|---|
| 808 | static int atkbd_probe(struct atkbd *atkbd) | 
|---|
| 809 | { | 
|---|
| 810 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 
|---|
| 811 | unsigned char param[2]; | 
|---|
| 812 |  | 
|---|
| 813 | /* | 
|---|
| 814 | * Some systems, where the bit-twiddling when testing the io-lines of the | 
|---|
| 815 | * controller may confuse the keyboard need a full reset of the keyboard. On | 
|---|
| 816 | * these systems the BIOS also usually doesn't do it for us. | 
|---|
| 817 | */ | 
|---|
| 818 |  | 
|---|
| 819 | if (atkbd_reset) | 
|---|
| 820 | if (ps2_command(ps2dev, NULL, ATKBD_CMD_RESET_BAT)) | 
|---|
| 821 | dev_warn(&ps2dev->serio->dev, | 
|---|
| 822 | "keyboard reset failed on %s\n", | 
|---|
| 823 | ps2dev->serio->phys); | 
|---|
| 824 |  | 
|---|
| 825 | if (atkbd_skip_getid(atkbd)) { | 
|---|
| 826 | atkbd->id = 0xab83; | 
|---|
| 827 | goto deactivate_kbd; | 
|---|
| 828 | } | 
|---|
| 829 |  | 
|---|
| 830 | /* | 
|---|
| 831 | * Then we check the keyboard ID. We should get 0xab83 under normal conditions. | 
|---|
| 832 | * Some keyboards report different values, but the first byte is always 0xab or | 
|---|
| 833 | * 0xac. Some old AT keyboards don't report anything. If a mouse is connected, this | 
|---|
| 834 | * should make sure we don't try to set the LEDs on it. | 
|---|
| 835 | */ | 
|---|
| 836 |  | 
|---|
| 837 | param[0] = param[1] = 0xa5;	/* initialize with invalid values */ | 
|---|
| 838 | if (ps2_command(ps2dev, param, ATKBD_CMD_GETID)) { | 
|---|
| 839 |  | 
|---|
| 840 | /* | 
|---|
| 841 | * If the get ID command failed, we check if we can at least set | 
|---|
| 842 | * the LEDs on the keyboard. This should work on every keyboard out there. | 
|---|
| 843 | * It also turns the LEDs off, which we want anyway. | 
|---|
| 844 | */ | 
|---|
| 845 | param[0] = 0; | 
|---|
| 846 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) | 
|---|
| 847 | return -1; | 
|---|
| 848 | atkbd->id = 0xabba; | 
|---|
| 849 | return 0; | 
|---|
| 850 | } | 
|---|
| 851 |  | 
|---|
| 852 | if (!ps2_is_keyboard_id(id: param[0])) | 
|---|
| 853 | return -1; | 
|---|
| 854 |  | 
|---|
| 855 | atkbd->id = (param[0] << 8) | param[1]; | 
|---|
| 856 |  | 
|---|
| 857 | if (atkbd->id == 0xaca1 && atkbd->translated) { | 
|---|
| 858 | dev_err(&ps2dev->serio->dev, | 
|---|
| 859 | "NCD terminal keyboards are only supported on non-translating controllers. " | 
|---|
| 860 | "Use i8042.direct=1 to disable translation.\n"); | 
|---|
| 861 | return -1; | 
|---|
| 862 | } | 
|---|
| 863 |  | 
|---|
| 864 | deactivate_kbd: | 
|---|
| 865 | /* | 
|---|
| 866 | * Make sure nothing is coming from the keyboard and disturbs our | 
|---|
| 867 | * internal state. | 
|---|
| 868 | */ | 
|---|
| 869 | if (!atkbd_skip_deactivate) | 
|---|
| 870 | atkbd_deactivate(atkbd); | 
|---|
| 871 |  | 
|---|
| 872 | return 0; | 
|---|
| 873 | } | 
|---|
| 874 |  | 
|---|
| 875 | /* | 
|---|
| 876 | * atkbd_select_set checks if a keyboard has a working Set 3 support, and | 
|---|
| 877 | * sets it into that. Unfortunately there are keyboards that can be switched | 
|---|
| 878 | * to Set 3, but don't work well in that (BTC Multimedia ...) | 
|---|
| 879 | */ | 
|---|
| 880 |  | 
|---|
| 881 | static int atkbd_select_set(struct atkbd *atkbd, int target_set, int ) | 
|---|
| 882 | { | 
|---|
| 883 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 
|---|
| 884 | unsigned char param[2]; | 
|---|
| 885 |  | 
|---|
| 886 | atkbd->extra = false; | 
|---|
| 887 | /* | 
|---|
| 888 | * For known special keyboards we can go ahead and set the correct set. | 
|---|
| 889 | * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and | 
|---|
| 890 | * IBM RapidAccess / IBM EzButton / Chicony KBP-8993 keyboards. | 
|---|
| 891 | */ | 
|---|
| 892 |  | 
|---|
| 893 | if (atkbd->translated) | 
|---|
| 894 | return 2; | 
|---|
| 895 |  | 
|---|
| 896 | if (atkbd->id == 0xaca1) { | 
|---|
| 897 | param[0] = 3; | 
|---|
| 898 | ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET); | 
|---|
| 899 | return 3; | 
|---|
| 900 | } | 
|---|
| 901 |  | 
|---|
| 902 | if (allow_extra) { | 
|---|
| 903 | param[0] = 0x71; | 
|---|
| 904 | if (!ps2_command(ps2dev, param, ATKBD_CMD_EX_ENABLE)) { | 
|---|
| 905 | atkbd->extra = true; | 
|---|
| 906 | return 2; | 
|---|
| 907 | } | 
|---|
| 908 | } | 
|---|
| 909 |  | 
|---|
| 910 | if (atkbd_terminal) { | 
|---|
| 911 | ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MB); | 
|---|
| 912 | return 3; | 
|---|
| 913 | } | 
|---|
| 914 |  | 
|---|
| 915 | if (target_set != 3) | 
|---|
| 916 | return 2; | 
|---|
| 917 |  | 
|---|
| 918 | if (!ps2_command(ps2dev, param, ATKBD_CMD_OK_GETID)) { | 
|---|
| 919 | atkbd->id = param[0] << 8 | param[1]; | 
|---|
| 920 | return 2; | 
|---|
| 921 | } | 
|---|
| 922 |  | 
|---|
| 923 | param[0] = 3; | 
|---|
| 924 | if (ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET)) | 
|---|
| 925 | return 2; | 
|---|
| 926 |  | 
|---|
| 927 | param[0] = 0; | 
|---|
| 928 | if (ps2_command(ps2dev, param, ATKBD_CMD_GSCANSET)) | 
|---|
| 929 | return 2; | 
|---|
| 930 |  | 
|---|
| 931 | if (param[0] != 3) { | 
|---|
| 932 | param[0] = 2; | 
|---|
| 933 | if (ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET)) | 
|---|
| 934 | return 2; | 
|---|
| 935 | } | 
|---|
| 936 |  | 
|---|
| 937 | ps2_command(ps2dev, param, ATKBD_CMD_SETALL_MBR); | 
|---|
| 938 |  | 
|---|
| 939 | return 3; | 
|---|
| 940 | } | 
|---|
| 941 |  | 
|---|
| 942 | static int atkbd_reset_state(struct atkbd *atkbd) | 
|---|
| 943 | { | 
|---|
| 944 | struct ps2dev *ps2dev = &atkbd->ps2dev; | 
|---|
| 945 | unsigned char param[1]; | 
|---|
| 946 |  | 
|---|
| 947 | /* | 
|---|
| 948 | * Set the LEDs to a predefined state (all off). | 
|---|
| 949 | */ | 
|---|
| 950 |  | 
|---|
| 951 | param[0] = 0; | 
|---|
| 952 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETLEDS)) | 
|---|
| 953 | return -1; | 
|---|
| 954 |  | 
|---|
| 955 | /* | 
|---|
| 956 | * Set autorepeat to fastest possible. | 
|---|
| 957 | */ | 
|---|
| 958 |  | 
|---|
| 959 | param[0] = 0; | 
|---|
| 960 | if (ps2_command(ps2dev, param, ATKBD_CMD_SETREP)) | 
|---|
| 961 | return -1; | 
|---|
| 962 |  | 
|---|
| 963 | return 0; | 
|---|
| 964 | } | 
|---|
| 965 |  | 
|---|
| 966 | /* | 
|---|
| 967 | * atkbd_cleanup() restores the keyboard state so that BIOS is happy after a | 
|---|
| 968 | * reboot. | 
|---|
| 969 | */ | 
|---|
| 970 |  | 
|---|
| 971 | static void atkbd_cleanup(struct serio *serio) | 
|---|
| 972 | { | 
|---|
| 973 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 974 |  | 
|---|
| 975 | atkbd_disable(atkbd); | 
|---|
| 976 | ps2_command(ps2dev: &atkbd->ps2dev, NULL, ATKBD_CMD_RESET_DEF); | 
|---|
| 977 | } | 
|---|
| 978 |  | 
|---|
| 979 |  | 
|---|
| 980 | /* | 
|---|
| 981 | * atkbd_disconnect() closes and frees. | 
|---|
| 982 | */ | 
|---|
| 983 |  | 
|---|
| 984 | static void atkbd_disconnect(struct serio *serio) | 
|---|
| 985 | { | 
|---|
| 986 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 987 |  | 
|---|
| 988 | atkbd_disable(atkbd); | 
|---|
| 989 |  | 
|---|
| 990 | input_unregister_device(atkbd->dev); | 
|---|
| 991 |  | 
|---|
| 992 | /* | 
|---|
| 993 | * Make sure we don't have a command in flight. | 
|---|
| 994 | * Note that since atkbd->enabled is false event work will keep | 
|---|
| 995 | * rescheduling itself until it gets canceled and will not try | 
|---|
| 996 | * accessing freed input device or serio port. | 
|---|
| 997 | */ | 
|---|
| 998 | cancel_delayed_work_sync(dwork: &atkbd->event_work); | 
|---|
| 999 |  | 
|---|
| 1000 | serio_close(serio); | 
|---|
| 1001 | serio_set_drvdata(serio, NULL); | 
|---|
| 1002 | kfree(objp: atkbd); | 
|---|
| 1003 | } | 
|---|
| 1004 |  | 
|---|
| 1005 | /* | 
|---|
| 1006 | * generate release events for the keycodes given in data | 
|---|
| 1007 | */ | 
|---|
| 1008 | static void atkbd_apply_forced_release_keylist(struct atkbd* atkbd, | 
|---|
| 1009 | const void *data) | 
|---|
| 1010 | { | 
|---|
| 1011 | const unsigned int *keys = data; | 
|---|
| 1012 | unsigned int i; | 
|---|
| 1013 |  | 
|---|
| 1014 | if (atkbd->set == 2) | 
|---|
| 1015 | for (i = 0; keys[i] != -1U; i++) | 
|---|
| 1016 | __set_bit(keys[i], atkbd->force_release_mask); | 
|---|
| 1017 | } | 
|---|
| 1018 |  | 
|---|
| 1019 | /* | 
|---|
| 1020 | * Most special keys (Fn+F?) on Dell laptops do not generate release | 
|---|
| 1021 | * events so we have to do it ourselves. | 
|---|
| 1022 | */ | 
|---|
| 1023 | static unsigned int atkbd_dell_laptop_forced_release_keys[] = { | 
|---|
| 1024 | 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8f, 0x93, -1U | 
|---|
| 1025 | }; | 
|---|
| 1026 |  | 
|---|
| 1027 | /* | 
|---|
| 1028 | * Perform fixup for HP system that doesn't generate release | 
|---|
| 1029 | * for its video switch | 
|---|
| 1030 | */ | 
|---|
| 1031 | static unsigned int atkbd_hp_forced_release_keys[] = { | 
|---|
| 1032 | 0x94, -1U | 
|---|
| 1033 | }; | 
|---|
| 1034 |  | 
|---|
| 1035 | /* | 
|---|
| 1036 | * Samsung NC10,NC20 with Fn+F? key release not working | 
|---|
| 1037 | */ | 
|---|
| 1038 | static unsigned int atkbd_samsung_forced_release_keys[] = { | 
|---|
| 1039 | 0x82, 0x83, 0x84, 0x86, 0x88, 0x89, 0xb3, 0xf7, 0xf9, -1U | 
|---|
| 1040 | }; | 
|---|
| 1041 |  | 
|---|
| 1042 | /* | 
|---|
| 1043 | * Amilo Pi 3525 key release for Fn+Volume keys not working | 
|---|
| 1044 | */ | 
|---|
| 1045 | static unsigned int atkbd_amilo_pi3525_forced_release_keys[] = { | 
|---|
| 1046 | 0x20, 0xa0, 0x2e, 0xae, 0x30, 0xb0, -1U | 
|---|
| 1047 | }; | 
|---|
| 1048 |  | 
|---|
| 1049 | /* | 
|---|
| 1050 | * Amilo Xi 3650 key release for light touch bar not working | 
|---|
| 1051 | */ | 
|---|
| 1052 | static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = { | 
|---|
| 1053 | 0x67, 0xed, 0x90, 0xa2, 0x99, 0xa4, 0xae, 0xb0, -1U | 
|---|
| 1054 | }; | 
|---|
| 1055 |  | 
|---|
| 1056 | /* | 
|---|
| 1057 | * Soltech TA12 system with broken key release on volume keys and mute key | 
|---|
| 1058 | */ | 
|---|
| 1059 | static unsigned int atkdb_soltech_ta12_forced_release_keys[] = { | 
|---|
| 1060 | 0xa0, 0xae, 0xb0, -1U | 
|---|
| 1061 | }; | 
|---|
| 1062 |  | 
|---|
| 1063 | /* | 
|---|
| 1064 | * Many notebooks don't send key release event for volume up/down | 
|---|
| 1065 | * keys, with key list below common among them | 
|---|
| 1066 | */ | 
|---|
| 1067 | static unsigned int atkbd_volume_forced_release_keys[] = { | 
|---|
| 1068 | 0xae, 0xb0, -1U | 
|---|
| 1069 | }; | 
|---|
| 1070 |  | 
|---|
| 1071 | /* | 
|---|
| 1072 | * OQO 01+ multimedia keys (64--66) generate e0 6x upon release whereas | 
|---|
| 1073 | * they should be generating e4-e6 (0x80 | code). | 
|---|
| 1074 | */ | 
|---|
| 1075 | static unsigned int atkbd_oqo_01plus_scancode_fixup(struct atkbd *atkbd, | 
|---|
| 1076 | unsigned int code) | 
|---|
| 1077 | { | 
|---|
| 1078 | if (atkbd->translated && atkbd->emul == 1 && | 
|---|
| 1079 | (code == 0x64 || code == 0x65 || code == 0x66)) { | 
|---|
| 1080 | atkbd->emul = 0; | 
|---|
| 1081 | code |= 0x80; | 
|---|
| 1082 | } | 
|---|
| 1083 |  | 
|---|
| 1084 | return code; | 
|---|
| 1085 | } | 
|---|
| 1086 |  | 
|---|
| 1087 | static int atkbd_get_keymap_from_fwnode(struct atkbd *atkbd) | 
|---|
| 1088 | { | 
|---|
| 1089 | struct device *dev = &atkbd->ps2dev.serio->dev; | 
|---|
| 1090 | int i, n; | 
|---|
| 1091 | u32 *ptr; | 
|---|
| 1092 | u16 scancode, keycode; | 
|---|
| 1093 |  | 
|---|
| 1094 | /* Parse "linux,keymap" property */ | 
|---|
| 1095 | n = device_property_count_u32(dev, propname: "linux,keymap"); | 
|---|
| 1096 | if (n <= 0 || n > ATKBD_KEYMAP_SIZE) | 
|---|
| 1097 | return -ENXIO; | 
|---|
| 1098 |  | 
|---|
| 1099 | ptr = kcalloc(n, sizeof(u32), GFP_KERNEL); | 
|---|
| 1100 | if (!ptr) | 
|---|
| 1101 | return -ENOMEM; | 
|---|
| 1102 |  | 
|---|
| 1103 | if (device_property_read_u32_array(dev, propname: "linux,keymap", val: ptr, nval: n)) { | 
|---|
| 1104 | dev_err(dev, "problem parsing FW keymap property\n"); | 
|---|
| 1105 | kfree(objp: ptr); | 
|---|
| 1106 | return -EINVAL; | 
|---|
| 1107 | } | 
|---|
| 1108 |  | 
|---|
| 1109 | memset(s: atkbd->keycode, c: 0, n: sizeof(atkbd->keycode)); | 
|---|
| 1110 | for (i = 0; i < n; i++) { | 
|---|
| 1111 | scancode = SCANCODE(ptr[i]); | 
|---|
| 1112 | keycode = KEYCODE(ptr[i]); | 
|---|
| 1113 | atkbd->keycode[scancode] = keycode; | 
|---|
| 1114 | } | 
|---|
| 1115 |  | 
|---|
| 1116 | kfree(objp: ptr); | 
|---|
| 1117 | return 0; | 
|---|
| 1118 | } | 
|---|
| 1119 |  | 
|---|
| 1120 | /* | 
|---|
| 1121 | * atkbd_set_keycode_table() initializes keyboard's keycode table | 
|---|
| 1122 | * according to the selected scancode set | 
|---|
| 1123 | */ | 
|---|
| 1124 |  | 
|---|
| 1125 | static void atkbd_set_keycode_table(struct atkbd *atkbd) | 
|---|
| 1126 | { | 
|---|
| 1127 | struct device *dev = &atkbd->ps2dev.serio->dev; | 
|---|
| 1128 | unsigned int scancode; | 
|---|
| 1129 | int i, j; | 
|---|
| 1130 |  | 
|---|
| 1131 | memset(s: atkbd->keycode, c: 0, n: sizeof(atkbd->keycode)); | 
|---|
| 1132 | bitmap_zero(dst: atkbd->force_release_mask, ATKBD_KEYMAP_SIZE); | 
|---|
| 1133 |  | 
|---|
| 1134 | if (!atkbd_get_keymap_from_fwnode(atkbd)) { | 
|---|
| 1135 | dev_dbg(dev, "Using FW keymap\n"); | 
|---|
| 1136 | } else if (atkbd->translated) { | 
|---|
| 1137 | for (i = 0; i < 128; i++) { | 
|---|
| 1138 | scancode = atkbd_unxlate_table[i]; | 
|---|
| 1139 | atkbd->keycode[i] = atkbd_set2_keycode[scancode]; | 
|---|
| 1140 | atkbd->keycode[i | 0x80] = atkbd_set2_keycode[scancode | 0x80]; | 
|---|
| 1141 | if (atkbd->scroll) | 
|---|
| 1142 | for (j = 0; j < ARRAY_SIZE(atkbd_scroll_keys); j++) | 
|---|
| 1143 | if ((scancode | 0x80) == atkbd_scroll_keys[j].set2) | 
|---|
| 1144 | atkbd->keycode[i | 0x80] = atkbd_scroll_keys[j].keycode; | 
|---|
| 1145 | } | 
|---|
| 1146 | } else if (atkbd->set == 3) { | 
|---|
| 1147 | memcpy(to: atkbd->keycode, from: atkbd_set3_keycode, len: sizeof(atkbd->keycode)); | 
|---|
| 1148 | } else { | 
|---|
| 1149 | memcpy(to: atkbd->keycode, from: atkbd_set2_keycode, len: sizeof(atkbd->keycode)); | 
|---|
| 1150 |  | 
|---|
| 1151 | if (atkbd->scroll) | 
|---|
| 1152 | for (i = 0; i < ARRAY_SIZE(atkbd_scroll_keys); i++) { | 
|---|
| 1153 | scancode = atkbd_scroll_keys[i].set2; | 
|---|
| 1154 | atkbd->keycode[scancode] = atkbd_scroll_keys[i].keycode; | 
|---|
| 1155 | } | 
|---|
| 1156 | } | 
|---|
| 1157 |  | 
|---|
| 1158 | /* | 
|---|
| 1159 | * HANGEUL and HANJA keys do not send release events so we need to | 
|---|
| 1160 | * generate such events ourselves | 
|---|
| 1161 | */ | 
|---|
| 1162 | scancode = atkbd_compat_scancode(atkbd, ATKBD_RET_HANGEUL); | 
|---|
| 1163 | atkbd->keycode[scancode] = KEY_HANGEUL; | 
|---|
| 1164 | __set_bit(scancode, atkbd->force_release_mask); | 
|---|
| 1165 |  | 
|---|
| 1166 | scancode = atkbd_compat_scancode(atkbd, ATKBD_RET_HANJA); | 
|---|
| 1167 | atkbd->keycode[scancode] = KEY_HANJA; | 
|---|
| 1168 | __set_bit(scancode, atkbd->force_release_mask); | 
|---|
| 1169 |  | 
|---|
| 1170 | /* | 
|---|
| 1171 | * Perform additional fixups | 
|---|
| 1172 | */ | 
|---|
| 1173 | if (atkbd_platform_fixup) | 
|---|
| 1174 | atkbd_platform_fixup(atkbd, atkbd_platform_fixup_data); | 
|---|
| 1175 | } | 
|---|
| 1176 |  | 
|---|
| 1177 | /* | 
|---|
| 1178 | * atkbd_set_device_attrs() sets up keyboard's input device structure | 
|---|
| 1179 | */ | 
|---|
| 1180 |  | 
|---|
| 1181 | static void atkbd_set_device_attrs(struct atkbd *atkbd) | 
|---|
| 1182 | { | 
|---|
| 1183 | struct input_dev *input_dev = atkbd->dev; | 
|---|
| 1184 | int i; | 
|---|
| 1185 |  | 
|---|
| 1186 | if (atkbd->extra) | 
|---|
| 1187 | snprintf(buf: atkbd->name, size: sizeof(atkbd->name), | 
|---|
| 1188 | fmt: "AT Set 2 Extra keyboard"); | 
|---|
| 1189 | else | 
|---|
| 1190 | snprintf(buf: atkbd->name, size: sizeof(atkbd->name), | 
|---|
| 1191 | fmt: "AT %s Set %d keyboard", | 
|---|
| 1192 | atkbd->translated ? "Translated": "Raw", atkbd->set); | 
|---|
| 1193 |  | 
|---|
| 1194 | scnprintf(buf: atkbd->phys, size: sizeof(atkbd->phys), | 
|---|
| 1195 | fmt: "%s/input0", atkbd->ps2dev.serio->phys); | 
|---|
| 1196 |  | 
|---|
| 1197 | input_dev->name = atkbd->name; | 
|---|
| 1198 | input_dev->phys = atkbd->phys; | 
|---|
| 1199 | input_dev->id.bustype = BUS_I8042; | 
|---|
| 1200 | input_dev->id.vendor = 0x0001; | 
|---|
| 1201 | input_dev->id.product = atkbd->translated ? 1 : atkbd->set; | 
|---|
| 1202 | input_dev->id.version = atkbd->id; | 
|---|
| 1203 | input_dev->event = atkbd_event; | 
|---|
| 1204 | input_dev->dev.parent = &atkbd->ps2dev.serio->dev; | 
|---|
| 1205 |  | 
|---|
| 1206 | input_set_drvdata(dev: input_dev, data: atkbd); | 
|---|
| 1207 |  | 
|---|
| 1208 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | | 
|---|
| 1209 | BIT_MASK(EV_MSC); | 
|---|
| 1210 |  | 
|---|
| 1211 | if (atkbd->write) { | 
|---|
| 1212 | input_dev->evbit[0] |= BIT_MASK(EV_LED); | 
|---|
| 1213 | input_dev->ledbit[0] = BIT_MASK(LED_NUML) | | 
|---|
| 1214 | BIT_MASK(LED_CAPSL) | BIT_MASK(LED_SCROLLL); | 
|---|
| 1215 | } | 
|---|
| 1216 |  | 
|---|
| 1217 | if (atkbd->extra) | 
|---|
| 1218 | input_dev->ledbit[0] |= BIT_MASK(LED_COMPOSE) | | 
|---|
| 1219 | BIT_MASK(LED_SUSPEND) | BIT_MASK(LED_SLEEP) | | 
|---|
| 1220 | BIT_MASK(LED_MUTE) | BIT_MASK(LED_MISC); | 
|---|
| 1221 |  | 
|---|
| 1222 | if (!atkbd->softrepeat) { | 
|---|
| 1223 | input_dev->rep[REP_DELAY] = 250; | 
|---|
| 1224 | input_dev->rep[REP_PERIOD] = 33; | 
|---|
| 1225 | } | 
|---|
| 1226 |  | 
|---|
| 1227 | input_dev->mscbit[0] = atkbd->softraw ? BIT_MASK(MSC_SCAN) : | 
|---|
| 1228 | BIT_MASK(MSC_RAW) | BIT_MASK(MSC_SCAN); | 
|---|
| 1229 |  | 
|---|
| 1230 | if (atkbd->scroll) { | 
|---|
| 1231 | input_dev->evbit[0] |= BIT_MASK(EV_REL); | 
|---|
| 1232 | input_dev->relbit[0] = BIT_MASK(REL_WHEEL) | | 
|---|
| 1233 | BIT_MASK(REL_HWHEEL); | 
|---|
| 1234 | __set_bit(BTN_MIDDLE, input_dev->keybit); | 
|---|
| 1235 | } | 
|---|
| 1236 |  | 
|---|
| 1237 | input_dev->keycode = atkbd->keycode; | 
|---|
| 1238 | input_dev->keycodesize = sizeof(unsigned short); | 
|---|
| 1239 | input_dev->keycodemax = ARRAY_SIZE(atkbd_set2_keycode); | 
|---|
| 1240 |  | 
|---|
| 1241 | for (i = 0; i < ATKBD_KEYMAP_SIZE; i++) { | 
|---|
| 1242 | if (atkbd->keycode[i] != KEY_RESERVED && | 
|---|
| 1243 | atkbd->keycode[i] != ATKBD_KEY_NULL && | 
|---|
| 1244 | atkbd->keycode[i] < ATKBD_SPECIAL) { | 
|---|
| 1245 | __set_bit(atkbd->keycode[i], input_dev->keybit); | 
|---|
| 1246 | } | 
|---|
| 1247 | } | 
|---|
| 1248 | } | 
|---|
| 1249 |  | 
|---|
| 1250 | static void atkbd_parse_fwnode_data(struct serio *serio) | 
|---|
| 1251 | { | 
|---|
| 1252 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 1253 | struct device *dev = &serio->dev; | 
|---|
| 1254 | int n; | 
|---|
| 1255 |  | 
|---|
| 1256 | /* Parse "function-row-physmap" property */ | 
|---|
| 1257 | n = device_property_count_u32(dev, propname: "function-row-physmap"); | 
|---|
| 1258 | if (n > 0 && n <= VIVALDI_MAX_FUNCTION_ROW_KEYS && | 
|---|
| 1259 | !device_property_read_u32_array(dev, propname: "function-row-physmap", | 
|---|
| 1260 | val: atkbd->vdata.function_row_physmap, | 
|---|
| 1261 | nval: n)) { | 
|---|
| 1262 | atkbd->vdata.num_function_row_keys = n; | 
|---|
| 1263 | dev_dbg(dev, "FW reported %d function-row key locations\n", n); | 
|---|
| 1264 | } | 
|---|
| 1265 | } | 
|---|
| 1266 |  | 
|---|
| 1267 | /* | 
|---|
| 1268 | * atkbd_connect() is called when the serio module finds an interface | 
|---|
| 1269 | * that isn't handled yet by an appropriate device driver. We check if | 
|---|
| 1270 | * there is an AT keyboard out there and if yes, we register ourselves | 
|---|
| 1271 | * to the input module. | 
|---|
| 1272 | */ | 
|---|
| 1273 |  | 
|---|
| 1274 | static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | 
|---|
| 1275 | { | 
|---|
| 1276 | struct atkbd *atkbd; | 
|---|
| 1277 | struct input_dev *dev; | 
|---|
| 1278 | int err = -ENOMEM; | 
|---|
| 1279 |  | 
|---|
| 1280 | atkbd = kzalloc(sizeof(*atkbd), GFP_KERNEL); | 
|---|
| 1281 | dev = input_allocate_device(); | 
|---|
| 1282 | if (!atkbd || !dev) | 
|---|
| 1283 | goto fail1; | 
|---|
| 1284 |  | 
|---|
| 1285 | atkbd->dev = dev; | 
|---|
| 1286 | ps2_init(ps2dev: &atkbd->ps2dev, serio, | 
|---|
| 1287 | pre_receive_handler: atkbd_pre_receive_byte, receive_handler: atkbd_receive_byte); | 
|---|
| 1288 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); | 
|---|
| 1289 | mutex_init(&atkbd->mutex); | 
|---|
| 1290 |  | 
|---|
| 1291 | switch (serio->id.type) { | 
|---|
| 1292 |  | 
|---|
| 1293 | case SERIO_8042_XL: | 
|---|
| 1294 | atkbd->translated = true; | 
|---|
| 1295 | fallthrough; | 
|---|
| 1296 |  | 
|---|
| 1297 | case SERIO_8042: | 
|---|
| 1298 | if (serio->write) | 
|---|
| 1299 | atkbd->write = true; | 
|---|
| 1300 | break; | 
|---|
| 1301 | } | 
|---|
| 1302 |  | 
|---|
| 1303 | atkbd->softraw = atkbd_softraw; | 
|---|
| 1304 | atkbd->softrepeat = atkbd_softrepeat; | 
|---|
| 1305 | atkbd->scroll = atkbd_scroll; | 
|---|
| 1306 |  | 
|---|
| 1307 | if (atkbd->softrepeat) | 
|---|
| 1308 | atkbd->softraw = true; | 
|---|
| 1309 |  | 
|---|
| 1310 | serio_set_drvdata(serio, data: atkbd); | 
|---|
| 1311 |  | 
|---|
| 1312 | err = serio_open(serio, drv); | 
|---|
| 1313 | if (err) | 
|---|
| 1314 | goto fail2; | 
|---|
| 1315 |  | 
|---|
| 1316 | if (atkbd->write) { | 
|---|
| 1317 |  | 
|---|
| 1318 | if (atkbd_probe(atkbd)) { | 
|---|
| 1319 | err = -ENODEV; | 
|---|
| 1320 | goto fail3; | 
|---|
| 1321 | } | 
|---|
| 1322 |  | 
|---|
| 1323 | atkbd->set = atkbd_select_set(atkbd, target_set: atkbd_set, allow_extra: atkbd_extra); | 
|---|
| 1324 | atkbd_reset_state(atkbd); | 
|---|
| 1325 |  | 
|---|
| 1326 | } else { | 
|---|
| 1327 | atkbd->set = 2; | 
|---|
| 1328 | atkbd->id = 0xab00; | 
|---|
| 1329 | } | 
|---|
| 1330 |  | 
|---|
| 1331 | atkbd_parse_fwnode_data(serio); | 
|---|
| 1332 |  | 
|---|
| 1333 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1334 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1335 |  | 
|---|
| 1336 | atkbd_enable(atkbd); | 
|---|
| 1337 | if (serio->write) | 
|---|
| 1338 | atkbd_activate(atkbd); | 
|---|
| 1339 |  | 
|---|
| 1340 | err = input_register_device(atkbd->dev); | 
|---|
| 1341 | if (err) | 
|---|
| 1342 | goto fail3; | 
|---|
| 1343 |  | 
|---|
| 1344 | return 0; | 
|---|
| 1345 |  | 
|---|
| 1346 | fail3:	serio_close(serio); | 
|---|
| 1347 | fail2:	serio_set_drvdata(serio, NULL); | 
|---|
| 1348 | fail1:	input_free_device(dev); | 
|---|
| 1349 | kfree(objp: atkbd); | 
|---|
| 1350 | return err; | 
|---|
| 1351 | } | 
|---|
| 1352 |  | 
|---|
| 1353 | /* | 
|---|
| 1354 | * atkbd_reconnect() tries to restore keyboard into a sane state and is | 
|---|
| 1355 | * most likely called on resume. | 
|---|
| 1356 | */ | 
|---|
| 1357 |  | 
|---|
| 1358 | static int atkbd_reconnect(struct serio *serio) | 
|---|
| 1359 | { | 
|---|
| 1360 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 1361 | struct serio_driver *drv = serio->drv; | 
|---|
| 1362 | int error; | 
|---|
| 1363 |  | 
|---|
| 1364 | if (!atkbd || !drv) { | 
|---|
| 1365 | dev_dbg(&serio->dev, | 
|---|
| 1366 | "reconnect request, but serio is disconnected, ignoring...\n"); | 
|---|
| 1367 | return -1; | 
|---|
| 1368 | } | 
|---|
| 1369 |  | 
|---|
| 1370 | guard(mutex)(T: &atkbd->mutex); | 
|---|
| 1371 |  | 
|---|
| 1372 | atkbd_disable(atkbd); | 
|---|
| 1373 |  | 
|---|
| 1374 | if (atkbd->write) { | 
|---|
| 1375 | error = atkbd_probe(atkbd); | 
|---|
| 1376 | if (error) | 
|---|
| 1377 | return error; | 
|---|
| 1378 |  | 
|---|
| 1379 | if (atkbd->set != atkbd_select_set(atkbd, target_set: atkbd->set, allow_extra: atkbd->extra)) | 
|---|
| 1380 | return -EIO; | 
|---|
| 1381 |  | 
|---|
| 1382 | /* | 
|---|
| 1383 | * Restore LED state and repeat rate. While input core | 
|---|
| 1384 | * will do this for us at resume time reconnect may happen | 
|---|
| 1385 | * because user requested it via sysfs or simply because | 
|---|
| 1386 | * keyboard was unplugged and plugged in again so we need | 
|---|
| 1387 | * to do it ourselves here. | 
|---|
| 1388 | */ | 
|---|
| 1389 | atkbd_set_leds(atkbd); | 
|---|
| 1390 | if (!atkbd->softrepeat) | 
|---|
| 1391 | atkbd_set_repeat_rate(atkbd); | 
|---|
| 1392 |  | 
|---|
| 1393 | } | 
|---|
| 1394 |  | 
|---|
| 1395 | /* | 
|---|
| 1396 | * Reset our state machine in case reconnect happened in the middle | 
|---|
| 1397 | * of multi-byte scancode. | 
|---|
| 1398 | */ | 
|---|
| 1399 | atkbd->xl_bit = 0; | 
|---|
| 1400 | atkbd->emul = 0; | 
|---|
| 1401 |  | 
|---|
| 1402 | atkbd_enable(atkbd); | 
|---|
| 1403 | if (atkbd->write) | 
|---|
| 1404 | atkbd_activate(atkbd); | 
|---|
| 1405 |  | 
|---|
| 1406 | return 0; | 
|---|
| 1407 | } | 
|---|
| 1408 |  | 
|---|
| 1409 | static const struct serio_device_id atkbd_serio_ids[] = { | 
|---|
| 1410 | { | 
|---|
| 1411 | .type	= SERIO_8042, | 
|---|
| 1412 | .proto	= SERIO_ANY, | 
|---|
| 1413 | .id	= SERIO_ANY, | 
|---|
| 1414 | .extra	= SERIO_ANY, | 
|---|
| 1415 | }, | 
|---|
| 1416 | { | 
|---|
| 1417 | .type	= SERIO_8042_XL, | 
|---|
| 1418 | .proto	= SERIO_ANY, | 
|---|
| 1419 | .id	= SERIO_ANY, | 
|---|
| 1420 | .extra	= SERIO_ANY, | 
|---|
| 1421 | }, | 
|---|
| 1422 | { | 
|---|
| 1423 | .type	= SERIO_RS232, | 
|---|
| 1424 | .proto	= SERIO_PS2SER, | 
|---|
| 1425 | .id	= SERIO_ANY, | 
|---|
| 1426 | .extra	= SERIO_ANY, | 
|---|
| 1427 | }, | 
|---|
| 1428 | { 0 } | 
|---|
| 1429 | }; | 
|---|
| 1430 |  | 
|---|
| 1431 | MODULE_DEVICE_TABLE(serio, atkbd_serio_ids); | 
|---|
| 1432 |  | 
|---|
| 1433 | static struct serio_driver atkbd_drv = { | 
|---|
| 1434 | .driver		= { | 
|---|
| 1435 | .name		= "atkbd", | 
|---|
| 1436 | .dev_groups	= atkbd_attribute_groups, | 
|---|
| 1437 | }, | 
|---|
| 1438 | .description	= DRIVER_DESC, | 
|---|
| 1439 | .id_table	= atkbd_serio_ids, | 
|---|
| 1440 | .interrupt	= ps2_interrupt, | 
|---|
| 1441 | .connect	= atkbd_connect, | 
|---|
| 1442 | .reconnect	= atkbd_reconnect, | 
|---|
| 1443 | .disconnect	= atkbd_disconnect, | 
|---|
| 1444 | .cleanup	= atkbd_cleanup, | 
|---|
| 1445 | }; | 
|---|
| 1446 |  | 
|---|
| 1447 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | 
|---|
| 1448 | ssize_t (*handler)(struct atkbd *, char *)) | 
|---|
| 1449 | { | 
|---|
| 1450 | struct serio *serio = to_serio_port(dev); | 
|---|
| 1451 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 1452 |  | 
|---|
| 1453 | return handler(atkbd, buf); | 
|---|
| 1454 | } | 
|---|
| 1455 |  | 
|---|
| 1456 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 
|---|
| 1457 | ssize_t (*handler)(struct atkbd *, const char *, size_t)) | 
|---|
| 1458 | { | 
|---|
| 1459 | struct serio *serio = to_serio_port(dev); | 
|---|
| 1460 | struct atkbd *atkbd = atkbd_from_serio(serio); | 
|---|
| 1461 | int retval; | 
|---|
| 1462 |  | 
|---|
| 1463 | scoped_guard(mutex_intr, &atkbd->mutex) { | 
|---|
| 1464 | atkbd_disable(atkbd); | 
|---|
| 1465 | retval = handler(atkbd, buf, count); | 
|---|
| 1466 | atkbd_enable(atkbd); | 
|---|
| 1467 |  | 
|---|
| 1468 | return retval; | 
|---|
| 1469 | } | 
|---|
| 1470 |  | 
|---|
| 1471 | return -EINTR; | 
|---|
| 1472 | } | 
|---|
| 1473 |  | 
|---|
| 1474 | static ssize_t (struct atkbd *atkbd, char *buf) | 
|---|
| 1475 | { | 
|---|
| 1476 | return sprintf(buf, fmt: "%d\n", atkbd->extra ? 1 : 0); | 
|---|
| 1477 | } | 
|---|
| 1478 |  | 
|---|
| 1479 | static ssize_t (struct atkbd *atkbd, const char *buf, size_t count) | 
|---|
| 1480 | { | 
|---|
| 1481 | struct input_dev *old_dev, *new_dev; | 
|---|
| 1482 | unsigned int value; | 
|---|
| 1483 | int err; | 
|---|
| 1484 | bool ; | 
|---|
| 1485 | unsigned char old_set; | 
|---|
| 1486 |  | 
|---|
| 1487 | if (!atkbd->write) | 
|---|
| 1488 | return -EIO; | 
|---|
| 1489 |  | 
|---|
| 1490 | err = kstrtouint(s: buf, base: 10, res: &value); | 
|---|
| 1491 | if (err) | 
|---|
| 1492 | return err; | 
|---|
| 1493 |  | 
|---|
| 1494 | if (value > 1) | 
|---|
| 1495 | return -EINVAL; | 
|---|
| 1496 |  | 
|---|
| 1497 | if (atkbd->extra != value) { | 
|---|
| 1498 | /* | 
|---|
| 1499 | * Since device's properties will change we need to | 
|---|
| 1500 | * unregister old device. But allocate and register | 
|---|
| 1501 | * new one first to make sure we have it. | 
|---|
| 1502 | */ | 
|---|
| 1503 | old_dev = atkbd->dev; | 
|---|
| 1504 | old_extra = atkbd->extra; | 
|---|
| 1505 | old_set = atkbd->set; | 
|---|
| 1506 |  | 
|---|
| 1507 | new_dev = input_allocate_device(); | 
|---|
| 1508 | if (!new_dev) | 
|---|
| 1509 | return -ENOMEM; | 
|---|
| 1510 |  | 
|---|
| 1511 | atkbd->dev = new_dev; | 
|---|
| 1512 | atkbd->set = atkbd_select_set(atkbd, target_set: atkbd->set, allow_extra: value); | 
|---|
| 1513 | atkbd_reset_state(atkbd); | 
|---|
| 1514 | atkbd_activate(atkbd); | 
|---|
| 1515 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1516 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1517 |  | 
|---|
| 1518 | err = input_register_device(atkbd->dev); | 
|---|
| 1519 | if (err) { | 
|---|
| 1520 | input_free_device(dev: new_dev); | 
|---|
| 1521 |  | 
|---|
| 1522 | atkbd->dev = old_dev; | 
|---|
| 1523 | atkbd->set = atkbd_select_set(atkbd, target_set: old_set, allow_extra: old_extra); | 
|---|
| 1524 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1525 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1526 |  | 
|---|
| 1527 | return err; | 
|---|
| 1528 | } | 
|---|
| 1529 | input_unregister_device(old_dev); | 
|---|
| 1530 |  | 
|---|
| 1531 | } | 
|---|
| 1532 | return count; | 
|---|
| 1533 | } | 
|---|
| 1534 |  | 
|---|
| 1535 | static ssize_t atkbd_show_force_release(struct atkbd *atkbd, char *buf) | 
|---|
| 1536 | { | 
|---|
| 1537 | size_t len = scnprintf(buf, PAGE_SIZE - 1, fmt: "%*pbl", | 
|---|
| 1538 | ATKBD_KEYMAP_SIZE, atkbd->force_release_mask); | 
|---|
| 1539 |  | 
|---|
| 1540 | buf[len++] = '\n'; | 
|---|
| 1541 | buf[len] = '\0'; | 
|---|
| 1542 |  | 
|---|
| 1543 | return len; | 
|---|
| 1544 | } | 
|---|
| 1545 |  | 
|---|
| 1546 | static ssize_t atkbd_set_force_release(struct atkbd *atkbd, | 
|---|
| 1547 | const char *buf, size_t count) | 
|---|
| 1548 | { | 
|---|
| 1549 | /* 64 bytes on stack should be acceptable */ | 
|---|
| 1550 | DECLARE_BITMAP(new_mask, ATKBD_KEYMAP_SIZE); | 
|---|
| 1551 | int err; | 
|---|
| 1552 |  | 
|---|
| 1553 | err = bitmap_parselist(buf, maskp: new_mask, ATKBD_KEYMAP_SIZE); | 
|---|
| 1554 | if (err) | 
|---|
| 1555 | return err; | 
|---|
| 1556 |  | 
|---|
| 1557 | memcpy(to: atkbd->force_release_mask, from: new_mask, len: sizeof(atkbd->force_release_mask)); | 
|---|
| 1558 | return count; | 
|---|
| 1559 | } | 
|---|
| 1560 |  | 
|---|
| 1561 |  | 
|---|
| 1562 | static ssize_t atkbd_show_scroll(struct atkbd *atkbd, char *buf) | 
|---|
| 1563 | { | 
|---|
| 1564 | return sprintf(buf, fmt: "%d\n", atkbd->scroll ? 1 : 0); | 
|---|
| 1565 | } | 
|---|
| 1566 |  | 
|---|
| 1567 | static ssize_t atkbd_set_scroll(struct atkbd *atkbd, const char *buf, size_t count) | 
|---|
| 1568 | { | 
|---|
| 1569 | struct input_dev *old_dev, *new_dev; | 
|---|
| 1570 | unsigned int value; | 
|---|
| 1571 | int err; | 
|---|
| 1572 | bool old_scroll; | 
|---|
| 1573 |  | 
|---|
| 1574 | err = kstrtouint(s: buf, base: 10, res: &value); | 
|---|
| 1575 | if (err) | 
|---|
| 1576 | return err; | 
|---|
| 1577 |  | 
|---|
| 1578 | if (value > 1) | 
|---|
| 1579 | return -EINVAL; | 
|---|
| 1580 |  | 
|---|
| 1581 | if (atkbd->scroll != value) { | 
|---|
| 1582 | old_dev = atkbd->dev; | 
|---|
| 1583 | old_scroll = atkbd->scroll; | 
|---|
| 1584 |  | 
|---|
| 1585 | new_dev = input_allocate_device(); | 
|---|
| 1586 | if (!new_dev) | 
|---|
| 1587 | return -ENOMEM; | 
|---|
| 1588 |  | 
|---|
| 1589 | atkbd->dev = new_dev; | 
|---|
| 1590 | atkbd->scroll = value; | 
|---|
| 1591 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1592 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1593 |  | 
|---|
| 1594 | err = input_register_device(atkbd->dev); | 
|---|
| 1595 | if (err) { | 
|---|
| 1596 | input_free_device(dev: new_dev); | 
|---|
| 1597 |  | 
|---|
| 1598 | atkbd->scroll = old_scroll; | 
|---|
| 1599 | atkbd->dev = old_dev; | 
|---|
| 1600 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1601 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1602 |  | 
|---|
| 1603 | return err; | 
|---|
| 1604 | } | 
|---|
| 1605 | input_unregister_device(old_dev); | 
|---|
| 1606 | } | 
|---|
| 1607 | return count; | 
|---|
| 1608 | } | 
|---|
| 1609 |  | 
|---|
| 1610 | static ssize_t atkbd_show_set(struct atkbd *atkbd, char *buf) | 
|---|
| 1611 | { | 
|---|
| 1612 | return sprintf(buf, fmt: "%d\n", atkbd->set); | 
|---|
| 1613 | } | 
|---|
| 1614 |  | 
|---|
| 1615 | static ssize_t atkbd_set_set(struct atkbd *atkbd, const char *buf, size_t count) | 
|---|
| 1616 | { | 
|---|
| 1617 | struct input_dev *old_dev, *new_dev; | 
|---|
| 1618 | unsigned int value; | 
|---|
| 1619 | int err; | 
|---|
| 1620 | unsigned char old_set; | 
|---|
| 1621 | bool ; | 
|---|
| 1622 |  | 
|---|
| 1623 | if (!atkbd->write) | 
|---|
| 1624 | return -EIO; | 
|---|
| 1625 |  | 
|---|
| 1626 | err = kstrtouint(s: buf, base: 10, res: &value); | 
|---|
| 1627 | if (err) | 
|---|
| 1628 | return err; | 
|---|
| 1629 |  | 
|---|
| 1630 | if (value != 2 && value != 3) | 
|---|
| 1631 | return -EINVAL; | 
|---|
| 1632 |  | 
|---|
| 1633 | if (atkbd->set != value) { | 
|---|
| 1634 | old_dev = atkbd->dev; | 
|---|
| 1635 | old_extra = atkbd->extra; | 
|---|
| 1636 | old_set = atkbd->set; | 
|---|
| 1637 |  | 
|---|
| 1638 | new_dev = input_allocate_device(); | 
|---|
| 1639 | if (!new_dev) | 
|---|
| 1640 | return -ENOMEM; | 
|---|
| 1641 |  | 
|---|
| 1642 | atkbd->dev = new_dev; | 
|---|
| 1643 | atkbd->set = atkbd_select_set(atkbd, target_set: value, allow_extra: atkbd->extra); | 
|---|
| 1644 | atkbd_reset_state(atkbd); | 
|---|
| 1645 | atkbd_activate(atkbd); | 
|---|
| 1646 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1647 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1648 |  | 
|---|
| 1649 | err = input_register_device(atkbd->dev); | 
|---|
| 1650 | if (err) { | 
|---|
| 1651 | input_free_device(dev: new_dev); | 
|---|
| 1652 |  | 
|---|
| 1653 | atkbd->dev = old_dev; | 
|---|
| 1654 | atkbd->set = atkbd_select_set(atkbd, target_set: old_set, allow_extra: old_extra); | 
|---|
| 1655 | atkbd_set_keycode_table(atkbd); | 
|---|
| 1656 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1657 |  | 
|---|
| 1658 | return err; | 
|---|
| 1659 | } | 
|---|
| 1660 | input_unregister_device(old_dev); | 
|---|
| 1661 | } | 
|---|
| 1662 | return count; | 
|---|
| 1663 | } | 
|---|
| 1664 |  | 
|---|
| 1665 | static ssize_t atkbd_show_softrepeat(struct atkbd *atkbd, char *buf) | 
|---|
| 1666 | { | 
|---|
| 1667 | return sprintf(buf, fmt: "%d\n", atkbd->softrepeat ? 1 : 0); | 
|---|
| 1668 | } | 
|---|
| 1669 |  | 
|---|
| 1670 | static ssize_t atkbd_set_softrepeat(struct atkbd *atkbd, const char *buf, size_t count) | 
|---|
| 1671 | { | 
|---|
| 1672 | struct input_dev *old_dev, *new_dev; | 
|---|
| 1673 | unsigned int value; | 
|---|
| 1674 | int err; | 
|---|
| 1675 | bool old_softrepeat, old_softraw; | 
|---|
| 1676 |  | 
|---|
| 1677 | if (!atkbd->write) | 
|---|
| 1678 | return -EIO; | 
|---|
| 1679 |  | 
|---|
| 1680 | err = kstrtouint(s: buf, base: 10, res: &value); | 
|---|
| 1681 | if (err) | 
|---|
| 1682 | return err; | 
|---|
| 1683 |  | 
|---|
| 1684 | if (value > 1) | 
|---|
| 1685 | return -EINVAL; | 
|---|
| 1686 |  | 
|---|
| 1687 | if (atkbd->softrepeat != value) { | 
|---|
| 1688 | old_dev = atkbd->dev; | 
|---|
| 1689 | old_softrepeat = atkbd->softrepeat; | 
|---|
| 1690 | old_softraw = atkbd->softraw; | 
|---|
| 1691 |  | 
|---|
| 1692 | new_dev = input_allocate_device(); | 
|---|
| 1693 | if (!new_dev) | 
|---|
| 1694 | return -ENOMEM; | 
|---|
| 1695 |  | 
|---|
| 1696 | atkbd->dev = new_dev; | 
|---|
| 1697 | atkbd->softrepeat = value; | 
|---|
| 1698 | if (atkbd->softrepeat) | 
|---|
| 1699 | atkbd->softraw = true; | 
|---|
| 1700 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1701 |  | 
|---|
| 1702 | err = input_register_device(atkbd->dev); | 
|---|
| 1703 | if (err) { | 
|---|
| 1704 | input_free_device(dev: new_dev); | 
|---|
| 1705 |  | 
|---|
| 1706 | atkbd->dev = old_dev; | 
|---|
| 1707 | atkbd->softrepeat = old_softrepeat; | 
|---|
| 1708 | atkbd->softraw = old_softraw; | 
|---|
| 1709 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1710 |  | 
|---|
| 1711 | return err; | 
|---|
| 1712 | } | 
|---|
| 1713 | input_unregister_device(old_dev); | 
|---|
| 1714 | } | 
|---|
| 1715 | return count; | 
|---|
| 1716 | } | 
|---|
| 1717 |  | 
|---|
| 1718 |  | 
|---|
| 1719 | static ssize_t atkbd_show_softraw(struct atkbd *atkbd, char *buf) | 
|---|
| 1720 | { | 
|---|
| 1721 | return sprintf(buf, fmt: "%d\n", atkbd->softraw ? 1 : 0); | 
|---|
| 1722 | } | 
|---|
| 1723 |  | 
|---|
| 1724 | static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t count) | 
|---|
| 1725 | { | 
|---|
| 1726 | struct input_dev *old_dev, *new_dev; | 
|---|
| 1727 | unsigned int value; | 
|---|
| 1728 | int err; | 
|---|
| 1729 | bool old_softraw; | 
|---|
| 1730 |  | 
|---|
| 1731 | err = kstrtouint(s: buf, base: 10, res: &value); | 
|---|
| 1732 | if (err) | 
|---|
| 1733 | return err; | 
|---|
| 1734 |  | 
|---|
| 1735 | if (value > 1) | 
|---|
| 1736 | return -EINVAL; | 
|---|
| 1737 |  | 
|---|
| 1738 | if (atkbd->softraw != value) { | 
|---|
| 1739 | old_dev = atkbd->dev; | 
|---|
| 1740 | old_softraw = atkbd->softraw; | 
|---|
| 1741 |  | 
|---|
| 1742 | new_dev = input_allocate_device(); | 
|---|
| 1743 | if (!new_dev) | 
|---|
| 1744 | return -ENOMEM; | 
|---|
| 1745 |  | 
|---|
| 1746 | atkbd->dev = new_dev; | 
|---|
| 1747 | atkbd->softraw = value; | 
|---|
| 1748 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1749 |  | 
|---|
| 1750 | err = input_register_device(atkbd->dev); | 
|---|
| 1751 | if (err) { | 
|---|
| 1752 | input_free_device(dev: new_dev); | 
|---|
| 1753 |  | 
|---|
| 1754 | atkbd->dev = old_dev; | 
|---|
| 1755 | atkbd->softraw = old_softraw; | 
|---|
| 1756 | atkbd_set_device_attrs(atkbd); | 
|---|
| 1757 |  | 
|---|
| 1758 | return err; | 
|---|
| 1759 | } | 
|---|
| 1760 | input_unregister_device(old_dev); | 
|---|
| 1761 | } | 
|---|
| 1762 | return count; | 
|---|
| 1763 | } | 
|---|
| 1764 |  | 
|---|
| 1765 | static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf) | 
|---|
| 1766 | { | 
|---|
| 1767 | return sprintf(buf, fmt: "%lu\n", atkbd->err_count); | 
|---|
| 1768 | } | 
|---|
| 1769 |  | 
|---|
| 1770 | static int __init atkbd_setup_forced_release(const struct dmi_system_id *id) | 
|---|
| 1771 | { | 
|---|
| 1772 | atkbd_platform_fixup = atkbd_apply_forced_release_keylist; | 
|---|
| 1773 | atkbd_platform_fixup_data = id->driver_data; | 
|---|
| 1774 |  | 
|---|
| 1775 | return 1; | 
|---|
| 1776 | } | 
|---|
| 1777 |  | 
|---|
| 1778 | static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | 
|---|
| 1779 | { | 
|---|
| 1780 | atkbd_platform_scancode_fixup = id->driver_data; | 
|---|
| 1781 |  | 
|---|
| 1782 | return 1; | 
|---|
| 1783 | } | 
|---|
| 1784 |  | 
|---|
| 1785 | static int __init atkbd_deactivate_fixup(const struct dmi_system_id *id) | 
|---|
| 1786 | { | 
|---|
| 1787 | atkbd_skip_deactivate = true; | 
|---|
| 1788 | return 1; | 
|---|
| 1789 | } | 
|---|
| 1790 |  | 
|---|
| 1791 | /* | 
|---|
| 1792 | * NOTE: do not add any more "force release" quirks to this table.  The | 
|---|
| 1793 | * task of adjusting list of keys that should be "released" automatically | 
|---|
| 1794 | * by the driver is now delegated to userspace tools, such as udev, so | 
|---|
| 1795 | * submit such quirks there. | 
|---|
| 1796 | */ | 
|---|
| 1797 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { | 
|---|
| 1798 | { | 
|---|
| 1799 | .matches = { | 
|---|
| 1800 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 
|---|
| 1801 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 
|---|
| 1802 | }, | 
|---|
| 1803 | .callback = atkbd_setup_forced_release, | 
|---|
| 1804 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 
|---|
| 1805 | }, | 
|---|
| 1806 | { | 
|---|
| 1807 | .matches = { | 
|---|
| 1808 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), | 
|---|
| 1809 | DMI_MATCH(DMI_CHASSIS_TYPE, "8"), /* Portable */ | 
|---|
| 1810 | }, | 
|---|
| 1811 | .callback = atkbd_setup_forced_release, | 
|---|
| 1812 | .driver_data = atkbd_dell_laptop_forced_release_keys, | 
|---|
| 1813 | }, | 
|---|
| 1814 | { | 
|---|
| 1815 | .matches = { | 
|---|
| 1816 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 
|---|
| 1817 | DMI_MATCH(DMI_PRODUCT_NAME, "HP 2133"), | 
|---|
| 1818 | }, | 
|---|
| 1819 | .callback = atkbd_setup_forced_release, | 
|---|
| 1820 | .driver_data = atkbd_hp_forced_release_keys, | 
|---|
| 1821 | }, | 
|---|
| 1822 | { | 
|---|
| 1823 | .matches = { | 
|---|
| 1824 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 
|---|
| 1825 | DMI_MATCH(DMI_PRODUCT_NAME, "Pavilion ZV6100"), | 
|---|
| 1826 | }, | 
|---|
| 1827 | .callback = atkbd_setup_forced_release, | 
|---|
| 1828 | .driver_data = atkbd_volume_forced_release_keys, | 
|---|
| 1829 | }, | 
|---|
| 1830 | { | 
|---|
| 1831 | .matches = { | 
|---|
| 1832 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 
|---|
| 1833 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4000"), | 
|---|
| 1834 | }, | 
|---|
| 1835 | .callback = atkbd_setup_forced_release, | 
|---|
| 1836 | .driver_data = atkbd_volume_forced_release_keys, | 
|---|
| 1837 | }, | 
|---|
| 1838 | { | 
|---|
| 1839 | .matches = { | 
|---|
| 1840 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 
|---|
| 1841 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4100"), | 
|---|
| 1842 | }, | 
|---|
| 1843 | .callback = atkbd_setup_forced_release, | 
|---|
| 1844 | .driver_data = atkbd_volume_forced_release_keys, | 
|---|
| 1845 | }, | 
|---|
| 1846 | { | 
|---|
| 1847 | .matches = { | 
|---|
| 1848 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 
|---|
| 1849 | DMI_MATCH(DMI_PRODUCT_NAME, "Presario R4200"), | 
|---|
| 1850 | }, | 
|---|
| 1851 | .callback = atkbd_setup_forced_release, | 
|---|
| 1852 | .driver_data = atkbd_volume_forced_release_keys, | 
|---|
| 1853 | }, | 
|---|
| 1854 | { | 
|---|
| 1855 | /* Inventec Symphony */ | 
|---|
| 1856 | .matches = { | 
|---|
| 1857 | DMI_MATCH(DMI_SYS_VENDOR, "INVENTEC"), | 
|---|
| 1858 | DMI_MATCH(DMI_PRODUCT_NAME, "SYMPHONY 6.0/7.0"), | 
|---|
| 1859 | }, | 
|---|
| 1860 | .callback = atkbd_setup_forced_release, | 
|---|
| 1861 | .driver_data = atkbd_volume_forced_release_keys, | 
|---|
| 1862 | }, | 
|---|
| 1863 | { | 
|---|
| 1864 | /* Samsung NC10 */ | 
|---|
| 1865 | .matches = { | 
|---|
| 1866 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 
|---|
| 1867 | DMI_MATCH(DMI_PRODUCT_NAME, "NC10"), | 
|---|
| 1868 | }, | 
|---|
| 1869 | .callback = atkbd_setup_forced_release, | 
|---|
| 1870 | .driver_data = atkbd_samsung_forced_release_keys, | 
|---|
| 1871 | }, | 
|---|
| 1872 | { | 
|---|
| 1873 | /* Samsung NC20 */ | 
|---|
| 1874 | .matches = { | 
|---|
| 1875 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 
|---|
| 1876 | DMI_MATCH(DMI_PRODUCT_NAME, "NC20"), | 
|---|
| 1877 | }, | 
|---|
| 1878 | .callback = atkbd_setup_forced_release, | 
|---|
| 1879 | .driver_data = atkbd_samsung_forced_release_keys, | 
|---|
| 1880 | }, | 
|---|
| 1881 | { | 
|---|
| 1882 | /* Samsung SQ45S70S */ | 
|---|
| 1883 | .matches = { | 
|---|
| 1884 | DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | 
|---|
| 1885 | DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"), | 
|---|
| 1886 | }, | 
|---|
| 1887 | .callback = atkbd_setup_forced_release, | 
|---|
| 1888 | .driver_data = atkbd_samsung_forced_release_keys, | 
|---|
| 1889 | }, | 
|---|
| 1890 | { | 
|---|
| 1891 | /* Fujitsu Amilo PA 1510 */ | 
|---|
| 1892 | .matches = { | 
|---|
| 1893 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 
|---|
| 1894 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 1510"), | 
|---|
| 1895 | }, | 
|---|
| 1896 | .callback = atkbd_setup_forced_release, | 
|---|
| 1897 | .driver_data = atkbd_volume_forced_release_keys, | 
|---|
| 1898 | }, | 
|---|
| 1899 | { | 
|---|
| 1900 | /* Fujitsu Amilo Pi 3525 */ | 
|---|
| 1901 | .matches = { | 
|---|
| 1902 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 
|---|
| 1903 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 3525"), | 
|---|
| 1904 | }, | 
|---|
| 1905 | .callback = atkbd_setup_forced_release, | 
|---|
| 1906 | .driver_data = atkbd_amilo_pi3525_forced_release_keys, | 
|---|
| 1907 | }, | 
|---|
| 1908 | { | 
|---|
| 1909 | /* Fujitsu Amilo Xi 3650 */ | 
|---|
| 1910 | .matches = { | 
|---|
| 1911 | DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), | 
|---|
| 1912 | DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"), | 
|---|
| 1913 | }, | 
|---|
| 1914 | .callback = atkbd_setup_forced_release, | 
|---|
| 1915 | .driver_data = atkbd_amilo_xi3650_forced_release_keys, | 
|---|
| 1916 | }, | 
|---|
| 1917 | { | 
|---|
| 1918 | .matches = { | 
|---|
| 1919 | DMI_MATCH(DMI_SYS_VENDOR, "Soltech Corporation"), | 
|---|
| 1920 | DMI_MATCH(DMI_PRODUCT_NAME, "TA12"), | 
|---|
| 1921 | }, | 
|---|
| 1922 | .callback = atkbd_setup_forced_release, | 
|---|
| 1923 | .driver_data = atkdb_soltech_ta12_forced_release_keys, | 
|---|
| 1924 | }, | 
|---|
| 1925 | { | 
|---|
| 1926 | /* OQO Model 01+ */ | 
|---|
| 1927 | .matches = { | 
|---|
| 1928 | DMI_MATCH(DMI_SYS_VENDOR, "OQO"), | 
|---|
| 1929 | DMI_MATCH(DMI_PRODUCT_NAME, "ZEPTO"), | 
|---|
| 1930 | }, | 
|---|
| 1931 | .callback = atkbd_setup_scancode_fixup, | 
|---|
| 1932 | .driver_data = atkbd_oqo_01plus_scancode_fixup, | 
|---|
| 1933 | }, | 
|---|
| 1934 | { | 
|---|
| 1935 | .matches = { | 
|---|
| 1936 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | 
|---|
| 1937 | }, | 
|---|
| 1938 | .callback = atkbd_deactivate_fixup, | 
|---|
| 1939 | }, | 
|---|
| 1940 | { } | 
|---|
| 1941 | }; | 
|---|
| 1942 |  | 
|---|
| 1943 | static int __init atkbd_init(void) | 
|---|
| 1944 | { | 
|---|
| 1945 | dmi_check_system(list: atkbd_dmi_quirk_table); | 
|---|
| 1946 |  | 
|---|
| 1947 | return serio_register_driver(&atkbd_drv); | 
|---|
| 1948 | } | 
|---|
| 1949 |  | 
|---|
| 1950 | static void __exit atkbd_exit(void) | 
|---|
| 1951 | { | 
|---|
| 1952 | serio_unregister_driver(drv: &atkbd_drv); | 
|---|
| 1953 | } | 
|---|
| 1954 |  | 
|---|
| 1955 | module_init(atkbd_init); | 
|---|
| 1956 | module_exit(atkbd_exit); | 
|---|
| 1957 |  | 
|---|