@@ -44,21 +44,23 @@ static const struct key_entry intel_vbtn_keymap[] = {
44
44
{ KE_IGNORE , 0xC7 , { KEY_VOLUMEDOWN } }, /* volume-down key release */
45
45
{ KE_KEY , 0xC8 , { KEY_ROTATE_LOCK_TOGGLE } }, /* rotate-lock key press */
46
46
{ KE_KEY , 0xC9 , { KEY_ROTATE_LOCK_TOGGLE } }, /* rotate-lock key release */
47
+ { KE_END }
47
48
};
48
49
49
50
static const struct key_entry intel_vbtn_switchmap [] = {
50
51
{ KE_SW , 0xCA , { .sw = { SW_DOCK , 1 } } }, /* Docked */
51
52
{ KE_SW , 0xCB , { .sw = { SW_DOCK , 0 } } }, /* Undocked */
52
53
{ KE_SW , 0xCC , { .sw = { SW_TABLET_MODE , 1 } } }, /* Tablet */
53
54
{ KE_SW , 0xCD , { .sw = { SW_TABLET_MODE , 0 } } }, /* Laptop */
55
+ { KE_END }
54
56
};
55
57
56
58
#define KEYMAP_LEN \
57
59
(ARRAY_SIZE(intel_vbtn_keymap) + ARRAY_SIZE(intel_vbtn_switchmap) + 1)
58
60
59
61
struct intel_vbtn_priv {
60
- struct key_entry keymap [ KEYMAP_LEN ] ;
61
- struct input_dev * input_dev ;
62
+ struct input_dev * buttons_dev ;
63
+ struct input_dev * switches_dev ;
62
64
bool has_buttons ;
63
65
bool has_switches ;
64
66
bool wakeup_mode ;
@@ -77,48 +79,62 @@ static void detect_tablet_mode(struct platform_device *device)
77
79
return ;
78
80
79
81
m = !(vgbs & VGBS_TABLET_MODE_FLAGS );
80
- input_report_switch (priv -> input_dev , SW_TABLET_MODE , m );
82
+ input_report_switch (priv -> switches_dev , SW_TABLET_MODE , m );
81
83
m = (vgbs & VGBS_DOCK_MODE_FLAG ) ? 1 : 0 ;
82
- input_report_switch (priv -> input_dev , SW_DOCK , m );
84
+ input_report_switch (priv -> switches_dev , SW_DOCK , m );
83
85
}
84
86
87
+ /*
88
+ * Note this unconditionally creates the 2 input_dev-s and sets up
89
+ * the sparse-keymaps. Only the registration is conditional on
90
+ * have_buttons / have_switches. This is done so that the notify
91
+ * handler can always call sparse_keymap_entry_from_scancode()
92
+ * on the input_dev-s do determine the event type.
93
+ */
85
94
static int intel_vbtn_input_setup (struct platform_device * device )
86
95
{
87
96
struct intel_vbtn_priv * priv = dev_get_drvdata (& device -> dev );
88
- int ret , keymap_len = 0 ;
97
+ int ret ;
89
98
90
- if (priv -> has_buttons ) {
91
- memcpy (& priv -> keymap [keymap_len ], intel_vbtn_keymap ,
92
- ARRAY_SIZE (intel_vbtn_keymap ) *
93
- sizeof (struct key_entry ));
94
- keymap_len += ARRAY_SIZE (intel_vbtn_keymap );
95
- }
99
+ priv -> buttons_dev = devm_input_allocate_device (& device -> dev );
100
+ if (!priv -> buttons_dev )
101
+ return - ENOMEM ;
96
102
97
- if (priv -> has_switches ) {
98
- memcpy (& priv -> keymap [keymap_len ], intel_vbtn_switchmap ,
99
- ARRAY_SIZE (intel_vbtn_switchmap ) *
100
- sizeof (struct key_entry ));
101
- keymap_len += ARRAY_SIZE (intel_vbtn_switchmap );
102
- }
103
+ ret = sparse_keymap_setup (priv -> buttons_dev , intel_vbtn_keymap , NULL );
104
+ if (ret )
105
+ return ret ;
103
106
104
- priv -> keymap [keymap_len ].type = KE_END ;
107
+ priv -> buttons_dev -> dev .parent = & device -> dev ;
108
+ priv -> buttons_dev -> name = "Intel Virtual Buttons" ;
109
+ priv -> buttons_dev -> id .bustype = BUS_HOST ;
110
+
111
+ if (priv -> has_buttons ) {
112
+ ret = input_register_device (priv -> buttons_dev );
113
+ if (ret )
114
+ return ret ;
115
+ }
105
116
106
- priv -> input_dev = devm_input_allocate_device (& device -> dev );
107
- if (!priv -> input_dev )
117
+ priv -> switches_dev = devm_input_allocate_device (& device -> dev );
118
+ if (!priv -> switches_dev )
108
119
return - ENOMEM ;
109
120
110
- ret = sparse_keymap_setup (priv -> input_dev , priv -> keymap , NULL );
121
+ ret = sparse_keymap_setup (priv -> switches_dev , intel_vbtn_switchmap , NULL );
111
122
if (ret )
112
123
return ret ;
113
124
114
- priv -> input_dev -> dev .parent = & device -> dev ;
115
- priv -> input_dev -> name = "Intel Virtual Button driver " ;
116
- priv -> input_dev -> id .bustype = BUS_HOST ;
125
+ priv -> switches_dev -> dev .parent = & device -> dev ;
126
+ priv -> switches_dev -> name = "Intel Virtual Switches " ;
127
+ priv -> switches_dev -> id .bustype = BUS_HOST ;
117
128
118
- if (priv -> has_switches )
129
+ if (priv -> has_switches ) {
119
130
detect_tablet_mode (device );
120
131
121
- return input_register_device (priv -> input_dev );
132
+ ret = input_register_device (priv -> switches_dev );
133
+ if (ret )
134
+ return ret ;
135
+ }
136
+
137
+ return 0 ;
122
138
}
123
139
124
140
static void notify_handler (acpi_handle handle , u32 event , void * context )
@@ -127,13 +143,27 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
127
143
struct intel_vbtn_priv * priv = dev_get_drvdata (& device -> dev );
128
144
unsigned int val = !(event & 1 ); /* Even=press, Odd=release */
129
145
const struct key_entry * ke , * ke_rel ;
146
+ struct input_dev * input_dev ;
130
147
bool autorelease ;
131
148
132
- if (priv -> wakeup_mode ) {
133
- ke = sparse_keymap_entry_from_scancode (priv -> input_dev , event );
134
- if (!ke )
135
- goto out_unknown ;
149
+ if ((ke = sparse_keymap_entry_from_scancode (priv -> buttons_dev , event ))) {
150
+ if (!priv -> has_buttons ) {
151
+ dev_warn (& device -> dev , "Warning: received a button event on a device without buttons, please report this.\n" );
152
+ return ;
153
+ }
154
+ input_dev = priv -> buttons_dev ;
155
+ } else if ((ke = sparse_keymap_entry_from_scancode (priv -> switches_dev , event ))) {
156
+ if (!priv -> has_switches ) {
157
+ dev_warn (& device -> dev , "Warning: received a switches event on a device without switchess, please report this.\n" );
158
+ return ;
159
+ }
160
+ input_dev = priv -> switches_dev ;
161
+ } else {
162
+ dev_dbg (& device -> dev , "unknown event index 0x%x\n" , event );
163
+ return ;
164
+ }
136
165
166
+ if (priv -> wakeup_mode ) {
137
167
pm_wakeup_hard_event (& device -> dev );
138
168
139
169
/*
@@ -148,14 +178,10 @@ static void notify_handler(acpi_handle handle, u32 event, void *context)
148
178
* Even press events are autorelease if there is no corresponding odd
149
179
* release event, or if the odd event is KE_IGNORE.
150
180
*/
151
- ke_rel = sparse_keymap_entry_from_scancode (priv -> input_dev , event | 1 );
181
+ ke_rel = sparse_keymap_entry_from_scancode (input_dev , event | 1 );
152
182
autorelease = val && (!ke_rel || ke_rel -> type == KE_IGNORE );
153
183
154
- if (sparse_keymap_report_event (priv -> input_dev , event , val , autorelease ))
155
- return ;
156
-
157
- out_unknown :
158
- dev_dbg (& device -> dev , "unknown event index 0x%x\n" , event );
184
+ sparse_keymap_report_event (input_dev , event , val , autorelease );
159
185
}
160
186
161
187
static bool intel_vbtn_has_buttons (acpi_handle handle )
0 commit comments