asus-wmi.c (2f686b54fbfcd82ebfb650a5c628c1b9ba8b9863) asus-wmi.c (e07babde13460d7b03842a6de8f22fbef93709e1)
1/*
2 * Asus PC WMI hotkey driver
3 *
4 * Copyright(C) 2010 Intel Corporation.
5 * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
6 *
7 * Portions based on wistron_btns.c:
8 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>

--- 25 unchanged lines hidden (view full) ---

34#include <linux/input.h>
35#include <linux/input/sparse-keymap.h>
36#include <linux/fb.h>
37#include <linux/backlight.h>
38#include <linux/leds.h>
39#include <linux/rfkill.h>
40#include <linux/pci.h>
41#include <linux/pci_hotplug.h>
1/*
2 * Asus PC WMI hotkey driver
3 *
4 * Copyright(C) 2010 Intel Corporation.
5 * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
6 *
7 * Portions based on wistron_btns.c:
8 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>

--- 25 unchanged lines hidden (view full) ---

34#include <linux/input.h>
35#include <linux/input/sparse-keymap.h>
36#include <linux/fb.h>
37#include <linux/backlight.h>
38#include <linux/leds.h>
39#include <linux/rfkill.h>
40#include <linux/pci.h>
41#include <linux/pci_hotplug.h>
42#include <linux/hwmon.h>
43#include <linux/hwmon-sysfs.h>
42#include <linux/debugfs.h>
43#include <linux/seq_file.h>
44#include <linux/platform_device.h>
45#include <acpi/acpi_bus.h>
46#include <acpi/acpi_drivers.h>
47
48#include "asus-wmi.h"
49

--- 112 unchanged lines hidden (view full) ---

162
163struct asus_wmi {
164 int dsts_id;
165 int spec;
166 int sfun;
167
168 struct input_dev *inputdev;
169 struct backlight_device *backlight_device;
44#include <linux/debugfs.h>
45#include <linux/seq_file.h>
46#include <linux/platform_device.h>
47#include <acpi/acpi_bus.h>
48#include <acpi/acpi_drivers.h>
49
50#include "asus-wmi.h"
51

--- 112 unchanged lines hidden (view full) ---

164
165struct asus_wmi {
166 int dsts_id;
167 int spec;
168 int sfun;
169
170 struct input_dev *inputdev;
171 struct backlight_device *backlight_device;
172 struct device *hwmon_device;
170 struct platform_device *platform_device;
171
172 struct led_classdev tpd_led;
173 int tpd_led_wk;
174 struct workqueue_struct *led_workqueue;
175 struct work_struct tpd_led_work;
176
177 struct asus_rfkill wlan;

--- 608 unchanged lines hidden (view full) ---

786
787 if (result == -ENODEV)
788 result = 0;
789
790 return result;
791}
792
793/*
173 struct platform_device *platform_device;
174
175 struct led_classdev tpd_led;
176 int tpd_led_wk;
177 struct workqueue_struct *led_workqueue;
178 struct work_struct tpd_led_work;
179
180 struct asus_rfkill wlan;

--- 608 unchanged lines hidden (view full) ---

789
790 if (result == -ENODEV)
791 result = 0;
792
793 return result;
794}
795
796/*
797 * Hwmon device
798 */
799static ssize_t asus_hwmon_pwm1(struct device *dev,
800 struct device_attribute *attr,
801 char *buf)
802{
803 struct asus_wmi *asus = dev_get_drvdata(dev);
804 u32 value;
805 int err;
806
807 err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
808
809 if (err < 0)
810 return err;
811
812 value |= 0xFF;
813
814 if (value == 1) /* Low Speed */
815 value = 85;
816 else if (value == 2)
817 value = 170;
818 else if (value == 3)
819 value = 255;
820 else if (value != 0) {
821 pr_err("Unknown fan speed %#x", value);
822 value = -1;
823 }
824
825 return sprintf(buf, "%d\n", value);
826}
827
828static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0);
829
830static ssize_t
831show_name(struct device *dev, struct device_attribute *attr, char *buf)
832{
833 return sprintf(buf, "asus\n");
834}
835static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
836
837static struct attribute *hwmon_attributes[] = {
838 &sensor_dev_attr_pwm1.dev_attr.attr,
839 &sensor_dev_attr_name.dev_attr.attr,
840 NULL
841};
842
843static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
844 struct attribute *attr, int idx)
845{
846 struct device *dev = container_of(kobj, struct device, kobj);
847 struct platform_device *pdev = to_platform_device(dev->parent);
848 struct asus_wmi *asus = platform_get_drvdata(pdev);
849 bool ok = true;
850 int dev_id = -1;
851 u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
852
853 if (attr == &sensor_dev_attr_pwm1.dev_attr.attr)
854 dev_id = ASUS_WMI_DEVID_FAN_CTRL;
855
856 if (dev_id != -1) {
857 int err = asus_wmi_get_devstate(asus, dev_id, &value);
858
859 if (err < 0)
860 return err;
861 }
862
863 if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
864 /*
865 * We need to find a better way, probably using sfun,
866 * bits or spec ...
867 * Currently we disable it if:
868 * - ASUS_WMI_UNSUPPORTED_METHOD is returned
869 * - reverved bits are non-zero
870 * - sfun and presence bit are not set
871 */
872 if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
873 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
874 ok = false;
875 }
876
877 return ok ? attr->mode : 0;
878}
879
880static struct attribute_group hwmon_attribute_group = {
881 .is_visible = asus_hwmon_sysfs_is_visible,
882 .attrs = hwmon_attributes
883};
884
885static void asus_wmi_hwmon_exit(struct asus_wmi *asus)
886{
887 struct device *hwmon;
888
889 hwmon = asus->hwmon_device;
890 if (!hwmon)
891 return;
892 sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group);
893 hwmon_device_unregister(hwmon);
894 asus->hwmon_device = NULL;
895}
896
897static int asus_wmi_hwmon_init(struct asus_wmi *asus)
898{
899 struct device *hwmon;
900 int result;
901
902 hwmon = hwmon_device_register(&asus->platform_device->dev);
903 if (IS_ERR(hwmon)) {
904 pr_err("Could not register asus hwmon device\n");
905 return PTR_ERR(hwmon);
906 }
907 asus->hwmon_device = hwmon;
908 result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group);
909 if (result)
910 asus_wmi_hwmon_exit(asus);
911 return result;
912}
913
914/*
794 * Backlight
795 */
796static int read_backlight_power(struct asus_wmi *asus)
797{
798 int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT);
799
800 if (ret < 0)
801 return ret;

--- 524 unchanged lines hidden (view full) ---

1326 err = asus_wmi_platform_init(asus);
1327 if (err)
1328 goto fail_platform;
1329
1330 err = asus_wmi_input_init(asus);
1331 if (err)
1332 goto fail_input;
1333
915 * Backlight
916 */
917static int read_backlight_power(struct asus_wmi *asus)
918{
919 int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT);
920
921 if (ret < 0)
922 return ret;

--- 524 unchanged lines hidden (view full) ---

1447 err = asus_wmi_platform_init(asus);
1448 if (err)
1449 goto fail_platform;
1450
1451 err = asus_wmi_input_init(asus);
1452 if (err)
1453 goto fail_input;
1454
1455 err = asus_wmi_hwmon_init(asus);
1456 if (err)
1457 goto fail_hwmon;
1458
1334 err = asus_wmi_led_init(asus);
1335 if (err)
1336 goto fail_leds;
1337
1338 err = asus_wmi_rfkill_init(asus);
1339 if (err)
1340 goto fail_rfkill;
1341

--- 22 unchanged lines hidden (view full) ---

1364 wmi_remove_notify_handler(asus->driver->event_guid);
1365fail_wmi_handler:
1366 asus_wmi_backlight_exit(asus);
1367fail_backlight:
1368 asus_wmi_rfkill_exit(asus);
1369fail_rfkill:
1370 asus_wmi_led_exit(asus);
1371fail_leds:
1459 err = asus_wmi_led_init(asus);
1460 if (err)
1461 goto fail_leds;
1462
1463 err = asus_wmi_rfkill_init(asus);
1464 if (err)
1465 goto fail_rfkill;
1466

--- 22 unchanged lines hidden (view full) ---

1489 wmi_remove_notify_handler(asus->driver->event_guid);
1490fail_wmi_handler:
1491 asus_wmi_backlight_exit(asus);
1492fail_backlight:
1493 asus_wmi_rfkill_exit(asus);
1494fail_rfkill:
1495 asus_wmi_led_exit(asus);
1496fail_leds:
1497 asus_wmi_hwmon_exit(asus);
1498fail_hwmon:
1372 asus_wmi_input_exit(asus);
1373fail_input:
1374 asus_wmi_platform_exit(asus);
1375fail_platform:
1376 kfree(asus);
1377 return err;
1378}
1379
1380static int asus_wmi_remove(struct platform_device *device)
1381{
1382 struct asus_wmi *asus;
1383
1384 asus = platform_get_drvdata(device);
1385 wmi_remove_notify_handler(asus->driver->event_guid);
1386 asus_wmi_backlight_exit(asus);
1387 asus_wmi_input_exit(asus);
1499 asus_wmi_input_exit(asus);
1500fail_input:
1501 asus_wmi_platform_exit(asus);
1502fail_platform:
1503 kfree(asus);
1504 return err;
1505}
1506
1507static int asus_wmi_remove(struct platform_device *device)
1508{
1509 struct asus_wmi *asus;
1510
1511 asus = platform_get_drvdata(device);
1512 wmi_remove_notify_handler(asus->driver->event_guid);
1513 asus_wmi_backlight_exit(asus);
1514 asus_wmi_input_exit(asus);
1515 asus_wmi_hwmon_exit(asus);
1388 asus_wmi_led_exit(asus);
1389 asus_wmi_rfkill_exit(asus);
1390 asus_wmi_debugfs_exit(asus);
1391 asus_wmi_platform_exit(asus);
1392
1393 kfree(asus);
1394 return 0;
1395}

--- 132 unchanged lines hidden ---
1516 asus_wmi_led_exit(asus);
1517 asus_wmi_rfkill_exit(asus);
1518 asus_wmi_debugfs_exit(asus);
1519 asus_wmi_platform_exit(asus);
1520
1521 kfree(asus);
1522 return 0;
1523}

--- 132 unchanged lines hidden ---