Skip to content

Commit

Permalink
msi-laptop: Add i8042 filter to sync sw state with BIOS when function…
Browse files Browse the repository at this point in the history
… key pressed

There have some MSI netbook change devices state by EC when user press
wlan/bluetooth/wwan function keys. So, add a i8042 filter to sync sw
state with BIOS when function keys pressed.

Signed-off-by: Lee, Chun-Yi <jlee@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Lee, Chun-Yi authored and Matthew Garrett committed May 20, 2010
1 parent 3bb9702 commit 339e753
Showing 1 changed file with 58 additions and 1 deletion.
59 changes: 58 additions & 1 deletion drivers/platform/x86/msi-laptop.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <linux/backlight.h>
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/i8042.h>

#define MSI_DRIVER_VERSION "0.5"

Expand Down Expand Up @@ -581,6 +582,46 @@ static void rfkill_cleanup(void)
}
}

static void msi_update_rfkill(struct work_struct *ignored)
{
get_wireless_state_ec_standard();

if (rfk_wlan)
rfkill_set_sw_state(rfk_wlan, !wlan_s);
if (rfk_bluetooth)
rfkill_set_sw_state(rfk_bluetooth, !bluetooth_s);
if (rfk_threeg)
rfkill_set_sw_state(rfk_threeg, !threeg_s);
}
static DECLARE_DELAYED_WORK(msi_rfkill_work, msi_update_rfkill);

static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
struct serio *port)
{
static bool extended;

if (str & 0x20)
return false;

/* 0x54 wwan, 0x62 bluetooth, 0x76 wlan*/
if (unlikely(data == 0xe0)) {
extended = true;
return false;
} else if (unlikely(extended)) {
switch (data) {
case 0x54:
case 0x62:
case 0x76:
schedule_delayed_work(&msi_rfkill_work,
round_jiffies_relative(0.5 * HZ));
break;
}
extended = false;
}

return false;
}

static void msi_init_rfkill(struct work_struct *ignored)
{
if (rfk_wlan) {
Expand Down Expand Up @@ -706,9 +747,24 @@ static int load_scm_model_init(struct platform_device *sdev)
/* initial rfkill */
result = rfkill_init(sdev);
if (result < 0)
return result;
goto fail_rfkill;

result = i8042_install_filter(msi_laptop_i8042_filter);
if (result) {
printk(KERN_ERR
"msi-laptop: Unable to install key filter\n");
goto fail_filter;
}

return 0;

fail_filter:
rfkill_cleanup();

fail_rfkill:

return result;

}

static int __init msi_init(void)
Expand Down Expand Up @@ -819,6 +875,7 @@ static void __exit msi_cleanup(void)
platform_driver_unregister(&msipf_driver);
backlight_device_unregister(msibl_device);

i8042_remove_filter(msi_laptop_i8042_filter);
rfkill_cleanup();

/* Enable automatic brightness control again */
Expand Down

0 comments on commit 339e753

Please sign in to comment.