aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/macintosh/adbhid.c56
1 files changed, 47 insertions, 9 deletions
diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
index b46817f699f1..9ff2189d2e2a 100644
--- a/drivers/macintosh/adbhid.c
+++ b/drivers/macintosh/adbhid.c
@@ -52,6 +52,11 @@
52 52
53MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>"); 53MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>");
54 54
55static int restore_capslock_events;
56module_param(restore_capslock_events, int, 0644);
57MODULE_PARM_DESC(restore_capslock_events,
58 "Produce keypress events for capslock on both keyup and keydown.");
59
55#define KEYB_KEYREG 0 /* register # for key up/down data */ 60#define KEYB_KEYREG 0 /* register # for key up/down data */
56#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */ 61#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
57#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */ 62#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
@@ -217,6 +222,8 @@ struct adbhid {
217#define FLAG_FN_KEY_PRESSED 0x00000001 222#define FLAG_FN_KEY_PRESSED 0x00000001
218#define FLAG_POWER_FROM_FN 0x00000002 223#define FLAG_POWER_FROM_FN 0x00000002
219#define FLAG_EMU_FWDEL_DOWN 0x00000004 224#define FLAG_EMU_FWDEL_DOWN 0x00000004
225#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
226#define FLAG_CAPSLOCK_DOWN 0x00000010
220 227
221static struct adbhid *adbhid[16]; 228static struct adbhid *adbhid[16];
222 229
@@ -272,19 +279,50 @@ adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
272} 279}
273 280
274static void 281static void
275adbhid_input_keycode(int id, int keycode, int repeat) 282adbhid_input_keycode(int id, int scancode, int repeat)
276{ 283{
277 struct adbhid *ahid = adbhid[id]; 284 struct adbhid *ahid = adbhid[id];
278 int up_flag; 285 int keycode, up_flag;
279 286
280 up_flag = (keycode & 0x80); 287 keycode = scancode & 0x7f;
281 keycode &= 0x7f; 288 up_flag = scancode & 0x80;
289
290 if (restore_capslock_events) {
291 if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
292 /* Key pressed, turning on the CapsLock LED.
293 * The next 0xff will be interpreted as a release. */
294 ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
295 | FLAG_CAPSLOCK_DOWN;
296 } else if (scancode == 0xff) {
297 /* Scancode 0xff usually signifies that the capslock
298 * key was either pressed or released. */
299 if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
300 keycode = ADB_KEY_CAPSLOCK;
301 if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
302 /* Key released */
303 up_flag = 1;
304 ahid->flags &= ~FLAG_CAPSLOCK_DOWN;
305 } else {
306 /* Key pressed */
307 up_flag = 0;
308 ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE;
309 }
310 } else {
311 printk(KERN_INFO "Spurious caps lock event "
312 "(scancode 0xff).");
313 }
314 }
315 }
282 316
283 switch (keycode) { 317 switch (keycode) {
284 case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */ 318 case ADB_KEY_CAPSLOCK:
285 input_report_key(ahid->input, KEY_CAPSLOCK, 1); 319 if (!restore_capslock_events) {
286 input_report_key(ahid->input, KEY_CAPSLOCK, 0); 320 /* Generate down/up events for CapsLock everytime. */
287 input_sync(ahid->input); 321 input_report_key(ahid->input, KEY_CAPSLOCK, 1);
322 input_sync(ahid->input);
323 input_report_key(ahid->input, KEY_CAPSLOCK, 0);
324 input_sync(ahid->input);
325 }
288 return; 326 return;
289#ifdef CONFIG_PPC_PMAC 327#ifdef CONFIG_PPC_PMAC
290 case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */ 328 case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */