diff options
author | Ike Panhc <ike.pan@canonical.com> | 2010-10-01 03:39:59 -0400 |
---|---|---|
committer | Matthew Garrett <mjg@redhat.com> | 2010-10-21 09:36:50 -0400 |
commit | fa08359ee29bd0dc52a4281d0e482fff08664b96 (patch) | |
tree | 22e3835fd6ec0e4c939e9c60a796dcccaa6efd11 /drivers | |
parent | 2b7266bd49efc84f6642cf9bb7fb37d286345d15 (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.c | 37 |
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 @@ | |||
37 | struct ideapad_private { | 37 | struct 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 | ||
42 | static struct { | 42 | static 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 | ||
163 | static 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 | } | ||
181 | static ssize_t show_ideapad_cam(struct device *dev, | 164 | static 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 | ||
223 | static struct rfkill_ops ideapad_rfk_ops = { | 209 | static 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; |