aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMario Limonciello <Mario_Limonciello@Dell.com>2009-08-25 11:30:13 -0400
committerMatthew Garrett <mjg@redhat.com>2010-02-25 11:50:40 -0500
commit493e91433e966a50964e221db92756eeb90dd54e (patch)
treed9de18019429a82f5e38339ff56937d0706a0874 /drivers
parent34325b9d2a7d36e2ba74a6652f2e3e8d57dfb145 (diff)
compal-laptop: Replace sysfs support with rfkill support
This drops the support for manually groking the files in sysfs to turn on and off the WLAN and BT for Compal laptops in favor of platform rfkill support. It has been combined into a single patch to not introduce regressions in the process of simply adding rfkill support Signed-off-by: Mario Limonciello <Mario_Limonciello@Dell.com> Signed-off-by: Tim Gardner <tim.gardner@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com> Cc: Cezary Jackiewicz <cezary.jackiewicz@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/compal-laptop.c201
1 files changed, 63 insertions, 138 deletions
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index c78d254303bc..2740b40aad9b 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -26,17 +26,8 @@
26/* 26/*
27 * comapl-laptop.c - Compal laptop support. 27 * comapl-laptop.c - Compal laptop support.
28 * 28 *
29 * This driver exports a few files in /sys/devices/platform/compal-laptop/: 29 * The driver registers itself with the rfkill subsystem and
30 * 30 * the Linux backlight control subsystem.
31 * wlan - wlan subsystem state: contains 0 or 1 (rw)
32 *
33 * bluetooth - Bluetooth subsystem state: contains 0 or 1 (rw)
34 *
35 * raw - raw value taken from embedded controller register (ro)
36 *
37 * In addition to these platform device attributes the driver
38 * registers itself in the Linux backlight control subsystem and is
39 * available to userspace under /sys/class/backlight/compal-laptop/.
40 * 31 *
41 * This driver might work on other laptops produced by Compal. If you 32 * This driver might work on other laptops produced by Compal. If you
42 * want to try it you can pass force=1 as argument to the module which 33 * want to try it you can pass force=1 as argument to the module which
@@ -51,6 +42,7 @@
51#include <linux/dmi.h> 42#include <linux/dmi.h>
52#include <linux/backlight.h> 43#include <linux/backlight.h>
53#include <linux/platform_device.h> 44#include <linux/platform_device.h>
45#include <linux/rfkill.h>
54 46
55#define COMPAL_DRIVER_VERSION "0.2.6" 47#define COMPAL_DRIVER_VERSION "0.2.6"
56 48
@@ -63,6 +55,10 @@
63#define WLAN_MASK 0x01 55#define WLAN_MASK 0x01
64#define BT_MASK 0x02 56#define BT_MASK 0x02
65 57
58static struct rfkill *wifi_rfkill;
59static struct rfkill *bt_rfkill;
60static struct platform_device *compal_device;
61
66static int force; 62static int force;
67module_param(force, bool, 0); 63module_param(force, bool, 0);
68MODULE_PARM_DESC(force, "Force driver load, ignore DMI data"); 64MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -88,65 +84,75 @@ static int get_lcd_level(void)
88 return (int) result; 84 return (int) result;
89} 85}
90 86
91static int set_wlan_state(int state) 87static int compal_rfkill_set(void *data, bool blocked)
92{ 88{
89 unsigned long radio = (unsigned long) data;
93 u8 result, value; 90 u8 result, value;
94 91
95 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 92 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
96 93
97 if ((result & KILLSWITCH_MASK) == 0) 94 if (!blocked)
98 return -EINVAL; 95 value = (u8) (result | radio);
99 else { 96 else
100 if (state) 97 value = (u8) (result & ~radio);
101 value = (u8) (result | WLAN_MASK); 98 ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
102 else
103 value = (u8) (result & ~WLAN_MASK);
104 ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
105 }
106 99
107 return 0; 100 return 0;
108} 101}
109 102
110static int set_bluetooth_state(int state) 103static void compal_rfkill_poll(struct rfkill *rfkill, void *data)
111{ 104{
112 u8 result, value; 105 u8 result;
106 bool hw_blocked;
113 107
114 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 108 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
115 109
116 if ((result & KILLSWITCH_MASK) == 0) 110 hw_blocked = !(result & KILLSWITCH_MASK);
117 return -EINVAL; 111 rfkill_set_hw_state(rfkill, hw_blocked);
118 else {
119 if (state)
120 value = (u8) (result | BT_MASK);
121 else
122 value = (u8) (result & ~BT_MASK);
123 ec_write(COMPAL_EC_COMMAND_WIRELESS, value);
124 }
125
126 return 0;
127} 112}
128 113
129static int get_wireless_state(int *wlan, int *bluetooth) 114static const struct rfkill_ops compal_rfkill_ops = {
115 .poll = compal_rfkill_poll,
116 .set_block = compal_rfkill_set,
117};
118
119static int setup_rfkill(void)
130{ 120{
131 u8 result; 121 int ret;
132 122
133 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result); 123 wifi_rfkill = rfkill_alloc("compal-wifi", &compal_device->dev,
124 RFKILL_TYPE_WLAN, &compal_rfkill_ops,
125 (void *) WLAN_MASK);
126 if (!wifi_rfkill)
127 return -ENOMEM;
134 128
135 if (wlan) { 129 ret = rfkill_register(wifi_rfkill);
136 if ((result & KILLSWITCH_MASK) == 0) 130 if (ret)
137 *wlan = 0; 131 goto err_wifi;
138 else
139 *wlan = result & WLAN_MASK;
140 }
141 132
142 if (bluetooth) { 133 bt_rfkill = rfkill_alloc("compal-bluetooth", &compal_device->dev,
143 if ((result & KILLSWITCH_MASK) == 0) 134 RFKILL_TYPE_BLUETOOTH, &compal_rfkill_ops,
144 *bluetooth = 0; 135 (void *) BT_MASK);
145 else 136 if (!bt_rfkill) {
146 *bluetooth = (result & BT_MASK) >> 1; 137 ret = -ENOMEM;
138 goto err_allocate_bt;
147 } 139 }
140 ret = rfkill_register(bt_rfkill);
141 if (ret)
142 goto err_register_bt;
148 143
149 return 0; 144 return 0;
145
146err_register_bt:
147 rfkill_destroy(bt_rfkill);
148
149err_allocate_bt:
150 rfkill_unregister(wifi_rfkill);
151
152err_wifi:
153 rfkill_destroy(wifi_rfkill);
154
155 return ret;
150} 156}
151 157
152/* Backlight device stuff */ 158/* Backlight device stuff */
@@ -169,86 +175,6 @@ static struct backlight_ops compalbl_ops = {
169 175
170static struct backlight_device *compalbl_device; 176static struct backlight_device *compalbl_device;
171 177
172/* Platform device */
173
174static ssize_t show_wlan(struct device *dev,
175 struct device_attribute *attr, char *buf)
176{
177 int ret, enabled;
178
179 ret = get_wireless_state(&enabled, NULL);
180 if (ret < 0)
181 return ret;
182
183 return sprintf(buf, "%i\n", enabled);
184}
185
186static ssize_t show_raw(struct device *dev,
187 struct device_attribute *attr, char *buf)
188{
189 u8 result;
190
191 ec_read(COMPAL_EC_COMMAND_WIRELESS, &result);
192
193 return sprintf(buf, "%i\n", result);
194}
195
196static ssize_t show_bluetooth(struct device *dev,
197 struct device_attribute *attr, char *buf)
198{
199 int ret, enabled;
200
201 ret = get_wireless_state(NULL, &enabled);
202 if (ret < 0)
203 return ret;
204
205 return sprintf(buf, "%i\n", enabled);
206}
207
208static ssize_t store_wlan_state(struct device *dev,
209 struct device_attribute *attr, const char *buf, size_t count)
210{
211 int state, ret;
212
213 if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
214 return -EINVAL;
215
216 ret = set_wlan_state(state);
217 if (ret < 0)
218 return ret;
219
220 return count;
221}
222
223static ssize_t store_bluetooth_state(struct device *dev,
224 struct device_attribute *attr, const char *buf, size_t count)
225{
226 int state, ret;
227
228 if (sscanf(buf, "%i", &state) != 1 || (state < 0 || state > 1))
229 return -EINVAL;
230
231 ret = set_bluetooth_state(state);
232 if (ret < 0)
233 return ret;
234
235 return count;
236}
237
238static DEVICE_ATTR(bluetooth, 0644, show_bluetooth, store_bluetooth_state);
239static DEVICE_ATTR(wlan, 0644, show_wlan, store_wlan_state);
240static DEVICE_ATTR(raw, 0444, show_raw, NULL);
241
242static struct attribute *compal_attributes[] = {
243 &dev_attr_bluetooth.attr,
244 &dev_attr_wlan.attr,
245 &dev_attr_raw.attr,
246 NULL
247};
248
249static struct attribute_group compal_attribute_group = {
250 .attrs = compal_attributes
251};
252 178
253static struct platform_driver compal_driver = { 179static struct platform_driver compal_driver = {
254 .driver = { 180 .driver = {
@@ -257,8 +183,6 @@ static struct platform_driver compal_driver = {
257 } 183 }
258}; 184};
259 185
260static struct platform_device *compal_device;
261
262/* Initialization */ 186/* Initialization */
263 187
264static int dmi_check_cb(const struct dmi_system_id *id) 188static int dmi_check_cb(const struct dmi_system_id *id)
@@ -389,23 +313,21 @@ static int __init compal_init(void)
389 313
390 ret = platform_device_add(compal_device); 314 ret = platform_device_add(compal_device);
391 if (ret) 315 if (ret)
392 goto fail_platform_device1; 316 goto fail_platform_device;
393 317
394 ret = sysfs_create_group(&compal_device->dev.kobj, 318 ret = setup_rfkill();
395 &compal_attribute_group);
396 if (ret) 319 if (ret)
397 goto fail_platform_device2; 320 goto fail_rfkill;
398 321
399 printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION 322 printk(KERN_INFO "compal-laptop: driver "COMPAL_DRIVER_VERSION
400 " successfully loaded.\n"); 323 " successfully loaded.\n");
401 324
402 return 0; 325 return 0;
403 326
404fail_platform_device2: 327fail_rfkill:
405
406 platform_device_del(compal_device); 328 platform_device_del(compal_device);
407 329
408fail_platform_device1: 330fail_platform_device:
409 331
410 platform_device_put(compal_device); 332 platform_device_put(compal_device);
411 333
@@ -423,10 +345,13 @@ fail_backlight:
423static void __exit compal_cleanup(void) 345static void __exit compal_cleanup(void)
424{ 346{
425 347
426 sysfs_remove_group(&compal_device->dev.kobj, &compal_attribute_group);
427 platform_device_unregister(compal_device); 348 platform_device_unregister(compal_device);
428 platform_driver_unregister(&compal_driver); 349 platform_driver_unregister(&compal_driver);
429 backlight_device_unregister(compalbl_device); 350 backlight_device_unregister(compalbl_device);
351 rfkill_unregister(wifi_rfkill);
352 rfkill_destroy(wifi_rfkill);
353 rfkill_unregister(bt_rfkill);
354 rfkill_destroy(bt_rfkill);
430 355
431 printk(KERN_INFO "compal-laptop: driver unloaded.\n"); 356 printk(KERN_INFO "compal-laptop: driver unloaded.\n");
432} 357}