diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-26 16:44:46 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-26 16:44:46 -0400 |
commit | 78d425677217b655ed36c492a070b5002832fc73 (patch) | |
tree | a178a3bf773027f3a70ecec1ad6f9d35074e4263 /drivers/platform/x86/toshiba_bluetooth.c | |
parent | 36a8032d77649430f5ef11fbf0df2bb026be0b04 (diff) | |
parent | 358d6a2c3ecae2b22c7d7e61f9d5672557446dfb (diff) |
Merge tag 'platform-drivers-x86-v4.1-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86
Pull x86 platform driver updates from Darren Hart:
"This series includes significant updates to the toshiba_acpi driver
and the reintroduction of the dell-laptop keyboard backlight additions
I had to revert previously. Also included are various fixes for
typos, warnings, correctness, and minor bugs.
Specifics:
dell-laptop:
- add support for keyboard backlight.
toshiba_acpi:
- adaptive keyboard, hotkey, USB sleep and charge, and backlight
updates. Update sysfs documentation.
toshiba_bluetooth:
- fix enabling/disabling loop on recent devices
apple-gmux:
- lock iGP IO to protect from vgaarb changes
other:
- Fix typos, clear gcc warnings, clarify pr_* messages, correct
return types, update MAINTAINERS"
* tag 'platform-drivers-x86-v4.1-1' of git://git.infradead.org/users/dvhart/linux-platform-drivers-x86: (25 commits)
toshiba_acpi: Do not register vendor backlight when acpi_video bl is available
MAINTAINERS: Add me on list of Dell laptop drivers
platform: x86: dell-laptop: Add support for keyboard backlight
Documentation/ABI: Update sysfs-driver-toshiba_acpi entry
toshiba_acpi: Fix pr_* messages from USB Sleep Functions
toshiba_acpi: Update and fix USB Sleep and Charge modes
wmi: Use bool function return values of true/false not 1/0
toshiba_bluetooth: Fix enabling/disabling loop on recent devices
toshiba_bluetooth: Clean up *_add function and disable BT device at removal
toshiba_bluetooth: Add three new functions to the driver
toshiba_acpi: Fix the enabling of the Special Functions
toshiba_acpi: Use the Hotkey Event Type function for keymap choosing
toshiba_acpi: Add Hotkey Event Type function and definitions
x86/wmi: delete unused wmi_data_lock mutex causing gcc warning
apple-gmux: lock iGP IO to protect from vgaarb changes
MAINTAINERS: Add missing Toshiba devices and add myself as maintainer
toshiba_acpi: Update events in toshiba_acpi_notify
intel-oaktrail: Fix trivial typo in comment
thinkpad_acpi: off by one in adaptive_keyboard_hotkey_notify_hotkey()
thinkpad_acpi: signedness bugs getting current_mode
...
Diffstat (limited to 'drivers/platform/x86/toshiba_bluetooth.c')
-rw-r--r-- | drivers/platform/x86/toshiba_bluetooth.c | 133 |
1 files changed, 104 insertions, 29 deletions
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 2cb1ea62b4a7..249800763362 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Toshiba Bluetooth Enable Driver | 2 | * Toshiba Bluetooth Enable Driver |
3 | * | 3 | * |
4 | * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com> | 4 | * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com> |
5 | * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com> | ||
5 | * | 6 | * |
6 | * Thanks to Matthew Garrett for background info on ACPI innards which | 7 | * Thanks to Matthew Garrett for background info on ACPI innards which |
7 | * normal people aren't meant to understand :-) | 8 | * normal people aren't meant to understand :-) |
@@ -25,6 +26,10 @@ | |||
25 | #include <linux/types.h> | 26 | #include <linux/types.h> |
26 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
27 | 28 | ||
29 | #define BT_KILLSWITCH_MASK 0x01 | ||
30 | #define BT_PLUGGED_MASK 0x40 | ||
31 | #define BT_POWER_MASK 0x80 | ||
32 | |||
28 | MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); | 33 | MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); |
29 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver"); | 34 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver"); |
30 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
@@ -57,32 +62,107 @@ static struct acpi_driver toshiba_bt_rfkill_driver = { | |||
57 | .drv.pm = &toshiba_bt_pm, | 62 | .drv.pm = &toshiba_bt_pm, |
58 | }; | 63 | }; |
59 | 64 | ||
65 | static int toshiba_bluetooth_present(acpi_handle handle) | ||
66 | { | ||
67 | acpi_status result; | ||
68 | u64 bt_present; | ||
69 | |||
70 | /* | ||
71 | * Some Toshiba laptops may have a fake TOS6205 device in | ||
72 | * their ACPI BIOS, so query the _STA method to see if there | ||
73 | * is really anything there. | ||
74 | */ | ||
75 | result = acpi_evaluate_integer(handle, "_STA", NULL, &bt_present); | ||
76 | if (ACPI_FAILURE(result)) { | ||
77 | pr_err("ACPI call to query Bluetooth presence failed"); | ||
78 | return -ENXIO; | ||
79 | } else if (!bt_present) { | ||
80 | pr_info("Bluetooth device not present\n"); | ||
81 | return -ENODEV; | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | static int toshiba_bluetooth_status(acpi_handle handle) | ||
88 | { | ||
89 | acpi_status result; | ||
90 | u64 status; | ||
91 | |||
92 | result = acpi_evaluate_integer(handle, "BTST", NULL, &status); | ||
93 | if (ACPI_FAILURE(result)) { | ||
94 | pr_err("Could not get Bluetooth device status\n"); | ||
95 | return -ENXIO; | ||
96 | } | ||
97 | |||
98 | pr_info("Bluetooth status %llu\n", status); | ||
99 | |||
100 | return status; | ||
101 | } | ||
60 | 102 | ||
61 | static int toshiba_bluetooth_enable(acpi_handle handle) | 103 | static int toshiba_bluetooth_enable(acpi_handle handle) |
62 | { | 104 | { |
63 | acpi_status res1, res2; | 105 | acpi_status result; |
64 | u64 result; | 106 | bool killswitch; |
107 | bool powered; | ||
108 | bool plugged; | ||
109 | int status; | ||
65 | 110 | ||
66 | /* | 111 | /* |
67 | * Query ACPI to verify RFKill switch is set to 'on'. | 112 | * Query ACPI to verify RFKill switch is set to 'on'. |
68 | * If not, we return silently, no need to report it as | 113 | * If not, we return silently, no need to report it as |
69 | * an error. | 114 | * an error. |
70 | */ | 115 | */ |
71 | res1 = acpi_evaluate_integer(handle, "BTST", NULL, &result); | 116 | status = toshiba_bluetooth_status(handle); |
72 | if (ACPI_FAILURE(res1)) | 117 | if (status < 0) |
73 | return res1; | 118 | return status; |
74 | if (!(result & 0x01)) | 119 | |
75 | return 0; | 120 | killswitch = (status & BT_KILLSWITCH_MASK) ? true : false; |
121 | powered = (status & BT_POWER_MASK) ? true : false; | ||
122 | plugged = (status & BT_PLUGGED_MASK) ? true : false; | ||
76 | 123 | ||
77 | pr_info("Re-enabling Toshiba Bluetooth\n"); | 124 | if (!killswitch) |
78 | res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL); | ||
79 | res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL); | ||
80 | if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2)) | ||
81 | return 0; | 125 | return 0; |
126 | /* | ||
127 | * This check ensures to only enable the device if it is powered | ||
128 | * off or detached, as some recent devices somehow pass the killswitch | ||
129 | * test, causing a loop enabling/disabling the device, see bug 93911. | ||
130 | */ | ||
131 | if (powered || plugged) | ||
132 | return 0; | ||
133 | |||
134 | result = acpi_evaluate_object(handle, "AUSB", NULL, NULL); | ||
135 | if (ACPI_FAILURE(result)) { | ||
136 | pr_err("Could not attach USB Bluetooth device\n"); | ||
137 | return -ENXIO; | ||
138 | } | ||
139 | |||
140 | result = acpi_evaluate_object(handle, "BTPO", NULL, NULL); | ||
141 | if (ACPI_FAILURE(result)) { | ||
142 | pr_err("Could not power ON Bluetooth device\n"); | ||
143 | return -ENXIO; | ||
144 | } | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int toshiba_bluetooth_disable(acpi_handle handle) | ||
150 | { | ||
151 | acpi_status result; | ||
152 | |||
153 | result = acpi_evaluate_object(handle, "BTPF", NULL, NULL); | ||
154 | if (ACPI_FAILURE(result)) { | ||
155 | pr_err("Could not power OFF Bluetooth device\n"); | ||
156 | return -ENXIO; | ||
157 | } | ||
82 | 158 | ||
83 | pr_warn("Failed to re-enable Toshiba Bluetooth\n"); | 159 | result = acpi_evaluate_object(handle, "DUSB", NULL, NULL); |
160 | if (ACPI_FAILURE(result)) { | ||
161 | pr_err("Could not detach USB Bluetooth device\n"); | ||
162 | return -ENXIO; | ||
163 | } | ||
84 | 164 | ||
85 | return -ENODEV; | 165 | return 0; |
86 | } | 166 | } |
87 | 167 | ||
88 | static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) | 168 | static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) |
@@ -99,23 +179,18 @@ static int toshiba_bt_resume(struct device *dev) | |||
99 | 179 | ||
100 | static int toshiba_bt_rfkill_add(struct acpi_device *device) | 180 | static int toshiba_bt_rfkill_add(struct acpi_device *device) |
101 | { | 181 | { |
102 | acpi_status status; | 182 | int result; |
103 | u64 bt_present; | ||
104 | int result = -ENODEV; | ||
105 | 183 | ||
106 | /* | 184 | result = toshiba_bluetooth_present(device->handle); |
107 | * Some Toshiba laptops may have a fake TOS6205 device in | 185 | if (result) |
108 | * their ACPI BIOS, so query the _STA method to see if there | 186 | return result; |
109 | * is really anything there, before trying to enable it. | ||
110 | */ | ||
111 | status = acpi_evaluate_integer(device->handle, "_STA", NULL, | ||
112 | &bt_present); | ||
113 | 187 | ||
114 | if (!ACPI_FAILURE(status) && bt_present) { | 188 | pr_info("Toshiba ACPI Bluetooth device driver\n"); |
115 | pr_info("Detected Toshiba ACPI Bluetooth device - " | 189 | |
116 | "installing RFKill handler\n"); | 190 | /* Enable the BT device */ |
117 | result = toshiba_bluetooth_enable(device->handle); | 191 | result = toshiba_bluetooth_enable(device->handle); |
118 | } | 192 | if (result) |
193 | return result; | ||
119 | 194 | ||
120 | return result; | 195 | return result; |
121 | } | 196 | } |
@@ -123,7 +198,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) | |||
123 | static int toshiba_bt_rfkill_remove(struct acpi_device *device) | 198 | static int toshiba_bt_rfkill_remove(struct acpi_device *device) |
124 | { | 199 | { |
125 | /* clean up */ | 200 | /* clean up */ |
126 | return 0; | 201 | return toshiba_bluetooth_disable(device->handle); |
127 | } | 202 | } |
128 | 203 | ||
129 | module_acpi_driver(toshiba_bt_rfkill_driver); | 204 | module_acpi_driver(toshiba_bt_rfkill_driver); |