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