Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / platform / x86 / toshiba_bluetooth.c
1 /*
2  * Toshiba Bluetooth Enable Driver
3  *
4  * Copyright (C) 2009 Jes Sorensen <Jes.Sorensen@gmail.com>
5  * Copyright (C) 2015 Azael Avalos <coproscefalo@gmail.com>
6  *
7  * Thanks to Matthew Garrett for background info on ACPI innards which
8  * normal people aren't meant to understand :-)
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * Note the Toshiba Bluetooth RFKill switch seems to be a strange
15  * fish. It only provides a BT event when the switch is flipped to
16  * the 'on' position. When flipping it to 'off', the USB device is
17  * simply pulled away underneath us, without any BT event being
18  * delivered.
19  */
20
21 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22
23 #include <linux/kernel.h>
24 #include <linux/module.h>
25 #include <linux/init.h>
26 #include <linux/types.h>
27 #include <linux/acpi.h>
28
29 #define BT_KILLSWITCH_MASK      0x01
30 #define BT_PLUGGED_MASK         0x40
31 #define BT_POWER_MASK           0x80
32
33 MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>");
34 MODULE_DESCRIPTION("Toshiba Laptop ACPI Bluetooth Enable Driver");
35 MODULE_LICENSE("GPL");
36
37 static int toshiba_bt_rfkill_add(struct acpi_device *device);
38 static int toshiba_bt_rfkill_remove(struct acpi_device *device);
39 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event);
40
41 static const struct acpi_device_id bt_device_ids[] = {
42         { "TOS6205", 0},
43         { "", 0},
44 };
45 MODULE_DEVICE_TABLE(acpi, bt_device_ids);
46
47 #ifdef CONFIG_PM_SLEEP
48 static int toshiba_bt_resume(struct device *dev);
49 #endif
50 static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume);
51
52 static struct acpi_driver toshiba_bt_rfkill_driver = {
53         .name =         "Toshiba BT",
54         .class =        "Toshiba",
55         .ids =          bt_device_ids,
56         .ops =          {
57                                 .add =          toshiba_bt_rfkill_add,
58                                 .remove =       toshiba_bt_rfkill_remove,
59                                 .notify =       toshiba_bt_rfkill_notify,
60                         },
61         .owner =        THIS_MODULE,
62         .drv.pm =       &toshiba_bt_pm,
63 };
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 }
102
103 static int toshiba_bluetooth_enable(acpi_handle handle)
104 {
105         acpi_status result;
106         bool killswitch;
107         bool powered;
108         bool plugged;
109         int status;
110
111         /*
112          * Query ACPI to verify RFKill switch is set to 'on'.
113          * If not, we return silently, no need to report it as
114          * an error.
115          */
116         status = toshiba_bluetooth_status(handle);
117         if (status < 0)
118                 return status;
119
120         killswitch = (status & BT_KILLSWITCH_MASK) ? true : false;
121         powered = (status & BT_POWER_MASK) ? true : false;
122         plugged = (status & BT_PLUGGED_MASK) ? true : false;
123
124         if (!killswitch)
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         }
158
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         }
164
165         return 0;
166 }
167
168 static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event)
169 {
170         toshiba_bluetooth_enable(device->handle);
171 }
172
173 #ifdef CONFIG_PM_SLEEP
174 static int toshiba_bt_resume(struct device *dev)
175 {
176         return toshiba_bluetooth_enable(to_acpi_device(dev)->handle);
177 }
178 #endif
179
180 static int toshiba_bt_rfkill_add(struct acpi_device *device)
181 {
182         int result;
183
184         result = toshiba_bluetooth_present(device->handle);
185         if (result)
186                 return result;
187
188         pr_info("Toshiba ACPI Bluetooth device driver\n");
189
190         /* Enable the BT device */
191         result = toshiba_bluetooth_enable(device->handle);
192         if (result)
193                 return result;
194
195         return result;
196 }
197
198 static int toshiba_bt_rfkill_remove(struct acpi_device *device)
199 {
200         /* clean up */
201         return toshiba_bluetooth_disable(device->handle);
202 }
203
204 module_acpi_driver(toshiba_bt_rfkill_driver);