aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/platform/x86/ideapad-laptop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/ideapad-laptop.c')
-rw-r--r--drivers/platform/x86/ideapad-laptop.c43
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 7bc1b6c60e56..dae7abe1d711 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -64,8 +64,10 @@ enum {
64 VPCCMD_R_3G, 64 VPCCMD_R_3G,
65 VPCCMD_W_3G, 65 VPCCMD_W_3G,
66 VPCCMD_R_ODD, /* 0x21 */ 66 VPCCMD_R_ODD, /* 0x21 */
67 VPCCMD_R_RF = 0x23, 67 VPCCMD_W_FAN,
68 VPCCMD_R_RF,
68 VPCCMD_W_RF, 69 VPCCMD_W_RF,
70 VPCCMD_R_FAN = 0x2B,
69 VPCCMD_R_SPECIAL_BUTTONS = 0x31, 71 VPCCMD_R_SPECIAL_BUTTONS = 0x31,
70 VPCCMD_W_BL_POWER = 0x33, 72 VPCCMD_W_BL_POWER = 0x33,
71}; 73};
@@ -358,14 +360,46 @@ static ssize_t store_ideapad_cam(struct device *dev,
358 return -EINVAL; 360 return -EINVAL;
359 ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); 361 ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state);
360 if (ret < 0) 362 if (ret < 0)
361 return ret; 363 return -EIO;
362 return count; 364 return count;
363} 365}
364 366
365static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); 367static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam);
366 368
369static ssize_t show_ideapad_fan(struct device *dev,
370 struct device_attribute *attr,
371 char *buf)
372{
373 unsigned long result;
374
375 if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result))
376 return sprintf(buf, "-1\n");
377 return sprintf(buf, "%lu\n", result);
378}
379
380static ssize_t store_ideapad_fan(struct device *dev,
381 struct device_attribute *attr,
382 const char *buf, size_t count)
383{
384 int ret, state;
385
386 if (!count)
387 return 0;
388 if (sscanf(buf, "%i", &state) != 1)
389 return -EINVAL;
390 if (state < 0 || state > 4 || state == 3)
391 return -EINVAL;
392 ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state);
393 if (ret < 0)
394 return -EIO;
395 return count;
396}
397
398static DEVICE_ATTR(fan_mode, 0644, show_ideapad_fan, store_ideapad_fan);
399
367static struct attribute *ideapad_attributes[] = { 400static struct attribute *ideapad_attributes[] = {
368 &dev_attr_camera_power.attr, 401 &dev_attr_camera_power.attr,
402 &dev_attr_fan_mode.attr,
369 NULL 403 NULL
370}; 404};
371 405
@@ -379,7 +413,10 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
379 413
380 if (attr == &dev_attr_camera_power.attr) 414 if (attr == &dev_attr_camera_power.attr)
381 supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); 415 supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg));
382 else 416 else if (attr == &dev_attr_fan_mode.attr) {
417 unsigned long value;
418 supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value);
419 } else
383 supported = true; 420 supported = true;
384 421
385 return supported ? attr->mode : 0; 422 return supported ? attr->mode : 0;