|
@@ -52,6 +52,11 @@
|
|
|
|
|
|
MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>");
|
|
|
|
|
|
+static int restore_capslock_events;
|
|
|
+module_param(restore_capslock_events, int, 0644);
|
|
|
+MODULE_PARM_DESC(restore_capslock_events,
|
|
|
+ "Produce keypress events for capslock on both keyup and keydown.");
|
|
|
+
|
|
|
#define KEYB_KEYREG 0 /* register # for key up/down data */
|
|
|
#define KEYB_LEDREG 2 /* register # for leds on ADB keyboard */
|
|
|
#define MOUSE_DATAREG 0 /* reg# for movement/button codes from mouse */
|
|
@@ -217,6 +222,8 @@ struct adbhid {
|
|
|
#define FLAG_FN_KEY_PRESSED 0x00000001
|
|
|
#define FLAG_POWER_FROM_FN 0x00000002
|
|
|
#define FLAG_EMU_FWDEL_DOWN 0x00000004
|
|
|
+#define FLAG_CAPSLOCK_TRANSLATE 0x00000008
|
|
|
+#define FLAG_CAPSLOCK_DOWN 0x00000010
|
|
|
|
|
|
static struct adbhid *adbhid[16];
|
|
|
|
|
@@ -272,19 +279,50 @@ adbhid_keyboard_input(unsigned char *data, int nb, int apoll)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-adbhid_input_keycode(int id, int keycode, int repeat)
|
|
|
+adbhid_input_keycode(int id, int scancode, int repeat)
|
|
|
{
|
|
|
struct adbhid *ahid = adbhid[id];
|
|
|
- int up_flag;
|
|
|
-
|
|
|
- up_flag = (keycode & 0x80);
|
|
|
- keycode &= 0x7f;
|
|
|
+ int keycode, up_flag;
|
|
|
+
|
|
|
+ keycode = scancode & 0x7f;
|
|
|
+ up_flag = scancode & 0x80;
|
|
|
+
|
|
|
+ if (restore_capslock_events) {
|
|
|
+ if (keycode == ADB_KEY_CAPSLOCK && !up_flag) {
|
|
|
+ /* Key pressed, turning on the CapsLock LED.
|
|
|
+ * The next 0xff will be interpreted as a release. */
|
|
|
+ ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
|
|
|
+ | FLAG_CAPSLOCK_DOWN;
|
|
|
+ } else if (scancode == 0xff) {
|
|
|
+ /* Scancode 0xff usually signifies that the capslock
|
|
|
+ * key was either pressed or released. */
|
|
|
+ if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
|
|
|
+ keycode = ADB_KEY_CAPSLOCK;
|
|
|
+ if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
|
|
|
+ /* Key released */
|
|
|
+ up_flag = 1;
|
|
|
+ ahid->flags &= ~FLAG_CAPSLOCK_DOWN;
|
|
|
+ } else {
|
|
|
+ /* Key pressed */
|
|
|
+ up_flag = 0;
|
|
|
+ ahid->flags &= ~FLAG_CAPSLOCK_TRANSLATE;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ printk(KERN_INFO "Spurious caps lock event "
|
|
|
+ "(scancode 0xff).");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
switch (keycode) {
|
|
|
- case ADB_KEY_CAPSLOCK: /* Generate down/up events for CapsLock everytime. */
|
|
|
- input_report_key(ahid->input, KEY_CAPSLOCK, 1);
|
|
|
- input_report_key(ahid->input, KEY_CAPSLOCK, 0);
|
|
|
- input_sync(ahid->input);
|
|
|
+ case ADB_KEY_CAPSLOCK:
|
|
|
+ if (!restore_capslock_events) {
|
|
|
+ /* Generate down/up events for CapsLock everytime. */
|
|
|
+ input_report_key(ahid->input, KEY_CAPSLOCK, 1);
|
|
|
+ input_sync(ahid->input);
|
|
|
+ input_report_key(ahid->input, KEY_CAPSLOCK, 0);
|
|
|
+ input_sync(ahid->input);
|
|
|
+ }
|
|
|
return;
|
|
|
#ifdef CONFIG_PPC_PMAC
|
|
|
case ADB_KEY_POWER_OLD: /* Power key on PBook 3400 needs remapping */
|