[PATCH] Input: adbhid - fix capslock key state after suspend - Kernel

This is a discussion on [PATCH] Input: adbhid - fix capslock key state after suspend - Kernel ; If the adbhid module parameter restore_capslock_events is used, sometimes capslock will get stuck down after resuming. My fix is to remember the capslock state before suspend and then ignore the first 'caps lock key down' message after resume if the ...

+ Reply to Thread
Results 1 to 5 of 5

Thread: [PATCH] Input: adbhid - fix capslock key state after suspend

  1. [PATCH] Input: adbhid - fix capslock key state after suspend

    If the adbhid module parameter restore_capslock_events is used,
    sometimes capslock will get stuck down after resuming.

    My fix is to remember the capslock state before suspend and then
    ignore the first 'caps lock key down' message after resume if the
    capslock LED was on before suspending.

    Signed-off-by: Rodney Lorrimar
    ---
    drivers/macintosh/adbhid.c | 43 +++++++++++++++++++++++++++++++++++++------
    1 files changed, 37 insertions(+), 6 deletions(-)

    diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
    index ef4c117..19d0984 100644
    --- a/drivers/macintosh/adbhid.c
    +++ b/drivers/macintosh/adbhid.c
    @@ -219,11 +219,12 @@ struct adbhid {
    int flags;
    };

    -#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
    +#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
    +#define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020

    static struct adbhid *adbhid[16];

    @@ -291,8 +292,15 @@ adbhid_input_keycode(int id, int scancode, int repeat)
    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
    + if (ahid->flags & FLAG_CAPSLOCK_IGNORE_NEXT) {
    + /* Throw away this key event if it happens
    + * just after resume. */
    + ahid->flags &= ~FLAG_CAPSLOCK_IGNORE_NEXT;
    + return;
    + } else {
    + 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. */
    @@ -681,6 +689,20 @@ static int adbhid_kbd_event(struct input_dev *dev, unsigned int type, unsigned i
    return -1;
    }

    +static void
    +adbhid_kbd_capslock_remember(void)
    +{
    + struct adbhid *ahid;
    + int i;
    + for (i = 1; i < 16; i++) {
    + ahid = adbhid[i];
    +
    + if (ahid && ahid->id == ADB_KEYBOARD)
    + if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE)
    + ahid->flags |= FLAG_CAPSLOCK_IGNORE_NEXT;
    + }
    +}
    +
    static int
    adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
    {
    @@ -699,6 +721,15 @@ adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
    /* Stop pending led requests */
    while(leds_req_pending)
    adb_poll();
    +
    + /* After resume, and if the capslock LED is on, the PMU will
    + * send a "capslock down" key event. This confuses the
    + * restore_capslock_events logic. Remember if the capslock
    + * LED was on before suspend so the unwanted key event can
    + * be ignored after resume. */
    + if (restore_capslock_events)
    + adbhid_kbd_capslock_remember();
    +
    break;

    case ADB_MSG_POST_RESET:
    --
    1.5.4.4


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.6 (GNU/Linux)

    iD8DBQFH7Di7bBchLr+YxKcRAuJHAJ4ua5toMhPX/3PDTxfPhFEfHwhljACgg83V
    Rq1zXQC7WOLdPk4cibNSefk=
    =CLfS
    -----END PGP SIGNATURE-----


  2. Re: [PATCH] Input: adbhid - fix capslock key state after suspend

    On Fri 2008-03-28 01:15:56, Rodney Lorrimar wrote:
    > If the adbhid module parameter restore_capslock_events is used,
    > sometimes capslock will get stuck down after resuming.


    Hmmm, why does that need to be a parameter? I mean... can we just do
    the right thing?

    Pavel
    --
    (english) http://www.livejournal.com/~pavelmachek
    (cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pav...rses/blog.html
    pomozte zachranit klanovicky les: http://www.ujezdskystrom.info/
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. Re: [PATCH] Input: adbhid - fix capslock key state after suspend

    On Fri, Mar 28, 2008 at 11:58:55AM +0100, Pavel Machek wrote:
    > On Fri 2008-03-28 01:15:56, Rodney Lorrimar wrote:
    > > If the adbhid module parameter restore_capslock_events is used,
    > > sometimes capslock will get stuck down after resuming.

    >
    > Hmmm, why does that need to be a parameter? I mean... can we just do
    > the right thing?


    I agree. There really don't seem to be any drawbacks to keeping track
    of capslock state. The worst thing that can happen is that it somehow
    occasionally fails to do the right thing.

    --
    Andrew McNabb
    http://www.mcnabbs.org/andrew/
    PGP Fingerprint: 8A17 B57C 6879 1863 DE55 8012 AB4D 6098 8826 6868

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.6 (GNU/Linux)

    iD8DBQFH7Rgiq01gmIgmaGgRAglDAKCFrF9fKhGLGW6azKSvxf Vr/wIGKQCgjOYq
    BCAMB86mqwoC4j7ZXim7jVE=
    =CrGZ
    -----END PGP SIGNATURE-----


  4. Re: [PATCH] Input: adbhid - fix capslock key state after suspend

    On Fri, Mar 28, 2008 at 11:58:55AM +0100, Pavel Machek wrote:
    > On Fri 2008-03-28 01:15:56, Rodney Lorrimar wrote:
    > > If the adbhid module parameter restore_capslock_events is used,
    > > sometimes capslock will get stuck down after resuming.

    >
    > Hmmm, why does that need to be a parameter? I mean... can we just do
    > the right thing?


    Hi Pavel,

    Sorry for taking so long to answer your questions. We can mostly do
    the right thing. I suppose it was a parameter so the quirk fixing
    didn't ruin the fun for the majority of users who don't remap their
    capslock. I know of two issues with the code:

    1. Under heavy capslock usage the capslock key will sometimes get
    stuck down.
    2. If the capslock LED is on and the power button is pressed, a "power
    button release" key event won't happen until capslock is pressed
    again. So in some situations (e.g. with pbbuttonsd) the next time
    capslock is hit the machine will suspend.


    I will send a patch for 2, and continue to investigate 1.

    Regarding the original patch, I think it's worth applying. If 1 is
    fixable then I will prepare two more patches to fix problem 1 and
    remove the parameter.


    Rodney

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.6 (GNU/Linux)

    iD8DBQFH/eUCbBchLr+YxKcRAg2IAJ4gIuRbzkd5K+D66XB+FZHG+qtWXwC gmDik
    WhziST4pHKHJbgCPAb9kc9g=
    =M/6n
    -----END PGP SIGNATURE-----


  5. [PATCH] Input: adbhid - capslock and power button fix

    If the adbhid module parameter restore_capslock_events is used,
    pressing the power button may confuse the capslock state. This is
    because the power button release scancode (0xff) is sometimes the same
    as the capslock press/release scancode.

    This fix adds yet another flag to track the state of the power button
    so that it works independently of capslock.

    Signed-off-by: Rodney Lorrimar
    ---

    This patch applies on top of the previous patch in the thread.

    ---
    drivers/macintosh/adbhid.c | 15 ++++++++++++---
    1 files changed, 12 insertions(+), 3 deletions(-)

    diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c
    index 19d0984..72b9011 100644
    --- a/drivers/macintosh/adbhid.c
    +++ b/drivers/macintosh/adbhid.c
    @@ -225,6 +225,7 @@ struct adbhid {
    #define FLAG_CAPSLOCK_TRANSLATE 0x00000008
    #define FLAG_CAPSLOCK_DOWN 0x00000010
    #define FLAG_CAPSLOCK_IGNORE_NEXT 0x00000020
    +#define FLAG_POWER_KEY_PRESSED 0x00000040

    static struct adbhid *adbhid[16];

    @@ -301,9 +302,11 @@ adbhid_input_keycode(int id, int scancode, int repeat)
    ahid->flags |= FLAG_CAPSLOCK_TRANSLATE
    | FLAG_CAPSLOCK_DOWN;
    }
    - } else if (scancode == 0xff) {
    + } else if (scancode == 0xff &&
    + !(ahid->flags & FLAG_POWER_KEY_PRESSED)) {
    /* Scancode 0xff usually signifies that the capslock
    - * key was either pressed or released. */
    + * key was either pressed or released, or that the
    + * power button was released. */
    if (ahid->flags & FLAG_CAPSLOCK_TRANSLATE) {
    keycode = ADB_KEY_CAPSLOCK;
    if (ahid->flags & FLAG_CAPSLOCK_DOWN) {
    @@ -317,7 +320,7 @@ adbhid_input_keycode(int id, int scancode, int repeat)
    }
    } else {
    printk(KERN_INFO "Spurious caps lock event "
    - "(scancode 0xff).");
    + "(scancode 0xff).\n");
    }
    }
    }
    @@ -344,6 +347,12 @@ adbhid_input_keycode(int id, int scancode, int repeat)
    }
    break;
    case ADB_KEY_POWER:
    + /* Keep track of the power key state */
    + if (up_flag)
    + ahid->flags &= ~FLAG_POWER_KEY_PRESSED;
    + else
    + ahid->flags |= FLAG_POWER_KEY_PRESSED;
    +
    /* Fn + Command will produce a bogus "power" keycode */
    if (ahid->flags & FLAG_FN_KEY_PRESSED) {
    keycode = ADB_KEY_CMD;
    --
    1.5.4.5


    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.6 (GNU/Linux)

    iD8DBQFH/emrbBchLr+YxKcRAgA8AJ4g9ikLc8+Kv86V4B9/OvD+PvtrrgCgvWMV
    VSscjITOI8GWMf18/CHsdJQ=
    =Ha79
    -----END PGP SIGNATURE-----


+ Reply to Thread