aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorIke Panhc <ike.pan@canonical.com>2010-10-01 03:39:59 -0400
committerMatthew Garrett <mjg@redhat.com>2010-10-21 09:36:50 -0400
commitfa08359ee29bd0dc52a4281d0e482fff08664b96 (patch)
tree22e3835fd6ec0e4c939e9c60a796dcccaa6efd11 /drivers
parent2b7266bd49efc84f6642cf9bb7fb37d286345d15 (diff)
ideapad: rewrite the sw rfkill set
Control power of rf modules by ec commands Signed-off-by: Ike Panhc <ike.pan@canonical.com> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/ideapad_acpi.c37
1 files changed, 12 insertions, 25 deletions
diff --git a/drivers/platform/x86/ideapad_acpi.c b/drivers/platform/x86/ideapad_acpi.c
index 09f6ce6b378d..e9f7395efc3a 100644
--- a/drivers/platform/x86/ideapad_acpi.c
+++ b/drivers/platform/x86/ideapad_acpi.c
@@ -37,18 +37,19 @@
37struct ideapad_private { 37struct ideapad_private {
38 acpi_handle handle; 38 acpi_handle handle;
39 struct rfkill *rfk[5]; 39 struct rfkill *rfk[5];
40}; 40} *ideapad_priv;
41 41
42static struct { 42static struct {
43 char *name; 43 char *name;
44 int cfgbit; 44 int cfgbit;
45 int opcode;
45 int type; 46 int type;
46} ideapad_rfk_data[] = { 47} ideapad_rfk_data[] = {
47 { "ideapad_camera", 19, NUM_RFKILL_TYPES }, 48 { "ideapad_camera", 19, 0x1E, NUM_RFKILL_TYPES },
48 { "ideapad_wlan", 18, RFKILL_TYPE_WLAN }, 49 { "ideapad_wlan", 18, 0x15, RFKILL_TYPE_WLAN },
49 { "ideapad_bluetooth", 16, RFKILL_TYPE_BLUETOOTH }, 50 { "ideapad_bluetooth", 16, 0x17, RFKILL_TYPE_BLUETOOTH },
50 { "ideapad_3g", 17, RFKILL_TYPE_WWAN }, 51 { "ideapad_3g", 17, 0x20, RFKILL_TYPE_WWAN },
51 { "ideapad_killsw", 0, RFKILL_TYPE_WLAN } 52 { "ideapad_killsw", 0, 0, RFKILL_TYPE_WLAN }
52}; 53};
53 54
54/* 55/*
@@ -160,24 +161,6 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data)
160} 161}
161/* the above is ACPI helpers */ 162/* the above is ACPI helpers */
162 163
163static int ideapad_dev_set_state(int device, int state)
164{
165 acpi_status status;
166 union acpi_object in_params[2];
167 struct acpi_object_list input = { 2, in_params };
168
169 in_params[0].type = ACPI_TYPE_INTEGER;
170 in_params[0].integer.value = device + 1;
171 in_params[1].type = ACPI_TYPE_INTEGER;
172 in_params[1].integer.value = state;
173
174 status = acpi_evaluate_object(NULL, "\\_SB_.SECN", &input, NULL);
175 if (ACPI_FAILURE(status)) {
176 printk(KERN_WARNING "IdeaPAD \\_SB_.SECN method failed %d\n", status);
177 return -ENODEV;
178 }
179 return 0;
180}
181static ssize_t show_ideapad_cam(struct device *dev, 164static ssize_t show_ideapad_cam(struct device *dev,
182 struct device_attribute *attr, 165 struct device_attribute *attr,
183 char *buf) 166 char *buf)
@@ -217,7 +200,10 @@ static int ideapad_rfk_set(void *data, bool blocked)
217 200
218 if (device == IDEAPAD_DEV_KILLSW) 201 if (device == IDEAPAD_DEV_KILLSW)
219 return -EINVAL; 202 return -EINVAL;
220 return ideapad_dev_set_state(device, !blocked); 203
204 return write_ec_cmd(ideapad_priv->handle,
205 ideapad_rfk_data[device].opcode,
206 !blocked);
221} 207}
222 208
223static struct rfkill_ops ideapad_rfk_ops = { 209static struct rfkill_ops ideapad_rfk_ops = {
@@ -318,6 +304,7 @@ static int ideapad_acpi_add(struct acpi_device *adevice)
318 304
319 priv->handle = adevice->handle; 305 priv->handle = adevice->handle;
320 dev_set_drvdata(&adevice->dev, priv); 306 dev_set_drvdata(&adevice->dev, priv);
307 ideapad_priv = priv;
321 for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) { 308 for (i = IDEAPAD_DEV_WLAN; i <= IDEAPAD_DEV_KILLSW; i++) {
322 if (!devs_present[i]) 309 if (!devs_present[i])
323 continue; 310 continue;