summaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/sony-laptop.c
diff options
context:
space:
mode:
authorMarco Chiappero <marco@absence.it>2012-05-19 15:35:44 +0200
committerMatthew Garrett <mjg@redhat.com>2012-05-31 20:29:33 +0200
commitd6f15ed876b83a1a0eba1d0473eef58acc95444a (patch)
tree2434fbf98aaab70b7a876af865cb407385e0f0cd /drivers/platform/x86/sony-laptop.c
parenthp-wmi: check for allocation failures (diff)
downloadlinux-d6f15ed876b83a1a0eba1d0473eef58acc95444a.tar.xz
linux-d6f15ed876b83a1a0eba1d0473eef58acc95444a.zip
sony-laptop: use soft rfkill status stored in hw
The SNC device on recent Vaio laptops also stores the soft status and leaves it available after reboot. Use it and always set the last soft and hard status on module load. [malattia@linux.it: patch taken from a largely modified sony-laptop.c, smaller modifications to the original code to simplify it] Signed-off-by: Mattia Dongili <malattia@linux.it> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers/platform/x86/sony-laptop.c')
-rw-r--r--drivers/platform/x86/sony-laptop.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 8a51795aa02a..c6dc3f741ccd 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -1213,7 +1213,7 @@ static int sony_nc_rfkill_set(void *data, bool blocked)
int argument = sony_rfkill_address[(long) data] + 0x100;
if (!blocked)
- argument |= 0xff0000;
+ argument |= 0x030000;
return sony_call_snc_handle(sony_rfkill_handle, argument, &result);
}
@@ -1230,7 +1230,7 @@ static int sony_nc_setup_rfkill(struct acpi_device *device,
enum rfkill_type type;
const char *name;
int result;
- bool hwblock;
+ bool hwblock, swblock;
switch (nc_type) {
case SONY_WIFI:
@@ -1258,8 +1258,21 @@ static int sony_nc_setup_rfkill(struct acpi_device *device,
if (!rfk)
return -ENOMEM;
- sony_call_snc_handle(sony_rfkill_handle, 0x200, &result);
+ if (sony_call_snc_handle(sony_rfkill_handle, 0x200, &result) < 0) {
+ rfkill_destroy(rfk);
+ return -1;
+ }
hwblock = !(result & 0x1);
+
+ if (sony_call_snc_handle(sony_rfkill_handle,
+ sony_rfkill_address[nc_type],
+ &result) < 0) {
+ rfkill_destroy(rfk);
+ return -1;
+ }
+ swblock = !(result & 0x2);
+
+ rfkill_init_sw_state(rfk, swblock);
rfkill_set_hw_state(rfk, hwblock);
err = rfkill_register(rfk);
@@ -1295,7 +1308,7 @@ static void sony_nc_rfkill_update(void)
sony_call_snc_handle(sony_rfkill_handle, argument, &result);
rfkill_set_states(sony_rfkill_devices[i],
- !(result & 0xf), false);
+ !(result & 0x2), false);
}
}